Skip to main content
austane
Participant
August 21, 2018
Answered

How do I add a hitbox/hitTestObject to my vehicle to nock a ball when they touch?

  • August 21, 2018
  • 2 replies
  • 1120 views

Hi Guys and Girls

I have been creating a game for a school project for the last few days and ran into a large problem. I don't know how to add a hitbox to my vehicles. So the game is called GO41 (cringy, i know) and it is a top down view multi-player game where the aim is to nock the ball into the other persons goal. The vehicles move using WASD and the arrow keys. Here is what it looks like at the moment.

The vehicle on the on the left is called Helicopter_Red and the vehicle on the right is called Quadcopter_Blue. Can anyone please help me out, I am completely stuck.

Thanks for Reading and hopefully you can help!

Austin

This topic has been closed for replies.
Correct answer kglad

your ball needs to be a movieclip (eg, ball_mc) too.  you can then use

Helicopter_red.hitTestObject(ball_mc)

though you may not be happy with the bounding box issues.

2 replies

JoãoCésar17023019
Community Expert
Community Expert
August 22, 2018

Hi.

Here is a very simple soccer game prototype just for fun.

I didn't use external class files, very extensive OOP techiniques, frameworks, or anything like that. Everything inside of Animate so it can be easier for beginners.

Just don't laugh at the players running. Haha

Preview:

AS3 code:

import flash.events.Event;

import flash.events.KeyboardEvent;

import flash.ui.Keyboard;

import flash.display.DisplayObjectContainer;

import flash.utils.getTimer;

import flash.utils.setTimeout;

import flash.utils.clearTimeout;

var fieldScale:Number = 1.5;

var pauseDelay:Number = 2;

var screenOffsetX:Number = 100;

var screenOffsetY:Number = 100;

var isPaused:Boolean = false;

var noKeys:Boolean = false;

var startTime:uint = 0;

var delta:Number;

var timeout:uint = 0;

var didGoal:Boolean = false;

var gamepad:Array =

[

     {

          keys:

          {

               up:Keyboard.W,

               left:Keyboard.A,

               down:Keyboard.S,

               right:Keyboard.D,

               kick:Keyboard.SPACE

          },

          states:

          {

               up:false,

               left:false,

               down:false,

               right:false,

               kick:false

          }

     },

     {

          keys:

          {

               up:Keyboard.UP,

               left:Keyboard.LEFT,

               down:Keyboard.DOWN,

               right:Keyboard.RIGHT,

               kick:Keyboard.SPACE

          },

          states:

          {

               up:false,

               left:false,

               down:false,

               right:false,

               kick:false

          }

     }

];

var cam:Object =

{

     target:camera

};

var world:Object =

{

     FRICTION:0.85

};

var ball:Object =

{

     target:cam.target.ball,

     speedX:0,

     speedY:0,

     maxSpeedX:10000,

     maxSpeedY:10000,

     idleSpeedX:2,

     idleSpeedY:2,

     collisionEdge:""

}

var teams:Array =

[

     {

          target:cam.target.player00,

          score:0,

          initialX:cam.target.player00.x,

          initialY:cam.target.player00.y,

          initialRotation:cam.target.player00.rotation,

          speedX:0,

          speedY:0,

          maxSpeedX:200,

          maxSpeedY:200,

          idleSpeedX:2,

          idleSpeedY:2,

          forceX:30,

          forceY:30,

          kickForce:2000,

          collisionEdge:"",

          states:

          {

               idle:"idle",

               running:"running"

          },

          keys:

          {

               up:gamepad[0].keys.up,

               left:gamepad[0].keys.left,

               down:gamepad[0].keys.down,

               right:gamepad[0].keys.right,

               kick:gamepad[0].keys.kick

          }

     },

     {

          target:cam.target.player10,

          initialX:cam.target.player10.x,

          initialY:cam.target.player10.y,

          initialRotation:cam.target.player10.rotation,

          score:0,

          speedX:0,

          speedY:0,

          maxSpeedX:200,

          maxSpeedY:200,

          idleSpeedX:2,

          idleSpeedY:2,

          forceX:30,

          forceY:30,

          kickForce:2000,

          collisionEdge:"",

          states:

          {

               idle:"idle",

               running:"running"

          },

          keys:

          {

               up:gamepad[1].keys.up,

               left:gamepad[1].keys.left,

               down:gamepad[1].keys.down,

               right:gamepad[1].keys.right,

               kick:gamepad[1].keys.kick

          }

     }

];

