?? base.java
字號:
// Copyright 2003 Nokia Corporation.//// THIS SOURCE CODE IS PROVIDED 'AS IS', WITH NO WARRANTIES WHATSOEVER,// EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, FITNESS// FOR ANY PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE// OR TRADE PRACTICE, RELATING TO THE SOURCE CODE OR ANY WARRANTY OTHERWISE// ARISING OUT OF ANY PROPOSAL, SPECIFICATION, OR SAMPLE AND WITH NO// OBLIGATION OF NOKIA TO PROVIDE THE LICENSEE WITH ANY MAINTENANCE OR// SUPPORT. FURTHERMORE, NOKIA MAKES NO WARRANTY THAT EXERCISE OF THE// RIGHTS GRANTED HEREUNDER DOES NOT INFRINGE OR MAY NOT CAUSE INFRINGEMENT// OF ANY PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OWNED OR CONTROLLED// BY THIRD PARTIES//// Furthermore, information provided in this source code is preliminary,// and may be changed substantially prior to final release. Nokia Corporation// retains the right to make changes to this source code at// any time, without notice. This source code is provided for informational// purposes only.//// Nokia and Nokia Connecting People are registered trademarks of Nokia// Corporation.// Java and all Java-based marks are trademarks or registered trademarks of// Sun Microsystems, Inc.// Other product and company names mentioned herein may be trademarks or// trade names of their respective owners.//// A non-exclusive, non-transferable, worldwide, limited license is hereby// granted to the Licensee to download, print, reproduce and modify the// source code. The licensee has the right to market, sell, distribute and// make available the source code in original or modified form only when// incorporated into the programs developed by the Licensee. No other// license, express or implied, by estoppel or otherwise, to any other// intellectual property rights is granted herein.import javax.microedition.lcdui.*;// The player uses the base (or ship) to fly up, down, left and right.// It can fire bullets at blocks. Base is also used to draw itself.class Base{ final static int COLOR = 0xFFFF00; // YELLOW final static int MAX_CANNON_COOLDOWN_TICKS = (12000 / GameManager.MILLIS_PER_TICK); // 12 seconds final static int MAX_CANNON_HEAT = 2; final static int MAX_CANNON_FIRE_RATE = 2; // 2 bullets per second private final GameManager gameManager; private final int xMin; private final int yMin; private final int xMax; private final int yMax; private final int dx; private final int dy; private final int dCannon; private final boolean useLimitedFiringRate; private int x; private int y; private int w; private int h; private int xCannon; private int yCannon; private int collideTicks = 0; private int lives; private boolean gameActionLeft = false; private boolean gameActionRight = false; private boolean gameActionUp = false; private boolean gameActionDown = false; private boolean gameActionFire = false; private int clockTickMillis = 0; private int clockTickSeconds = 0; private int cannonHeat = 0; private int cannonCoolDownTicks = 0; private int cannonFireCount = 0; // bullets private int cannonFireRate = 0; // bullets/sec Base(GameManager gameManager, boolean useLimitedFiringRate, int lives, int xMin, int yMin, int xMax, int yMax) { this.gameManager = gameManager; this.lives = lives; this.xMin = xMin; this.yMin = yMin; this.xMax = xMax; this.yMax = yMax; this.useLimitedFiringRate = useLimitedFiringRate; // In general, the height and width of the base only need to depend // on the game screen's size (xMin, xMax, yMin, yMax). // I've chosen to make the base about the same size as the blocks, // which is why the Block size dimensions are used below. h = (9 * Block.getDimension()) / 10; // base height is 90% of block's if (h > (yMax / 8)) { h = yMax / 8; } w = h / 2; y = (yMax - h) / 2; x = xMin; dCannon = h / 3; xCannon = w; yCannon = y + ((h - dCannon) / 2); dy = h / 2; dx = w; } public void tick() { if (collideTicks > 0) { collideTicks--; } if (cannonCoolDownTicks > 0) { cannonCoolDownTicks--; } if (gameActionUp) { // move up if ((y - dy) >= yMin) { y -= dy; } else if ((y - (dy / 4)) >= yMin) { // use a smaller step near a boundary y -= (dy / 4); } } else if (gameActionDown) { // move down if ((y + dy) <= (yMax - h)) { y += dy; } else if ((y + (dy / 4)) <= (yMin - h)) { // use a smaller step near a boundary y += (dy / 4); } } if (gameActionLeft) { // move left if ((x - dx) >= xMin) { x -= dx; } } if (gameActionRight) { // move right if ((x + dx) <= (xMax - w - dCannon)) { x += dx; } } yCannon = y + ((h - dCannon) / 2); xCannon = x + w; // ticking of virtual millisecond clock clockTickMillis++; int millis = (clockTickMillis * GameManager.MILLIS_PER_TICK); int seconds = millis / 1000; boolean isNewSecondTick = false; if (seconds > clockTickSeconds) { clockTickSeconds = seconds; cannonFireRate = cannonFireCount / seconds; isNewSecondTick = true; } if (gameActionFire) { if (!useLimitedFiringRate) { // There are no limits on firing the cannon. We may fire it. int d = dCannon; // Bullet is d x d pixels Bullet b = new Bullet(xCannon, xMax, yCannon, d, d, (2 * d)); gameManager.addBullet(b); } else { if (cannonCoolDownTicks == 0) { // compute the cannon's firing rate and heat every second if (isNewSecondTick) { if (cannonFireRate >= MAX_CANNON_FIRE_RATE) { cannonHeat++; } else { if (cannonHeat > 0) { cannonHeat--; } } } if (cannonHeat > MAX_CANNON_HEAT) { // The cannon is overheating due to excessive // continuous firing, and will be cooled down // by setting cannonCoolDownTicks. It is not fired. cannonCoolDownTicks = MAX_CANNON_COOLDOWN_TICKS; cannonFireCount = 0; cannonHeat = 0; clockTickMillis = 0; clockTickSeconds = 0; } else { // We may fire the cannon. int d = dCannon; // Bullet is d x d pixels Bullet b = new Bullet(xCannon, xMax, yCannon, d, d, (2 * d)); gameManager.addBullet(b); cannonFireCount++; } } else { // The cannon is cooling down, and can not be fired // until it has cooled down. if (isNewSecondTick) { reduceCannonHeat(); } } } } else { // The player is not pressing the game fire action, // we can cool down the cannon if needed. if (useLimitedFiringRate && isNewSecondTick && (cannonHeat > 0)) { reduceCannonHeat(); } } } private void reduceCannonHeat() { if (cannonHeat > 0) { cannonHeat--; } if (cannonHeat == 0) { cannonFireCount = 0; cannonFireRate = 0; clockTickMillis = 0; clockTickSeconds = 0; } } int getCannonHeat() { return cannonHeat; } int getCannonCoolDownTicks() { return cannonCoolDownTicks; } void gameActionPressed(int action, boolean isPressed) { switch (action) { case Canvas.UP: gameActionUp = isPressed; break; case Canvas.DOWN: gameActionDown = isPressed; break; case Canvas.LEFT: gameActionLeft = isPressed; break; case Canvas.RIGHT: gameActionRight = isPressed; break; case Canvas.FIRE: gameActionFire = isPressed; break; } } void draw(Graphics g) { g.setColor(COLOR); // draw the body of the base if (collideTicks > 0) { // 'Just collided' // during the 'isColliding' state, we draw base's body // as 'flashing' to indicate this state to the player if ((collideTicks % 2) == 0) { // even tick: un-filled rectangle g.drawRect(x, y, (w - 1), (h - 1)); } else { // odd tick: filled rectangle g.fillRect(x, y, w, h); } } else { // 'Not colliding' // use a filled rectangle with the default base color g.fillRect(x, y, w, h); } // draw the cannon of the base if (cannonCoolDownTicks > 0) { g.drawRect(xCannon, yCannon, dCannon - 1, dCannon - 1); } else { g.fillRect(xCannon, yCannon, dCannon, dCannon); } } int getX() { return x; } int getY() { return y; } int getWidth() { return w; } int getCannonDimension() { return dCannon; } int getHeight() { return h; } int getLives() { if (lives < 0) { lives = 0; } return lives; } void doCollision() { lives--; // For two seconds, the base is in a state of 'isColliding'. // This is indicated by collideTicks > 0. collideTicks is decremented // by method tick. During this state, new block collisions do not // affect the base. // // This was done so that if the base is hit simultaneously by two // blocks, that its life count is only decremented by one rather // than by two. // // The base's draw method draws a 'flashing base' during the // 'isColliding' state. collideTicks = (2000 / GameManager.MILLIS_PER_TICK); } boolean isColliding() { return collideTicks > 0; }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -