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 + -
显示快捷键?