⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gametank.java

📁 一个非常不错的J2ME坦克大战的游戏,可以在机顶盒上实际运行.
💻 JAVA
字号:
package com.ipanel.games.tank;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;

public class GameTank implements bulletTarget, boomDrawer {

	private static Image imageTank = null;

	private Sprite spriteTank = null;

	private final int FRAME_SEQUENCE_UP = 0;

	private final int FRAME_SEQUENCE_RIGHT = 1;

	private final int FRAME_SEQUENCE_DOWN = 2;

	private final int FRAME_SEQUENCE_LEFT = 3;

	private static Image imageBoom = null;

	/**
	 * 程序中所有N处不同地方使用的Random,应该是各不相同的,所以用这个数组来存储。 但是由此引发的是,必须保证不会出现数组越界的行为。
	 */
	private IPTankRandom[] tankRandoms = null;

	private Timer timer = new Timer();

	private int X_INIT;

	private int Y_INIT;

	private final int NO_ACTION = 0;

	private final int ACTION_DIRECTION_UP = 1;

	private final int ACTION_DIRECTION_DOWN = 2;

	private final int ACTION_DIRECTION_LEFT = 3;

	private final int ACTION_DIRECTION_RIGHT = 4;

	private final int ACTION_MOVE = 5;

	private final int ACTION_FIRE = 6;

	private final int DIRECTION_UP = 1;

	private final int DIRECTION_DOWN = 2;

	private final int DIRECTION_LEFT = 3;

	private final int DIRECTION_RIGHT = 4;

	private final GameLayer layer;

	private int iDirection;

	private int X;

	private int Y;

	private final int STEP;

	private final int MAX_FIRE_NUMBER = 2;

	private int iFireNumber = 0;

	/**
	 * 调度时间的间隔。 这同时影响到ACTION的速度,和对canvas.paint()的配合。
	 */
	private final int TIMER_INTERVAL = 50;

	static {
		/*
		 * try { // imageTank = Image.createImage("/res/TankAll.png"); imageTank =
		 * Image.createImage("/res/Tank.png"); imageBoom =
		 * Image.createImage("/res/explosion13.png"); } catch (IOException e) {
		 * System.out.println("Exception when createImage in GameTank()!"); }
		 */
	}

	public GameTank(GameLayer layer, long lRandomSeed) throws IOException {
		super();

		this.layer = layer;
		try {
			imageTank = Image.createImage("/res/EnemyTankAll.png");
			// imageTank = Image.createImage("/res/TankAll.png");
			imageBoom = Image.createImage("/res/explosion13.png");
		} catch (IOException e) {
			layer.paintException("Exception when createImage in GameTank()!");
			throw e;
		}
		// spriteTank = new Sprite(imageTank);
		spriteTank = new Sprite(imageTank, 32, 32);

		spriteTank
				.setFrameSequence(new int[] { FRAME_SEQUENCE_UP,
						FRAME_SEQUENCE_RIGHT, FRAME_SEQUENCE_DOWN,
						FRAME_SEQUENCE_LEFT });

		tankRandoms = new IPTankRandom[] { new IPTankRandom(lRandomSeed),
				new IPTankRandom(lRandomSeed / 2),
				new IPTankRandom(lRandomSeed * 3),
				new IPTankRandom(lRandomSeed / 5),
				new IPTankRandom(lRandomSeed * 10) };

		initPosition();
		X = X_INIT;
		Y = Y_INIT;
		spriteTank.setPosition(X, Y);
		iDirection = DIRECTION_DOWN;
		spriteTank.setFrame(FRAME_SEQUENCE_DOWN);

		layer.registGameTank(this);

		STEP = 3;

		tankBusiness();

	}

	private void initPosition() {
		Y_INIT = 0;
		/**
		 * 2^2=4
		 */
		switch (tankRandoms[0].next(2)) {
		case 0:
			X_INIT = GameLayer.AREA_UP_LEFT_X;
			break;
		case 1:
			X_INIT = GameLayer.AREA_UP_LEFT_X + GameLayer.AREA_WIDTH / 2
					- spriteTank.getWidth() / 2;
			break;
		case 2:
			X_INIT = GameLayer.AREA_UP_LEFT_X + GameLayer.AREA_WIDTH
					- spriteTank.getWidth();
			break;
		case 4:
			X_INIT = GameLayer.AREA_UP_LEFT_X + GameLayer.AREA_WIDTH / 2
					- spriteTank.getWidth() / 2;
			break;
		}
	}

