Spawning inside collision!


(Michael Faultless) #1

Hi, I’m reasonably new to Flash Punk I’m trying to create a co-op game where two players have to kill one another.

Now I’m slowly getting there however now I’ve added the following in:

add(new MyEntity(Math.random()*800, Math.random()*600));
add(new MyEntity2 (Math.random()*800, Math.random()*600));

Because I’m wanting my characters to spawn in random location, this works however I’m now spawning actually within my collision, and obviously I can not mover out of it any help or suggestions would be greatly appreciated!

You can see what I mean for yourself at the link bellow,

Player 1: Up Arrow, Down Arrow, Left Arrow, Right Arrow Shoot: M

Player 2: W, S, A, D Shoot: X

http://www.fastswf.com/WVzvTHw

(By the way images, currently used are placeholders ONLY!)

Thanks M


(Darrin) #2

Looking cool. Perhaps just do a collision detection with the wall tile. If it hits, respawn randomly until clear. Or you can search for the closest open tile, the spawn it there.


(Michael Faultless) #3

Thanks! Why did I not think of that! I’ll give it a try! :smiley:


(Jacob Albano) #4

While that approach will get you an acceptable result eventually, in the worst case it could end up taking a very long time as it continually attempts to find a spot without collision. Here’s an approach that guarantees a valid spot if you use a Grid for collision:

public static function randomEmptyTile(grid:Grid):Point
{
    var allEmpty:Array = [];
    for (var x:int = 0; x < grid.columns; x++) 
    {
        for (var y:int = 0; y < grid.rows; y++) 
        {
            // pack x and y into a single number to limit Point allocations
            if (!grid.getTile(x, y))
                allEmpty.push(y * grid.width + x);
        }
    }
    
    var choice:int = FP.choose(allEmpty);
    // unpack indexes here
    return new Point(choice % grid.width, Math.floor(choice / grid.width));
}

Worth pointing out, it seems that you’re using a Pixelmask for collision. Your map would be much better served by using a Grid instead. I’d be happy to give you some pointers on how to implement it.


(Michael Faultless) #5

Hi, thanks for getting in touch.

And yeah I’m not sure what exactly a grid is or how to actually implement it so I would appreciate it very much! :smile:

Update: Yeah you can see for yourself here whats happened after adding:

if (collide(“wall”, x, y)) FP.world = new Levels.Level1;;

http://www.fastswf.com/P-BMk4E


(Darrin) #6

Ah so I wouldn’t reload the world. The pseudo code would be something like this:

// when bullet collide, set player.visible = false;

var bNotClear:Boolean = true;
while (bNotClear){
 var x:int = FP.rand(screenWidth);
 var y:int = FP.rand(screenHeight);
  if (collide("wall", x, y) == false)
        bNotClear = false;
}
player.x = x;
player.y = y;
player.visible = true;

Jacob’s solution is better and faster because you only go through all the tiles only 1 x. The above may go through the list several times.


(Jacob Albano) #7

It’s pretty simple. Right now you’re using a Pixelmask; instead of creating a new Pixelmask when you create your world, create a Grid instead.

It’s hard to give any further information without knowing how you’re designing your levels – are you using a Tilemap or is your level layout all part of one image?