超级玛丽游戏开发(角色与障碍物的互动)
实现功能:马里奥可以跳跃到障碍物上面,不能穿过障碍物
1.继续修改马里奥的跳跃功能的实现
- 之前马里奥的跳跃:①通过一个jump方法里面分别实现向上、向下的移动过程,使用了Thread.sleep()和循环 ②通过jump方法里面改变y方向的速度,运用Thread.sleep()来控制跳跃过程的时间,设置了跳跃的最高点高度,通过跳跃标记是否不为0 +posy是否为0来判断是否落地。
- 但是到了与障碍物互动的时候,就显得很不方便,因为马里奥不能在跳跃过程中穿过障碍物,因此我们在Collide类里面不断进行检测,如果在跳跃过程中撞击到障碍物,那么我们需要改变它对应的x、y方向的速度,所以我们不能让跳跃的过程太“死板”。
- 改动:马里奥的y方向的运动和x方向一样,通过dx,dy来控制,当跳跃的时候只需要让y方向有一个向上的速度。在Mario的运动线程里面①高度的控制:我们控制跳跃的上升过程中y+dy只执行jumpTimes次 ②落地的控制:posy>=400, y方向速度大于0时,表示跳跃落地
- Mario的run方法:
/*
* 在线程里面移动角色
* */
public void run(){
while(!dead){
posx += dx;
if(posx<0)
posx=0;
if(posx>screenWidth-50)
posx = screenWidth-50;
if(jumpTimes == 0){//跳到了最高点/最低点
if(posy != 400)
dy = -dy;
jumpTimes = 25;
}
posy += dy;
if(posy>400 && dy !=0){//到达地面
posy = 400;
dy = 0;
overHead = 0;
jumpTimes = 25;
}
if(dy < 0) jumpTimes--;//处于跳跃上升过程中
switchN--;
if(switchN==0){
index = (index+1)%4;
switchN = 5;
}
try {
Thread.sleep(15);
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
2. 与障碍物的撞击判断
- 需要分别判断从左侧、右侧、上侧、下侧撞击障碍物
- 其中从上侧撞击的时候角色应该降落子啊障碍物上
- 当角色从障碍物上离开时,会掉到地面上
这里对之前表示障碍物集合的队列objects进行修改,因为绘图的时候是一个物体一个物体绘制的,但是最后可能多个物体组成障碍物,因此障碍物的边界应该在整个物体基础上来看的,再包装一个Background的内部类:
public class Construction{
public int l,r,up,down;
public Construction(int l,int r,int up ,int down){
this.l = l;
this.r = r;
this.up = up;
this.down = down;
}
}
Background里面多一个队列:
private List<Construction> allConstructions = new ArrayList<Construction>();//障碍物个体
private List<Object> allObjects = new ArrayList<Object>();//障碍物整体
/*
* 得到障碍物
* */
public List<Object> getObjects(){
return allObjects;
}
建立障碍物的时候:
//柱子
Object object1 = new Object(300,400,360,500,StaticValue.constructionsImgs.get(6));
Object object2 = new Object(290,350,330,360,StaticValue.constructionsImgs.get(8));
Object object3 = new Object(350,420,330,360,StaticValue.constructionsImgs.get(7));
allObjects.add(object1);
allObjects.add(object2);
allObjects.add(object3);
allConstructions.add(new Construction(290,420,330,500));
//砖块
Object object4 = new Object(600,650,300,350,StaticValue.constructionsImgs.get(0));
Object object5 = new Object(650,700,300,350,StaticValue.constructionsImgs.get(4));
Object object6 = new Object(700,750,300,350,StaticValue.constructionsImgs.get(0));
allObjects.add(object4);
allObjects.add(object5);
allObjects.add(object6);
allConstructions.add(new Construction(600,750,300,350));
然后就是检测的方法(Collide类里面):
/*
*
* 1检测与障碍物的互动*/
public void testCrash (Background.Construction construction){
int l = construction.l, r = construction.r, up = construction.up, down = construction.down;
if(mario.isMoving==1&&mario.posx<=l&&mario.posx+50>=l&&mario.posy+100>up&&mario.posy<down){//从左边撞击
mario.posx = l-50;
mario.dx = 0;
}
else if(mario.isMoving==2&&mario.posx<=r&&mario.posx+50>=r&&mario.posy+100>up&&mario.posy<down){//从右侧撞击
mario.posx = r;
mario.dx = 0;
}
else if(mario.overHead!=0&&mario.posy<=down&&mario.posy+100>=down&&mario.posx+50>l&&mario.posx<r){//从下侧撞击
System.out.println("Crash from downwards");
mario.posy = down+1;
mario.dy = - mario.dy;
}
else if(mario.posy+100>=up&&mario.posy<up&&mario.posx+50>l&&mario.posx<r){//跳到障碍物顶上
mario.dy = 0;
mario.posy = up - 100;
mario.overHead = 0;
onConstruction = true;//标记在障碍物上
System.out.println("on construction");
}
}
}