예제 #1
0
  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);
      }
    }
  }
예제 #2
0
  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);
    }
  }
예제 #3
0
  public void init() {
    Level.loadBehaviors();

    Sprite.spriteContext = this;
    sprites.clear();

    mario = new Mario(this);
    sprites.add(mario);
    startTime = 1;

    timeLeft = totalTime * 15;

    tick = 1;
  }
예제 #4
0
  // 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;
  }
예제 #5
0
  public void tick() {
    // advance the world state. directly from the original physics engine.
    timeLeft--;
    if (timeLeft == 0) {
      mario.die();
    }
    xCamO = xCam;
    yCamO = yCam;

    if (startTime > 0) {
      startTime++;
    }

    float targetXCam = mario.x - 160;

    xCam = targetXCam;

    if (xCam < 0) xCam = 0;
    if (xCam > level.width * 16 - 320) xCam = level.width * 16 - 320;

    fireballsOnScreen = 0;

    for (Sprite sprite : sprites) {
      if (sprite != mario) {
        float xd = sprite.x - xCam;
        float yd = sprite.y - yCam;
        if (xd < -64 || xd > 320 + 64 || yd < -64 || yd > 240 + 64) {
          removeSprite(sprite);
        } else {
          if (sprite instanceof Fireball) {
            fireballsOnScreen++;
          }
        }
      }
    }
    if (paused) {
      for (Sprite sprite : sprites) {
        if (sprite == mario) {
          sprite.tick();
        } else {
          sprite.tickNoMove();
        }
      }
    } else {
      tick++;
      level.tick();

      for (int x = (int) xCam / 16 - 1; x <= (int) (xCam + 320) / 16 + 1; x++)
        for (int y = (int) yCam / 16 - 1; y <= (int) (yCam + 240) / 16 + 1; y++) {
          int dir = 0;

          if (x * 16 + 8 > mario.x + 16) dir = -1;
          if (x * 16 + 8 < mario.x - 16) dir = 1;

          if (dir != 0) {
            byte b = level.getBlock(x, y);
            if (((Level.TILE_BEHAVIORS[b & 0xff]) & Level.BIT_ANIMATED) > 0) {
              if ((b % 16) / 4 == 3 && b / 16 == 0) {
                if ((tick - x * 2) % 100 == 0) {
                  addSprite(new BulletBill(this, x * 16 + 8 + dir * 8, y * 16 + 15, dir));
                }
              }
            }
          }
        }

      for (Sprite sprite : sprites) {
        sprite.tick();
      }

      for (Sprite sprite : sprites) {
        sprite.collideCheck();
      }
      // System.out.println("Sim Mario ya: " + mario.ya);
      for (Shell shell : shellsToCheck) {
        for (Sprite sprite : sprites) {
          if (sprite != shell && !shell.dead) {
            if (sprite.shellCollideCheck(shell)) {
              if (mario.carried == shell && !shell.dead) {
                mario.carried = null;
                shell.die();
              }
              enemiesKilled++;
            }
          }
        }
      }
      shellsToCheck.clear();

      for (Fireball fireball : fireballsToCheck) {
        for (Sprite sprite : sprites) {
          if (sprite != fireball && !fireball.dead) {
            if (sprite.fireballCollideCheck(fireball)) {
              fireball.die();
              enemiesKilled++;
            }
          }
        }
      }
      fireballsToCheck.clear();
    }

    sprites.addAll(0, spritesToAdd);
    sprites.removeAll(spritesToRemove);
    spritesToAdd.clear();
    spritesToRemove.clear();
  }