📄 tanksprite.java
字号:
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import java.io.*;
import java.lang.*;
import java.util.*;
public class TankSprite extends Sprite{
public final static int ANCHOR_LEFTTOP=1;
public final static int ANCHOR_CENTER=2;
//constant definitions
protected final static int BULLET_WIDTH = 6;
protected final static int BULLET_HEIGHT = 7;
private final static int MISSILE_WIDTH=7;
private final static int MISSILE_HEIGHT=14;
private final static int BABY_BULLET_WIDTH=18;
private final static int BABY_BULLET_HEIGHT=18;
protected final static int MAX_BULLET_COUNT = 3;
protected final static int RETIRED_TANK_MOVING =3;
protected final static int RETIRED_TANK_STAY = 4;
protected final static int BULLET_TIMER_DELAY = 1000;//俩个子弹之间的间隔为2秒
private final static int INVICIBLE_TIMER_DELAY = 10*1000;//10秒内坦克被攻击无效
private final static int DOUBLE_POINTS_TIMER_DELAY = 30*1000;//30秒内击毁坦克积分翻倍;(×2)
private final static int BOMB_IMAGE_WIDTH = 20;
private final static int BOMB_IMAGE_HEIGHT = 20;
private static final int RANDOM__STEP = 2;//enemy tank move 2 pixels per step
private final static int NUM_OF_BOMB_FRAMES=3;
private final static int NUM_OF_LIGHT_FRAMES=2;
private final static int NUM_OF_UPGRADE_FRAMES=5;
private static final int[] kTransformLookup = {
Sprite.TRANS_NONE,
Sprite.TRANS_ROT90,
Sprite.TRANS_ROT180,
Sprite.TRANS_ROT270
};
//tank index
private int m_tankIndex;
//display scene
//bomb scene
private Sprite m_bombSprite;
private int m_tankBombFrame;
private boolean m_bBombStarted;
//lightening image
private Sprite m_lighteningImageSprite;
private int m_tankLightFrame;
private boolean m_bLighteningStarted;
//FSM related definitions
protected boolean m_threadAlive = true;//run循环是否运行
/**
* 坦克的共同属性
*/
//基本生命数
//基本攻击
//攻击频率
//基本血量
//基本机动
//坦克级别
protected int m_bulletCount = 0;
protected int m_bulletSpeed;
protected int m_tankBlood = 0;
protected int m_tankType;
protected int m_bombCount = 0;
protected int m_tankLife = 0;
private int m_tankSpeed;
private int m_tankPoints;//坦克获得的分数
private int m_bulletType;
private int m_bulletDamage;//坦克的攻击值,可以二次叠加
private int m_bulletDamageAddTimes;//坦克的攻击已经叠加的次数
private final static int MAX_BULLET_DAMAGE_ADD_TIMES = 2;
private boolean m_invicible;//坦克是否无敌模式
private boolean m_doublePoints;//坦克是否在积分获得加倍模式
protected int m_curretBullet ;//当前第几颗子弹
protected int m_currentState;//GAME LOOP状态
protected int m_currentFrame[] ={0,0};//当前TANK的状态图片(静止/运行)
protected int m_currentDirection;//left/right/up/down 当前TANK的运行方向
protected Timer m_timer;
protected BulletScheduler m_timerTask;//子弹延时
protected BulletScheduler m_timerTaskDoublePoints;//积分获得加倍延时
protected BulletScheduler m_timerTaskInvicible;//无敌防护
protected int mKX, mKY;//当前TANK的REF PIXEL所在位置。
//当前坦克复活的时候的开始位置.
private int m_startPositionX;
private int m_startPositionY;
protected int mLastDelta;//发生碰撞前坦克的移动距离
protected boolean mLastWasTurn = false;
protected boolean m_bulletLocked = false;//是否有子弹还在运行中(未超时或者未撞到障碍物)
protected String strBulletImage = "/tank/bullet.png";
private Image m_missileImage;
private Image m_trackerImage;
private int m_missileCount;//当前坦克的跟踪导弹的个数
protected int m_frameWidth ;
protected int m_frameHeight;
protected int m_currentAngel;//炮口向上 当前TANK的运行方向。
protected BulletSprite m_bullet[];
protected int m_bulletOwner;
protected int m_tankOwner;
private int m_defaultDirectionImage;
private boolean m_init ;//确定是否是坦克的最开始出现位置;
private static Random m_rand;
private final static int TANK_ONE_REGION=80;
private final static int TANK_TWO_REGION=160;
private final static int TANK_THREE_REGION=240;
private final static int BULLET_DELAY_FRAMES=60;
private final static int BULLET_DELAY_FRAMES_MIDDLE=10;
//confirm whether the enemy tank should fire
private int m_bulletDelayFrame;//current circle is 100 ms ,we need 60 circles in easy level
private boolean m_underAttack=false;
private boolean m_backToNormal=false;
private int m_underAttackFrame=0;//whether the enemy tank should adjust its tracking path;
private int m_backFrame=0;//whether the enemy tank should adjust its tracking path when come back;
private int m_destRow=0;
private int m_destCol=0;
//vectors that contains the enemies attacked by user tank
Vector m_enemiesAttacked;
//the cell that collides with current enemy tank,case collided,steer clear of this cell in the path;
private int m_rowCollided=0;
private int m_colCollided=0;
public void start() {
setVisible(true);
if (m_tankOwner == GameLogic.ENEMY_TANK) {
m_tankLife = 1;
}
setGameState(GameLogic.GAME_STATE_LOOP);
}
public void pause() {
m_currentState = GameLogic.GAME_STATE_PAUSE;
}
public void stop() {
try {
m_currentState = GameLogic.GAME_STATE_END;
m_threadAlive = false;
releaseResource();
setVisible(false);
}
catch (Exception ex) {
ex.printStackTrace();
}
}
private boolean isBalk(int x, int y)
{
if(x < 0||x >=GameLogic.MAP_ROW_NUM||y < 0||y >=GameLogic.MAP_COLUM_NUM){
return true;
}
if(GameLogic.map_element[y][x][GameLogic.MAP_ELEMENT_PROPERTY_GRID_TYPE] !=1){
return true;
}
return false;
}
private int getReverseAngel(int angel) {
int direction = Sprite.TRANS_NONE;
try {
/**
* 1.find the available direction (no fence/no tank/)
* 2.choose from available directions randomly;
* 2.1 form an array contains the
* directions;
* 2.2 choose from the array randomly
*/
int bx = (getRefPixelY() / GameLogic.MAP_CELL_HEIGHT) - 1, by = (getRefPixelX() / GameLogic.MAP_CELL_WIDTH);
int directionCounts = 0;
int direction_array[] = {0,0,0,0};
// 1.find the available direction (no fence/no tank/)
if (!isBalk(bx + 1, by)) {// down
direction_array[directionCounts] = Sprite.TRANS_ROT180;
directionCounts++;
}
if (!isBalk(bx - 1, by)) {// up
direction_array[directionCounts] = Sprite.TRANS_NONE;
directionCounts++;
}
if (!isBalk(bx, by + 1)) {// right
direction_array[directionCounts] = Sprite.TRANS_ROT90;
directionCounts++;
}
if (!isBalk(bx, by - 1)) {// left
direction_array[directionCounts] = Sprite.TRANS_ROT270;
directionCounts++;
}
int i = m_rand.nextInt(100);
i = i % directionCounts;
direction = direction_array[i];
System.out.println("current direction=" + m_currentDirection
+ " change direction=" + direction);
} catch (Exception e) {
e.printStackTrace();
}
return direction;
}
private boolean enemy_middle_process(){
int iAngel = 0;
boolean bCollided=false;
try {
/**
* 1.enemy tanks moves in restricted area;
* enemy tank 1(map coodinate):(0-80)
* enemy tank 2(map coodinate):(80-160)
* enemy tank 3(map coodinate):(161-240)
* enemy tank 4,5(Y coordinate):(123-203)
* 2.fire the bullet in 1 second the case the former bullet disappears;
*
* 3.IF(the enemy tank is attacked),it will attack the user tank in whole region until it is destroyed;
*/
int x=getRefPixelX();
int y=getRefPixelY();
int begin_col=0,begin_row=0;
int curRow = (y / GameLogic.MAP_CELL_HEIGHT)-1,curCol = (x / GameLogic.MAP_CELL_WIDTH);
int srcRow = (GameLogic.m_tank.getRefPixelY() / GameLogic.MAP_CELL_HEIGHT)-1,srcCol = (GameLogic.m_tank.getRefPixelX() / GameLogic.MAP_CELL_WIDTH);
if(0==m_bulletDelayFrame){
fire();
}
m_bulletDelayFrame++;
if(m_bulletDelayFrame>=BULLET_DELAY_FRAMES_MIDDLE){
m_bulletDelayFrame=0;
}
if(false ==m_underAttack){
/**
* 1.judge the current enemy tank status(under attack->normal or normal)
* IF(normal state) the tank move in normal way;
* IF(under attack->normal)
* 1.1.judge the position to assure whether enemy tank in the specified region;
* 2.1.handle enemy tanks that not in specified region;
* 2.1.1 find the path enemy tank move back to its start position
* 2.1.2 move along the path,the case collides with other fence,change its path;
* 2.1.3 when the tank reaches the specified region,stop move along the path;move in the
* normal way;
* 3.1.handle enemy tanks that in the specified region;
* 3.1.1 change the tank state from attack->normal to normal,so that the tank will move
* in normal way;
*
*/
switch (m_tankIndex) {
case 0:
if (x + GameLogic.TANK_WIDTH / 2 > TANK_ONE_REGION
|| x - GameLogic.TANK_WIDTH / 2 <= 0) {
bCollided = true;
}
break;
case 1:
if(x+GameLogic.TANK_WIDTH/2>TANK_TWO_REGION ||x-GameLogic.TANK_WIDTH/2<=TANK_ONE_REGION){
bCollided=true;
}
break;
case 2:
if(x+GameLogic.TANK_WIDTH/2>TANK_THREE_REGION||x-GameLogic.TANK_WIDTH/2<=TANK_TWO_REGION){
bCollided=true;
}
break;
case 3:
case 4:
if(y+GameLogic.TANK_HEIGHT/2>=203 ||y-GameLogic.TANK_HEIGHT/2<=123){
bCollided=true;
}
break;
default:
break;
}
if (true == m_backToNormal) {// under attack->normal
if(0==m_backFrame &&true == bCollided){
m_destRow=GameLogic.m_enemyStartPlace[m_tankIndex][GameLogic.ENEMY_TANK_LOCATION_PROPERTY_ROW];
m_destCol=GameLogic.m_enemyStartPlace[m_tankIndex][GameLogic.ENEMY_TANK_LOCATION_PROPERTY_COL];
}else if(false == bCollided){
//3.1.1 change the tank state from attack->normal to normal
//2.1.3 when the tank reaches the specified region,stop move along the path;move in the
// * normal way;
m_backToNormal=false;
return bCollided;
}
System.out.println("back to normal,curRow ="+ curRow+"curCol="+curCol+"destRow="+m_destRow+"destCol="+m_destCol);
enemy_moveto_dest(curRow,curCol,m_destRow,m_destCol);
}else{
if (true == bCollided) {
undo();
}
}
}else{
if (0 == m_underAttackFrame) {
m_destRow= srcRow;
m_destCol= srcCol;
}
enemy_moveto_dest(curRow,curCol,m_destRow,m_destCol);
}
} catch (Exception e) {
e.printStackTrace();
}
return bCollided;
}
private void enemy_moveto_dest(int curRow, int curCol, int destRow,
int destCol) {
try {
/**
* 1.handle situation as that when tank collides with another tank in the path;
* 1.1 IF(collides with another tank)calculate the current column and row of another tank ,
* make that cell a fence;
* 1.2 reset the cell 's grid status after recalculate the path;
* 2.handle situations as that tank collides with fence;
*/
if (curRow == destRow && curCol == destCol) {
if (true == m_underAttack) {
m_underAttackFrame = 0;
System.out
.println("enemy_moveto_dest move to the destination under attack");
}
if (true == m_backToNormal) {
// reach the dest ,state changed to normal state
m_backToNormal = false;
m_backFrame=0;
System.out
.println("enemy_moveto_dest move to the destination back state");
}
return;
}
if (0 == m_backFrame && true == m_backToNormal) {
//1.1 IF(collides with another tank)calculate the current column and row of another tank
GameLogic.m_asterisk
.find_path(curRow, curCol, destRow, destCol);
//1.2 reset the cell 's grid status after recalculate the path;
m_backFrame = 1;
resetCellToBeAvoided();
}
if (0 == m_underAttackFrame && true == m_underAttack) {
GameLogic.m_asterisk
.find_path(curRow, curCol, destRow, destCol);
m_underAttackFrame = 1;
resetCellToBeAvoided();
}
/**
* 1.move the tank until it go to the middle point of the specified cell;
* 1.1 IF(reach middle point) recalculate the next cell to move;
* 1.2 move until reach the middle point;
*/
// the enemy reach the destination,recalculate
if (curRow == GameLogic.m_asterisk.m_xPosition
&& curCol == GameLogic.m_asterisk.m_yPosition) {
//1.1 IF(reach middle point) recalculate the next cell to move;
int x=curCol*GameLogic.MAP_CELL_WIDTH + GameLogic.MAP_CELL_WIDTH/2;
int y=(curRow+1)*GameLogic.MAP_CELL_HEIGHT+GameLogic.MAP_CELL_HEIGHT/2;
if(x==getRefPixelX() && y== getRefPixelY()){
System.out.println("reach the middle point,row ="+ curRow+" col="+curCol);
GameLogic.m_asterisk.AAsterisk_t(
GameLogic.m_asterisk.m_xPosition,
GameLogic.m_asterisk.m_yPosition, m_destRow, m_destCol);
}else{
//1.2 move until reach the middle point;
showfather(GameLogic.m_asterisk.m_xPosition,
GameLogic.m_asterisk.m_yPosition);
}
} else {
//1.2 move until reach the middle point;
showfather(GameLogic.m_asterisk.m_xPosition,
GameLogic.m_asterisk.m_yPosition);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void showfather(int x, int y)
{
int iAngel=0;
switch(GameLogic.m_asterisk.m_openList[y][x][4])
{//up/down/left/right
case 1:
iAngel=Sprite.TRANS_NONE;
move(iAngel,2);
break;
case 2:
iAngel=Sprite.TRANS_ROT180;
move(iAngel,2);
break;
case 3:
iAngel=Sprite.TRANS_ROT270;
move(iAngel,2);
break;
case 4:
iAngel= Sprite.TRANS_ROT90;
move(iAngel,2);
break;
default:
break;
}
}
private boolean enenmy_easy_process(){
int iAngel = 0;
boolean bCollided=false;
try {
/**
* 1.enemy tanks moves in restricted area;
* enemy tank 1(map coodinate):(0-80)
* enemy tank 2(map coodinate):(80-160)
* enemy tank 3(map coodinate):(161-240)
* 2.enemy tank fires in 6 seconds;
*/
int x=getRefPixelX();
int y=getRefPixelY();
if(0==m_bulletDelayFrame){
fire();
}
m_bulletDelayFrame++;
if(m_bulletDelayFrame>=BULLET_DELAY_FRAMES){
m_bulletDelayFrame=0;
}
switch (m_tankIndex) {
case 0:
if(x+GameLogic.TANK_WIDTH/2>TANK_ONE_REGION||x-GameLogic.TANK_WIDTH/2<=0){
undo();
bCollided=true;
}
break;
case 1:
if(x+GameLogic.TANK_WIDTH/2>TANK_TWO_REGION ||x-GameLogic.TANK_WIDTH/2<=TANK_ONE_REGION){
undo();
bCollided=true;
}
break;
case 2:
if(x+GameLogic.TANK_WIDTH/2>TANK_THREE_REGION||x-GameLogic.TANK_WIDTH/2<=TANK_TWO_REGION){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -