且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-09-17 14:27:15

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


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(00);
        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 / 20);
        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, 20.5f);
        }
    }
}

分析:

 1.在该类中,我们写了一个方法renderObjects()用于渲染游戏中各种物体(Bob,跳板,松鼠,弹簧,城堡,金币)

   2.渲染跳板renderPlatforms ()方法里我们取出集合中的跳板对象,对应加载资源,并将其绘制出来。


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

声明:

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

实例化:

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


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

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


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


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






     本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1263869,如需转载请自行联系原作者