Game Android

/*
 *                 [[ Frozen-Bubble ]]
 *
 * Copyright (c) 2000-2003 Guillaume Cottenceau.
 * Java sourcecode - Copyright (c) 2003 Glenn Sanson.
 *
 * This code is distributed under the GNU General Public License
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 * Artwork:
 *    Alexis Younes <73lab at free.fr>
 *      (everything but the bubbles)
 *    Amaury Amblard-Ladurantie 
 *      (the bubbles)
 *
 * Soundtrack:
 *    Matthias Le Bidan 
 *      (the three musics and all the sound effects)
 *
 * Design & Programming:
 *    Guillaume Cottenceau 
 *      (design and manage the project, whole Perl sourcecode)
 *
 * Java version:
 *    Glenn Sanson 
 *      (whole Java sourcecode, including JIGA classes
 *             http://glenn.sanson.free.fr/jiga/)
 *
 * Android port:
 *    Pawel Aleksander Fedorynski 
 *
 *          [[ http://glenn.sanson.free.fr/fb/ ]]
 *          [[ http://www.frozen-bubble.org/   ]]
 */
//package ch.racic.frozenegg;
import java.util.Random;
import java.util.Vector;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Bundle;
public class PenguinSprite extends Sprite {
  public final static int STATE_TURN_LEFT = 0;
  public final static int STATE_TURN_RIGHT = 1;
  public final static int STATE_FIRE = 2;
  public final static int STATE_VOID = 3;
  public final static int STATE_GAME_WON = 4;
  public final static int STATE_GAME_LOST = 5;
  public final static int[][] LOST_SEQUENCE = { { 1, 0 }, { 2, 8 }, { 3, 9 },
      { 4, 10 }, { 5, 11 }, { 6, 12 }, { 7, 13 }, { 5, 14 } };
  public final static int[][] WON_SEQUENCE = { { 1, 0 }, { 2, 7 }, { 3, 6 },
      { 4, 15 }, { 5, 16 }, { 6, 17 }, { 7, 18 }, { 4, 19 } };
  private final BmpWrap spritesImage;
  private int currentPenguin;
  private int count;
  private final Random rand;
  private int finalState;
  private int nextPosition;
  public PenguinSprite(BmpWrap sprites, Random rand) {
    super(new Rect(361, 436, 361 + 55, 436 + 43));
    spritesImage = sprites;
    this.rand = rand;
    currentPenguin = 0;
    finalState = STATE_VOID;
    nextPosition = 0;
  }
  public PenguinSprite(BmpWrap sprites, Random rand, int currentPenguin,
      int count, int finalState, int nextPosition) {
    super(new Rect(361, 436, 361 + 55, 436 + 43));
    spritesImage = sprites;
    this.rand = rand;
    this.currentPenguin = currentPenguin;
    this.count = count;
    this.finalState = finalState;
    this.nextPosition = nextPosition;
  }
  @Override
  public void saveState(Bundle map, Vector saved_sprites) {
    if (getSavedId() != -1)
      return;
    super.saveState(map, saved_sprites);
    map.putInt(String.format("%d-currentPenguin", getSavedId()),
        currentPenguin);
    map.putInt(String.format("%d-count", getSavedId()), count);
    map.putInt(String.format("%d-finalState", getSavedId()), finalState);
    map.putInt(String.format("%d-nextPosition", getSavedId()), nextPosition);
  }
  @Override
  public int getTypeId() {
    return Sprite.TYPE_PENGUIN;
  }
  public void updateState(int state) {
    if (finalState != STATE_VOID) {
      count++;
      if (count % 6 == 0) {
        if (finalState == STATE_GAME_LOST) {
          currentPenguin = LOST_SEQUENCE[nextPosition][1];
          nextPosition = LOST_SEQUENCE[nextPosition][0];
        } else if (finalState == STATE_GAME_WON) {
          currentPenguin = WON_SEQUENCE[nextPosition][1];
          nextPosition = WON_SEQUENCE[nextPosition][0];
        }
      }
    } else {
      count++;
      switch (state) {
      case STATE_TURN_LEFT:
        count = 0;
        currentPenguin = 3;
        break;
      case STATE_TURN_RIGHT:
        count = 0;
        currentPenguin = 2;
        break;
      case STATE_FIRE:
        count = 0;
        currentPenguin = 1;
        break;
      case STATE_VOID:
        if ((currentPenguin < 4) || (currentPenguin > 7)) {
          currentPenguin = 0;
        }
        break;
      case STATE_GAME_WON:
      case STATE_GAME_LOST:
        count = 0;
        finalState = state;
        currentPenguin = 0;
        return;
      }
      if (count > 100) {
        currentPenguin = 7;
      } else if ((count % 15 == 0) && (count > 25)) {
        currentPenguin = (rand.nextInt() % 3) + 4;
        if (currentPenguin < 4) {
          currentPenguin = 0;
        }
      }
    }
  }
  @Override
  public void paint(Canvas c, double scale, int dx, int dy) {
    Rect r = getSpriteArea();
    drawImageClipped(spritesImage, 360 - (currentPenguin % 4) * 57,
        435 - (currentPenguin / 4) * 45, r, c, scale, dx, dy);
  }
}
abstract class Sprite {
  public static int TYPE_BUBBLE = 1;
  public static int TYPE_IMAGE = 2;
  public static int TYPE_LAUNCH_BUBBLE = 3;
  public static int TYPE_PENGUIN = 4;
  private Rect spriteArea;
  private int saved_id;
  public Sprite(Rect spriteArea) {
    this.spriteArea = spriteArea;
    saved_id = -1;
  }
  public void saveState(Bundle map, Vector saved_sprites) {
    if (saved_id != -1)
      return;
    saved_id = saved_sprites.size();
    saved_sprites.addElement(this);
    map.putInt(String.format("%d-left", saved_id), spriteArea.left);
    map.putInt(String.format("%d-right", saved_id), spriteArea.right);
    map.putInt(String.format("%d-top", saved_id), spriteArea.top);
    map.putInt(String.format("%d-bottom", saved_id), spriteArea.bottom);
    map.putInt(String.format("%d-type", saved_id), getTypeId());
  }
  public final int getSavedId() {
    return saved_id;
  }
  public final void clearSavedId() {
    saved_id = -1;
  }
  public abstract int getTypeId();
  public void changeSpriteArea(Rect newArea) {
    spriteArea = newArea;
  }
  public final void relativeMove(Point p) {
    spriteArea = new Rect(spriteArea);
    spriteArea.offset(p.x, p.y);
  }
  public final void relativeMove(int x, int y) {
    spriteArea = new Rect(spriteArea);
    spriteArea.offset(x, y);
  }
  public final void absoluteMove(Point p) {
    spriteArea = new Rect(spriteArea);
    spriteArea.offsetTo(p.x, p.y);
  }
  public final Point getSpritePosition() {
    return new Point(spriteArea.left, spriteArea.top);
  }
  public final Rect getSpriteArea() {
    return spriteArea;
  }
  public static void drawImage(BmpWrap image, int x, int y, Canvas c,
      double scale, int dx, int dy) {
    c.drawBitmap(image.bmp, (float) (x * scale + dx),
        (float) (y * scale + dy), null);
  }
  public static void drawImageClipped(BmpWrap image, int x, int y,
      Rect clipr, Canvas c, double scale, int dx, int dy) {
    c.save(Canvas.CLIP_SAVE_FLAG);
    c.clipRect((float) (clipr.left * scale + dx), (float) (clipr.top
        * scale + dy), (float) (clipr.right * scale + dx),
        (float) (clipr.bottom * scale + dy), Region.Op.REPLACE);
    c.drawBitmap(image.bmp, (float) (x * scale + dx),
        (float) (y * scale + dy), null);
    c.restore();
  }
  public abstract void paint(Canvas c, double scale, int dx, int dy);
}
/*
 * [[ Frozen-Bubble ]]
 * 
 * Copyright (c) 2000-2003 Guillaume Cottenceau. Java sourcecode - Copyright (c)
 * 2003 Glenn Sanson.
 * 
 * This code is distributed under the GNU General Public License
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2, as published by the
 * Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
 * Ave, Cambridge, MA 02139, USA.
 * 
 * 
 * Artwork: Alexis Younes <73lab at free.fr> (everything but the bubbles) Amaury
 * Amblard-Ladurantie  (the bubbles)
 * 
 * Soundtrack: Matthias Le Bidan  (the three
 * musics and all the sound effects)
 * 
 * Design & Programming: Guillaume Cottenceau 
 * (design and manage the project, whole Perl sourcecode)
 * 
 * Java version: Glenn Sanson  (whole Java sourcecode,
 * including JIGA classes http://glenn.sanson.free.fr/jiga/)
 * 
 * Android port: Pawel Aleksander Fedorynski 
 * 
 * [[ http://glenn.sanson.free.fr/fb/ ]] [[ http://www.frozen-bubble.org/ ]]
 */
// Various classes take arguments of this type during construction. We need
// one level of indirection in case we want to swap the images from under them
// (e.g., to resize them when the surface resolution changes.) We couldn't
// do it if references to Bitmap were kept directly everywhere since you can't
// overwrite an Android Bitmap in place (or at least I haven't found how to
// do it.)
class BmpWrap {
  BmpWrap(int id) {
    this.id = id;
  }
  public Bitmap bmp;
  // Image id used for saving and restoring the image sprites.
  public int id;
}