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

游戏中物体比较多,这里源码里用了两个类封装了游戏中物体的主要属性,方便游戏中物体的封装。


1.GameObject类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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.DynamicGameObject类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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类:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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类中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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.渲染跳板renderPlatforms ()方法里我们取出集合中的跳板对象,对应加载资源,并将其绘制出来。


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

声明:

1
2
//游戏中各种物体
public static TextureRegion platform;   //跳板

实例化:

1
2
//游戏中各个物体
platform = new TextureRegion(items, 64 , 160 , 64 , 16 );   //跳板


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


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


源码下载:http://down.51cto.com/data/896982




你可能感兴趣的:(游戏,开发,position,坐标系,起点)