您的位置:首页 > 移动开发 > Android开发

libgdx游戏引擎开发笔记(十一)SuperJumper游戏例子的讲解(篇五)---- .游戏中的物体的创建

2013-08-04 12:11 633 查看
游戏中物体比较多,这里源码里用了两个类封装了游戏中物体的主要属性,方便游戏中物体的封装。

1.GameObject类:

package com.zhf.mylibgdx;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
/**
* 所有的游戏物体都会在一个平面内绘制(或者说在屏幕大小内绘制),那么所有的物体都应该包含一个位置(position) 和一个作用范围(bounds)
* @author ZHF
*
*/
public class GameObject {
public final Vector2 position;  //位置
public final Rectangle bounds;  //作用范围

/**postion在这里是指游戏物体的中心点,而bounds中的x ,y 坐标是指这个游戏原素在屏幕坐标系中的作用起点,也就是矩形的左下角顶点**/
public GameObject(float x, float y, float width, float height) {
this.position = new Vector2(x, y);
this.bounds = new Rectangle(x - width / 2, y - height / 2, width, height);
}
}
2.[b]DynamicGameObject类[/b]
package com.zhf.mylibgdx;
import com.badlogic.gdx.math.Vector2;
/**
* 会移动的游戏物体
* @author ZHF
*
*/
public class DynamicGameObject extends GameObject {
//包含了 x, y 轴方向相关的运动信息。
public final Vector2 velocity;  //速度
public final Vector2 accel;   //加速度
public DynamicGameObject (float x, float y, float width, float height) {
super(x, y, width, height);
velocity = new Vector2();
accel = new Vector2();
}
}


接下来就是让游戏中的物体来分别根据自己的情况去继承它们:

Bob ------> 主角
Castle -----> 城堡
Coin -----> 金币
Platform ------> 平台
Spring -------> 弹簧
Squirrel -------> 空中飞行的松鼠
这里我们先将这六个类写出来,待会实现一下跳板是如何显示出来,我们就大体知道了整个游戏的逻辑了。ok! 上代码!

1.Bob类:

package com.zhf.mylibgdx;
/**
* 主角
* @author ZHF
*
*/
public class Bob extends DynamicGameObject {
//主角状态
public static final int BOB_STATE_JUMP = 0;  //跳跃
public static final int BOB_STATE_FALL = 1;  //下落
public static final int BOB_STATE_HIT = 2;   //碰撞
//速度
public static final float BOB_JUMP_VELOCITY = 11; //跳跃的速度
public static final float BOB_MOVE_VELOCITY = 20;  //移动的速度
//宽和高
public static final float BOB_WIDTH = 0.8f;
public static final float BOB_HEIGHT = 0.8f;

int state;  //状态
float stateTime; //状态持时间
public Bob(float x, float y) {
super(x, y, BOB_WIDTH, BOB_HEIGHT);
//初始化状态
state = BOB_STATE_FALL;
stateTime = 0;
}

/**刷新**/
public void update (float deltaTime) {
//x,y轴速度的大小
velocity.add(World.gravity.x * deltaTime, World.gravity.y * deltaTime);
//主角当前移动的位置
position.add(velocity.x * deltaTime, velocity.y * deltaTime);
bounds.x = position.x - bounds.width / 2;
bounds.y = position.y - bounds.height / 2;
//跳跃状态
if (velocity.y > 0 && state != BOB_STATE_HIT) {
if (state != BOB_STATE_JUMP) {
state = BOB_STATE_JUMP;
stateTime = 0;
}
}
//下落状态
if (velocity.y < 0 && state != BOB_STATE_HIT) {
if (state != BOB_STATE_FALL) {
state = BOB_STATE_FALL;
stateTime = 0;
}
}
//边界限制
if (position.x < 0) position.x = World.WORLD_WIDTH;
if (position.x > World.WORLD_WIDTH) position.x = 0;
//状态持续时间
stateTime += deltaTime;
}
/**撞到松鼠**/
public void hitSquirrel () {
velocity.set(0, 0);
state = BOB_STATE_HIT;
stateTime = 0;
}
/**撞到跳板**/
public void hitPlatform () {
velocity.y = BOB_JUMP_VELOCITY;
state = BOB_STATE_JUMP;
stateTime = 0;
}
/**撞到弹簧**/
public void hitSpring () {
velocity.y = BOB_JUMP_VELOCITY * 1.5f;
state = BOB_STATE_JUMP;
stateTime = 0;
}
}


2.Castle类:

package com.zhf.mylibgdx;
/**
* 城堡
* @author ZHF
*
*/
public class Castle extends GameObject {
//宽和高
public static float CASTLE_WIDTH = 1.7f;
public static float CASTLE_HEIGHT = 1.7f;
public Castle(float x, float y) {
super(x, y, CASTLE_WIDTH, CASTLE_HEIGHT);
}
}


3.Coin类:

package com.zhf.mylibgdx;
/**
* 金币
* @author ZHF
*
*/
public class Coin extends GameObject {
// 宽和高
public static final float COIN_WIDTH = 0.5f;
public static final float COIN_HEIGHT = 0.8f;
// 金币的分值
public static final int COIN_SCORE = 10;
float stateTime; // 状态持续时间
public Coin(float x, float y) {
super(x, y, COIN_WIDTH, COIN_HEIGHT);
stateTime = 0;
}
/**刷新**/
public void update(float deltaTime) {
stateTime += deltaTime;
}
}


4.Platform类:

package com.zhf.mylibgdx;
/**
* 跳板
* @author ZHF
*
*/
public class Platform extends DynamicGameObject {
//宽和高
public static final float PLATFORM_WIDTH = 2;
public static final float PLATFORM_HEIGHT = 0.5f;
//跳板的类型
public static final int PLATFORM_TYPE_STATIC = 0;  //静止
public static final int PLATFORM_TYPE_MOVING = 1;  //运动
//跳板的状态
public static final int PLATFORM_STATE_NORMAL = 0; //正常
public static final int PLATFORM_STATE_PULVERIZING = 1; //破碎

public static final float PLATFORM_PULVERIZE_TIME = 0.2f * 4;  //破碎所需时间
public static final float PLATFORM_VELOCITY = 2;  //跳板移动速度

int type;  //类型 :静止、移动
int state;  //状态:正常、破碎
float stateTime;  //状态持续时间
public Platform (int type, float x, float y) {
super(x, y, PLATFORM_WIDTH, PLATFORM_HEIGHT);
this.type = type;
this.state = PLATFORM_STATE_NORMAL; //正常状态
this.stateTime = 0;
//若为移动类型,赋值移动速度
if (type == PLATFORM_TYPE_MOVING) {
velocity.x = PLATFORM_VELOCITY;
}
}

/**刷新**/
public void update (float deltaTime) {
//移动跳板
if (type == PLATFORM_TYPE_MOVING) {
//跳板移动位置
position.add(velocity.x * deltaTime, 0);
bounds.x = position.x - PLATFORM_WIDTH / 2;
bounds.y = position.y - PLATFORM_HEIGHT / 2;
//左边界限制
if (position.x < PLATFORM_WIDTH / 2) {
velocity.x = -velocity.x;
position.x = PLATFORM_WIDTH / 2;
}
//右边界限制
if (position.x > World.WORLD_WIDTH - PLATFORM_WIDTH / 2) {
velocity.x = -velocity.x;
position.x = World.WORLD_WIDTH - PLATFORM_WIDTH / 2;
}
}
//状态持续时间
stateTime += deltaTime;
}
/**破碎**/
public void pulverize () {
state = PLATFORM_STATE_PULVERIZING;
stateTime = 0;
velocity.x = 0;
}
}


5.Spring类:

package com.zhf.mylibgdx;
/**
* 弹簧
* @author ZHF
*
*/
public class Spring extends GameObject {
//宽和高
public static float SPRING_WIDTH = 0.3f;
public static float SPRING_HEIGHT = 0.3f;
public Spring(float x, float y) {
super(x, y, SPRING_WIDTH, SPRING_HEIGHT);
}
}


6.Squirrel类:

package com.zhf.mylibgdx;
/**
* 松鼠
* @author ZHF
*
*/
public class Squirrel extends DynamicGameObject {
//宽和高
public static final float SQUIRREL_WIDTH = 1;
public static final float SQUIRREL_HEIGHT = 0.6f;
//速度
public static final float SQUIRREL_VELOCITY = 3f;

float stateTime = 0;  //状态持续时间
public Squirrel (float x, float y) {
super(x, y, SQUIRREL_WIDTH, SQUIRREL_HEIGHT);
//为松鼠x轴方向赋值
velocity.set(SQUIRREL_VELOCITY, 0);
}

/**刷新**/
public void update (float deltaTime) {
//松鼠移动位置
position.add(velocity.x * deltaTime, velocity.y * deltaTime);
bounds.x = position.x - SQUIRREL_WIDTH / 2;
bounds.y = position.y - SQUIRREL_HEIGHT / 2;
//左边界限制
if (position.x < SQUIRREL_WIDTH / 2) {
position.x = SQUIRREL_WIDTH / 2;
velocity.x = SQUIRREL_VELOCITY;
}
//右边界限制
if (position.x > World.WORLD_WIDTH - SQUIRREL_WIDTH / 2) {
position.x = World.WORLD_WIDTH - SQUIRREL_WIDTH / 2;
velocity.x = -SQUIRREL_VELOCITY;
}
//状态持续时间
stateTime += deltaTime;
}
}


以上就是游戏中六个物体类的代码,都十分的相似,代码里都注释了,这里不再一一讲解,可能有些变量没有完全写出,大家还是以源码为主,接下来我们要干的工作就是如何在游戏界面里显示出跳板?

首先,在World类中:

package com.zhf.mylibgdx;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.badlogic.gdx.math.Vector2;
/**
* 统一管理世界中各个部分
* @author ZHF
*
*/
public class World {
/**世界监听器接口**/
public interface WorldListener {
//跳跃
public void jump ();
//高跳
public void highJump ();
//碰撞
public void hit ();
//收集金币
public void coin ();
}

//宽和高
public static final float WORLD_WIDTH = 10;
public static final float WORLD_HEIGHT = 15 * 20;
//状态
public static final int WORLD_STATE_RUNNING = 0;  //运行
public static final int WORLD_STATE_NEXT_LEVEL = 1;  //下一关
public static final int WORLD_STATE_GAME_OVER = 2;  //游戏结束
//世界监听器
public  WorldListener listener;

//重力
public static final Vector2 gravity = new Vector2(0, -12);
//随机数
public Random rand;
//游戏中物体
public final List<Platform> platforms;  //跳板

public World(WorldListener listener) {
this.listener = listener;
this.platforms = new ArrayList<Platform>();

rand = new Random();
generateLevel();
}

/**生成关卡中除了Bob外所有的物体**/
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);

y += (maxJumpHeight - 0.5f);
y -= rand.nextFloat() * (maxJumpHeight / 3);
}
}
/**刷新界面**/
public void update(float deltaTime, float accelX) {
updatePlatforms(deltaTime);
}
/**刷新跳板**/
private void updatePlatforms(float deltaTime) {
int len = platforms.size();
for (int i = 0; i < len; i++) {
Platform platform = platforms.get(i);
//取出集合中的跳板对象,调用其自身的刷新方法
platform.update(deltaTime);
//若状态为破碎状态,将该跳板对象移除出去
if (platform.state == Platform.PLATFORM_STATE_PULVERIZING && platform.stateTime > Platform.PLATFORM_PULVERIZE_TIME) {
platforms.remove(platform);
len = platforms.size();
}
}
}
}


分析:这里我们还是在上一讲的代码的基础上,增加了platform对象及其实例化,还有与其相关的刷新方法。最重要的是在World的构造方法中,初始化跳板集合,并且调用了 generateLevel()方法来生成关卡中除了Bob外所有的物体。
游戏中物体的创建主要是围绕Platform来生成的。在While循环内,通过不断增加y坐标的值,使用随机数rand 和 物体的内置属性来生成不同的游戏物体。比如,对于Playform 有移动和不移动两种,同时它内置的宽度为2(每单位为32个像素),高度为0.5,结合rand就能达到随机生成Playform的效果。

其次就是WorldRenderer类:


package com.zhf.mylibgdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
/**
* 用来把每个对象关联相应的图片资源,同时控制相机,实现动画。
* @author ZHF
*
*/
public class WorldRenderer {
//宽和高
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;
//OrthographicCamera 被定义成 宽度为10,高度为15,同样的也把相机对准中心点。
this.cam = new OrthographicCamera(FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
//它指定了和屏幕一样大小的 OrthographicCamera ,并把相机对准屏幕的中心。
this.cam.position.set(FRUSTUM_WIDTH / 2, FRUSTUM_HEIGHT / 2, 0);
this.batch = batch;
}

/**渲染**/
public void render () {
cam.update();
//它的作用都是通过把映射矩阵绑定给SpritBatch,告诉SpritBatch怎么去绘制图形
batch.setProjectionMatrix(cam.combined);
//渲染背景
renderBackground();
//渲染游戏中各种元素(Bob,跳板,松鼠,弹簧。。)下一讲中会具体讲到
renderObjects();
}

/**渲染游戏中各种物体(Bob,跳板,松鼠,弹簧,城堡,金币)**/
private void renderObjects() {
batch.enableBlending();
batch.begin();
//绘制跳板
renderPlatforms();

batch.end();
}
/**渲染背景**/
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();
}

/**渲染跳板**/
private void renderPlatforms () {
int len = world.platforms.size();
for (int i = 0; i < len; i++) {
Platform platform = world.platforms.get(i);
TextureRegion keyFrame = Assets.platform;
//          if (platform.state == Platform.PLATFORM_STATE_PULVERIZING) {
//              keyFrame = Assets.brakingPlatform.getKeyFrame(platform.stateTime, Animation.ANIMATION_NONLOOPING);
//          }
batch.draw(keyFrame, platform.position.x - 1, platform.position.y - 0.25f, 2, 0.5f);
}
}
}
分析:
1.在该类中,我们写了一个方法renderObjects()用于渲染游戏中各种物体(Bob,跳板,松鼠,弹簧,城堡,金币)
2.[b]渲染跳板renderPlatforms ()方法里我们取出集合中的跳板对象,对应加载资源,并将其绘制出来。[/b]

最后,就是在Asset类中加载跳板资源

声明:

//游戏中各种物体
public static TextureRegion platform;  //跳板
实例化:
//游戏中各个物体
platform = new TextureRegion(items, 64, 160, 64, 16);  //跳板

运行一下,效果图:(每次运行起来跳板的位置都是随机的)







目前游戏还是没有主人公哦,在下一讲中,我们会加上主人公,同时显示出其他游戏物体,当然还有最重要的游戏碰撞检测,以及场景的移动。

源码下载:http://down.51cto.com/data/896982
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