Collision for rotated objects?


(Ortson) #1

I have a problem when rotating an entitys sprite and its collision. It seems like I cant get the collision right. Here you can play an example: [Here][1][1]: https://dl.dropboxusercontent.com/u/37437508/Test.swf

Use wsad or arrows and space to move

The collision seems to be happening to early if the collision happens on the right side.

Here is part of the class that is shooting the bullet:

public function Shooter(xPos:int, yPos:int, speed:Number, isRotating:String, angle:String) 
	{
		x = xPos+ (width/2);
		y = yPos+ (height/2);
		fireSpeed = speed/100;
		
		pixelMask.originX = 16;
		
		layer = -2;
		
		graphic = pixelMask;
		
		if(isRotating == "False")
			this.isRotating = false;
		else if(isRotating == "True")
			this.isRotating = true;
		
		angle = angle.replace(angle.charAt(1), ".");
		
		this.angle = (Number(angle)*(180/Math.PI));
		
		type = "shooter";
		
		pixelMask.originX = width / 2;
		pixelMask.originY = height / 2;
		
	}

And:

if (player != null) {
	if(timer >= 1){
		bulletAngle = pixelMask.angle-90;
		FP.world.add(new Bullet(x, y, bulletAngle));
		timer = 0;
	}
	timer += fireSpeed;

}

And here is part of the bullet class:

public function Bullet(xPos:int, yPos:int, angle:Number, isSearching:Boolean = false, ignoreCollision:Boolean = false ) 
	{
		this.angle = angle;
		x = xPos;
		y = yPos;
		
		BULLET_SPEED = 10;
		
		this.isSearching = isSearching;
		this.ignoreCollision = ignoreCollision;
		
		xVel = BULLET_SPEED * Math.cos(angle * FP.RAD);
		yVel = BULLET_SPEED * Math.sin(angle * FP.RAD);
		
		sprite.centerOrigin();
		
		sprite.angle = angle;
		
		type = "bulletDamage";
		
		graphic = sprite;
		
			mask = new Pixelmask(sprite.getBuffer());
				
	}
override public function update(): void {
		
		lifeTime += FP.elapsed;
		
		if (lifeTime > 15) {
			FP.world.recycle(this);
		}
		
		moveBy(xVel, yVel, ["level", "damage", "player"]);
		
	}

override public function moveCollideX(e:Entity):Boolean {
		
		if (!collide("level", x, y) && !collide("damage", x, y) && !collide("player", x, y)) {
				
			return false;

		}else {
			FP.world.recycle(this);
			return true;
		}
		
	}
	override public function moveCollideY(e:Entity):Boolean {
	
		if (!collide("level", x, y) && !collide("damage", x, y) && !collide("player", x, y)) {
	
			return false;

		}else {
			FP.world.recycle(this);
			return true;
		}
	
		
	}

I also have modified the Image class so I can acces the buffer.

Anyody got any ideas?


(Ssnyder Coder) #2

The problem is probably this line in your Bullet class constructor:

	sprite.centerOrigin();

The Pixelmask doesn’t take into account any kind of image transformations when computing collisions. It seems that the actual sprite if offset slightly north-west because of that statement, but the collisions are calculated without considering that offset. That is why the collisions occur early when the bullet hits an object below it or to the right of it, but occur late when the bullet hits an object above it or to the left of it.

Since your sprite is not actually rotating, there is no need for that centerOrigin() method call. You could just remove it to fix the problem. However, if you do plan to add some sort of rotation, you might be able to fix it by adding the following to the constructor:

	sprite.x = sprite.width / 2;
	sprite.y = sprite.height / 2;

In theory, that would offset the sprite slightly south-east, canceling out with the offset caused by the centerOrigin() method. I don’t know for sure if it will work, but you can try it.


(Ortson) #3

That dosen´t do it, now it looks okay on the right/bottom side but on the other side it just goes further into the wall. Using this way the bullet dosen´t start from the right position of the gun, the offset gets weird. Any other suggestions?


(Ssnyder Coder) #4

Did you remove the centerOrigin() call, add the 2 lines I suggested, or do both at the same time? I meant for you to only try 1 of those at a time; sorry I wasn’t clear on that. Otherwise, if neither solution worked, then I don’t know what else to try for that pixelmask.

Have you tried using Flashpunk’s debug mode? That might help identify the problem. Perhaps just using a hitbox instead of a pixelmask would also work. If your concerned about a regular hitbox triggering too early, then you could decrease the size of the hitbox slightly.


(Ortson) #5

Thanks, I needed too have it like this:

sprite.centerOrigin(); sprite.x = sprite.width / 2; sprite.y = sprite.height / 2;

Now I just need to fix so it starts from the middle of the canon again