这一篇主要讲讲怎么做小鸟的敌人——管道。
先给出管道的具体代码,然后我们慢慢分析。
public class Pipe {
private Image IMG_PIPE_UP = new ImageIcon("images/pipe1.png").getImage();
private Image IMG_PIPE_DOWN = new ImageIcon("images/pipe2.png").getImage();
public int pipeType=0;
private final int PIPE_TYPE_UP = 0;
private final int PIPE_TYPE_DOWN = 1;
public int x;
public int y;
public final int w = IMG_PIPE_UP.getWidth(null);
public final int h = IMG_PIPE_UP.getHeight(null);
public boolean isDead=false;
public boolean isThrough=false;
public Pipe(int type,int x,int y) {
this.x=x;
this.y = y;
this.pipeType = type;
}
public void draw(Graphics g) {
if(this.pipeType==PIPE_TYPE_UP)
g.drawImage(IMG_PIPE_UP, x,-y, null);
else if(this.pipeType==PIPE_TYPE_DOWN)
g.drawImage(IMG_PIPE_DOWN, x, IMG_PIPE_DOWN.getHeight(null)+y, null);
}
public void logic() {
this.x-=8;
if(this.x<-250) {
this.isDead = true;
}
}
}
首先,加载管道的图片。有两张,一张向下,一张向上。
定义了两个常量表示向上和向下:
private final int PIPE_TYPE_UP = 0;
private final int PIPE_TYPE_DOWN = 1;
public boolean isDead=false;
public boolean isThrough=false;
这两个变量分别表示管道是否离开屏幕,是否被小鸟通过。在我们主循环中,就能通过循环管道的Vector判断是否是isDead,true就可以从Vector移除,以免一直占用内存。我们可以通过isThrough来判断小鸟是否得分。
draw方法根据管道是向上还是向下,画不同的图片。logic就是管道不停往前移动,如果移出屏幕if(this.x<-250) 就标记isDead为true。
下面来看看主循环中的管道相关的代码:
pipeCount++;
//1500ms出现一个管道
if(pipeCount%30==0) {
int y = (int) (Math.random()*100);
if(this.isUpPiepe) {
pipes.add(new Pipe(0, gameW,y));
} else {
pipes.add(new Pipe(1, gameW,y));
}
isUpPiepe=!isUpPiepe;
}
//判断管道是否与小鸟相撞
for(int i=0;i<pipes.size();i++) {
Pipe pipe = pipes.get(i);
int x1 = pipe.x;
int y1=0;
int y = pipe.y;
if(pipe.pipeType==0) {
y1=-y;
} else if(pipe.pipeType==1) {
y1=pipe.h+y;
}
int x2 = x1 + pipe.w;
int y2 = y1 + pipe.h;
//如果相撞
if(bird.isCollision(x1, y1, x2, y2) || bird.isFall()) {
gameState=GAME_STATE_OVER;
//撞击音效
playHit();
}
//未相撞且之前未穿过该管道即得分
if(bird.x>pipe.x+pipe.w && pipe.isThrough==false) {
score++;
//得分音效
playPoint();
pipe.isThrough=true;
}
pipe.logic();
//删除离开屏幕范围的管道
if(pipe.isDead) {
pipes.remove(pipe);
}
}
每30帧产生一个管道,加入pipes,循环pipes,判断每一个管道是否和小鸟相撞,调用小鸟的isCollision方法。如果小鸟x坐标大于管道x坐标,且之前是未通过的,则标记该管道为通过并给玩家加一分。调用管道的logic移动管道。如果管道isDead为true,就移除管道。
总结:至此,我们的游戏界面已经基本完成了,接下来我们要讲游戏结束画面了。大功就要告成了^_^