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

📄 maincanvas.java

📁 坦克大战
💻 JAVA
字号:
import java.util.Random;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;


public class MainCanvas extends GameCanvas 
				implements Runnable, CommandListener{
	public static final int GAME_UI				= 0;	//进入用户界面
	public static final int GAME_GAMING			= 1;	//进行游戏
	public static final int GAME_BUTTON			= 2;	//游戏时显示界面按钮
	public static final int GAME_END				= 3;	//游戏结束
	public static final int GAME_STATE_NUM 		= 4;	//状态总数
	private int m_nState	= GAME_UI;						//存储当前的游戏状态
	
	private boolean		m_bRunning;			    		//控制线程运行
	private MyUI			m_UI;							//界面对象
	private Sprite			m_TextSp;						//图形文字对象
	private PlayerTank 	m_Tank;							//玩家坦克对象
	private int			m_nTotalETank;					//敌方坦克总数
	private int			m_nDestroyETank;				//目前消灭的敌方坦克数
	private EnemyTank 		m_eTank[];						//敌方坦克对象
	private Scene 			m_Scene;						//场景对象
	private ExplosionSprite m_aExplosion[];				//爆炸对象
	private Random			m_Random;						//随机数对象
	private LayerManager m_LayerManager;					//层管理器对象
	private Command MenuCommand;							//高级按钮对象
	public MainCanvas( ){
		super(true);			
		try{
			//创建用户界面,并设置界面中的按钮
			MyButton button = new MyButton(41, 21, 0, 1, -1, -1, -1, 2);
			m_UI = new MyUI(button);
        }
        catch(Exception exception){}
        setState(GAME_UI);
		Start();
	}
	//重新开牌
	private void Reset(){	
		//创建随机数对象
		if( m_Random == null )
			m_Random = new Random();
		if( m_Tank == null )
		{
			m_eTank 		= new EnemyTank[2];
			m_aExplosion 	= new ExplosionSprite[3];
			try{ 
				//创建坦克对象
				Image image = Image.createImage("/demo/tank.png");
				m_Tank = new PlayerTank( image, 13, 13 );
				image = Image.createImage("/demo/enemyTank.png");
				for( int n = 0; n < m_eTank.length; n ++ ){
					m_eTank[n] = new EnemyTank( image, 13, 13 );
				}
				//创建爆炸对象
				image = Image.createImage("/demo/explosion.png");
				for( int m = 0; m < m_aExplosion.length; m ++ ){
					m_aExplosion[m] = new ExplosionSprite( image, 21, 17 );
				}
			}
		    catch(Exception e){}
		}
		//创建场景对象
	    if( m_Scene == null )
	 	    m_Scene = new Scene();
	    if( m_LayerManager == null )
	    {//创建层管理器,并将所有图层添加到管理器
	    	m_LayerManager = new LayerManager();
		    for( int m = 0; m < m_aExplosion.length; m ++ )
		    {
		    	m_LayerManager.append(m_aExplosion[m]);
		    }
		    m_LayerManager.append(m_Scene.m_LyCanPass);
		    m_LayerManager.append( m_Tank );
		    m_LayerManager.append( m_Tank.m_Bullet );
		    for( int n = 0; n < m_eTank.length; n ++ )
		    {
		    	m_LayerManager.append(m_eTank[n]);
		    	m_LayerManager.append(m_eTank[n].m_Bullet);
			}
		    m_LayerManager.append(m_Scene.m_LyBulletPass);
		    m_LayerManager.append(m_Scene.m_LyCanHit);
		    m_LayerManager.append(m_Scene.m_LyNotPass);
		    m_LayerManager.append(m_Scene.m_LyHQ);
	    }
	    //敌方坦克总共20辆
	    m_nTotalETank = 20;
	    //当前尚未消灭敌方坦克
	    m_nDestroyETank = 0;
	    //读取场景地图
		m_Scene.LoadMap();
		//玩家坦克启动
		m_Tank.Start( 15 * 3 + 7, 15 * 10 + 7, 0, 2 );
		//设置游戏画面的显示区域
		SetViewWindow();
		
        if( MenuCommand == null ){
        	//创建菜单
        	MenuCommand = new Command("Menu", Command.OK, 0);
        	addCommand(MenuCommand);
            setCommandListener(this);
        }
        if( m_TextSp == null ){
        	//创建图形文字对象
        	try{
        		Image img = Image.createImage("/demo/text.png");
        		m_TextSp = new Sprite(img, 82, 25);
        		m_TextSp.defineReferencePixel(41, 23);
        		int x = getWidth()/2;
        		int y = getHeight()/2 - 10;
        		m_TextSp.setRefPixelPosition(x, y);
        	}
        	catch(Exception exception){}
        }
        
	}
	//设置游戏画面的显示区域
	private void SetViewWindow(){
		if( m_LayerManager == null )
			return;
		//根据玩家坦克的位置,设置游戏画面的显示区域
		int nX = m_Tank.getRefPixelX() - getWidth()/2;
		int nY = m_Tank.getRefPixelY() - getHeight()/2;
		if( nX < 0 )
			nX = 0;
		else if( nX > 15 * 13 - getWidth() )
			nX = 15 * 13 - getWidth();
		if( nY < 0 )
			nY = 0;
		else if( nY > 15 * 12 - getHeight() )
			nY = 15 * 12 - getHeight();
		m_LayerManager.setViewWindow( nX, nY, getWidth(), getHeight() );
	}
	private void setState( int state ){					//设置游戏状态
		if( state < 0 || state >= GAME_STATE_NUM )
			return;
		m_nState = state;
		switch( m_nState ){
		case GAME_UI:										//进入用户界面
			m_UI.setState(MyUI.UI_TITLE);					//显示标题界面
			//设置本游戏的按钮类型,本游戏有:开始及退出两种按钮
			m_UI.getButton().setShow(true, false, false, false, false, true );
			break;
		case GAME_BUTTON:									//在游戏中途显示按钮
			m_UI.setState(MyUI.UI_BUTTON);
			//游戏中途,显示复位与退出按钮
			m_UI.getButton().setShow(false, true, false, false, false, true );
			break;
		case GAME_GAMING:									//正在游戏
			m_UI.setState(MyUI.UI_HIDE);
			break;
		case GAME_END:										//游戏结束
			m_UI.setState(MyUI.UI_HIDE);
			break;
		}
	}
	public void Start(){
		m_bRunning = true;
		Thread thread = new Thread(this);	//分配新线程
		thread.start();						//线程启动
	}
	public void run() {
		//得到系统当前时间,并将时间换算成毫秒
		long T1 = System.currentTimeMillis();
		long T2 = T1;
		while(m_bRunning){
			T2 = System.currentTimeMillis();
			if( T2 - T1 > 50 ){			//间隔50毫秒
				T1 = T2;
				Input();
				Logic();
				Paint();
			}
		}
	}
	public void Stop(){
		m_bRunning = false;
	}
	public void Input(){
		int keyStates = getKeyStates();
		switch( m_nState ){
		case GAME_UI:
			{
				switch( m_UI.Input( keyStates ) ){
				case MyButton.BUTTON_START:					//按下开始键
					Reset();
					setState(GAME_GAMING);
					break;
				case MyButton.BUTTON_EXIT:					//按下退出键
					TankMidlet.midlet.notifyDestroyed();
					break;
				}
			}
			break;			
		case GAME_GAMING:									//游戏中
			m_Tank.Input( keyStates );
			SetViewWindow();
			break;
		case GAME_BUTTON:									//游戏中途显示按钮
			{
				switch( m_UI.Input( keyStates ) ){
				case MyButton.BUTTON_RESET:					//按下复位键
					Reset();
					setState(GAME_GAMING);
					break;
				case MyButton.BUTTON_EXIT:					//按下退出键
					TankMidlet.midlet.notifyDestroyed();
					break;
				}
			}
			break;
		case GAME_END:
			if( ( keyStates & GameCanvas.FIRE_PRESSED ) != 0 ){
				Reset();
				setState(GAME_GAMING);
			}
			break;
		}
	}
	public void Logic(){	
		switch( m_nState ){
		case GAME_GAMING:
			//爆炸逻辑
			for( int m = 0; m < m_aExplosion.length; m ++ ){
				m_aExplosion[m].Logic();
			}
			//坦克逻辑
			m_Tank.Logic();
		    for( int n = 0; n < m_eTank.length; n ++ ){
		    	m_eTank[n].Logic();
			}
		    //碰撞检测
		    CheckCollision();
		    //产生新的敌方坦克
		    CreateETank();
			break;
		}
	}
	public void Paint(){
		Graphics g = getGraphics();
		//用黑色清屏
		g.setColor(0);
		g.fillRect( 0, 0, getWidth(), getHeight() );
		
		g.setColor(0xFFFF0000);
		switch( m_nState ){
		case GAME_UI:								//显示界面
			m_UI.Paint(g, getWidth(), getHeight());
			break;			
		case GAME_GAMING:							//显示游戏画面
		case GAME_BUTTON:
		case GAME_END:
			m_LayerManager.paint(g, 0, 0);
			if( m_nState == GAME_END )
				m_TextSp.paint(g);
			m_UI.Paint(g, getWidth(), getHeight());
			break;
		}
		flushGraphics();
	}
	//碰撞检测
	private void CheckCollision()
	{
		BulletSprite mB = m_Tank.m_Bullet;
		BulletSprite mEB = null;
		for( int n = 0; n < m_eTank.length; n ++ ){
			mEB = m_eTank[n].m_Bullet;
			//敌人子弹和我方坦克碰撞
			if( mEB.collidesWith( m_Tank, false ) ){
				mEB.setVisible(false);
				//游戏失败
				m_TextSp.setFrame(1);
				setState(GAME_END);
				break;
			}
			//我方子弹和敌人坦克碰撞
			if( mB.collidesWith( m_eTank[n], false ) ){
				CreateExplosion(mB.getRefPixelX(), mB.getRefPixelY());
				mB.setVisible( false );
				m_eTank[n].setVisible( false );
				m_nDestroyETank ++;
				if( m_nDestroyETank >= 20 ){
					//消灭的所有坦克,游戏胜利
					m_TextSp.setFrame(0);
					setState(GAME_END);
					return;
				}
			}
			//我方坦克和敌人碰撞
			if( m_Tank.collidesWith( m_eTank[n], false ) ){
				//都向后退
				m_Tank.MoveBack();
				m_eTank[n].MoveBack();
			}
			//敌人和地图碰撞,敌人向后退
			if( m_eTank[n].collidesWith( m_Scene.m_LyBulletPass, false ) ){
				m_eTank[n].MoveBack();
			}
			else if( m_eTank[n].collidesWith( m_Scene.m_LyCanHit, false ) ){
				m_eTank[n].MoveBack();
			}
			else if( m_eTank[n].collidesWith( m_Scene.m_LyNotPass, false ) ){
				m_eTank[n].MoveBack();
			}		
			//敌人子弹与地图相撞
			int nERow = mEB.GetCurRow();
			int nECol = mEB.GetCurCol();
			if( nERow < 0 || nERow >= m_Scene.m_LyCanHit.getRows() ||
					nECol < 0 || nECol >= m_Scene.m_LyCanHit.getColumns() )
			{//子弹超出场景范围
				mEB.setVisible(false);
				continue;
			}
			if( mEB.collidesWith( m_Scene.m_LyHQ, false ) )
			{//子弹打到司令部
				m_Scene.m_LyHQ.setCell( nECol, nERow, 6 );
				CreateExplosion(mEB.getRefPixelX(), mEB.getRefPixelY());
				mEB.setVisible( false );
				//游戏失败
				m_TextSp.setFrame(1);
				setState(GAME_END);
				return;
			}
			if( mEB.collidesWith( m_Scene.m_LyCanHit, false ) )
			{//子弹打到可摧毁的区域
				m_Scene.m_LyCanHit.setCell( nECol, nERow, 0 );
				CreateExplosion(mEB.getRefPixelX(), mEB.getRefPixelY());
				mEB.setVisible( false );
			}
			else if( mEB.collidesWith( m_Scene.m_LyNotPass, false ) )
			{//子弹打到不可摧毁的区域
				CreateExplosion(mEB.getRefPixelX(), mEB.getRefPixelY());
				mEB.setVisible( false );
			}
		}
		//我方坦克和地图碰撞,则向后退
		if( m_Tank.collidesWith( m_Scene.m_LyBulletPass, false ) ){
			m_Tank.MoveBack();
		}
		else if( m_Tank.collidesWith( m_Scene.m_LyCanHit, false ) ){
			m_Tank.MoveBack();
		}
		else if( m_Tank.collidesWith( m_Scene.m_LyNotPass, false ) ){
			m_Tank.MoveBack();
		}		
		//我方子弹与地图相撞
		int nRow = mB.GetCurRow();
		int nCol = mB.GetCurCol();
		if( nRow < 0 || nRow >= m_Scene.m_LyCanHit.getRows() ||
				nCol < 0 || nCol >= m_Scene.m_LyCanHit.getColumns() )
		{//子弹超出场景范围
			mB.setVisible(false);
			return;
		}
			
		if( mB.collidesWith( m_Scene.m_LyHQ, false ) )
		{//子弹打到司令部
			m_Scene.m_LyHQ.setCell( nCol, nRow, 6 );
			CreateExplosion(mB.getRefPixelX(), mB.getRefPixelY());
			//游戏失败
			m_TextSp.setFrame(1);
			setState(GAME_END);
			mB.setVisible( false );
		}
		else if( mB.collidesWith( m_Scene.m_LyCanHit, false ) )
		{//子弹打到可摧毁的区域
			m_Scene.m_LyCanHit.setCell( nCol, nRow, 0 );
			CreateExplosion(mB.getRefPixelX(), mB.getRefPixelY());
			mB.setVisible( false );
		}
		else if( mB.collidesWith( m_Scene.m_LyNotPass, false ) )
		{//子弹打到不可摧毁的区域
			CreateExplosion(mB.getRefPixelX(), mB.getRefPixelY());
			mB.setVisible( false );
		}
	}
	//随机产生敌方坦克
	public void  CreateETank() {
		if( m_nTotalETank <= 0 )
			return;
		//以20分之一的概率产生坦克
		int nRs = m_Random.nextInt() % 20;
		if( Math.abs(nRs) != 0 )
			return;
		//如果某一位置的坦克被摧毁,则可以产生新坦克
		for( int n = 0; n < m_eTank.length; n ++ ){
	    	if( m_eTank[n].isVisible() )
	    		continue;
	    	m_eTank[n].Start( n * 2 * 15 + 15 + 7, 15 + 7, 2, 1 );
	    	break;
		}
	}
	//产生爆炸,参数nX、nY分别是爆炸位置的横纵坐标
	public void CreateExplosion( int nX, int nY ){
		for( int m = 0; m < m_aExplosion.length; m ++ ){
	    	if( m_aExplosion[m].isVisible() )
	    		continue;
	    	m_aExplosion[m].Start( nX, nY );
	    	break;
		}
	}
	public void commandAction(Command c, Displayable s){
		if( c == MenuCommand ){
			switch( m_nState ){	
			case GAME_END:							//游戏结束,显示按钮
			case GAME_GAMING:						//正在游戏,显示按钮	
				setState(GAME_BUTTON);
				break;
			case GAME_BUTTON:						//正显示按钮,退回游戏
				setState(GAME_GAMING);
				break;
			default:
				break;
			}
		}
	}
}

⌨️ 快捷键说明

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