📄 role.java
字号:
case STATE_ATTACK_ONE:
actionIndex = 5;
break;
case STATE_ATTACK_TWO:
actionIndex = 6;
break;
case STATE_ATTACK_THREE:
actionIndex = 7;
break;
case STATE_ATTACK_FOUR:
actionIndex = 8;
break;
case STATE_ATTACK_FIVE:
actionIndex = 9;
break;
case STATE_ATTACK_SIX:
actionIndex = 10;
break;
case STATE_ATTACK_SEVEN:
actionIndex = 11;
break;
case STATE_INJURE:
HP -= 10;
if(HP <= 0){
curStatus = STATE_DEAD;
actionIndex = 13;
return;
}
actionIndex = 12;
break;
case STATE_DEAD:
actionIndex = 13;
break;
}
curStatus = status; //将主角的状态赋值为需要的状态,需要在此函数内进行一些切换状态时初始的工作,后续章节会逐一添加。
}
/**
* nextState > 0 切换状态
* nextState = -1 循环播放
* nextState < -1 停留在最后一帧
* @param nextState byte
*/
private int aniIndex; //切换帧使用到的中间过渡变量
private final void changeRoleFrameIndex(int nextState)
{
if (aniIndex >= Data.frameItemIndex[0][actionIndex].length)
{
if (nextState >= 0)
{
aniIndex = 0;
frameIndex = Data.frameItemIndex[0][actionIndex][aniIndex];
setStatus((byte)nextState);
return;
}
else if (nextState == -1)
{
aniIndex = 0;
}
else
{
return;
}
}
frameIndex = Data.frameItemIndex[0][actionIndex][aniIndex];
aniIndex++;
}
/**
* 人物移动包括与地图块的碰撞
* @param stepX int
* @param stepY int
*/
protected final void roleMove(int stepX, int stepY)
{
this.getRoleSize();
/**********Y方向上的移动**********/
if (stepY > 0) //向下移动
{
/*这里使用到的函数isFall()只需要了解其作用是判断输入的坐标所在的地图块是否可以下落即可,具体实现内容后面逐一讲述*/
if (!Map.isFall(x - (w >> 1), y + stepY) ||
!Map.isFall(x + (w >> 1), y + stepY))
{
/*检测主角脚下最左边边界和最右边边界在移动目标距离(stepY)后,所在的位置的地图块的属性是否可以站立*/
/*如果不可以下落则纠正主角的Y值到与主角碰撞的地图块的最上沿*/
y = (short) ( (y + stepY) / Map.cellHeight * Map.cellHeight);
downToStand(); //同时切换到站立状态,切换到站立状态必须是下落的过程
}
else
{ //反之则可以向下移动
y += stepY; //主角的y值移动
if (! (curStatus == STATE_DOWN || //上跳对应的下\uFFFF状态
curStatus == STATE_DECLINE)) //自由掉落的下落状态
{
/*非下落状态切换到下落状态,如果已经是下落状态则无需切换*/
setStatus(STATE_DECLINE);
}
}
}
else if (stepY < 0)
{ //向上移动
if (!Map.isUp(x - (w >> 1), y + stepY - 60) ||//由于资源中上跳状态下有灰尘,所以人物的高度约为60像素
!Map.isUp(x + (w >> 1), y + stepY - 60))
{
/*检测人物头顶最左边和最右边向上与地图块的碰撞*/
/*如果发生碰撞则纠正主角的Y值到与主角碰撞的地图块的最下沿*/
y = (short) ( (y + stepY) / Map.cellHeight * Map.cellHeight);
}
else
{
/*与地图块没有发生碰撞情况*/
y += stepY;
}
}
/**********X方向上的移动**********/
if (stepX != 0)
{
if (isLeft)
{
if (!Map.isRun(x - (w >> 1) - stepX, y - 2) || //主角左侧脚下处可以行走(即判断主角头顶处前方移动的地图块是否可以通过)
!Map.isRun(x - (w >> 1) - stepX, y - h))
{ //主角左侧头顶处可以行走(即判断主角头顶处前方移动的地图块是否可以通过)
x = (short) ( (x -(w >>> 1)- stepX) / Map.cellWidth * Map.cellWidth
+ Map.cellWidth + (w >>> 1)); //不能行走则纠正主角的x坐标至前方遇到地图块的最右侧
toStand(); //切换至站立状态
}
else
{
/*与地图块没有发生碰状情况*/
x -= stepX; //行走
}
}
else
{
if (!Map.isRun(x + (w >> 1) + stepX, y - 2) || //主角右侧脚下处可以行走(即判断主角头顶处前方移动的地图块是否可以通过)
!Map.isRun(x + (w >> 1) + stepX, y - h))
{ //主角右侧头顶处可以行走(即判断主角头顶处前方移动的地图块是否可以通过)
x = (short) ( (x +(w >>> 1) +stepX) / Map.cellWidth *
Map.cellWidth - (w >>> 1)); //不能行走则纠正主角的x坐标至前方遇到地图块的最左侧
toStand(); //切换至站立状态
}
else
{
/*与地图块没有发生碰状情况*/
x += stepX;
}
}
x = (short) (Math.max(x - (w >> 1), Map.leftTopX)); //纠正主角的x坐标不会移处屏幕外
x = (short) (Math.min(x + (w >> 1), Map.leftTopX +
GameCanvas.SCREEN_WIDTH));
}
}
/**
* 切换到停止状态
*/
protected final void toStand()
{
/*只有下落过程中才会转变为站立状态,
因为正常的行走也会判断脚下是否有地图块
也会纠正坐标*/
if (curStatus == STATE_DOWN ||
curStatus == STATE_DECLINE)
{
setStatus(STATE_STAND);
}
}
/**
* 切换到停止状态
*/
protected final void downToStand()
{
/*只有下落过程中才会转变为站立状态,
因为正常的行走也会判断脚下是否有地图块
也会纠正坐标*/
if (curStatus == STATE_DOWN ||
curStatus == STATE_DECLINE)
{
setStatus(STATE_DECLINE_AFTER);
}
}
protected final void getRoleSize()
{
int actionIndex = 0;//站立状态的动作索引;
int frameIndex = 0; //选择任意一帧作为普通状态下的被攻击帧。
w = 20;//Data.npcItemDataSize[0][actionIndex][frameIndex * 4 + 2]; //从保存动画数据帧的尺寸的数组npcItemDataSize中取得(此数据的获得及应用见备注)
h = 36;//Data.npcItemDataSize[0][actionIndex][frameIndex * 4 + 3];
}
protected final void getAttackSize(int tempActionIndex)
{
int tempFrameIndex = 2;
int objectIndex = 0;
//根据游戏类型获得游戏的攻击帧
//以下部分获得攻击帧
try
{
/*根据动画数据我们定义数据npcItemDataSize 来保存所有动画数据中的每帧的宽、高以及X、Y方向最小偏移,存贮格式为:
第一维:表示对象的索引(即objectIndex表示某个对象,与动画数据的对象索引对应,所以此维的长度与npcItemData长度相同)。
第二维:表示此对象的动作的索引。
第三维:所有帧的x方向的最大偏移,Y方向的最大偏移,宽度、高度。如果是很多帧则下4为分别为第二帧的x方向的最大偏移,Y方向的最大偏移,宽度、高度。依此类推。
*/
pw = Data.npcItemDataSize[objectIndex][tempActionIndex][tempFrameIndex * 4 + 2];
//从存贮动画数据的每帧的宽、高以及X、Y方向最小偏移的数组中获得,数据npcItemDataSize的或者后面讲述。
ph = Data.npcItemDataSize[objectIndex][tempActionIndex][tempFrameIndex * 4 + 3];
px = (short) (x +
Data.npcItemDataSize[objectIndex][tempActionIndex][tempFrameIndex * 4 + 0]);
py = (short) (y +
Data.npcItemDataSize[objectIndex][tempActionIndex][tempFrameIndex * 4 + 1]);
}
catch (Exception ex)
{
}
}
void checkRoleAttack(){
if(frameIndex % 3 != 0) return;
this.getAttackSize(8);//根据主角的攻击动作,获得其碰撞区域
for (int i = 0; i < engine.enemy.length; i++)
{
if (isLeft)
{
if (engine.enemy[i].x < x)//只考虑主角前方的敌人
{
if (Tools.hit(px, py, pw, ph, engine.enemy[i].x-(engine.enemy[i].w>>1), engine.enemy[i].y-engine.enemy[i].h, engine.enemy[i].w, engine.enemy[i].h))//发生碰撞的条件
{
engine.enemy[i].setStatus(Enemy.STATE_INJURE);
}
}
}
else
{
if (engine.enemy[i].x > x)
{
if (Tools.hit(px, py, pw, ph, engine.enemy[i].x, engine.enemy[i].y, engine.enemy[i].w, engine.enemy[i].h))
{
engine.enemy[i].setStatus(Enemy.STATE_INJURE);
}
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -