📄 demogamecanvas.java
字号:
package demo;import java.io.IOException;import java.util.Timer;import java.util.TimerTask;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.game.GameCanvas;import javax.microedition.lcdui.game.LayerManager;import javax.microedition.lcdui.game.Sprite;import javax.microedition.lcdui.game.TiledLayer;/** * * @author Sławomir Król * @version 1.0 */public class DemoGameCanvas extends GameCanvas implements Runnable { private static final int SPEED = 4; private static final int MIN_BUFFER = 20; private int viewPortX = 0; private int viewPortY = 0; private byte lastDirection = -1; private TiledLayer tlBackground; private boolean interrupted; private LayerManager lm; private GameDesign gameDesign; private Timer timer; private Sprite spriteMario; private SpriteAnimationTask spriteMarioAnimator; private Sprite spriteGoomba; private SpriteAnimationTask spriteGoombaAnimator; private SpriteRandomMovement spriteGoombaRandomMovement; private Sprite spriteBomb; private SpriteAnimationTask spriteBombAnimator; //private TiledLayer tlWater; private TiledLayer tlTrees; private TiledLayer tlRocks; //private TileAnimationTask waterAnimator; public DemoGameCanvas() { super(true); try { this.setFullScreenMode(true); this.init(); } catch (IOException ex) { ex.printStackTrace(); } } /** * Initialize the Game Design, then load all layers and start animation threads. */ private void init() throws IOException { this.timer = new Timer(); this.gameDesign = new GameDesign(); this.spriteMario = gameDesign.getMario(); //define the reference in the midle of sprites frame so that transformations work well this.spriteMario.defineReferencePixel(8, 8); this.spriteMarioAnimator = new SpriteAnimationTask(this.spriteMario, false); this.timer.scheduleAtFixedRate(this.spriteMarioAnimator, 0, gameDesign.MarioSeqWalkDownDelay); this.spriteBomb = gameDesign.getBomb(); this.spriteBomb.defineReferencePixel(8, 8); this.spriteBombAnimator = new SpriteAnimationTask(this.spriteBomb, false); this.timer.scheduleAtFixedRate(this.spriteBombAnimator, 0, gameDesign.BombSeqTickingDelay); this.tlRocks = this.gameDesign.getRocks(); this.tlTrees = this.gameDesign.getTrees(); //this.tlWater = this.gameDesign.getWater(); this.tlBackground = this.gameDesign.getBackground(); this.lm = new LayerManager(); gameDesign.updateLayerManagerForForest(lm); this.spriteGoomba = gameDesign.getGoomba(); //define the reference in the midle of sprites frame so that transformations work well this.spriteGoomba.defineReferencePixel(8, 8); this.spriteGoombaAnimator = new SpriteAnimationTask(this.spriteGoomba, true); this.spriteGoombaAnimator.setMoving(true); this.timer.scheduleAtFixedRate(this.spriteGoombaAnimator, 0, gameDesign.GoombaSeqWalkSideDelay); this.spriteGoombaRandomMovement = new SpriteRandomMovement(this, spriteGoomba); this.spriteGoombaRandomMovement.setSequences( gameDesign.GoombaSeqWalkDown, Sprite.TRANS_NONE, gameDesign.GoombaSeqWalkUp, Sprite.TRANS_NONE, gameDesign.GoombaSeqWalkLeft, Sprite.TRANS_NONE, gameDesign.GoombaSeqWalkSide, Sprite.TRANS_NONE ); (new Thread(spriteGoombaRandomMovement)).start(); } /** * Check if sprite collides with either the other sprite or * with a layer that holds obstacles or with the edge of the Background layer. * * @param sprite the sprite checked for collision with other layers * @return true is sprite does collide, false otherwise */ public boolean spriteCollides(Sprite sprite) { return sprite.collidesWith( sprite == this.spriteMario ? this.spriteGoomba : this.spriteMario, true) || sprite.collidesWith(this.tlRocks, true) || sprite.collidesWith(this.tlTrees, true) || sprite.collidesWith(this.spriteBomb,true) //|| sprite.collidesWith(this.tlWater, true) || sprite.getX() < 0 || sprite.getY() < 0 || sprite.getX() > (this.tlBackground.getWidth() - sprite.getWidth()) || sprite.getY() > (this.tlBackground.getHeight() - sprite.getHeight() ); } /** * Adjust the viewport to keep the main animated sprite inside the screen. * The coordinates are checked for game bounaries and adjusted only if it * makes sense. * * @param x viewport X coordinate * @param y viewport Y coordinate */ private void adjustViewport(int x, int y) { int sx = this.spriteMario.getX(); int sy = this.spriteMario.getY(); int xmin = this.viewPortX + MIN_BUFFER; int xmax = this.viewPortX + this.getWidth() - this.spriteMario.getWidth() - MIN_BUFFER; int ymin = this.viewPortY + MIN_BUFFER; int ymax = this.viewPortY + this.getHeight() - this.spriteMario.getHeight() - MIN_BUFFER; //if the sprite is not near the any screen edges don't adjust if (sx >= xmin && sx <= xmax && sy >= ymin && sy <= ymax) { return; } //if the sprite is moving left but isn't near the left edge of the screen don't adjust if (this.lastDirection == LEFT && sx >= xmin) { return; } //if the sprite is moving right but isn't near the right edge of the screen don't adjust if (this.lastDirection == RIGHT && sx <= xmax) { return; } //if the sprite is moving up but isn't at near top edge of the screen don't adjust if (this.lastDirection == UP && sy >= ymin) { return; } //if the sprite is moving down but isn't at near bottom edge of the screen don't adjust if (this.lastDirection == DOWN && sy <= ymax) { return; } //only adjust x to values that ensure the Background tiled layer remains visible //and no white space is shown if (x < this.tlBackground.getX()) { this.viewPortX = this.tlBackground.getX(); } else if (x > this.tlBackground.getX() + this.tlBackground.getWidth() - this.getWidth()) { this.viewPortX = this.tlBackground.getX() + this.tlBackground.getWidth() - this.getWidth(); } else { this.viewPortX = x; } //only adjust y to values that ensure the Background tiled layer remains visible //and no white space is shown if (y < this.tlBackground.getY()) { this.viewPortY = this.tlBackground.getY(); } else if (y > this.tlBackground.getY() + this.tlBackground.getHeight() - this.getHeight()) { this.viewPortY = this.tlBackground.getY() + this.tlBackground.getHeight() - this.getHeight(); } else { this.viewPortY = y; } //adjust the viewport this.lm.setViewWindow(this.viewPortX, this.viewPortY, this.getWidth(), this.getHeight()); } /** * The main game loop that checks for user input and repaints canvas. */ public void run() { Graphics g = getGraphics(); while (!this.interrupted) { //check for user input int keyState = getKeyStates(); //if user is pressing the left button if ((keyState & LEFT_PRESSED) != 0) { //if the previous direction was other than left set the sequence //correct sequence & transform needed for walking to the left if (this.lastDirection != LEFT) { this.lastDirection = LEFT; this.spriteMario.setFrameSequence(gameDesign.MarioSeqWalkSide); this.spriteMario.setTransform(Sprite.TRANS_MIRROR); continue; } //assign the sequence playback direction this.spriteMarioAnimator.forward(); //move the sprite to the left this.spriteMario.move(-SPEED, 0); //if moving the sprite generates a collision return sprite back //to its original position if (this.spriteCollides(this.spriteMario)) { this.spriteMario.move(SPEED, 0); continue; } //attempt to adjust the viewport to keep the sprite on the screen this.adjustViewport(this.viewPortX - SPEED, this.viewPortY); } else if ((keyState & RIGHT_PRESSED) != 0) { if (this.lastDirection != RIGHT) { this.lastDirection = RIGHT; this.spriteMario.setFrameSequence(gameDesign.MarioSeqWalkSide); this.spriteMario.setTransform(Sprite.TRANS_NONE); continue; } this.spriteMarioAnimator.forward(); this.spriteMario.move(SPEED, 0); if (this.spriteCollides(this.spriteMario)) { this.spriteMario.move(-SPEED, 0); continue; } this.adjustViewport(this.viewPortX + SPEED, this.viewPortY); } else if ((keyState & UP_PRESSED) != 0) { if (this.lastDirection != UP) { this.lastDirection = UP; this.spriteMario.setFrameSequence(gameDesign.MarioSeqWalkUp); this.spriteMario.setTransform(Sprite.TRANS_NONE); continue; } this.spriteMarioAnimator.forward(); this.spriteMario.move(0, -SPEED); if (this.spriteCollides(this.spriteMario)) { this.spriteMario.move(0, SPEED); continue; } this.adjustViewport(this.viewPortX, this.viewPortY - SPEED); } else if ((keyState & DOWN_PRESSED) != 0) { if (this.lastDirection != DOWN) { this.lastDirection = DOWN; this.spriteMario.setFrameSequence(gameDesign.MarioSeqWalkDown); this.spriteMario.setTransform(Sprite.TRANS_NONE); continue; } this.spriteMarioAnimator.forward(); this.spriteMario.move(0, SPEED); if (this.spriteCollides(this.spriteMario)) { this.spriteMario.move(0, -SPEED); continue; } this.adjustViewport(this.viewPortX, this.viewPortY + SPEED); }else if((keyState & FIRE_PRESSED) != 0){ //Wlaczenie bomby }else { this.spriteMarioAnimator.setMoving(false); } this.lm.paint(g, 0, 0); flushGraphics(0, 0, this.getWidth(), this.getHeight()); try { Thread.sleep(20); } catch (InterruptedException ex) { ex.printStackTrace(); } } } /** * Stops the main game loop. */ public void stop() { this.interrupted = true; this.spriteGoombaRandomMovement.stop(); }/** * Animates a sprite. */ private class SpriteAnimationTask extends TimerTask { private boolean moving = false; private boolean forward = true; private Sprite sprite; public SpriteAnimationTask(Sprite sprite, boolean forward) { this.sprite = sprite; this.forward = forward; } public void run() { if (!this.moving) { return; } if (this.forward) { this.sprite.nextFrame(); } else { this.sprite.prevFrame(); } } public void forward() { this.forward = true; this.moving = true; } public void backward() { this.forward = false; this.moving = true; } public void setMoving(boolean isMoving) { this.moving = isMoving; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -