[AS2] Hit Detection issues with my car movement

15 posts

Flag Post

Yes, I know I should be coding in AS3. Just going to get that out of the way. I’ll make the jump soon enough, but this project needs to be finished first, then I’ll change to AS3. I might even re-write this project in AS3 as a getting-started test. Anyway, I’ve been coding it for some time, and although it is my first major game I would like to think I’ve got a fair bit better at AS2 now. I’ve written up the entire game, bar the tutorial – nothing that will be technically difficult. I wrote my own car physics, but I’m not sure if they way I’m moving the _x and _y of the car is the way that is optimal – this is the code I’m using currently:

_root.background1.car._x += Math.sin (_rotation * Math.PI / 180) * speed;
_root.background1.car._y += Math.cos (_rotation * Math.PI / 180) * -speed;

It was the one part of the car physics that I couldn’t figure out – I hadn’t even thought about converting the _rotation to work it out, so glad that I searched to find it out. My problem now, is that my car is reporting it’s _x and _y locations in correctly. At first I thought it might be because the “car” movieclip is inside the background1 movie clip, as you can see from the code. I hadn’t thought this would cause problems, but I checked it anyway – nothing causing it there. After some more … inventive solutions, nothing was working. I’m not sure why it’s not working, but I’m sure the people here in Game Programming would know. You’re all brilliant :D

If you guys need to, I can post the download link to a .fla with just my car code in it, and a sample building to hitTest. I’m not sure why it’s not working – the strange part is, if I just use the car’s instance name, it works fine. But if I try and enable the shapeFlag function (which as far as I know, requires a _x and a _y value to be submitted), it doesn’t work.

Here is the total code I use for the car:

onClipEvent (load) { 
var speed:Number = new Number (0);
}
onClipEvent(enterFrame){
	speed = speed * 0.98;
	if(Key.isDown(Key.UP) && !Key.isDown(Key.CONTROL)){
		speed += 1.2
	 }
	 if(Key.isDown(Key.DOWN)){ 
	 	speed -= 0.8;
	 }
    if (Key.isDown(Key.RIGHT)){
		if(speed < 5 && speed >= 0){
			_rotation += 1 * speed;
		} 
		if(speed < 0 && speed >= -2.5){ 
			_rotation += 1 * speed;
		}
		if(speed < -2.5){
			_rotation += 2.5;
		}
		else if(speed > 5){
			_rotation += 4.5;
		}
		speed *= 0.95;
	}
    if (Key.isDown(Key.LEFT)){
		if(speed < 5 && speed >= 0){
			_rotation -= 1 * speed;
		}
		if(speed < 0 && speed >= -2.5){ 
			_rotation -= 1 * speed;
		}
		if(speed < -2.5){
			_rotation -= 2.5;
		}
	else if(speed > 5){
		_rotation -= 4.5;
		}
		speed *= 0.95;
	}
	
	_x += Math.sin (_rotation * Math.PI / 180) * speed;
    _y += Math.cos (_rotation * Math.PI / 180) * -speed;
	
    if (Math.abs(speed) > 12.5){
		speed = 12.5;
	}
	if(speed < -5){
		speed = -5;
	}
	if (Key.isDown(Key.CONTROL)){
		speed -= speed / 5;
		if(Key.isDown(Key.RIGHT)){
			_rotation += speed / 2;
			}
		if(Key.isDown(Key.LEFT)){
			_rotation -= speed / 2;
			}
		}
	}
 
Flag Post

Proper Code Formatting Guide

 
Flag Post

Could you elaborate on what you mean by “reports the _x and _y locations incorrectly”? Give an example. Where is the registration point of that object?

Regarding the shapeFlag function, take a look at this (specifically Mazoonist’s post) and see if that helps you.

Also, why do you do this:

if (Key.isDown(Key.RIGHT)){
  if(speed < 5 && speed >= 0){
    _rotation += 1 * speed;
  } 
  if(speed < 0 && speed >= -2.5){ 
    _rotation += 1 * speed;
   }
  // remaining tests excised
}

(and again with Key.LEFT, but with -= in place of +=), instead of this:

if (Key.isDown(Key.RIGHT)) {
  if(speed < 5 && speed >= -2.5){
    _rotation += speed;    // multiplying by one doesn't do anything useful
  } 
  // remaining checks excised
}

There doesn’t seem to be any reason to separate the checks that I can see (is one of them supposed to do something different?)…

if (Math.abs(speed) > 12.5){ 
  speed = 12.5;
}
if(speed < -5){
  speed = -5;
}

Why do an expensive Math call? If speed is less than -5, it gets set to -5 by the second check; the first check says that if speed is, say, -20, it would be set to 12.5 — which I’m sure is not what you’d want even if it were possible to do (which it shouldn’t be).

 
Flag Post

Not going to help you but instead of using Math.abs() use:

i = (x ^ (x >> 31)) - (x >> 31);

It’s about 25 times faster.

 
Flag Post

Ignore RTL_Shadow’s suggestion. If you really need the speed, use a ternary operation, like so:

i = x > 0 ? x : -x;

Otherwise, just stick with Math.abs().

Whatever you do, do not use code as unreadable as that for something as simple as finding an absolute value.

 
Flag Post

Surely the salient point with respect to the OP’s code in question, regardless of the best way to achieve an absolute value, is that it wasn’t necessary or even at all remotely useful in the first place.

 
Flag Post
Originally posted by player_03:

Ignore RTL_Shadow’s suggestion. If you really need the speed, use a ternary operation, like so:

i = x &gt; 0 ? x : -x;

Otherwise, just stick with Math.abs().

Whatever you do, do not use code as unreadable as that for something as simple as finding an absolute value.

That’s entirely opinionated. And if you do not want to use unreadable code, might as well use if/else statements considering they are faster and easier to read.

E: Also- just through that code in a function and replace i with return and x with the value- there you go, completely readable as abs(-32)

 
Flag Post

Sorry about that code formatting – I didn’t know how to put in the pre tags, and forgot to check the stickies. Posting a thread at 12am is probably not a good idea, now that I’m thinking about it. Sorry about that. Trying to answer the questions now.

@dragon_of celts
What I mean is that when you try and do anything that requires the object’s x andy, it doesn’t work properly. As an example, I made it so that when I press E, it traces the _x and _y locations of both the atm (a small object) and the car. Then I drove the car over the atm, pressed E, and the car’s _x and _y were something like ~500 away from the atm, although I was over it graphically. It’s confused the hell out of me.

What I meant by shapeflag is, I try and hitTest like this:

if(_root.background1.atm.hitTest(_root.background1.car._x, _root.background1.car._y, true)){
//blah
}

Then it doesn’t work. This is the same way I hitTest for my character’s collision with the same buildings, and it works correctly. However, if I do this:

if(_root.background1.atm.hitTest(_root.background1.car)){
//blah
}

It works fine. When I tested further, the car wasn’t reporting it’s _x and _y values as what they should be, and such the hitTesting was off. And thanks for that thread, reading it now and it looks like it could well be the problem – funny, as thats what I thought it was at first, but discounted it later on. I’ll do some testing with that soon, hopefully today :)

And I am not multiplying by one really, I did do that for a reason. The reason it’s one is because it’s a value I can change to allow for bettter or worse turning, and I felt that 1 suited the pace of my game. The reason I multiply it with speed rather than simply add speed, is because if the speed is very low (as in below 5 or above -2.5, as shown in the code), then it’s going to get a rather small amount of rotation turn, which is what I wanted. On top of this, if the speed hits 0, then you can’t turn at all. You can get this by adding speed directly, but like this I could change that 1 to a 5 and the turning angle would change significantly – say I wanted to create a high-speed GTA2-style game, I imagine I could use similar code. Hopefully at least – but you are definitely right in that I should merge those two if statements together, don’t know why I did it like that. I’ve got the tutorial to do, and this car hitTesting. Then, hopefully, I can work on cleaning up the code and some optimizations before a release shortly.

As to the Math.abs call, I knew they were inefficient, but I didn’t think they are 25 times slower. I’ve not had trouble with lag so far, but if I find I need to make some optimizations, I’ll change that. Thankfully, it’s one of the few Math calls I’ve made in the code. As to the speed, yeah, you’re right. The Maths.abs doesn’t make that much sense there anyway, just plain speed is what I wanted. I wrote some of this a little late, but the plan was to get the hitTesting working then look at the code. Probably should’ve done that first :)

And thanks for the suggestions on the speed, I’ll definitely look into it if I need speed – at the moment, I’m fine with it at the moment, but if people wants some optimizations, then I’l definitely do it.

 
Flag Post
Originally posted by RTL_Shadow:
Originally posted by player_03:

Ignore RTL_Shadow’s suggestion. If you really need the speed, use a ternary operation, like so:

i = x &amp;gt; 0 ? x : -x;

Otherwise, just stick with Math.abs().

Whatever you do, do not use code as unreadable as that for something as simple as finding an absolute value.

That’s entirely opinionated. And if you do not want to use unreadable code, might as well use if/else statements considering they are faster and easier to read.

E: Also- just through that code in a function and replace i with return and x with the value- there you go, completely readable as abs(-32)

Either way, your bitwise operations are slower than ternary

 
Flag Post
Originally posted by qwerberberber:
Originally posted by RTL_Shadow:
Originally posted by player_03:

Ignore RTL_Shadow’s suggestion. If you really need the speed, use a ternary operation, like so:

i = x &amp;amp;gt; 0 ? x : -x;

Otherwise, just stick with Math.abs().

Whatever you do, do not use code as unreadable as that for something as simple as finding an absolute value.

That’s entirely opinionated. And if you do not want to use unreadable code, might as well use if/else statements considering they are faster and easier to read.

E: Also- just through that code in a function and replace i with return and x with the value- there you go, completely readable as abs(-32)

Either way, your bitwise operations are slower than ternary

For AS2 maybe (don’t feel like wasting time checking), but in AS3, the bitwise version is a bit faster.*

In this case, it’s irrelevant. You don’t use “optimize” and “AS2” in the same sentence.

* Given that x is an int. Otherway the bitwise version can take over 200% the time required to do the same with the ternary option.

 
Flag Post

Yeah….. AS2 is the rate determining component.

Anyways, with AS2 Hittest you can only have these inaccurate collision and resolutions. For accurate physics, you will need to compute everything in a mathematical/geometric way.

 
Flag Post

I’ll more than likely be changing to AS3 after this project is done. Most likely I’ll be using this game as a base, and re-coding it in AS3. But the AS2 hit detection isn’t terrible for what I’m doing, so I will most likely release it in AS2. Thanks for the help guys – can’t try out that link now, no flash on this comp.

 
Flag Post

I wasn’t saying that you can’t use AS2; It should be more than enough for what you are doing. What I’m saying is that the hitTest function does not return enough information for a precise collision response.

 
Flag Post

Ah, right. Read your post incorrectly. Yeah, I know it can’t be that precise, but for what I’m doing, it’s perfectly fine :D

 
Flag Post

Alright guys, thanks a bunch! That was the problem, it just took me a while to figure out how to do the whole parentToGlobal() thing, but got it now. It’s working! Thanks :D