注:请务必结合代码理解!
public final Bob bob;
public final List<Platform> platforms;
public final List<Spring> springs;
public final List<Squirrel> squirrels;
public final List<Coin> coins;
public Castle castle;
public World(WorldListener listener) {
this.bob = new Bob(5, 1);
this.platforms = new ArrayList<Platform>();
this.springs = new ArrayList<Spring>();
this.squirrels = new ArrayList<Squirrel>();
this.coins = new ArrayList<Coin>();
this.listener = listener;
rand = new Random();
generateLevel();
this.heightSoFar = 0;
this.score = 0;
this.state = WORLD_STATE_RUNNING;
}
其中,在World的构造方法中,初始化了Bob ,Castle和所有的List,并且调用了 generateLevel()方法来生成关卡中除了Bob外所有的物体, generateLevel()方法代码如下:
private void generateLevel() {
float y = Platform.PLATFORM_HEIGHT / 2;
float maxJumpHeight = Bob.BOB_JUMP_VELOCITY * Bob.BOB_JUMP_VELOCITY
/ (2 * -gravity.y);
while (y < WORLD_HEIGHT - WORLD_WIDTH / 2)
{
int type = rand.nextFloat() > 0.8f ? Platform.PLATFORM_TYPE_MOVING
: Platform.PLATFORM_TYPE_STATIC;
float x = rand.nextFloat()
* (WORLD_WIDTH - Platform.PLATFORM_WIDTH)
+ Platform.PLATFORM_WIDTH / 2;
Platform platform = new Platform(type, x, y);
platforms.add(platform);
if (rand.nextFloat() > 0.9f
&& type != Platform.PLATFORM_TYPE_MOVING) {
Spring spring = new Spring(platform.position.x,
platform.position.y + Platform.PLATFORM_HEIGHT / 2
+ Spring.SPRING_HEIGHT / 2);
springs.add(spring);
}
if (y > WORLD_HEIGHT / 3 && rand.nextFloat() > 0.8f) {
Squirrel squirrel = new Squirrel(platform.position.x
+ rand.nextFloat(), platform.position.y
+ Squirrel.SQUIRREL_HEIGHT + rand.nextFloat() * 2);
squirrels.add(squirrel);
}
if (rand.nextFloat() > 0.6f) {
Coin coin = new Coin(platform.position.x + rand.nextFloat(),
platform.position.y + Coin.COIN_HEIGHT
+ rand.nextFloat() * 3);
coins.add(coin);
}
y += (maxJumpHeight - 0.5f);
y -= rand.nextFloat() * (maxJumpHeight / 3);
}
castle = new Castle(WORLD_WIDTH / 2, y);
}
游戏中物体的创建主要是围绕Platform来生成的。在While循环内,通过不断增加y坐标的值,使用随机数rand 和 物体的内置属性来生成不同的游戏物体。比如,对于Playform 有移动和不移动两种,同时它内置的宽度为2(每单位为32个像素),高度为0.5,结合rand就能达到随机生成Playform的效果。
另外,对于每次Y坐标要增加多少,这里提供了一个参考的值为maxJumpHeight ,这个值表示每次主角Bob能跳过高,也就是在y轴上往上增加多少个单位。而它就是根据物理公式计算的,如下:
float maxJumpHeight = Bob.BOB_JUMP_VELOCITY * Bob.BOB_JUMP_VELOCITY / (2 * -gravity.y);
其中Bob.BOB_JUMP_VELOCITY就是跳跃的初速度 为 11;gravity为重力,在World成员变量中已经定义,如下:
public static final Vector2 gravity = new Vector2(0, -12);
因为我们现在是要模拟在有重力的情况下的跳跃过程,那么真实的跳跃过程就是,一开始跳跃时,会有一个初速度,也就是Bob.BOB_JUMP_VELOCITY,但是受到重力gravity的影响gravity,主角Bob的速度会慢慢的减至为0,然后开始往下掉下来。所以Y方向重力被设置为-12,那么根据物理公式,在知道初速度,末速度,还有重力三个条件下,就可以计算出位移,在这里就是主角Bob能跳多高了。
那么把这个值作为每次Y坐标增加的基准,再用随机数rand做一些处理,让每次生Y坐标的增加量都有所不同。
这样一个World(关卡)就生成了,接下来就可以交给WorldRender开始渲染。
之前已经说过,WorldRender 是把World里面的游戏物体拿出来,把他们渲染到屏幕上,那么显然它需要在构造的时候传入两个东西,一个SpriteBatch,另一个则是World。再者,WorldRnder需要定义不同于GameScreen的OrthographicCamera,然后将OrthographicCamera的投影矩阵绑定给SpriteBatch。最后就是根据World中物体的属性,把它们绘制到屏幕上,关键代码如下:
static final float FRUSTUM_WIDTH = 10;
static final float FRUSTUM_HEIGHT = 15;
World world;
OrthographicCamera cam;
SpriteBatch batch;
TextureRegion background;
public WorldRenderer (SpriteBatch batch, World world) {
this.world = world;
this.cam = new OrthographicCamera(FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
this.cam.position.set(FRUSTUM_WIDTH / 2, FRUSTUM_HEIGHT / 2, 0);
this.batch = batch;
}
public void render () {
if (world.bob.position.y > cam.position.y) cam.position.y = world.bob.position.y;
cam.update();
batch.setProjectionMatrix(cam.combined);
renderBackground();
renderObjects();
}
public void renderBackground () {
batch.disableBlending();
batch.begin();
batch.draw(Assets.backgroundRegion, cam.position.x - FRUSTUM_WIDTH / 2, cam.position.y - FRUSTUM_HEIGHT / 2, FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
batch.end();
}
public void renderObjects () {
batch.enableBlending();
batch.begin();
renderBob();
renderPlatforms();
renderItems();
renderSquirrels();
renderCastle();
batch.end();
}
其中,render()方法中第一行规定了,当bob的y坐标值,大于WorldRender中OrthographicCamera的position的y值时,就把bob的y值赋OrthographicCamera。
正式这句话,实现了游戏场景的移动。接着就是调用update 和 setProjectionMatrix把投影矩阵绑定给SpriteBatch告诉它要怎么绘图。
renderBackground ()方法是绘制背景图片。而renderObjects()就是真正根据World中游戏物体来绘制游戏画面,在这里作者把不同的物体分开来,让代码更为清晰。
欢迎转载!请注明原文链接,谢谢!
http://tonmly.blog.163.com/blog/static/17471285620116319463879/