New entity stuck in grid - how to get positions? (SOLVED)


(christopf) #1

Hi longtime no see! The last month i worked more on the graphic side of my game but today i switched to my code again (different OS) and encountered several problems, one i didnt managed to solve myself. (Its a little bit weird when i came back to the code after a few weeks codeless it all seems more difficult and more messy as remembered :D)

My problem is: When my hero dies another enemy entity spawns on the position but sometimes the entity gets stuck in the grid when the spawnpoint is too near. I thought i could check for FP.angle and depending on the degree i move it a bit. But i didnt found a way to get the position (getTile just gives me a boolean) and anyway i am wondering if theres maybe any easier more clever solution to it?

Has anybody an idea?

thanks in advance (& its feeling good being back in here)


(David Williams) #2

You could make the enemy spawn in exact grid coordinates. EX:

new Enemy(int(player.x / CELLW) * CELLW, int(player.y / CELLH) * CELLH)

(christopf) #3

Ah i just thought, yes, this is it. But this seems to work only when the hitboxes are the same as the tilesize. The entities in my game got weird hitboxes since they got weird shapes :smiley:
The int() method i didnt know but i think i can get use of it very often ( i just thought about a kinda solution but i didnt know how to make the rounding) thanks anyway


(Jonathan Stoler) #4

Can you clarify about the problem? Perhaps post a screenshot?

Are you saying spawned Entities are getting “stuck” in solid Grid tiles?

PS: rather than the int() casting, you can use Math.floor() (round down), Math.ceil() (round up) or Math.round() (round to nearest integer, up or down).


(christopf) #5

I captured a small gif of it:

(is that okay how i implemented this?, in other threads ive seen the chance of press to play)

the problem is when my hero “dies” he sets a point at that after the callback of the dieng animation the enemy entity spawns that last contacted him. but they all got different hitboxes, so sometimes, when the hero get knocked back at the grid the enemy stucks at spawning. my problem is, that i dont know how to identify the collision? is it maybe possible to check if the the shadows collide with the grid on a special side (with the left,right,top,bottom method i read in the documentation?). so they would get thrown back a little bit they collide with the grid any time (that wouldnt be so bad i guess)

i thought about this earlier but i dont know how to check for the angle between the boids and the gridtiles. one idea on this was so far to look for the tiles around the transpoint if they are soild with getTile and if yes to get the angle to it. but this would be very complicated and i thought there is maybe an easier way to it?


(christopf) #6

So the last hours i tried to find a way and came up with a pretty loosy and messy solution i’m not so happy with yet. Maybe i find a more mathematical solution because this version works for now in this environment but when i think of moving the meant-to-be map later i’m kind of scared. Additionally it aint so accurate like i would like to wish, maybe you have a thought on this or two you want to share? Would love to hear it.