	/**
	 * 因为timer.schdule()会顺延TimerTask的执行,所以以下所有ACTION的执行不会有时间上的重叠。
	 * 同时,因为需要和IPTankGameCanvas.GameTask.run()的同步
	 * (比如不能让GameTank正处于"界外"的情况下被flushGraphics()出来), 这里仍然采用了synchronized。
	 */
	private void tankBusiness() {

		timer.schedule(new GameTankTask(), 0, TIMER_INTERVAL);

	}

	class GameTankTask extends TimerTask {
		public void run() {
			try {
				Thread.currentThread().sleep(50);
			} catch (InterruptedException e) {
				layer.paintException("Exception from Thread.sleep()!");
			}
			/**
			 * 所有Timer调度的线程,应该被synchronized(GameLayer)。
			 */
			synchronized (layer) {
				switch (generateAction()) {
				case NO_ACTION:
					break;
				case ACTION_DIRECTION_UP:
					directionUP();
					break;
				case ACTION_DIRECTION_DOWN:
					directionDOWN();
					break;
				case ACTION_DIRECTION_LEFT:
					directionLEFT();
					break;
				case ACTION_DIRECTION_RIGHT:
					directionRIGHT();
					break;
				case ACTION_MOVE:
					Move();
					break;
				case ACTION_FIRE:
					Fire();
					break;
				}
			}
		}
	}

	private void directionUP() {
		int iLastDirection = iDirection;
		iDirection = DIRECTION_UP;
		spriteTank.setFrame(FRAME_SEQUENCE_UP);
		adjustDirection(iLastDirection);
	}

	private void directionDOWN() {
		int iLastDirection = iDirection;
		iDirection = DIRECTION_DOWN;
		spriteTank.setFrame(FRAME_SEQUENCE_DOWN);
		adjustDirection(iLastDirection);
	}

	private void directionLEFT() {
		int iLastDirection = iDirection;
		iDirection = DIRECTION_LEFT;
		spriteTank.setFrame(FRAME_SEQUENCE_LEFT);
		adjustDirection(iLastDirection);
	}

	private void directionRIGHT() {
		int iLastDirection = iDirection;
		iDirection = DIRECTION_RIGHT;
		spriteTank.setFrame(FRAME_SEQUENCE_RIGHT);
		adjustDirection(iLastDirection);
	}

	private void adjustDirection(int iLastDirection) {
		if (isUnAvailablePosition()) {
			iDirection = iLastDirection;
			switch (iDirection) {
			case DIRECTION_UP:
				spriteTank.setFrame(FRAME_SEQUENCE_UP);
				break;
			case DIRECTION_DOWN:
				spriteTank.setFrame(FRAME_SEQUENCE_DOWN);
				break;
			case DIRECTION_LEFT:
				spriteTank.setFrame(FRAME_SEQUENCE_LEFT);
				break;
			case DIRECTION_RIGHT:
				spriteTank.setFrame(FRAME_SEQUENCE_RIGHT);
				break;
			}
		}
	}

	private void Move() {
		switch (iDirection) {
		case DIRECTION_UP:
			Y -= STEP;
			spriteTank.setPosition(X, Y);
			if (isUnAvailablePosition()) {
				Y += STEP;
				spriteTank.setPosition(X, Y);
			}
			break;
		case DIRECTION_DOWN:
			Y += STEP;
			spriteTank.setPosition(X, Y);
			if (isUnAvailablePosition()) {
				Y -= STEP;
				spriteTank.setPosition(X, Y);
			}
			break;
		case DIRECTION_LEFT:
			X -= STEP;
			spriteTank.setPosition(X, Y);
			if (isUnAvailablePosition()) {
				X += STEP;
				spriteTank.setPosition(X, Y);
			}
			break;
		case DIRECTION_RIGHT:
			X += STEP;
			spriteTank.setPosition(X, Y);
			if (isUnAvailablePosition()) {
				X -= STEP;
				spriteTank.setPosition(X, Y);
			}
			break;
		}
	}

