public void bump(int x, int y, boolean canBreakBricks) { byte block = level.getBlock(x, y); if ((Level.TILE_BEHAVIORS[block & 0xff] & Level.BIT_BUMPABLE) > 0) { bumpInto(x, y - 1); level.setBlock(x, y, (byte) 4); // level.setBlockData(x, y, (byte) 4); if (((Level.TILE_BEHAVIORS[block & 0xff]) & Level.BIT_SPECIAL) > 0) { if (!mario.large) { addSprite(new Mushroom(this, x * 16 + 8, y * 16 + 8)); } else { addSprite(new FireFlower(this, x * 16 + 8, y * 16 + 8)); } } else { mario.getCoin(); coinsCollected++; // addSprite(new CoinAnim(x, y)); } } if ((Level.TILE_BEHAVIORS[block & 0xff] & Level.BIT_BREAKABLE) > 0) { bumpInto(x, y - 1); if (canBreakBricks) { level.setBlock(x, y, (byte) 0); } else { // level.setBlockData(x, y, (byte) 4); } } }
public void bumpInto(int x, int y) { byte block = level.getBlock(x, y); if (((Level.TILE_BEHAVIORS[block & 0xff]) & Level.BIT_PICKUPABLE) > 0) { mario.getCoin(); coinsCollected++; level.setBlock(x, y, (byte) 0); } for (Sprite sprite : sprites) { sprite.bumpCheck(x, y); } }
// Update internal level representation to what we get from the API. // includes some gap detection code public boolean setLevelScene(byte[][] data) { int HalfObsWidth = 11; int HalfObsHeight = 11; int MarioXInMap = (int) mario.x / 16; int MarioYInMap = (int) mario.y / 16; boolean gapAtLast = true; boolean gapAtSecondLast = true; int lastEventX = 0; int[] heights = new int[22]; for (int i = 0; i < heights.length; i++) heights[i] = 0; int gapBorderHeight = 0; int gapBorderMinusOneHeight = 0; int gapBorderMinusTwoHeight = 0; for (int y = MarioYInMap - HalfObsHeight, obsX = 0; y < MarioYInMap + HalfObsHeight; y++, obsX++) { for (int x = MarioXInMap - HalfObsWidth, obsY = 0; x < MarioXInMap + HalfObsWidth; x++, obsY++) { if (x >= 0 && x <= level.xExit && y >= 0 && y < level.height && obsX < data.length && obsY < data.length) { byte datum = data[obsX][obsY]; if (datum != 0 && datum != -10 && datum != 1 && obsY > lastEventX) { lastEventX = obsY; } if (datum != 0 && datum != 1) { if (heights[obsY] == 0) { heights[obsY] = y; } } // cannon detection: if there's a one-block long hill, it's a cannon! // i think this is not required anymore, because we get the cannon data straight from the // API. if (x == MarioXInMap + HalfObsWidth - 3 && datum != 0 && y > 5) { if (gapBorderMinusTwoHeight == 0) gapBorderMinusTwoHeight = y; } if (x == MarioXInMap + HalfObsWidth - 2 && datum != 0 && y > 5) { if (gapBorderMinusOneHeight == 0) gapBorderMinusOneHeight = y; gapAtSecondLast = false; } if (x == MarioXInMap + HalfObsWidth - 1 && datum != 0 && y > 5) { if (gapBorderHeight == 0) gapBorderHeight = y; gapAtLast = false; } if (datum != 1 && level.getBlock(x, y) != 14) level.setBlock(x, y, datum); } } } if (gapBorderHeight == gapBorderMinusTwoHeight && gapBorderMinusOneHeight < gapBorderHeight) { // found a cannon! // System.out.println("Got a cannon!"); level.setBlock(MarioXInMap + HalfObsWidth - 2, gapBorderMinusOneHeight, (byte) 14); } if (gapAtLast && !gapAtSecondLast) { // found a gap. int holeWidth = 3; // make the gap wider before we see the end to allow ample time for the // planner to jump over. for (int i = 0; i < holeWidth; i++) { for (int j = 0; j < 15; j++) { level.setBlock(MarioXInMap + HalfObsWidth + i, j, (byte) 0); } level.isGap[MarioXInMap + HalfObsWidth + i] = true; level.gapHeight[MarioXInMap + HalfObsWidth + i] = gapBorderMinusOneHeight; } for (int j = gapBorderMinusOneHeight; j < 16; j++) { level.setBlock(MarioXInMap + HalfObsWidth + holeWidth, gapBorderMinusOneHeight, (byte) 4); } return true; } return false; }