3 Replies - 1733 Views - Last Post: 25 February 2009 - 05:29 PM

#1 ryrocks  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 13-February 09

hittest y position

Post icon  Posted 16 February 2009 - 01:35 PM

Hey,
I have 2 movieclip class's.
-A ball which you control
-a series of rectangles that the ball "lands" on.

using a hittest, when the ball "hits" the rectangle movieclip it stops directly on top of that rectangle.

I have 3 rectangles all linked to the same class containing the hittest.

My problem is that when I move the ball across each rectangle, it does not land in the same place each time. I believe this is because since I'm using an ENTER_FRAME event, the hitCheck doesn't coincide with the ball's true first contact, and sometimes makes the ball move a little lower than desired.

I've uploaded the .swf: http://www.activ8-3d.../test/floor.swf
(use arrow keys to control)

To overcome this I added to the hittest:
[as]
if (_ball_mc.hitTestObject(this))
{
_ball_mc.onGround = true;
}
....
if (_ball_mc.onGround)
{
_ball_mc.y = this.y - this.height - 13;
}
[/as]

_ball_mc.y = this.y - this.height - 13; is the correct position I want the ball to land each time, I thought this would have cracked it, but alas! Its such a minor problem that I didn't want to ask for help on it, but I just can't take it no more!

Here's the full code:

Ball.as document class controls the ball:

 package
{
	import flash.ui.Keyboard;
	import flash.events.*;
	import flash.display.*;

	public class Ball extends MovieClip
	{		
		public var leftDown:Boolean = false;
		public var rightDown:Boolean = false;
		public var jump:Boolean = false;
		public var velocity:Number = 20;
		public var falling:Boolean = true;
		public var speed:int = 5;
		public var onGround:Boolean = false;
	
		public function Ball()
		{			
			stage.addEventListener(KeyboardEvent.KEY_DOWN, downDetect);
			stage.addEventListener(KeyboardEvent.KEY_UP, upDetect);
			stage.addEventListener(Event.ENTER_FRAME, moveChar);
		}
		
		public function downDetect(event:KeyboardEvent):void 
		{
			if(event.keyCode == Keyboard.LEFT) 
			{
				leftDown = true;
			}
			if(event.keyCode == Keyboard.RIGHT) 
			{
				rightDown = true;
			}
			if(event.keyCode == Keyboard.UP && !falling) 
			{
				jump = true;
			}
		}
		
		
		public function upDetect(event:KeyboardEvent):void 
		{
			if(event.keyCode == Keyboard.LEFT) 
			{
				leftDown = false;
			}
			if(event.keyCode == Keyboard.RIGHT) 
			{
				rightDown = false;
			}
		}
		
		public function moveChar(event:Event):void
		{
			if (leftDown) 
			{
				this.x -= speed;
			}
			if (rightDown) 
			{
				this.x += speed;
			}
			if (jump) 
			{
				this.y -= velocity;
				velocity -= 1.5;
			}
		}
	}
}



Ground.as class containing the hittest:
package 
{
  import flash.display.MovieClip;
  import flash.ui.Keyboard;
  import flash.events.*;
  
  public class Ground extends MovieClip
  {
	private var _ball_mc:MovieClip;
	private var _findStageInstances:Boolean;
	
	public function Ground()
	{
		stage.addEventListener(Event.ENTER_FRAME, hitCheck);
		_findStageInstances = true;
	}
	
	public function hitCheck(event:Event):void
	{
		if (_findStageInstances)
		{
			_ball_mc = parent.getChildByName("ball_mc") as MovieClip;
			_findStageInstances = false;
		}

		if (_ball_mc.hitTestObject(this))
		{
			_ball_mc.jump = false;
			_ball_mc.falling = false;
			_ball_mc.onGround = true;
			_ball_mc.velocity = 20;
			_ball_mc.onGround = true;
			
			stage.addEventListener(KeyboardEvent.KEY_DOWN, downDetect);
			function downDetect(event:KeyboardEvent):void 
			{
				if(event.keyCode == Keyboard.UP) 
				{
					stage.removeEventListener(Event.ENTER_FRAME, hitCheck);
					_ball_mc.jump = true;
				}
			stage.addEventListener(Event.ENTER_FRAME, hitCheck);
			}
		}
		
		if (!_ball_mc.hitTestObject(this))
		{
			_ball_mc.onGround = false;
		}		
		
		if (!_ball_mc.hitTestObject(this) && !_ball_mc.jump && !_ball_mc.onGround)
		{
			_ball_mc.y += 7;
			_ball_mc.falling = true;
		}
		
		if (_ball_mc.onGround)
		{
			_ball_mc.y = this.y - this.height - 13;
		}
	}
  }
}



Thank you!

Is This A Good Question/Topic? 0
  • +

Replies To: hittest y position

#2 GreenSpiral  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 64
  • Joined: 30-December 08

Re: hittest y position

Posted 16 February 2009 - 04:29 PM

I have the same problem, my ball cannot detect the exact time of hitting it... alas, I have no solution, except to do if _root.Ball._y == #
Was This Post Helpful? 0
  • +
  • -

#3 ryrocks  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 13-February 09

Re: hittest y position

Posted 17 February 2009 - 09:16 AM

I've fixed it...

I was close before, I was just overcomplicating things. I needed to remove the eventlistener when the hittest was detected because there was a certain point where flash thought the objects were hitting and wern't hitting at the same time :-\ Therefore it set the ball position to the desired position, but then moved it down 7px as if it were falling.



I then reattached the eventlistener after the hittest true method.



That probably didn't make any sense to you! (hard to explain!)



Anywhoooo, heres the working code:


 public function hitCheck(event:Event):void

 {

  if (_findStageInstances)

  {

   _ball_mc = parent.getChildByName("ball_mc") as MovieClip;

   _findStageInstances = false;

  }

  if (_ball_mc.hitTestObject(this))

  {

   _ball_mc.jump = false;

   _ball_mc.falling = false;

   _ball_mc.y = (this.y);

   _ball_mc.velocity = 17;   

   stage.removeEventListener(Event.ENTER_FRAME, hitCheck);

  }

  stage.addEventListener(Event.ENTER_FRAME, hitCheck);

 

  if (!_ball_mc.hitTestObject(this) && !_ball_mc.jump)

  {

   _ball_mc.y += 4;

   _ball_mc.falling = true; 

  }

 }



Was This Post Helpful? 0
  • +
  • -

#4 theRemix  Icon User is offline

  • D.I.C Regular

Reputation: 15
  • View blog
  • Posts: 440
  • Joined: 19-October 05

Re: hittest y position

Posted 25 February 2009 - 05:29 PM

lets say the rectangle's registration point is top left.

then the top of the rectangle is the rectangle's y.

so if ball_mc.hitTestObject(rectangle) // then we are actually either rectangle.y or greater (lower)
then ball_mc.y = rectangle.y; // or rectangle.y - 13;

then the ball will never go below the rectangle's top border, or when it does due to falling, it resets it to sit on top of the rectangle, before you can even see it.

there is more code, hope you got it.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1