var leftGoal:Object =

{

     target:camera.field.leftGoal,

     collisionEdge:""

}

var rightGoal:Object =

{

     target:camera.field.rightGoal,

     collisionEdge:""

}

function keyHandler(e:KeyboardEvent):void

{

     if (noKeys)

          return;

     if (e.type == KeyboardEvent.KEY_DOWN)

          checkKeys(e, true);

     else if (e.type == KeyboardEvent.KEY_UP)

          checkKeys(e, false);

}

function checkKeys(e:KeyboardEvent, state:Boolean = true):void

{

     for (var i:int = 0, total:int = gamepad.length; i < total; i++)

     {

          for (var key in gamepad.keys)

               if (e.keyCode == gamepad.keys[key])

                    gamepad.states[key] = state;

     }

}

function setKeyForce(gamepad:Object, obj:Object, dir0:String = "left", dir1:String = "right", speed:String = "speedX", force:String = "forceX"):void

{

     if (gamepad.states[dir0])

          obj[speed] -= obj[force];

     else if (gamepad.states[dir1])

          obj[speed] += obj[force];

}

function enterFrameHandler(e:Event):void

{

     if (isPaused)

          return;

     var currentTime:uint = getTimer();

     delta = (currentTime - startTime) / 1000;

     startTime = currentTime;

     for (var i:int = 0, total:int = teams.length; i < total; i++)

     {

          setKeyForce(gamepad, teams, "left", "right", "speedX", "forceX");

          setKeyForce(gamepad, teams, "up", "down", "speedY", "forceY");

          move(teams, world, "x", "speedX", "maxSpeedX");

          move(teams, world, "y", "speedY", "maxSpeedY");

          rotate(teams);

          setStates(teams);

          if (checkCollision(teams, ball))

          {

               ball.speedX += teams.speedX * 0.5;

               ball.speedY += teams.speedY * 0.5;

               if (gamepad.states.kick)

               {

                    if (gamepad.states.left)

                         ball.speedX -= teams.kickForce;

                    else if (gamepad.states.right)

                         ball.speedX += teams.kickForce;

                    if (gamepad.states.up)

                         ball.speedY -= teams.kickForce;

                    else if (gamepad.states.down)

                         ball.speedY += teams.kickForce;

               }

          }

     }

     ball.target.rotation += ball.speedX * 0.1;

     ball.target.rotation += ball.speedY * 0.1;

     move(ball, world, "x", "speedX", "maxSpeedX");

     move(ball, world, "y", "speedY", "maxSpeedY");

     screenBounds([ball]);

     depthSort(cam.target, "y", [cam.target.field, ball.target]);

     moveCam(ball);

     if (!didGoal && checkCollision(ball, leftGoal, {left:true, top:true, bottom:true}) && leftGoal.collisionEdge == "right")

          onGoal(1);

     else if (!didGoal && checkCollision(ball, rightGoal, {right:true, top:true, bottom:true}) && rightGoal.collisionEdge == "left")

          onGoal(0);

}

function moveCam(obj:Object):void

{

     cam.target.x = -obj.target.x * fieldScale + stage.stageWidth * 0.5;

     cam.target.y = -obj.target.y * fieldScale + stage.stageHeight * 0.5;

}

function screenBounds(array:Array):void

{

     for (var i:int = 0, total:int = array.length; i < total; i++)

     {

          array.target.x = clamp(array.target.x, -stage.stageWidth * 0.5 - screenOffsetX, stage.stageWidth * 0.5 + screenOffsetX);

          array.target.y = clamp(array.target.y, -stage.stageHeight * 0.5 - screenOffsetY, stage.stageHeight * 0.5 + screenOffsetY);

     }

}

function move(obj:Object, world:Object, axis:String = "x", speed:String = "speedX", maxSpeed:String = "maxSpeedX"):void

{

     obj[speed] *= world.FRICTION;

     obj[speed] = clamp(obj[speed], -obj[maxSpeed], obj[maxSpeed]);

     obj["target"][axis] += int(obj[speed]) * delta;

}

function rotate(obj:Object):void

{

     obj["target"].rotation = Math.atan2(obj["speedY"], obj["speedX"]) * 180 / Math.PI;

}

function setStates(obj:Object):void