private function stuckCheck():void
{	
	var nw:Point = new Point(x - 16, y - 16);
	var n:Point = new Point(x, y - 16);
	var no:Point = new Point(x +16, y - 16);		
	var w:Point = new Point(x - 16, y);
	var o:Point = new Point(x + 16, y);
	var sw:Point = new Point(x - 16, y + 16);
	var s:Point = new Point(x, y + 16);
	var so:Point = new Point(x + 16, y + 16);	
	var nw2:Point = new Point(x - 32, y - 32);		//
	var nnw:Point = new Point(x - 16, y - 32);		//
	var nww:Point = new Point(x - 32, y - 16);		//
	var n2:Point = new Point(x, y - 32);			//
	var nno:Point = new Point(x +16, y - 32);		//
	var no2:Point = new Point(x +32, y - 32);		//	
	var noo:Point = new Point(x +32, y - 16);		//
	var w2:Point = new Point(x - 32, y);			//
	var o2:Point = new Point(x + 32, y);			//
	var sww:Point = new Point(x - 32, y + 16);		//
	var sw2:Point = new Point(x - 32, y + 32);		//
	var ssw:Point = new Point(x - 16, y + 32);		//
	var s2:Point = new Point(x, y + 32);			//
	var sso:Point = new Point(x + 16, y + 32);		//
	var so2:Point = new Point(x + 32, y + 32);		//
	var soo:Point = new Point(x + 32, y + 16);		//
		
	if (collideTypes(["solid", "schlucht"], x, y))
	{
		if ((world as Alabsa)._mapGrid.getTile(Math.round(w.x / 16), Math.round(w.y / 16)) == true)		{ trace("WEST");  x+6}
			
		if ((world as Alabsa)._mapGrid.getTile(Math.round(w2.x / 16), Math.round(w2.y / 16)) == true)	{ trace("WEST2");  x += 6 }
			
		if ((world as Alabsa)._mapGrid.getTile(Math.round(nw2.x / 16), Math.round(nw2.y / 16)) == true)	{ trace("NORDWEST2"); x += 6; y+=6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(nnw.x / 16), Math.round(nnw.y / 16)) == true)	{ trace("NORDNORDWEST"); y += 6; x+=6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(nww.x / 16), Math.round(nww.y / 16)) == true)	{ trace("NORDWESTWEST");  y += 6; x += 6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(n2.x / 16), Math.round(n2.y / 16)) == true)	{ trace("NORD2");  y += 6;  }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(nno.x / 16), Math.round(nno.y / 16)) == true)	{ trace("NORDNORDOST");  y += 6; x -=6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(no2.x / 16), Math.round(no2.y / 16)) == true)	{ trace("NORDOST2");  y += 6; x -= 6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(noo.x / 16), Math.round(noo.y / 16)) == true)	{ trace("NORDOSTOST");  y += 6; x -= 6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(o2.x / 16), Math.round(o2.y / 16)) == true)	{ trace("OST2") ; x -= 6}

		if ((world as Alabsa)._mapGrid.getTile(Math.round(sww.x / 16), Math.round(sww.y / 16)) == true)	{ trace("SUWESTWEST");  y -= 6; x += 6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(sw2.x / 16), Math.round(sw2.y / 16)) == true)	{ trace("SUDWEST2") ;  y -= 6; x += 6}

		if ((world as Alabsa)._mapGrid.getTile(Math.round(ssw.x / 16), Math.round(ssw.y / 16)) == true)	{ trace("SUDSUDWEST");  y -= 6; x += 6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(s2.x / 16), Math.round(s2.y / 16)) == true)	{ trace("SUD2") ;  y -= 6; }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(soo.x / 16), Math.round(soo.y / 16)) == true)	{ trace("SUDSUDOST");  y -= 6; x -= 6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(so2.x / 16), Math.round(so2.y / 16)) == true)	{ trace("SUDOST2");  y -=6; x -= 6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(sso.x / 16), Math.round(sso.y / 16)) == true)	{ trace("SUDSUDOST") ;  y -= 6; x -=6}	
																												
		if ((world as Alabsa)._mapGrid.getTile(Math.round(s.x / 16), Math.round(s.y / 16)) == true)		{ trace("SUD") ;  y -= 6}

		if ((world as Alabsa)._mapGrid.getTile(Math.round(o.x / 16), Math.round(o.y / 16)) == true)		{ trace("OST") ; x -= 6}

		if ((world as Alabsa)._mapGrid.getTile(Math.round(nw.x / 16), Math.round(nw.y / 16)) == true)	{ trace("NORDWEST");  y += 6; x += 6 }
			
		if ((world as Alabsa)._mapGrid.getTile(Math.round(sw.x / 16), Math.round(sw.y / 16)) == true)	{ trace("SUDWEST");  y -= 6; x += 6 }

		if ((world as Alabsa)._mapGrid.getTile(Math.round(no.x / 16), Math.round(no.y / 16)) == true)	{ trace("NORDOST");  y += 6; x -= 6 }
			
		if ((world as Alabsa)._mapGrid.getTile(Math.round(so.x / 16), Math.round(so.y / 16)) == true)	{ trace("SUDOST");  y -= 6; x -= 6 }
			
		if ((world as Alabsa)._mapGrid.getTile(Math.round(n.x / 16), Math.round(n.y / 16)) == true)		{ trace("NORD") ;  y +=6}
		
	
		stuckCheckBegin = false;
	}

}

this looks messy too - sorry for that!
the points in the top are possible tides around the enemy entity after spawning (in the end is a stuckCheckBegin to keep it only for added entities) somehow it didnt work in the added function.
and the // after some points is for the second circle around the entity because i wasnt sure if this is maybe over the top but later it seemed to be necessary because sometimes i didnt find a tile in the first circle but got still stucked (but not with a second circle)


(Zachary Lewis) #7

When your entity is created, you’ll want to check for collision with your grid. If it is in collision with your grid, you’ll want to calculate how far you should move it so it resolves the collision. I’m sure I have an animated gif around here somewhere showing a similar solution… ah. Here it is.

Don’t worry about the player movement, but look at how the collision is handled when the hitbox is colliding with the world. You’ll probably want to move it out of the collision in the direction of the center of the entity.


(christopf) #8

When you write it like this it sounds so easy but i wonder two things:

- How do i get the second Point (the first is the origin on my entity) to get a direction?
- How do i get the distance to resolve the collision?

I’m still very beginner and i’m not yet so well informed about the possible tools to solve such situations (but i would like to learn it).

What do you mean by “how the collision is handled when the hitbox is colliding with the world” ?
Thank you anyway


(Zachary Lewis) #9

It’s just math. Look at what you know and what you don’t know.

You want to know:

  • How far should the entity be moved to resolve a collision

You know:

  • The location of the entity
  • If the entity is colliding with the grid
  • If a tile on the grid is solid

The thought process to figure out what you don’t know is:

  1. What tiles does the entity occupy?
  2. Which of those tiles are solid?
  3. How far should the entity be moved so it is out of the solid tiles?

(christopf) #10

Thanks for the love tap, now it works so as i would like it to. I played a little with the left,bottom,top,right and reduced the change of 6 to 1 but until there aint no more collision checking (and only after being summoned).
this may not the most elegant solution but it works for now. kinda s0lv3d