rpgcanvas.java
来自「一个J2ME的RPG游戏」· Java 代码 · 共 1,841 行 · 第 1/4 页
JAVA
1,841 行
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.Vector;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
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.media.MediaException;
public class RPGCanvas extends GameCanvas implements Runnable, CommandListener {
private int screenwidth = getWidth(); //屏幕宽
private int screenheight = getHeight(); //屏幕高
private int imgbackgroundwidth = 512; //地图背景宽
private int imgbackgroundheight = 512; //地图背景高
Thread t; //游戏线程
Random r; //随机数
RPGMidlet midlet;
Vector vectormessage; //保存会话内容
Vector vectorpicture; //保存图画
LayerManager lmscene1, lmscene2; //场景一,二管理对象
String missionmessage, curmessage; //任务消息和当前人物会话内容
Mainrole mrole; //游戏主角色
Load load; //加载游戏画面
Graphics g;
Image curpicture;
private boolean catchcat = false; //判断与猫的接触
private boolean catchcat2 = false;
private boolean showyesorno = false; //是否显示会话内容
private boolean mainroleanswer = false; //人物回答
private boolean iscollide = false; //是否与老人接触了
private int scene = 1; // check for scene //场景
private int inputmode = 0; //输入模式
int screenx, screeny, lastscreenx, lastscreeny; //屏幕当前坐标 和上次移动的坐标大小
int tempx = 0, tempy = 0;
int selecty = 152; //当进行模式选择时,选择光标的位置
int key; //获得键盘状态
static int mroleProperty[]; //人物属性数组
private int roleBloodHeight = 40; //人物血气的长度
private boolean ismessage = false; //npc人物是否显示对话
private boolean firstTouch = true; //完成寻找猫后,第一次与老人接触后为false
private boolean isbeat = false; //判断是否与野怪接触
public static final int GAME_MENU = 0; //游戏菜单状态
public static final int GAME_START = 1; //游戏进行状态
public static final int GAME_PAUSE = 2; //游戏停止状态
public static final int GAME_ABOUT = 8; //游戏介绍状态
private static final int MENU_START = 3; //菜单:进入游戏
private static final int MENU_LOAD = 4; //菜单:载入进度
private static final int MENU_VOL = 5; //菜单:声音播放
private static final int MENU_QUIT = 6;// 菜单: 退出
private static final int MENU_ABOUT = 7; //菜单:关于游戏
private static final int MENU_SAVE = 8;// 菜单:保存游戏
// public static int DEFAULT_FPS = 10;
//
// private int interval = 1000 / DEFAULT_FPS;
public Command exitGame = new Command("退出", Command.EXIT, 1);
public Command mainMenu = new Command("菜单", Command.OK, 1);
public Command backMenu = new Command("返回菜单", Command.BACK, 2);
public Command backGame = new Command("返回游戏", Command.BACK, 2);
private Font font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD,
Font.SIZE_SMALL);
private int fHeight = font.getHeight();
private int gameAboutY = 0;
public SaveStateRecord record = null;
public AudioPlayer bgPlayer;
// public AudioPlayer beatPlayer;
public boolean isVolOn = false;
private boolean isFirstStart; //判断是否刚启动游戏,尚未进入游戏状态
private boolean gameOver = false; //游戏结束标志
private boolean isBoss = false; //是否与boss接触
private boolean isSoldier = false; //是否与野怪接触
private boolean isAttack = false; // 是否攻击选择
private int number; //判断接触的是第几个野怪2,3,4分表表示第一,二,三个野怪
private String soldierWord; //存放野怪或boss对话内容
private int blood; //存放野怪或boss所出招数引起的血气减少量
private int attackWidth; //每帧招数图片的宽
private int attackHeight; //每帧招数图片的高
private String roleWord = ""; //人物对话内容
private boolean roleAttack = false; // 人物招数选择
private int attackSelecty = screenwidth - 35; //有三项选择时,游戏光标位置
private int tempNum; //随机数
private boolean roleBeat = false; //人物放招画面
private boolean isBossDead = false; //判断boss死亡
private boolean isFood = false; //判断与食物接触
private boolean isSword = false; //判断与宝剑接触
private boolean isChoose = false; //判断是否攻击boss
private boolean isBossAttack = false; //boss攻击
private int bossBlood = 30; //boss血气
private boolean warEnd = false; //判断与boss战斗是否结束
private int randX, randY; //随机获得坐标,用来随机产生道具
private int gameState; //游戏状态
private int menuState; //菜单状态
private String choose1, choose2, choose3; //选择项
private boolean isGold = false; //是否与黄金碰撞
private boolean isSeller = false; //是否与商人碰撞
private boolean isBuy = false; //是否买
private boolean isSell = false; //是否卖
private boolean forBuy = false; //选择买
private boolean forSell = false; //选择卖
private boolean sellerAsk = false; //商人询问买卖
private boolean roleChoose = false; //人物是否选择买卖
private int tempH = 0; //游戏介绍的总高度
private String pMessage;
private boolean isProperty = false;
private Image pImage = null;
private boolean isJump = false;
private boolean isSelectAttack = false;
private boolean isRoleAttack = false;
protected RPGCanvas(RPGMidlet midlet) { // 构造函数,初始类
super(true);
this.midlet = midlet;
g = getGraphics();
r = new Random();
// t = new Thread(this);
mroleProperty = new int[] { 0, 0, 0, 0, 0 }; // 分别表示等级,宝物,完成任务数,血气,宝物
// mroleProperty = new int[] { 1, 1, 1, 1, 1 }; // 为什么只有mroleproperty【4】才等于1
vectormessage = new Vector();
vectorpicture = new Vector();
load = new Load();
curmessage = null;
missionmessage = null;
curpicture = null;
if (scene == 1)
mrole = new Mainrole(load.imgrole, 16, 24, 50, 50, 80, 153);
else if (scene == 2) {
mrole = new Mainrole(load.imgrole, 16, 24, 80, 153);
inputmode = 2;
}
lmscene1 = new LayerManager();
lmscene2 = new LayerManager();
setCommandListener(this);
record = new SaveStateRecord("RPGRecord2");
bgPlayer = new AudioPlayer("bg.mid", "audio/midi");
// beatPlayer = new AudioPlayer("beat.mmf", "application/vnd.smaf");
isFirstStart = true;
gameState = GAME_MENU;
menuState = MENU_START;
try {
// addendshowtalk();
load.p.start();
} catch (MediaException e) {
e.printStackTrace();
}
// t.start();
}
public void stop() {
t = null;
}
public void start(){
t = new Thread(this); //为什么需要加上对象参数this??当无this时无游戏画面
t.start();
System.out.println("Thread Start!");
}
//产生随机数
int getrand(int m) {
int n = r.nextInt();
if (n < 0)
n *= -1;
n %= m;
return n;
}
public void screenmove(int increasex, int increasey) { // 屏幕移动函数
screenx = screenx + increasex;
screeny = screeny + increasey;
lastscreenx = increasex;
lastscreeny = increasey;
}
void screenunmove() {// 屏幕负移动函数
screenmove(-lastscreenx, -lastscreeny);
}
void draw() { // 绘画函数
// 清屏
if (!gameOver) {
// 设置window
if (!isAttack && !roleAttack && !roleBeat && !isSelectAttack) {
g.setColor(255, 255, 255);
g.fillRect(0, 0, getWidth(), getHeight());
if (scene == 1) { //加载场景一
lmscene1.setViewWindow(screenx, screeny, screenwidth,screenheight);
append();
if(isBossDead)load.property[1].setVisible(false);
lmscene1.paint(g, 0, 0);
drawProperty();
}
else if (scene == 2) { //加载场景2
mrole.setPosition(mrole.roomx, mrole.roomy);
lmscene2.setViewWindow(0, 0, screenwidth, screenheight);
append2();
lmscene2.paint(g, 0, 0);
}
}
if (missionmessage != null) {
g.setColor(255, 255, 255);
g.drawString(missionmessage, 0, screenheight, g.BOTTOM| g.LEFT);
}
// 显示对话
drawmessage();
if (showyesorno == true) {
drawlist(); //显示选择框
}
if (sellerAsk) { //商人询问框 :买,卖,放弃
g.setColor(0, 0, 100);
g.fillRect(0, getHeight() - 40, getWidth(), 40);
g.setColor(255, 255, 128);
g.drawImage(load.sellerbig, 0, screenheight - 40, g.TOP
| g.LEFT);
g.setColor(255, 255, 255);
g.drawString(choose1, 60, getHeight() - 40, 0);
g.drawString(choose2, 60, getHeight() - 30, 0);
g.drawString(choose3, 60, screenheight - 20, 0);
g.setColor(255, 255, 0);
// g.fillArc(45, attackSelecty, 5, 5, 0, 360);
g.drawImage(load.selectIcon,40, attackSelecty ,g.TOP|g.LEFT );
Font ff = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN,
Font.SIZE_SMALL);
g.setFont(ff);
g.setColor(255, 255, 255);
g.drawString("Push FIRE", screenwidth, screenheight, g.BOTTOM
| g.RIGHT);
// sellerAsk = false;
roleChoose = true;
}
if (isBuy) { //角色选择买商品时的选择框:黄金-》血气,黄金-》宝物,放弃
g.setColor(0, 0, 100);
g.fillRect(0, getHeight() - 57, getWidth(), 57);
g.drawImage(load.sellerbig, 0, getHeight() - 57, 0);
g.setColor(255, 255, 255);
g.drawString(choose1, 60, getHeight() - 40, 0);
g.drawString(choose2, 60, getHeight() - 30, 0);
g.drawString(choose3, 60, getHeight() - 20, 0);
g.setColor(255, 255, 0);
// g.fillArc(42, attackSelecty, 5, 5, 0, 360);
g.drawImage(load.selectIcon, 40, attackSelecty, g.TOP|g.LEFT);
forBuy = true;
}
if (isSell) { //角色选择卖商品时的选择框:宝物-》黄金,放弃
g.setColor(0, 0, 100);
g.fillRect(0, getHeight() - 40, getWidth(), 40);
g.drawImage(load.sellerbig, 0, getHeight() - 40, 0);
g.setColor(255, 255, 255);
g.drawString(choose1, 60, getHeight() - 30, 0);
g.drawString(choose2, 60, getHeight() - 20, 0);
g.setColor(255, 255, 0);
// g.fillArc(42, selecty, 5, 5, 0, 360);
g.drawImage(load.selectIcon, 40, selecty, g.TOP|g.LEFT);
forSell = true;
}
if (isChoose) { //人物碰到npc时选择框:攻击,放弃
g.setColor(0, 0, 100);
g.fillRect(0, getHeight() - 57, getWidth(), 57);
g.drawImage(load.hero, 0, getHeight() - 57, 0);
g.setColor(255, 255, 128);
g.drawString(choose1, 70, getHeight() - 30, 0);
g.drawString(choose2, 70, getHeight() - 20, 0);
g.setColor(255, 255, 0);
// g.fillArc(52, selecty, 5, 5, 0, 360);
g.drawImage(load.selectIcon, 50, selecty, g.TOP|g.LEFT);
Font ff = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN,
Font.SIZE_SMALL);
g.setFont(ff);
g.setColor(255, 255, 255);
g.drawString("Push FIRE", screenwidth, screenheight, g.BOTTOM
| g.RIGHT);
g.setColor(0);
g.drawRoundRect(0, screenheight - 65, 40, 5, 4, 2);
g.setColor(0xB84909);
g.fillRoundRect(0, screenheight - 65, roleBloodHeight, 5, 4, 2);
g.setColor(255);
}
if(isJump){
g.setColor(255,255,255);
g.fillRect((screenwidth - attackWidth) >> 1,
(screenheight - attackHeight) >> 1, attackWidth, attackHeight);
// g.setClip(mrole.x, mrole.y, 70, 64);
// g.drawImage(load.heroJump, mrole.x - 70 * i, mrole.y, g.TOP|g.LEFT);
g.setClip((screenwidth - attackWidth) >> 1,
(screenheight - attackHeight) >> 1, attackWidth,attackHeight);
g.drawImage(load.heroJump, screenwidth / 2 - attackWidth* i,
screenheight >> 1, g.HCENTER | g.VCENTER);
g.setClip(0, 0, screenwidth, screenheight);
i ++;
if(i == 6){
isJump = false;
isSelectAttack = false;
i = 0;
inputmode = 0;
if (!warEnd) { //当是boss的时候,根据人物等级不同,攻击力野不相同
if (mroleProperty[0] <= 5)
bossBlood -= 5;
else if (mroleProperty[0] >= 11)
bossBlood -= 10;
else
bossBlood -= mroleProperty[0];
if (bossBlood >= 0) {
isBossAttack = true;
tempNum = getrand(4);
switch (tempNum) {
case 0:
soldierWord = "看招:一击即中";
blood = 4;
attackWidth = 29;
attackHeight = 32;
break;
case 1:
soldierWord = "看招:所向披靡";
attackWidth = 101;
attackHeight = 76;
blood = 3;
break;
case 2:
soldierWord = "看招:怒海狂潮";
blood = 5;
attackWidth = 80;
attackHeight = 80;
break;
case 3:
soldierWord = "看招:天翻地覆";
blood = 10;
attackWidth = 78;
attackHeight = 98;
break;
default:
break;
}
} else
isBossDead = true;
}
}
g.setClip(0, 0, screenwidth, screenheight);
}
if (isAttack) { //当人物选择攻击时,npc先进行攻击,在三招中随机选择一招
switch (tempNum) {
case 0:
soldierWord = "看招:一击即中";
blood = 4;
attackWidth = 29;
attackHeight = 32;
break;
case 1:
soldierWord = "看招:所向披靡";
attackWidth = 101;
attackHeight = 76;
blood = 3;
break;
case 2:
soldierWord = "看招:怒海狂潮";
blood = 5;
attackWidth = 80;
attackHeight = 80;
break;
default:
break;
}
g.setColor(255, 255, 255);
g.fillRect(0, 0, screenwidth, screenheight);
g.setColor(0, 0, 100);
g.fillRect(0, 0, getWidth(), 50);
g.drawImage(load.soldierbig, 0, 0, 0);
Font f = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN,
Font.SIZE_MEDIUM);
g.setFont(f);
g.setColor(255, 255, 255);
g.drawString(soldierWord, 37, 0, 0);
g.setClip((screenwidth - attackWidth) >> 1,
(screenheight - attackHeight) >> 1, attackWidth,attackHeight);
g.drawImage(load.attack[tempNum], screenwidth / 2 - attackWidth* i,
screenheight >> 1, g.HCENTER | g.VCENTER);
g.setClip(0, 0, screenwidth, screenheight);
if (i == 6) { //招数六个画面播放完后
isAttack = false;
isSoldier = false;
// roleAttack = true;
// inputmode = 3;
isChoose = true;
inputmode = 1;
choose1 = "普通攻击";
choose2 = "魔法攻击";
isSelectAttack = true;
i = -1;
load.npc[number].setVisible(false);
randX = getrand(480);
randY = getrand(450); //在地图上随机生成相同的野怪
load.npc[number] = new Npc(load.imgsoldier, 16, 24,
load.npc[number].name, load.npc[number].message1,
randX, randY, load.npc[number].message2,
load.npc[number].img);
mroleProperty[0]++; //人物增加等级与野怪等级相同
if (number == 3)
mroleProperty[0]++;
roleBloodHeight -= blood;
// drawRoleAttack();
}
i++;
}
if (roleAttack) { //人物进行攻击招数选择,共三种
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?