views:

233

answers:

4

I'm building a pacman game. Basically, I want to have a map representation of this window consisting of blocks/tiles. Then as the pacman character/ghost moves i would change their position on the map to represent what's on the screen, and use that for collision detection etc.

How can I build this map, especially since the screen is made of x,y coordinates, so how can I correctly represent them in tiles/on this map?

A: 

Kind of difficult to come up with this without writing it myself but.

First you'll need to create entity definitions that implement ICollidable. Entities would include ghosts, pacman, dots and powerups. Each element in the map would contain, along with other information, a list of all present entities with a sort of "position" value for added precision. The ICollidable interface would include not only logic for determining which entities collide with one another (ghosts don't collide with dots for example.) but determining if they're in position to collide with one another. IE if pacman is entering a space from the right and a ghost is leaving that space from the left there's no collision. It will also help determine when exactly pacman has eaten a dot so that graphically it looks correct. IE if you destroy a dot right as pacman enters a space it's going to disappear before he even touches it graphically.

Spencer Ruport
Java interfaces don't follow the IXxxx naming convention
Alnitak
Well I'm certain whatever he calls the interface is entirely irrelevant regardless of the language.
Spencer Ruport
+3  A: 

I know it's tempting to start thinking of objects and interfaces but have you thought about a 2-dimensional array with each element representing 40 pixels or something? I don't remember pacman being pixel accurate when it came to collision, more a question of the direction each piece was moving in.

Bedwyr Humphreys
+1  A: 

Generally you have an abstract representation that doesn't reference pixels as such (for example, maybe the Pac-Man maze is simply w units wide), and then you have a linear transformation (you know, y = mx + b) to carry the abstract representation to actual pixels.

To make it concrete, let's say that you want your abstract representation to be 100 units wide, and you want to render it as 400 pixels. Then the transformation is just scrn_x = 4 * x.

Willie Wheeler
A: 

Your sprites such as pacman and the ghost are represented by positions (x,y). To determine if they collide with each other, use this psuedocode:

sprites = [ ... list of sprites ... ]
for i1=0 to len(sprites):
    sprite1 = sprites[i1]
    for i2 = i1+1 to len(sprites):
        sprite2 = sprites[i2]
        if (sprite1.x-sprite2.x)^2+(sprite1.y-sprite2.y)^2 < radius_of_sprites^2:
            collide(sprite1, sprite2)

Note that this doesn't involve the map at all. We can check for collisions between pacman and the map separately. The key trick here is you divide the pixel coordinate of each of pacman's sides (top, bottom, left, right) and check for collisions. For example, if pacman is going to the right, we need to check the right edge for a collision:

pacman_tile_x = (pacman.x+tilesize/2)/tilesize    # added tilesize/2 to check the middle of pacman
pacman_tile_y = pacman.y/tilesize + 1   # +1 because right edge is 1 tile to the right of the sprite's coordinate
if tile[pacman_tile_x][pacman_tile_y].is_a_wall:
    ... wall collide code ...

Now, if you have a huge number of sprites on the screen, you can optimize the sprite-to-sprite collision detection by storing which sprites exist on any particular tile in the map, and so you only have to check against sprites in adjacent tiles. But for a first pass and for this pacman game, it's probably not a necessary optimization.

Paul
too hard to understand, and it relies on the radius of the sprites to be hardcoded. there must be a simpler way
Click Upvote
That's a demonstration of the general approach: check every moving object for collision against every other one. In pacman, every object has roughly the same radius and so using the radius (tilesize/2) is a good simplification, however you're free to use other methods.
Paul