{

     if (Math.abs(obj["speedX"]) > obj["idleSpeedX"] || Math.abs(obj["speedY"]) > obj["idleSpeedY"])

     {

          obj["target"].gotoAndStop(obj["states"]["running"]);

          obj["target"]["anim"].play();

     }

     else

          obj["target"].gotoAndStop(obj["states"]["idle"]);

}

function onGoal(teamIndex:uint):void

{

     didGoal = true;

     teams[teamIndex].score++;

     scoreText.text = teams[0].score + " X " + teams[1].score;

     goalMessage.gotoAndPlay(2);

     clearTimeout(timeout);

     timeout = setTimeout(function():void

     {

          ball.target.x = 0;

          ball.target.y = 0;

          leftGoal.collisionEdge = "";

          rightGoal.collisionEdge = "";

          for (var i:int = 0, total:int = teams.length; i < total; i++)

          {

               teams.target.x = teams.initialX;

               teams.target.y = teams.initialY;

               teams.target.rotation = teams.initialRotation;

          }

          didGoal = false;

     }, pauseDelay * 1000);

}

function checkCollision(p:Object, obstacle:Object, block:Object = null):Boolean

{

     if (!block)

          block = {left:true, right:true, top:true, bottom:true};

     if (p.target.hitTestObject(obstacle.target))

     {

          if (p.target.x < obstacle.target.x - obstacle.target.width * 0.5 || p.target.x > obstacle.target.x + obstacle.target.width * 0.5)

          {

               if (p.target.x <= obstacle.target.x)

               {

                    if (block.left)

                         p.target.x = obstacle.target.x - p.target.width * 0.5 - obstacle.target.width * 0.5;

                    p.collisionEdge = "right";

                    obstacle.collisionEdge = "left";

                    return true;

               }

               else if (p.target.x > obstacle.target.x)

               {

                    if (block.right)

                         p.target.x = obstacle.target.x + p.target.width * 0.5 + obstacle.target.width * 0.5;

                    p.collisionEdge = "left";

                    obstacle.collisionEdge = "right";

                    return true;

               }

          }

          else if (p.target.y < obstacle.target.y - obstacle.target.height * 0.5 || p.target.y > obstacle.target.y + obstacle.target.height * 0.5)

          {

               if (p.target.y <= obstacle.target.y)

               {

                    if (block.top)

                         p.target.y = obstacle.target.y - p.target.height * 0.5 - obstacle.target.height * 0.5;

                    p.collisionEdge = "bottom";

                    obstacle.collisionEdge = "top";

                    return true;

               }

               else if (p.target.y > obstacle.target.y)

               {

                    if (block.bottom)

                         p.target.y = obstacle.target.y + p.target.height * 0.5 + obstacle.target.height * 0.5;

                    p.collisionEdge = "top";

                    obstacle.collisionEdge = "bottom";

                    return true;

               }

          }

          return false;

     }

     else

          return false;

}

function depthSort(container:DisplayObjectContainer, axis:String = "y", exceptions:Array = null):void

{

     var array:Array = [];

     var i:int, total:int;

     var count:uint = 0;

     for (i = 0, total = container.numChildren; i < total; i++)

     {

          if (exceptions && exceptions.indexOf(container.getChildAt(i)) > -1)

               continue;

          array[count] = container.getChildAt(i);

          count++;

     }

     array.sortOn(axis, Array.NUMERIC);

     for (i = 0, total = array.length; i < total; i++)

          container.addChild(array);

}

function clamp(value:Number, min:Number, max:Number):Number

{

     if (value < min)

          return min;

     if (value > max)

          return max;

     else

          return value;

}

function start():void

{

     cam.target.scaleX = cam.target.scaleY = fieldScale;

     stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);

     stage.addEventListener(KeyboardEvent.KEY_UP, keyHandler);

     stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);

}

start();

Font used: Scoreboard | dafont.com

Most of the assets are from https://kenney.nl/ .

FLA download:

animate_cc_as3_soccer_game.zip - Google Drive

I hope this helps and please don't hesitate to ask if you have any questions.

Regards,

JC

austane
austaneAuthor
Participant
August 22, 2018

Hey JC

Sorry about that post before, I didn't realise that I had posted in the wrong thread. I have attached the game at the top again. Hopefully you will get the time to look over it.

Kind regards

Austin Calver

kglad
Community Expert
kgladCommunity ExpertCorrect answer
Community Expert
August 21, 2018

your ball needs to be a movieclip (eg, ball_mc) too.  you can then use

Helicopter_red.hitTestObject(ball_mc)

though you may not be happy with the bounding box issues.