📄 map.java
字号:
}
}
for (int i = 0; i < m_RoleArr.length; i++) {
m_RoleArr[i] = null; //地图中每个角色都已经建立,不再需要角色种类数据因此删除
}
m_RoleArr = null; //删除角色种类数组
di.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
public void loadRole(){
InputStream fi = getClass().getResourceAsStream("/role.bin");//打开文件
DataInputStream din = new DataInputStream(fi);
try {
int imgNum = din.readByte();//读图片数量
Data.imgRole=new Image[imgNum];//
for (int i = 0; i < imgNum; i++) { //创建角色用到的Image对象
Data.imgRole[i]=Image.createImage("/"+din.readUTF()+".png");
}
int roleNum=din.readInt();//角色数量
m_RoleArr=new Role[roleNum];
for (int i = 0; i < roleNum; i++) {
m_RoleArr[i]=new Role(this);
m_RoleArr[i].loadRoleData(din);//读取角色数据
}
din.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
/**
* 按键事件
* @param keyCode int 按键值
*/
public void keyEvent(int id, int keyCode) {
int _keyCodeBack = 0; //相反方向的按键
//把角色当前所在的位置单元格置0
mapArr2[m_ActionRoleArr[id].getIY() /
m_CellHeight][m_ActionRoleArr[id].getIX() / m_CellWidth] = 0;
switch (keyCode) {
case Data.MYKEY_UP: // 当按上方向键时
m_ActionRoleArr[id].setActionID(1, 0, 0); //设置角色当前播放iActionID为1的动作
_keyCodeBack = Data.MYKEY_DOWN;
break;
case Data.MYKEY_RIGHT: // 当按右方向键时
m_ActionRoleArr[id].setActionID(2, 1, 0); //设置角色当前播放iActionID为2的动作
_keyCodeBack = Data.MYKEY_LEFT;
break;
case Data.MYKEY_DOWN: // 当按下方向键时
m_ActionRoleArr[id].setActionID(0, 0, 0); //设置角色当前播放iActionID为0的动作
_keyCodeBack = Data.MYKEY_UP;
break;
case Data.MYKEY_LEFT: // 当按左方向键时
m_ActionRoleArr[id].setActionID(2, 0, 0); //设置角色当前播放iActionID为2的动作
_keyCodeBack = Data.MYKEY_RIGHT;
break;
}
m_ActionRoleArr[id].roleMove(keyCode, 1); //角色移动
if (checkRoleHit(id)) { //如果碰到了!
m_ActionRoleArr[id].roleMove(_keyCodeBack, -1); //则退回那一步
}
//把角色当前所在的位置单元格置为id+1
mapArr2[m_ActionRoleArr[id].getIY() /
m_CellHeight][m_ActionRoleArr[id].getIX() / m_CellWidth] = (byte)(id+1);
if (!bRunEvent && id == 0) { //如果当前不是在脚本执行状态切角色为主角
int _mapEventID = mapArr3[m_ActionRoleArr[id].getIY() / m_CellHeight][
m_Role.getIX() / m_CellWidth]; //取得人物当前所在位置的事件ID
if (_mapEventID <= GATE_MAX &&
_mapEventID >= GATE_MIN ) {//判断是不是门数据
int _id = Math.abs(_mapEventID) - Math.abs( GATE_MAX);
int _xMap = Integer.parseInt(m_strGate[_id][1]) * 16
, _yMap = Integer.parseInt(m_strGate[_id][2]) * 16;
if (Data.iNowEventIndex < Integer.parseInt(m_strGate[_id][3])) {
strScript= "a(系统," + m_strGate[_id][4] + ")";
getCmd(strScript);
return ;
}
loadRole();//重新载入角色种类
loadMap(m_strGate[_id][0]);//切换地图
m_Role = m_ActionRoleArr[0];//主角操作对象的赋值
m_Role.setIX(_xMap );//设置角色在新地图中的坐标
m_Role.setIY(_yMap );
return;
}else if (_mapEventID > 0 && Data.iNowEventIndex ==
Data.eventsID[_mapEventID - 1][0]) { //事件ID>0
Data.iNowEventIndex = Data.eventsID[_mapEventID - 1][1]; //下一个事件
strScript =m_StrEvents[_mapEventID - 1];//获得脚本内容
getCmd(strScript); //解析命令
}
}
}
public void keyRelease(){//释放按键
m_Role.setActionID(-1,-1,1);
}
private long eventTime;//脚本执行开始的时间
/**
* 解析当前命令 取得命令和参数
* @param str String 命令
*/
private void getCmd(String str) {
bRunEvent = true;
eventTime = System.currentTimeMillis(); //脚本命令开始的时间
int _si = 0, _pIndex = 1;
if (iNowScriptIndex >= str.length()) { //如果索引超过了命令的长度
bRunEvent = false;//退出脚本执行
iNowScriptIndex = 0;//事件字符串索引值置0
return;
}
for (int i = iNowScriptIndex; i < str.length(); i++) {
if (str.substring(i, i + 1).equals("(")) {
_si = i + 1;
cmd[0] = str.substring(iNowScriptIndex, i); //取得命令
}
else if (str.substring(i, i + 1).equals(",")) {
cmd[_pIndex] = str.substring(_si, i); //取得命令参数
_si = i + 1;
_pIndex++;
}
else if (str.substring(i, i + 1).equals(")")) {
cmd[_pIndex] = str.substring(_si, i); //取得命令参数
_si = i + 1;
iNowScriptIndex = _si;
return;
}
}
}
private String strScript; //当前的事件
private int iNowScriptIndex; //当前所取的事件字符串索引
/**
* 取下一条脚本命令
*/
private void nextCmd() {
getCmd(strScript);
}
/**
* 主角的攻击动作设置函数
*/
public void attack(int id){
m_ActionRoleArr[id].setRoleState(Data.ROLE_ATTACK);//设置主角的状态为攻击状态
switch (m_ActionRoleArr[id].getRoleDir()) {
case Data.MYKEY_UP:
m_ActionRoleArr[id].setActionID(4, -1,0); //设置角色当前播放动作
break;
case Data.MYKEY_RIGHT:
m_ActionRoleArr[id].setActionID(5, -1,0); //设置角色当前播放动作
break;
case Data.MYKEY_DOWN:
m_ActionRoleArr[id].setActionID(3, -1,0); //设置角色当前播放动作
break;
case Data.MYKEY_LEFT:
m_ActionRoleArr[id].setActionID(5, -1,0); //设置角色当前播放动作
break;
}
}
/**
* 角色之间的攻击碰撞检测
* @param id int 角色ID
*/
public boolean checkAttackHit(int id ){
int _x = m_ActionRoleArr[id].getIX() + m_ActionRoleArr[id].getAttackRect()[0];//攻击区域的起始位置
int _y = m_ActionRoleArr[id].getIY() + m_ActionRoleArr[id].getAttackRect()[1];
int _w = m_ActionRoleArr[id].getAttackRect()[2]; //攻击区域的宽
int _h = m_ActionRoleArr[id].getAttackRect()[3]; //攻击区域的高
for (int i = _startY; i < _endY; i++) {
for (int j = _startX; j < _endX; j++) {
if (mapArr2[i][j] > 0&&id!=mapArr2[i][j]-1) { //角色的攻击矩形检测
int _roleId = mapArr2[i][j] - 1;
int _x2 = m_ActionRoleArr[_roleId].getIX() +
m_ActionRoleArr[_roleId].getHitRect()[0]; //角色碰撞区域的坐标
int _y2 = m_ActionRoleArr[_roleId].getIY() +
m_ActionRoleArr[_roleId].getHitRect()[1];
int _w2 = m_ActionRoleArr[_roleId].getHitRect()[2]; //碰撞区域的宽
int _h2 = m_ActionRoleArr[_roleId].getHitRect()[3]; //碰撞区域的高
if (isInRect(_x, _y, _w, _h, _x2, _y2, _w2, _h2)) { //检测人物之间的攻击碰撞
System.out.println("attack Role ID= "+_roleId);
return true;//攻击到了
}
}
}
}
return false;//没攻击到
}
/**
* 检测角色是否碰到地表建筑或其他角色
* @return boolean
*/
private boolean checkRoleHit(int id) {
if (mapArr2[m_ActionRoleArr[id].getIY() / m_CellHeight][m_ActionRoleArr[id].getIX()
/ m_CellWidth] > 0) { //如果碰到的是其他角色所在位置
return true;
}
//角色的坐标+角色当前帧的碰撞区域的坐标=角色碰撞区域的地图坐标
int _x = m_ActionRoleArr[id].getIX() + m_ActionRoleArr[id].getHitRect()[0];
int _y = m_ActionRoleArr[id].getIY() + m_ActionRoleArr[id].getHitRect()[1];
int _w = m_ActionRoleArr[id].getHitRect()[2]; //碰撞区域的宽
int _h = m_ActionRoleArr[id].getHitRect()[3]; //碰撞区域的高
for (int i = _startY; i < _endY; i++) {
for (int j = _startX; j < _endX; j++) {
if (!(mapArr3[i][j]<=GATE_MAX&&mapArr3[i][j]>=GATE_MIN)
&&mapArr3[i][j] < 0) { //小于0是碰撞块的
if (isInRect(_x, _y, _w, _h, j * m_CellWidth, i * m_CellHeight,
m_CellWidth, m_CellHeight)) { //检测人物碰撞区域和地表碰撞区域是否相交
return true;
}
}
if (mapArr1[i][j] != 0) { //如果数值为0那么表示该格子没有建筑单元
// 其当前帧的碰撞矩形的地图坐标=建筑单元的地图坐标j * m_CellWidth+其当前帧的碰撞矩形的帧坐标
int _tileUnitX = j * m_CellWidth + m_TileUnit[mapArr1[i][j] -
1].getHitRect()[0];
int _tileUnitY = i * m_CellHeight + m_TileUnit[mapArr1[i][j] -
1].getHitRect()[1];
int _tileUnitW = m_TileUnit[mapArr1[i][j] - 1].getHitRect()[2]; //碰撞矩形宽
int _tileUnitH = m_TileUnit[mapArr1[i][j] - 1].getHitRect()[3]; //碰撞矩形高
if (isInRect(_x, _y, _w, _h, _tileUnitX, _tileUnitY,
_tileUnitW, _tileUnitH)) { //检测人物碰撞区域和建筑单元碰撞区域是否相交
return true;
}
}
if (mapArr2[i][j] > 0&&mapArr2[i][j]-1!=id) { //角色的碰撞矩形检测
int _roleId = mapArr2[i][j] - 1;
int _x2 = m_ActionRoleArr[_roleId].getIX() +
m_ActionRoleArr[_roleId].getHitRect()[0]; //角色碰撞区域的坐标
int _y2 = m_ActionRoleArr[_roleId].getIY() +
m_ActionRoleArr[_roleId].getHitRect()[1];
int _w2 = m_ActionRoleArr[_roleId].getHitRect()[2]; //碰撞区域的宽
int _h2 = m_ActionRoleArr[_roleId].getHitRect()[3]; //碰撞区域的高
if (isInRect(_x, _y, _w, _h, _x2, _y2, _w2, _h2)) { //检测人物之间的碰撞
return true;
}
}
}
}
return false;
}
/**
* 判断2矩形是否相交
* @param ax int 矩形a的 左上顶点的X轴坐标
* @param ay int 矩形a的 左上顶点的Y轴坐标
* @param aw int 矩形a的 宽
* @param ah int 矩形a的 高
* @param bx int 矩形b的 左上顶点的X轴坐标
* @param by int 矩形b的 左上顶点的Y轴坐标
* @param bw int 矩形b的 宽
* @param bh int 矩形b的 高
* @return boolean
*/
public static final boolean isInRect(int ax, int ay, int aw, int ah,
int bx, int by, int bw, int bh) {
if (aw <= 0 || ah <= 0 || bw <= 0 || bh <= 0) { //2个矩形的宽高都不能小于或等于0
return false;
}
if (by + bh < ay || //四种情况只要有一种符合就不相交
ay + ah < by ||
bx + bw < ax ||
ax + aw < bx)
return false; //没有相交
return true; //相交
}
public byte getM_Height() { //得到地图高
return m_Height;
}
public byte getM_Width() { //得到地图宽
return m_Width;
}
public byte getM_CellHeight() {//得到单元格高
return m_CellHeight;
}
public byte getM_CellWidth() {//得到单元格高
return m_CellWidth;
}
public boolean isBRunEvent() {//是否在执行脚本
return bRunEvent;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -