游戏界面的滚动背景
上一篇我们讲了如何制作开始菜单,开始菜单比较简单,就只涉及了一个Entity,接下来几篇,我们要一步步实现游戏界面,对应的gameState为GAME_STATE_PLAYING。
这一篇,我们先讲滚动的背景是怎么做到的。
FlappyBird从游戏效果来说,算是一个横板的卷轴游戏。什么叫横板卷轴游戏呢?比如马里奥,就是随着人物的移动,背景会不断滚动变换,像是卷轴展开一样的效果。
横板卷轴游戏的背景有一副很长的图,事先绘制好之后,随着人物的移动,移动背景图,达到卷轴的效果。说到这里大家可能有疑问了。FlappyBird这游戏是没有终点也没有关卡一说的啊,那他的背景理论上是无限滚动的,永远没有尽头,那么要怎么实现这样的背景呢?其实,FlappyBird只有一副背景图,但是确能做到背景无限滚动,这背后是有一个技巧的。
假如我们拿两张背景图横着拼在一起,我们看看是什么情况:
发现了没,这个背景图设计的很巧妙,两段正好是可以“无缝链接”的。其实我们就可以这样一直连接下去,就能创造无限的背景图了。具体在程序里怎么做呢?请看下面这张图。
两幅背景图(其实都是同样的图)暂时叫BG1,BG2吧,两张图一起往右边运动,当BG2的左侧要离开屏幕的最右边时把BG2再移回BG1开始的位置,这样相当于又回到图中的情况,开始下一次循环。
如果还是不理解,可以看下代码:
public class Background {
private final Image IMG_BG = new ImageIcon("images/bg.png").getImage();
private int firstBgX=-IMG_BG.getWidth(null),secBgX=0;
private int rollingSpeed = 6;
public void draw(Graphics g) {
g.drawImage(IMG_BG, firstBgX, 0, null);
g.drawImage(IMG_BG, secBgX, 0, null);
}
public void logic() {
firstBgX+=rollingSpeed;
secBgX+=rollingSpeed;
if(firstBgX==0) {
secBgX = -IMG_BG.getWidth(null);
}
if(firstBgX==IMG_BG.getWidth(null)) {
firstBgX = -IMG_BG.getWidth(null);
}
}
}
可以看到firstBgX也就是前面背景的x坐标开始是在负的IMG_BG.WIDTH,rollingSpeed表示移动的速度,每一帧两幅背景的x坐标加上rollingSpeed,当firstBgX等于0,也就是第一张图完全进入了屏幕,第二张图完全离开了屏幕,此时,把第二张图的x坐标设置成负的IMG_BG.WIDTH,当第一张图的x坐标等于正的IMG_BG.WIDTH,也就是第一张图完全移出了屏幕,第二张图完全进入了屏幕,此时,再把第一张图的x坐标设置为负的IMG_BG.WIDTH,即又回到了开始状态,继续循环下去。这样我们就得到了无限滚动的背景。
看一下实现的效果:
小结
这一篇讲了滚轴游戏的背景滚动的特点,FlappyBird的背景图设计的很巧妙,使我们只需要一幅图就能做出无限滚动的背景图片。
下一篇,我们要开始讲我们的主角,小鸟的实现代码,对应的Entity为Bird。