📄 cman.java
字号:
import java.io.IOException;
import java.util.Random;
import javax.microedition.lcdui.*;
/*
* 主角类
* 包括了画地图和行走碰撞检测
* 使用方法:
* 只需构造函数带入参数:Graphics 画笔指针,主角图片路径
* 切换场景时调用函数: LoadScene() 参数带入地图的序号
* 画地图和主角时只需调用: DrawMap() 和 DrawPlayer()
* 在读键盘事件中调用: KeyPressed() 和 KeyReleased()
*/
public class CMan
{
private Graphics m_offG; //画笔
private CMap m_map; //地图信息
private CCollision m_collision; //碰撞信息
private CBattle m_battle; //战斗类
private int m_posX = 80; //人物坐标
private int m_posY = 96;
private int m_nowFrame = 0; //当前帧
private int m_moveFrame[][] = //控制动作变化的帧序号
{
{0,1,2}, //down
{3,4,5}, //right
{6,7,8}, //up
{9,10,11} //left
};
private int m_dir = 0; //人物走动方向: 1--下 2--右 3--上 4--左
private int m_faceDir = 1; //面向
private int m_placeX; //滚屏之用
private int m_placeY;
private Image m_image; //加载地图用的图片
private Image m_player; //加载主角用的图片
private Image m_imnpc; //加载NPC用的图片
private int m_nextGrid; //下一步的格序号
private int m_stepToFight; //离地雷式战斗还剩余的步数
private boolean m_fighted = false; //是否正在战斗
private int m_playerLv; //主角的级别
private int m_playerHP; //主角的生命值
private int m_playerMP; //主角的体力值
private int m_playerExp; //主角当前经验值
private CNPC m_npc[];
private int m_scene; //当前的场景号
private int m_nextCollideNPC; //即将与这个 NPC 发生碰撞,如果不与任何一个 NPC 碰撞,其值为 -1
//---------------------------------------------------------
// 构造函数
// 加载主角图片
//---------------------------------------------------------
public CMan(Graphics offG, String manFilePath)
{
m_offG = offG;
m_playerLv = 1; //游戏开始主角级别为 1
m_playerHP = m_playerLv * 100;
m_playerMP = m_playerLv * 50;
try
{
m_player = Image.createImage(manFilePath);
m_imnpc = Image.createImage("/data/npc.png");
} catch (IOException ex)
{
ex.printStackTrace();
}
m_battle = new CBattle(offG);
m_npc = new CNPC[5];
for (int i = 0; i < m_npc.length; i++)
{
m_npc[i] = new CNPC();
}
m_npc[0].init(2, 1, 80, 12, 6, 0); //霍恩
m_npc[1].init(4, 2, 100, 74, 0, 0); //阿美
m_npc[2].init(1, 1, 128, 76, 11, 13); //胡尔
m_npc[3].init(0, 1, 80, 76, 2, 10); //萨耶
m_npc[4].init(3, 1, 96, 12, 11, 0); //尤诺
}
//---------------------------------------------------------
// 重置人物各属性
// 用于第一次进入游戏
//---------------------------------------------------------
public void reset()
{
m_playerLv = 1;
m_playerHP = m_playerLv * 100;
m_playerMP = m_playerLv * 50;
m_playerExp = 0;
m_posX = 48;
m_posY = 64;
m_nowFrame = 0;
m_dir = 0;
m_faceDir = 2;
m_placeX = 0;
m_placeY = 0;
m_fighted = false; //是否正在战斗
m_scene = 2;
}
//---------------------------------------------------------
// 主角生命值、体力值全恢复
//---------------------------------------------------------
public void restoreHPMP()
{
m_playerHP = m_playerLv * 100;
m_playerMP = m_playerLv * 50;
}
//---------------------------------------------------------
// 加载地图图片、地图拼接信息、碰撞信息
// 初始化各成员变量
// 参数分别是:从 fromMap 号地图到 toMap 号地图
//---------------------------------------------------------
public void loadScene(int fromMap, int toMap)
{
m_scene = toMap;
try
{
m_image = Image.createImage("/data/map0" + toMap + ".png");
m_map = new CMap("/data/map0" + toMap + ".dat");
m_collision = new CCollision("/data/map0" + toMap + ".cls");
} catch (IOException ex)
{
ex.printStackTrace();
}
System.gc();
m_dir = 0; //站立
m_placeX = 0;
m_placeY = 0;
switch (toMap) //根据地图初始化主角初始位置
{
case 1: //切换到大地图( 1 号地图)
if (fromMap == 2) //从 2 号地图切换过来
{
m_posX = 80;
m_posY = 16;
m_placeX = 3;
m_placeY = 0;
m_faceDir = 1;
}
m_stepToFight = 50;
break;
case 2: //切换到 2 号地图
if (fromMap == 0) //第一次出现在地图中,即游戏开始时
{
// m_posX = 48;
// m_posY = 64;
// m_faceDir = 2; //面向右
}
else if (fromMap == 1) //从大地图( 1 号地图)切换过来
{
m_posX = 120;
m_posY = 100;
m_faceDir = 4; //面向左
}
break;
}
}
//----------------------------------------------------------
// 画地图,n 代表在地图编辑器中一行的块数
//----------------------------------------------------------
public void drawMap()
{
int n = m_image.getWidth() / 16;
for(int row=0;row<13;row++)
{
for(int col=0;col<11;col++)
{
int k = m_map.GetMapData(row + m_placeY, col + m_placeX) - 1;
int mx = col * 16; //当前绘制的横坐标
int my = row * 16; //当前绘制的纵坐标
m_offG.setClip(mx, my, 16, 16); //设定剪裁区
int movex = (k % n) * 16; //图片向左移动像素
int movey = (k / n) * 16; //图片向上移动的像素
m_offG.drawImage(m_image, mx - movex, my - movey, Graphics.LEFT | Graphics.TOP);
}
}
}
//---------------------------------------------------
// 画人物
// 在大地图中横竖着走,小地图中45度角斜走
//---------------------------------------------------
public void drawPlayer()
{
int row = (m_posY + 48) / 16 - 1;
int col = m_posX / 16;
int step = 8;
switch(m_dir) //根据方向判断人物要画第几帧
{
case 0: //站立
m_offG.setClip(m_posX - 6, m_posY + 6, 24, 48); //加 6 减 6 是为了让主角对准格子
switch(m_faceDir)
{
case 1:
m_offG.drawImage(m_player, m_posX - 6, m_posY + 6, 0);
break;
case 2:
m_offG.drawImage(m_player, m_posX - 6 - 72, m_posY + 6, 0);
break;
case 3:
m_offG.drawImage(m_player, m_posX - 6 - 144, m_posY + 6, 0);
break;
case 4:
m_offG.drawImage(m_player, m_posX - 6 - 216, m_posY + 6, 0);
break;
}
break;
case 1: //向下走
if (m_collision.InBigMap()) //在大地图中
{
if (row + 1 + m_placeY <= m_map.getRowNum()) //防止越界
{
m_nextGrid = m_map.GetMapData(row + 1 + m_placeY, col + m_placeX); //下一步的地图块序号
if (m_collision.InCanGoGrid(m_nextGrid)) //是否碰撞
{
if (row >= 6 && m_placeY + 1 < m_map.getRowNum() - 12)
{
boolean collide = false; //是否碰撞
for (int i = 0; i < m_npc.length; i++) //与当前场景中所有 NPC 都进行碰撞检测
{
if (m_npc[i].getSceneID() == 1 && //是否是大场景中的一个NPC
RectInRect(m_posX - 6, m_posY + 16, 18, 32, m_npc[i].getPosX() + 6, m_npc[i].getPosY() + 3 - 16, 8, 14)) //不与 NPC 碰撞才移动,-6、+16、+6、+3 是为了对齐人物,drawPlayer()最后的drawRect执行上就会明白
{
collide = true; //与第 i 个 NPC 碰撞
m_nextCollideNPC = m_npc[i].getID();
break;
}
}
if (!collide)
{
m_placeY++; //滚屏
m_nextCollideNPC = -1;
}
}
else
{
boolean collide = false; //是否碰撞
for (int i = 0; i < m_npc.length; i++) //与当前场景中所有 NPC 都进行碰撞检测
{
if (m_npc[i].getSceneID() == 1 && //是否是大场景中的一个NPC
RectInRect(m_posX - 6, m_posY + 16 + 16, 18, 32, m_npc[i].getPosX() + 6, m_npc[i].getPosY() + 3, 8, 14)) //不与 NPC 碰撞才移动,-6、+16、+6、+3 是为了对齐人物,drawPlayer()最后的drawRect执行上就会明白
{
collide = true; //与第 i 个 NPC 碰撞
m_nextCollideNPC = m_npc[i].getID();
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -