gamecanvas.java

来自「j2me 手机游戏」· Java 代码 · 共 946 行 · 第 1/2 页

JAVA
946
字号
package cn.hxex.fire;



import javax.microedition.lcdui.*;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class GameCanvas extends Canvas implements Runnable{
	private Image d_logo,menuBK,menu;
	public long lastTime;
	private byte menuState=0;
	public Image im;
	public Graphics offG;
	protected short SCREENWIDTH=176,SCREENHEIGHT=208;
	public static final byte MENU=-2;
	public static final byte LOAD=0;
	public static final byte GAMEING=1;
	public static final byte GAMEOVER=2;
	public static final byte PAUSE=4;
	public byte gameState=0;
	public byte endCount=0;
	public static boolean ISRUN=true;
	public byte level_Mode=1,proess=0;
	public byte nowFramemenu=0;
	public boolean soundOn=true;
	public Image mapbk,mirromap;
	private int[][] enemyPlane = new int[30][7];
	public long levelStart=0;
	public int mapLength;
	public int mappy=0;
	public Image plane1,plane2,transform;
	public Image fire;
	public Image imPlane;
	public int px,py;
	public int direct;
	public int dirFrame[]={0,4,3,1,2};
	public Image imBullet;
	public Vector allBullet;
	public Vector allEnemyPlane;
	public Timer t;
	public boolean isFire=false;
	Image bulletImg;
	/**
	 * 敌人飞机数组
	 * enemyPlane[0][0]代表飞机是否可见,
	 *            0代表不可见,1代表可见
	 * enemyPlane[0][1]代表飞机类型和移动轨迹类型
	 * enemyPlane[0][2]代表飞机的x坐标
	 * enemyPlane[0][3]代表飞机的y坐标
	 * enemyPlane[0][4]代表间隔多少次继续发射子弹
	 * enemyPlane[0][5]代表飞机移动到轨迹中的索引值
	 * enemyPlane[0][6]代表飞机是否开始发射子弹
	 *            0代表不发射,1代表发射
	 */

    public Image[] enemyPlaneImg;
    
    /**敌人类型1,该值也代表敌人飞机间隔多少次线程循环发射子弹*/
	final int ENEMY1 = 3;
	/**敌人类型2*/
	final int ENEMY2 = 5;
	final int[] ENEMY1_MOVE_PATH = {10,10,5,5,5,5,5,5,5,5,5,
	         -5,-5,-5,-5,-5,-5,-5,-5,-5,-10,-10};
	final int[] ENEMY2_MOVE_PATH = {10,10,5,5,5,5,5,5,5,5,5,10,10,10,0,0,0,0,0,
    -10,-10,-10,-10,-10,-10,-10,-10};
	
	//敌人飞机出现的位置类型
	/**左侧位置*/
	final int LEFT_POSITION = 0;
	/**右侧位置*/
	final int RIGHT_POSITION = 1;
	/**中间位置*/
	final int CENTER_POSITION = 2;
	//子弹类型
	/**直上直下*/
	final static int NORMAL = 0;
	/**左斜类型*/
	final static int LEFT = 1;
	/**右斜类型*/
	final static int RIGHT = 2;
	final int BULLET_WIDTH = 4;
	final int BULLET_HEIGHT = 4; 
	//速度常量
	final static int NORMAL_SPEED = 4;
	final static int HIGH_SPEED = 8;
	
	final int ENEMY1PLANE_WIDTH = 16;
	final int ENEMY1PLANE_HEIGHT = 20;
	
	final int ENEMY2PLANE_WIDTH = 26 ;
	final int ENEMY2PLANE_HEIGHT = 23;
	/**敌人发射的子弹数组
	 * 功能说明:
	 * 例如enemyBullet[0]代表一个子弹
	 * enemyBullet[0][0] 代表子弹是否可见,0为不可见,1为可见
	 * enemyBullet[0][1] 代表子弹的x坐标
	 * enemyBullet[0][2] 代表子弹的y坐标
	 * enemyBullet[0][3] 代表子弹的类型
	 * enemyBullet[0][4] 代表子弹的速度 
	 */
	int[][] enemyBullet = new int[100][5];
	/**代表滚屏次数,使用该参数控制各种类型飞机的生成*/
	int num = 0;
	
	public GameCanvas(){
		this.setFullScreenMode(true);
		im=Image.createImage(SCREENWIDTH, SCREENHEIGHT);
		offG=im.getGraphics();
		try {
			menuBK=Image.createImage("/caidan.png");
			menu=Image.createImage("/caidan1.png");
			imPlane=Image.createImage("/zhujue1.png");
			imBullet=Image.createImage("/bullet13.png");
			bulletImg = Image.createImage("/bullet.png");
			enemyPlaneImg=new Image[2];
			//第一种类型的飞机
			enemyPlaneImg[0] = Image.createImage("/j2.png");
			//第二种类型的飞机
			enemyPlaneImg[1] = Image.createImage("/j3.png");
		} catch (Exception e) {
			System.out.println("nopic");
		}
		px=176/2-15;
		py=208-30;
		direct=0;

		allBullet=new Vector();

		t=new Timer();
		TimerTask ts1=new TimerTask(){
			public void run(){
				if(isFire){
					int tmp[]=new int[3];
					tmp[0]=px+10;
					tmp[1]=py;
					tmp[2]=0;
					allBullet.addElement(tmp);
				}
			}
		};
		
		t.schedule(ts1, 0, 20);
		TimerTask ts2=new TimerTask(){
			public void run(){
				for(int i=0;i<allBullet.size();i++){
					int tmp[]=(int [])allBullet.elementAt(i);
					tmp[2]++;
					if(tmp[2]>2){
						tmp[2]=0;
					}
					tmp[1]-=8;
					if(tmp[1]<0){
						allBullet.removeElementAt(i);
					}
				}
				repaint();
			}
		};		
	    t.schedule(ts2, 0, 10);
	    loadLogicData(1);
	    TimerTask ts3=new TimerTask(){
	    	public void run(){
				//记忆滚屏次数
				scorll();
				//出现敌人
				generateEnemy();
				//移动敌人
				enemyMove();
				//敌人发射子弹
				enemyFire();
				//移动敌人子弹
				moveEnemyBullet();
				//重画
				repaint();
	    	}
	    };
	    t.schedule(ts3, 0, 100);
	    new Thread(this).start();
	}
	
	
	/**
	 * 记忆滚屏次数
	 */
	public void scorll(){
		num++;
	}
	int[][] logicData;
	
	/**
	 * 从配置文件中导入逻辑数据
	 * @param level 关卡数
	 */
	private void loadLogicData(int level){
		try{
			//建立流
			InputStream is = 
				getClass().getResourceAsStream("/state" + level + ".abc");
			DataInputStream dis = new DataInputStream(is);
			
			//解析文件
			int len = dis.readInt();  //数组长度
			//构造数组
			logicData = new int[len][4];
			//读取数据
			for(int i = 0;i < logicData.length;i++){
				for(int j = 0;j < logicData[i].length -1;j++){
					logicData[i][j] = dis.readInt();
				}
			}
			//关闭流
			dis.close();
			is.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	/**
	 * 产生敌人的逻辑规则
	 */
	public void generateEnemy(){
		for(int i = 0;i < logicData.length;i++){
			if(num == logicData[i][0] && logicData[i][3] == 0){
				addEnemy(logicData[i][1],logicData[i][2]);
				logicData[i][3] = 1;
			}
		}
	}
	
	/**
	 * 添加敌人
	 * @param enemyType 敌人类型
	 * @param positionType 位置类型
	 */
	private void addEnemy(int enemyType,int positionType){
		//找到未使用的飞机
		for(int i = 0;i < enemyPlane.length;i++){
			//不可见
			if(enemyPlane[i][0] == 0){
				//添加,设置参数
				enemyPlane[i][0] = 1; //可见
				enemyPlane[i][1] = enemyType;  //类型
				enemyPlane[i][3] = -20; //y坐标
				//根据位置参数确定x坐标
				switch(positionType){
				case LEFT_POSITION:
					enemyPlane[i][2] = 3;
					break;
				case CENTER_POSITION:
					enemyPlane[i][2] = SCREENWIDTH/2 - 10;
					break;
				case RIGHT_POSITION:
					enemyPlane[i][2] = SCREENWIDTH - 26;
					break;
				}
				//初始化发射子弹间隔的次数
				enemyPlane[i][4] = enemyType;
				//初始化移动次数
				enemyPlane[i][5] = 0;
				break;
			}
		}
	}
	
	/**
	 * 敌人飞机移动
	 */
	public void enemyMove(){
		for(int i = 0;i < enemyPlane.length;i++){
			//飞机可见
			if(enemyPlane[i][0] == 1){
				//根据类型移动
				switch(enemyPlane[i][1]){
				case ENEMY1:
					if(enemyPlane[i][5] < ENEMY1_MOVE_PATH.length){
						enemyPlane[i][3] += ENEMY1_MOVE_PATH[enemyPlane[i][5]];
					}else{//飞机消失
						enemyPlane[i][0] = 0;
						//不发射子弹
						enemyPlane[i][6] = 0;
					}
					//如果飞机达到中央
					if(enemyPlane[i][5] == ENEMY1_MOVE_PATH.length / 2){
						enemyPlane[i][6] = 1; //可以发射子弹
					}
					break;
				case ENEMY2:
					if(enemyPlane[i][5] < ENEMY2_MOVE_PATH.length){
						enemyPlane[i][3] += ENEMY2_MOVE_PATH[enemyPlane[i][5]];
					}else{//飞机消失
						enemyPlane[i][0] = 0;
						//不发射子弹
						enemyPlane[i][6] = 0;
					}
					//如果飞机达到中央
					if(enemyPlane[i][5] == ENEMY2_MOVE_PATH.length / 2){
						enemyPlane[i][6] = 1; //可以发射子弹
					}
					break;
				}
				//索引值增加1
				enemyPlane[i][5]++;				
			}
		}
	}
	
	/**
	 * 绘制敌人飞机
	 * @param g 画笔
	 * @param enemyPlaneImg 敌人飞机图片
	 */
	public void paintEnemyPlane(Graphics offG,Image[] enemyPlaneImg){
//		//校验enemyPlane
//		System.out.println("enemyPlane为空:" + 
//				(enemyPlane == null));
//		//校验g
//		System.out.println("g为空:" + 
//				(offG == null));
//		//校验enemyPlaneImg
//		System.out.println("enemyPlaneImg为空:" + 
//				(enemyPlaneImg == null));
		
		for(int i = 0;i < enemyPlane.length;i++){
			//如果飞机可见
			if(enemyPlane[i][0] == 1){
				int index = convertTypeToIndex(enemyPlane[i][1]);
//				//校验enemyPlaneImg[index]
//				System.out.println("enemyPlaneImg[index]为空:" + 
//						(enemyPlaneImg[index] == null));
//				//校验index
//				System.out.println("index:" +  index);
				
				offG.drawImage(enemyPlaneImg[index], 
						enemyPlane[i][2], enemyPlane[i][3], 
						Graphics.LEFT | Graphics.TOP);
			}
		}
	}
	
	
	/**
	 * 敌人飞机发射子弹的逻辑
	 */
	public void enemyFire(){
		for(int i = 0;i < enemyPlane.length;i++){
			//可以发射子弹
			if(enemyPlane[i][6] == 1){
				//发射子弹
				if(enemyPlane[i][4] == enemyPlane[i][1]){
					switch(enemyPlane[i][1]){ //根据飞机的类型
					case ENEMY1:
						addEnemyBullet(NORMAL,
								enemyPlane[i][2] + (ENEMY1PLANE_WIDTH - BULLET_WIDTH) / 2,
								enemyPlane[i][3] + (ENEMY1PLANE_HEIGHT - BULLET_HEIGHT) / 2);
						//重新计算发射间隔
						enemyPlane[i][4] = 0;
						break;
					case ENEMY2:
						addEnemyBullet(NORMAL,
								enemyPlane[i][2] + (ENEMY2PLANE_WIDTH - BULLET_WIDTH) / 2,
								enemyPlane[i][3] + (ENEMY1PLANE_HEIGHT - BULLET_HEIGHT) / 2);
						addEnemyBullet(LEFT,
								enemyPlane[i][2] + (ENEMY2PLANE_WIDTH - BULLET_WIDTH) / 2,
								enemyPlane[i][3] + (ENEMY1PLANE_HEIGHT - BULLET_HEIGHT) / 2);
						addEnemyBullet(RIGHT,
								enemyPlane[i][2] + (ENEMY2PLANE_WIDTH - BULLET_WIDTH) / 2,
								enemyPlane[i][3] + (ENEMY1PLANE_HEIGHT - BULLET_HEIGHT) / 2);
						//重新计算发射间隔
						enemyPlane[i][4] = 0;
						break;
					}
				}else{
					enemyPlane[i][4]++;
				}
			}
		}
	}
	
	/**
	 * 将子弹添加到敌人子弹数组
	 * @param type 敌人子弹类型
	 * @param bulletX 敌人子弹x坐标
	 * @param bulletY 敌人子弹y坐标
	 */
	public void addEnemyBullet(int type,int bulletX,int bulletY){
		for(int i = 0;i < enemyBullet.length;i++){
			//找到第一个可以存储的位置
			if(enemyBullet[i][0] == 0){
				//设置子弹可见
				enemyBullet[i][0] = 1;
				//设置坐标
				enemyBullet[i][1] = bulletX;
				enemyBullet[i][2] = bulletY;
				//设置类型
				enemyBullet[i][3] = type;
				//设置速度
				enemyBullet[i][4] = NORMAL_SPEED;
				break;
			}
		}
	}
	
	/**
	 * 绘制敌人子弹的方法
	 * @param g 画笔
	 * @param enemyBulletImg 敌人子弹图片
	 */
	public void paintEnemyBullet(Graphics offG,Image enemyBulletImg){
		for(int i = 0;i < enemyBullet.length;i++){
			//子弹可见
			if(enemyBullet[i][0] == 1){
				offG.drawImage(enemyBulletImg, enemyBullet[i][1],
						enemyBullet[i][2],Graphics.TOP | Graphics.LEFT);
			}
		}
	}
	
	/**
	 * 移动敌人发射的子弹
	 */
	public void moveEnemyBullet(){
		for(int i = 0;i < enemyBullet.length;i++){
			//子弹可见
			if(enemyBullet[i][0] == 1){
				//根据类型来进行移动
				switch(enemyBullet[i][3]){
				case NORMAL:
					enemyBullet[i][2] += enemyBullet[i][4];
					break;
				case LEFT:
					enemyBullet[i][2] += enemyBullet[i][4];
					enemyBullet[i][1] -= enemyBullet[i][4] / 3;
					break;
				case RIGHT:
					enemyBullet[i][2] += enemyBullet[i][4];
					enemyBullet[i][1] += enemyBullet[i][4] / 3;
					break;
				}
				//边界检测
				if(enemyBullet[i][1] < 0 ||
						enemyBullet[i][1] > SCREENWIDTH ||
						enemyBullet[i][2] < 0 ||
						enemyBullet[i][2] > SCREENHEIGHT){
					//子弹不可见
					enemyBullet[i][0] = 0;
				}
			}
		}
	}


	/**
	 * 把敌人飞机类型转换为对应敌人图片数组的下标
	 * @param enemyType 敌人的类型
	 * @return 敌人图片数组的下标
	 */
	public int convertTypeToIndex(int enemyType){
		switch(enemyType){
		case ENEMY1:
			return 1;
		case ENEMY2:
			return 0;
		}
		return 0;
	}

	
	public void drawmenubk(Graphics offG){
		offG.setClip(0, 0, SCREENWIDTH, SCREENHEIGHT);

⌨️ 快捷键说明

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