	private void Fire() {
		synchronized (this) {
			if (iFireNumber < MAX_FIRE_NUMBER) {
				iFireNumber++;
				int X_Bullet = 0;
				int Y_Bullet = 0;
				switch (iDirection) {
				case DIRECTION_UP:
					X_Bullet = X + spriteTank.getWidth() / 2 - 2;
					Y_Bullet = Y;
					break;
				case DIRECTION_DOWN:
					X_Bullet = X + spriteTank.getWidth() / 2 - 2;
					Y_Bullet = Y + spriteTank.getHeight();
					break;
				case DIRECTION_RIGHT:
					X_Bullet = X + spriteTank.getWidth();
					Y_Bullet = Y + spriteTank.getHeight() / 2 - 2;
					break;
				case DIRECTION_LEFT:
					X_Bullet = X;
					Y_Bullet = Y + spriteTank.getHeight() / 2 - 2;
					break;
				}
				new GameBullet(layer, this, iDirection, X_Bullet, Y_Bullet);
			}
		}
	}

	void releaseFireNumber() {
		synchronized (this) {
			iFireNumber--;
		}
	}

	private boolean isLayerCollision() {
		return spriteTank.collidesWith(layer.getTankLayer(), true);
	}

	private boolean isGameTankCollision() {
		Enumeration em = layer.getVGameTanks().elements();
		GameTank target = null;
		while (em.hasMoreElements()) {
			target = (GameTank) em.nextElement();
			if (this == target) {
				/**
				 * 不检查自己。
				 */
				continue;
			} else {
				if (getSpriteTank().collidesWith(target.getSpriteTank(), true)) {
					return true;
				}
			}
		}
		return false;
	}

	private boolean isPlayerTankCollision() {
		Enumeration em = layer.getVPlayerTanks().elements();
		GameTank target = null;
		while (em.hasMoreElements()) {
			target = (GameTank) em.nextElement();
			if (getSpriteTank().collidesWith(target.getSpriteTank(), true)) {
				return true;
			}
		}
		return false;
	}

	void paintGameTank(Graphics g) {
		spriteTank.paint(g);
	}

	private boolean isUnAvailablePosition() {
		return isLayerCollision() || GameLayer.isOutsideLayer(spriteTank);
	}

	/**
	 * 分配Random(多次)产生的随机数来得到所需概率和ACTION值。 NO_ACTION: 1/16 四个DIRECTION:
	 * 1/64*4=1/16 MOVE: 3/4=6/8 FIRE: 1/8
	 */
	private int generateAction() {
		/**
		 * 2^2=4
		 */
		switch (tankRandoms[1].next(2)) {
		case 0:
			/**
			 * 2^1=2
			 */
			switch (tankRandoms[2].next(1)) {
			case 0:
				/**
				 * 得到"1/8"。
				 */
				return ACTION_FIRE;
			case 1:
				/**
				 * 2^1=2
				 */
				switch (tankRandoms[3].next(1)) {
				/**
				 * 得到"1/16"。
				 */
				case 0:
					/**
					 * 四个DIRECTIOIN各自为1/64。
					 * 
					 * 2^2=4
					 */
					switch (tankRandoms[4].next(2)) {
					case 0:
						return ACTION_DIRECTION_UP;
					case 1:
						return ACTION_DIRECTION_DOWN;
					case 2:
						return ACTION_DIRECTION_LEFT;
					case 3:
						return ACTION_DIRECTION_RIGHT;
					}
				case 1:
					return NO_ACTION;
				}
			}
		case 1:
		case 2:
		case 3:
			/**
			 * 得到"3/4"。
			 */
			return ACTION_MOVE;
		}
		return 0;
	}

	Sprite getSpriteTank() {
		return spriteTank;
	}

	public void hit() {
		registBoomDrawer();
		layer.unRegistGameTank(this);
		spriteTank.setVisible(false);
		timer.cancel();
	}

	private void registBoomDrawer() {
		layer.registMultipleDrawer(this);
	}

	public void drawBoom(Graphics graphic) {
		graphic.drawImage(imageBoom, X, Y, 0);
	}

	void pauseGameTank() {
		timer.cancel();
	}

	void restartGameTank() {
		timer = new Timer();
		timer.schedule(new GameTankTask(), 0, TIMER_INTERVAL);
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -