walking and falling sprites

i’m developing a game with a map of 4 floor levels. every floor level has a hole.

question is how do i detect that a player has stepped in it?

i got a suggestion to make all the floors, except the holes, as sprites. i think its not practical to create several floor sprite objects considering we are on limited memory.

what do u think guys? :frowning:

Each time you move the player’s sprite, check to see if its position is above the hole’s position. If it is, they fall!

Note: if you’re building the level background from a grid of tiles, you probably have some 2-D array of tiles (e.g. tileType[12][5] == 2, where 2 means ‘ladder’, 3 means ‘hole’, etc.). Now just create an extra array isSolid[], where isSolid[2] == true and isSolid[3] == false, etc. Now you can just check whether the player’s sprite’s position is above a tile for which isSolid[x][y] == true. (Typically they’ll be above 2 or 3 tiles, so you may have to check each of these). If none of the tiles below them is solid, they fall!

yup. my background is a grid of tiles. regarding the isSolid array, does that mean that my tiles will have to be sprites also?

btw, i encapsulated my image tiles into one single image. is that right?

tnx david :smiley:

Your tiles don’t need to be sprites. Instead, your tiled background needs to have its own class. Have a look at how the MIDP 2.0 game API works, and write similar classes yourself.

The tile image PNG file could have all the different tile type images in e.g. a horizontal row. Then you build the real background image by drawing the ‘frames’ of that resource file image repeatedly onto a big blank image according to your tile grid (array ‘tiles’ below).

Since you’ve got the tile grid, you can also use it to find out which type of tile is at a certain grid position. If you have an array (‘isSolid’ below) telling which types of tile are solid, you can use that in an ‘isSolid’ method.

Warning: the code below is an adaptation from memory of part of a (working) demo game I wrote, but I just typed it in now and I haven’t even tried to compile it - no guarantees! :wink: I’m afraid YABB does wierd things with its indentation :(.

`class Background {
static final int TILE_WIDTH = 8;
static final int TILE_HEIGHT = 8;
static final int TILE_COLUMNS = 7; // see grid below
static final int TILE_ROWS = 5; // see grid below
static private int[][] tiles = new int[][]
{ { 0, 0, 0, 0, 0, 0, 0 }, // 0 is empty space
{ 1, 1, 0, 1, 1, 2, 1 }, // 1 is solid rock, 2 is a ladder
{ 0, 0, 0, 0, 0, 2, 0 },
{ 0, 0, 1, 0, 0, 2, 0 },
{ 1, 1, 1, 1, 0, 1, 1 } };
static private boolean isSolid[] = new boolean[]
{ false, true, true }; // space, rock, ladder
private Image backgroundImg;

// tilesImg is 24x8 pixels, with the images for space,
// then rock, then ladder in a horizontal row
Background(Image tilesImg) {
    backgroundImg = Image.createImage(
        TILE_WIDTH * TILE_COLUMNS,
        TILE_HEIGHT * TILE_ROWS);
    Graphics bg = backgroundImg.getGraphics();
    for (int tx = 0; tx < TILE_COLUMNS; ++tx) {
        for (int ty = 0; ty < TILE_ROWS; ++ty) {
             bg.setClip(tx * TILE_WIDTH, ty * TILE_HEIGHT,
                             TILE_WIDTH, TILE_HEIGHT);
            // draw tilesImg offset left so correct frame hits clip window
            bg.drawImage(tilesImg,
                                     (tx - tiles[ty][tx]) * TILE_WIDTH,
                                     ty * TILE_HEIGHT,
                                     Graphics.TOP | Graphics.LEFT);
        }
    }
}

void paint(Graphics g, int x, int y) {
    g.drawImage(backgroundImg, x, y, Graphics.TOP | Graphics.LEFT);
}

// tx & ty are tile index, not pixel locations, i.e. 0..6 and 0..4
boolean isSolid(int tx, int ty) {
    return isSolid[tile[ty][tx]];
}

}`

I leave you the fun of working out which tiles to check beneath your sprite.

tnx david :slight_smile: i’ll study ur code first.

whew! how i wish all phones supports midp 2.0 so that it wouldn’t be this tough!

hi again david!

the situation’s like this:

my main character/sprite is fixed at the bottom left corner of the screen. everytime there is a keypress, the background moves, not the character.

problem is i can’t detect whether the sprite is already beneath the “not Solid” tile.

need help very badly…tnx :-[

[quote]problem is i can’t detect whether the sprite is already beneath the “not Solid” tile.
[/quote]
Here’s another method for that Background class that might help you - it checks whether a rectangle on the screen overlaps a solid tile in the background, by finding which tiles the rectangle overlaps and checking each one in turn:
boolean overlapsSolid(int x, int y, int width, int height) { boolean overlaps = false; int tileXmin = Math.max(0, x / TILE_WIDTH); int tileYmin = Math.max(0, y / TILE_HEIGHT); int tileXmax = Math.min(TILE_COLUMNS, (x + width - 1) / TILE_WIDTH); int tileYmax = Math.min(TILE_ROWS, (y + height - 1) / TILE_HEIGHT); for (int tx = tileXmin; tx <= tileXmax; ++tx) { for (int ty = tileYmin; ty <= tileYmax; ++ty) { if (isSolid(tx, ty)) { overlaps = true; break; } } } return overlaps; }

I assume that you start the character sprite in a place that doesn’t overlap any solid tiles. Now each time the player wants to move left, check that the one-pixel-wide column of pixels to his left doesn’t overlap any solid tiles:

if (!background.overlapsSolid(sprite.getX()-1, sprite.getY(), 1, sprite.getHeight()) { // can move left }

Similarly, to check whether the sprite is standing with nothing solid underneath, check the one-pixel-tall row of pixels below him:

if (!background.overlapsSolid(sprite.getX(), sprite.getY() + sprite.getHeight(), sprite.getWidth(), 1) { // sprite starts falling }

One note: if you’re not drawing the background at 0,0 on the screen, you need to think about how the background’s position affects the ‘x’ & ‘y’ parameters you pass to ‘overlapsSolid’.