`
archy123
  • 浏览: 28726 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

libgdx学习笔记系列(七)控制演员的动作(二)

阅读更多
昨天在编译以前的代码的时候发现Stage类发生了变化,编译出错。Stage 开始使用viewpoint来初始化。
viewpoint是什么?
现在用个简单的方法来理解。
举起双手,两手食指和拇指圈一个类似的矩形,然后我们通过手指的这个矩形看我们的电脑屏幕。看到一小块地方是吗。
眼睛-->手指组成的矩形-->屏幕
眼睛是一个点,手指组成的矩形稍微大点,屏幕最大,这是不是一个类似金字塔样的锥形视角。
我们把手指组成的这个小矩形称为viewpoint,实际上屏幕也是个viewpoint。
通过手指的矩形看到的图像实际大小肯定远大于手指组成的矩形的大小。距离越远看到的越广,物体也越小。距离越近看到的越少,物体也就越大。我们把手指组成的矩阵看到的这部分投影到手机屏幕上,这就是手机屏幕显示的内容了。
然后介绍下正交相机,它就是我们上面说的那种情况的一种特殊情况,眼睛的视线不是随着距离增加不断变大的一个锥形视野,而是平行的。
可以想象一下我们的太阳,无限远。它发出的光我们近似认为是平行的。也就是说。距离再远视野也不会变大,物体也不会变小。所以正交相机一般用在二维游戏中。
想想我前面做的那些工作,把屏幕划分成10*6的方格,然后计算每个方格的像素大小。我突然发现,使用正交相机也是可以实现的
我们直接把10*6的正交相机的viewpoint投射到屏幕上不就是可以了。还省的计算了。
修改前面的GirlView代码:
 public GirlView(World<GirlActor> world) {

        assetManager = new AssetManager();
        assetManager.load("data/image/girlRun.atlas", TextureAtlas.class);
        this.world = world;
        girlsActor = world.getActors("girl");
        spriteBatch = new SpriteBatch();
        currentFrame = new TextureRegion();
        girlRunFrameLeft = new TextureRegion[16];
        girlRunFrameRight = new TextureRegion[16];
        this.camera = new OrthographicCamera(world.getWorldWidth(), world.getWorldHeight());
        this.camera.position.set(world.getWorldWidth() / 2, world.getWorldHeight() / 2, 0);
        this.camera.update();
        isload = false;


    }

很简单,定义一个正交相机,然后初始化。投影到屏幕的矩阵。
设置为10*6大小,位置在中间。最后那个0其实是三维中z轴。咱是二维的。
然后在spriteBatch begin之前插入
 spriteBatch.setProjectionMatrix(camera.combined);

Ok,搞定。渲染方法也不用根据像素进行相乘计算了。好happy。
 spriteBatch.draw(currentFrame
                , girlsActor.getPosition().x
                , girlsActor.getPosition().y
                , girlsActor.getBounds().getWidth()
                , girlsActor.getBounds().getHeight());

其实这只是个简单的相机的应用,例如天天酷跑的背景的移动,人物的放大缩小,都可以使用相机实现。具体可参考官方API和这篇介绍相机的文章。还不理解的可以去看看。
http://blog.sina.com.cn/s/blog_940dd50a0101cpnb.html

在正式开始之前先复习下中学物理知识,真是苦逼,都忘光了。我发现除了基本的加减乘除,和一次元运算,别的基本都还给老师了。物理数学完全没印象了。这对游戏开发来说无疑是个大坑啊。和我一样的同学来以前复习中学知识。这都是为了模拟出比较真实的游戏感觉。

游戏中的匀加速运动:
初速度不为0的情况:Vt=Vo+a*t (Vt为末速度,Vo为初速度,*为乘号,a为加速度)
初速度为0:Vt=a*t
再看看游戏中的跳跃动作。起跳的时候我们可以给它一个初速度Vo,受重力影响,达到最高点后开始回落。这里我们只需要第一个公式就可以了,具体后边要用到的物理知识和向量几何知识只能边学边写了。

先修改GirlActor类。有两个地方需要修改。我们要增加一个加速度的属性。
还要修改下update方法
 //演员加速度向量
    private Vector2 acceleration = new Vector2();

修改update
 public void update(float deltaTime) {
        stateTime += deltaTime;
        //根据时间和速度来运算当前的演员位置信息。
        //这里进行一次拷贝操作,不改变原有的velocity值
        //因为在匀加速运动中,我们需要它作为初始速度值进行计算
        position.add(velocity.cpy().scl(deltaTime));
    }

多了个cpy,其实就是返回一个新的对象,不对原来对象进行修改。
原来我么直接使用velocity.scl(deltatime)
这会改变velocity的值。上面的公式中,我们每刷新一次屏幕,就要获取现在的速度做为初始速度Vo计算下次的Vt,下次的Vt作为下下次的Vo,所以为了不修改这个变量的值,使用cpy方法new个新的。

上篇我们使用枚举类型定义按键状态,后来我发现这么做不怎么合适。
因为普遍我们的输入不是单点输入的,可能会同时按下几个按键,所以我们略微变通下,让控制可以支持多按键。
修改GirlControl
package com.me.mygdxgame.control;

import com.badlogic.gdx.Gdx;
import com.me.mygdxgame.actor.GirlActor;
import com.me.mygdxgame.actor.World;

import java.util.HashMap;
import java.util.Map;

import static com.me.mygdxgame.actor.World.GRAVITY;

/**
 * control层,演员的控制
 */
public class GirlControl {
    private World<GirlActor> world;
    private GirlActor girl;


    /**
     * 枚举类型的按键
     */
    public enum KEY {
        LEFT, RIGTH, JUMP
    }

    /**
     * 定义个map来存放按键状态。这样就可以支持多按键了。
     * 并且每个按键的状态只能存在一种,这样比较符合实际需要
     */
    private static Map<KEY, Boolean> keys = new HashMap<>();

    static {
        keys.put(KEY.LEFT, false);
        keys.put(KEY.RIGTH, false);
        keys.put(KEY.JUMP, false);
    }

    //定义一组改变按键状态的方法
    public void leftDown() {
        keys.put(KEY.LEFT, true);
    }

    public void leftUp() {
        keys.put(KEY.LEFT, false);
    }

    public void rightDown() {
        keys.put(KEY.RIGTH, true);
    }

    public void rigthUp() {
        keys.put(KEY.RIGTH, false);
    }

    public void jumpDown() {
        keys.put(KEY.JUMP, true);
    }

    public void jumpUp() {
        keys.put(KEY.JUMP, false);
    }

    /**
     * 构造器
     *
     * @param world 游戏世界
     */
    public GirlControl(World<GirlActor> world) {
        this.world = world;
        girl = world.getActors("girl");
        //设置演员受到的世界中的重力加速度
        girl.getAcceleration().y = GRAVITY;
    }


    /**
     * 不断执行的方法
     * 在MyGame的render方法中调用来不断判断和更新演员状态
     */
    public void update() {

        state();
        if (girl.getState().equals(GirlActor.State.JUMPING)) {
            girl.getVelocity().add(girl.getAcceleration().cpy().scl(Gdx.graphics.getDeltaTime()));
        }


        //边界检查,是否超出屏幕右边。世界的宽度-人物纹理的宽度
        //这里就体现出我们定义世界网格的好处了。我根本不需要知道屏幕纹理的具体大小。
        if (girl.getPosition().x > world.getWorldWidth() - girl.getBounds().getWidth()) {
            girl.getPosition().x = world.getWorldWidth() - girl.getBounds().getWidth();

        }
        //左边界判断,这个更简单些可以直接判断x是否小于0,也就是是否移动到原点的左边
        if (girl.getPosition().x < girl.getBounds().x) {
            girl.getPosition().x = 0;
        }
        if (girl.getPosition().y < 0) {
            girl.getPosition().y = 0;
            if (girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.getVelocity().y = 0;
                girl.setState(GirlActor.State.IDLE);
            }
        }

        if (girl.getPosition().y > world.getWorldHeight() - girl.getBounds().getHeight()) {
            girl.getPosition().y = world.getWorldHeight() - girl.getBounds().getHeight();

        }

    }

    /**
     * 判断当前按下的按键状态
     * 跳跃和左右方向是可以同时按下的
     */
    private void state() {
        if (keys.get(KEY.JUMP)) {
            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.setState(GirlActor.State.JUMPING);
                girl.getVelocity().y = girl.getSpeed_y();

            }

        }
        if (keys.get(KEY.LEFT)) {

            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.setState(GirlActor.State.RUNING);
                girl.setFacingRight(false);
                girl.getVelocity().x = -girl.getSpeed_x();
            } else {
                girl.setFacingRight(false);
                girl.getVelocity().x = -girl.getSpeed_x();
            }
        } else if (keys.get(KEY.RIGTH)) {
            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.setState(GirlActor.State.RUNING);
                girl.setFacingRight(true);
                girl.getVelocity().x = girl.getSpeed_x();

            } else {
                girl.setFacingRight(true);
                girl.getVelocity().x = girl.getSpeed_x();
            }
        } else {
            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.setState(GirlActor.State.IDLE);
                girl.getVelocity().x = 0;
            }
        }

    }
}

我在world中定义了一个静态的重力变量GRAVITY,设置为-18。
这样在上升中girlActor的初始速度 private float speed_y = 10f;会不断减少,然后变成负值,直到落回地面。然后我们判断演员的位置的Y的值是否小于0来判断是否落地。并改变演员状态为站立状态。
重点代码的含义。
girl.getVelocity().add(girl.getAcceleration().cpy().scl(Gdx.graphics.getDeltaTime()));

这里我们为了理解,我把这段代码拆分开
//设置演员受到的世界中的重力加速度,下面那段代码会改变y的值,所以每次必须重置为重力的值
            girl.getAcceleration().y = GRAVITY;
            //求出每刷新一次的加速度,也就是每帧的速度相当于a*t
            girl.getAcceleration().scl(Gdx.graphics.getDeltaTime());

            //把这个速度和人物的初始速度相加,也就是当前的末速度Vt=Vo+a*t
            //这个末速度会在下次屏幕刷新时当作初始速度进行计算,所以需要修改演员的update方法
            girl.getVelocity().add(girl.getAcceleration().x, girl.getAcceleration().y);

这样就好理解了。我们这里也使用了cpy,所以acceleration的值不会因为运算发生变化,那么我们每次也不用重新赋值给它。这和演员类中的update方法中的修改是一样的道理。

处理下mygame的按键的操作。
 @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {

        //点击屏幕左半边就左移,右半边就右移
        if (screenX < world.getWidth() / 2 && screenY > world.getHeight() / 2) {
            control.leftDown();
            return false;
        }
        if (screenX > world.getWidth() / 2 && screenY > world.getHeight() / 2) {
            control.rightDown();
            return false;
        }
        if (screenY < world.getHeight() / 2) {
            control.jumpDown();
            return false;
        }

        return false;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        if (screenX < world.getWidth() / 2 && screenY > world.getHeight() / 2) {
            control.leftUp();
            return false;
        }
        if (screenX > world.getWidth() / 2 && screenY > world.getHeight() / 2) {
            control.rigthUp();
            return false;
        }
        if (screenY < world.getHeight() / 2) {
            control.jumpUp();
            return false;
        }
        return false;
    }

点击屏幕上半部分就是跳起操作。
需要注意的就一点。screenX,screenY是以屏幕左上角为原点的,这和android的坐标系相同。
源码
/** Called when the screen was touched or a mouse button was pressed. The button parameter will be {@link Buttons#LEFT} on
	 * Android and iOS.
	 * @param screenX The x coordinate, origin is in the upper left corner
	 * @param screenY The y coordinate, origin is in the upper left corner
	 * @param pointer the pointer for the event.
	 * @param button the button
	 * @return whether the input was processed */
	public boolean touchDown (int screenX, int screenY, int pointer, int button);

指明左上角开始的。
接下来实现下演员的飞行,其实这里不能算飞行,相当于扔东西的感觉,把演员抛出去。抛物线运动,实现非常简单。
前几篇有提到使用屏幕的手势操作,因为当时用不到所以现在我们实现下手势操作。
修改Mygame实现GestureDetector.GestureListener
public class MyGame implements ApplicationListener, InputProcessor, GestureDetector.GestureListener {

修改下输入监听的注册
 @Override
    public void create() {
        world = new World<>();
        GirlActor girlsActor = new GirlActor(new Vector2(0, 0), new Vector2(2, 2));
        world.addActors("girl", girlsActor);
        girlView = new GirlView(world);
        control = new GirlControl(world);
        //游戏输入进程注册当前界面
        InputMultiplexer multiplexer = new InputMultiplexer();
        multiplexer.addProcessor(this);
        multiplexer.addProcessor(new GestureDetector(this));
        Gdx.input.setInputProcessor(multiplexer);

    }

这里使用到了InputMultiplexer,很好理解,可以监听多个进程的输入事件。
因为 GestureDetector 没有touchUp这些操作,所以我们保留InputProcessor
并且同时监听这两个输入进程。

接下来实现GestureDetector.GestureListener的方法,我们现在只实现它的fling方法
@Override
    public boolean fling(float velocityX, float velocityY, int button) {
        //反转下Y坐标以左下角开始
        Vector2 vector2_fly = new Vector2(velocityX / world.getPixelsX()
                , (world.getHeight() - velocityY) / world.getPixelsY());

        control.flyDown(vector2_fly);
        return false;
    }

顾名思义:滑动操作,它实际上返回的是一个速度向量,也就是我们滑动的速度和方向的这样一个向量。想一想,把它和演员的位置信息的向量进行加运算就可以了。
修改下控制类
package com.me.mygdxgame.control;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Vector2;
import com.me.mygdxgame.actor.GirlActor;
import com.me.mygdxgame.actor.World;

import java.util.HashMap;
import java.util.Map;

import static com.me.mygdxgame.actor.World.GRAVITY;

/**
 * control层,演员的控制
 */
public class GirlControl {
    private World<GirlActor> world;
    private GirlActor girl;
    private Vector2 vector2_fly;

    /**
     * 枚举类型的按键
     */
    public enum KEY {
        LEFT, RIGTH, JUMP, FLY
    }

    /**
     * 定义个map来存放按键状态。这样就可以支持多按键了。
     * 并且每个按键的状态只能存在一种,这样比较符合实际需要
     */
    private static Map<KEY, Boolean> keys = new HashMap<>();

    static {
        keys.put(KEY.LEFT, false);
        keys.put(KEY.RIGTH, false);
        keys.put(KEY.JUMP, false);
        keys.put(KEY.FLY, false);
    }

    //定义一组改变按键状态的方法
    public void leftDown() {
        keys.put(KEY.LEFT, true);
    }

    public void leftUp() {
        keys.put(KEY.LEFT, false);
    }

    public void rightDown() {
        keys.put(KEY.RIGTH, true);
    }

    public void rigthUp() {
        keys.put(KEY.RIGTH, false);
    }

    public void jumpDown() {
        keys.put(KEY.JUMP, true);
    }

    public void jumpUp() {
        keys.put(KEY.JUMP, false);
    }

    public void flyDown(Vector2 vector2_fly) {
        this.vector2_fly = vector2_fly;
        keys.put(KEY.FLY, true);
    }

    public void flyUp() {

        keys.put(KEY.FLY, false);
    }

    /**
     * 构造器
     *
     * @param world 游戏世界
     */
    public GirlControl(World<GirlActor> world) {
        this.world = world;
        girl = world.getActors("girl");
        //设置演员受到的世界中的重力加速度
        girl.getAcceleration().y = GRAVITY;
    }


    /**
     * 不断执行的方法
     * 在MyGame的render方法中调用来不断判断和更新演员状态
     */
    public void update() {

        state();
        if (girl.getState().equals(GirlActor.State.JUMPING)) {

            girl.getVelocity().add(girl.getAcceleration().cpy().scl(Gdx.graphics.getDeltaTime()));
        }


        //边界检查,是否超出屏幕右边。世界的宽度-人物纹理的宽度
        //这里就体现出我们定义世界网格的好处了。我根本不需要知道屏幕纹理的具体大小。
        if (girl.getPosition().x > world.getWorldWidth() - girl.getBounds().getWidth()) {
            girl.getPosition().x = world.getWorldWidth() - girl.getBounds().getWidth();

        }
        //左边界判断,这个更简单些可以直接判断x是否小于0,也就是是否移动到原点的左边
        if (girl.getPosition().x < girl.getBounds().x) {
            girl.getPosition().x = 0;
        }
        if (girl.getPosition().y < 0) {
            girl.getPosition().y = 0;
            if (girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.getVelocity().y = 0;
                girl.setState(GirlActor.State.IDLE);
            }
        }

        if (girl.getPosition().y > world.getWorldHeight() - girl.getBounds().getHeight()) {
            girl.getPosition().y = world.getWorldHeight() - girl.getBounds().getHeight();

        }

    }

    /**
     * 判断当前按下的按键状态
     * 跳跃和左右方向是可以同时按下的
     */
    private void state() {
        if (keys.get(KEY.JUMP)) {
            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.setState(GirlActor.State.JUMPING);
                girl.getVelocity().y = girl.getSpeed_y();

            }

        }
        if (keys.get(KEY.FLY)) {
            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.getVelocity().add(vector2_fly);
                girl.setState(GirlActor.State.JUMPING);
                //直接释放按钮
                flyUp();
            }
        }
        if (keys.get(KEY.LEFT)) {

            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.setState(GirlActor.State.RUNING);
                girl.setFacingRight(false);
                girl.getVelocity().x = -girl.getSpeed_x();
            } else {
                girl.setFacingRight(false);
                girl.getVelocity().x = -girl.getSpeed_x();
            }
        } else if (keys.get(KEY.RIGTH)) {
            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.setState(GirlActor.State.RUNING);
                girl.setFacingRight(true);
                girl.getVelocity().x = girl.getSpeed_x();

            } else {
                girl.setFacingRight(true);
                girl.getVelocity().x = girl.getSpeed_x();
            }
        } else {
            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.setState(GirlActor.State.IDLE);
                girl.getVelocity().x = 0;
            }
        }

    }
}

增加了滑动的按键状态。
 if (keys.get(KEY.FLY)) {
            if (!girl.getState().equals(GirlActor.State.JUMPING)) {
                girl.getVelocity().add(vector2_fly);
                girl.setState(GirlActor.State.JUMPING);
                //直接释放按钮
                flyUp();
            }
        }


这里为了方便简单,直接设置为跳起状态,让它受跳动作重力影响。当然可以自己定义一个飞行的状态。
好了,轻轻滑动下屏幕,演员被扔飞了。别滑动太大,因为我们判断按键状态是把屏幕分成了左右和上下几部分,小范围的滑动就可以了。如果从左边滑到右边演员状态会出现异常。
源码地址:http://pan.baidu.com/s/1mgM9QdU
分享到:
评论

相关推荐

    libgdx中的舞台与演员

    在 libGDX 中,“舞台”和“演员”是两个核心概念,它们是游戏场景管理和对象渲染的基础。下面将详细介绍这两个概念及其相关知识点。 **舞台(Stage)** 舞台在 libGDX 中扮演着游戏场景的角色,它负责组织和管理...

    libgdx学习资料

    这个“libgdx学习资料”压缩包包含了丰富的资源,帮助你深入理解和掌握LibGDX的各个方面。 1. **基础知识**: - LibGDX是基于OpenGL的,它提供了对底层图形处理的高级抽象,简化了游戏渲染。 - 它的核心组件包括...

    Libgdx专题系列 第一篇 第七节

    在"Libgdx专题系列 第一篇 第七节"中,我们将深入探讨Libgdx中的文本渲染和处理技术。 首先,让我们了解一下Libgdx中的文本渲染基础。Libgdx提供了`BitmapFont`类来处理游戏中的文本显示。`BitmapFont`是基于位图的...

    libGDX学习记录(二)阶段源码

    libGDX学习记录(二)阶段源码 展示TexturePacker合成的图片,详细地址: https://blog.csdn.net/weixin_47450795/article/details/110037945

    Libgdx专题系列 UI篇

    通过学习和实践这个"Libgdx专题系列 UI篇",你将掌握如何利用TWL库和TableLayout在Libgdx中创建出高效、美观的用户界面,为你的游戏或应用增添更多互动性和吸引力。记得不断尝试和迭代,让UI设计适应你的项目需求,...

    libGDX学习记录(一)源码

    libGDX学习记录(一)源码,搭建一个桌面端和android端的libGDX框架,展示图片。 详细地址:https://blog.csdn.net/weixin_47450795/article/details/110003413

    Libgdx专题系列 斜45°地图

    通过深入学习和实践,开发者可以利用LibGDX创造出具有丰富视觉效果和互动性的2D游戏世界。提供的文件“LibgdxText_3”可能是这个专题系列的源代码或文档,可以帮助进一步理解和实现斜45°地图的细节。

    Libgdx专题系列第一篇 第一节

    本专题系列将深入探讨Libgdx的使用方法,帮助你掌握这个工具并开始你的游戏开发之旅。 在“Libgdx专题系列第一篇 第一节”中,我们将着重介绍Libgdx的基础知识和环境搭建。首先,你需要下载并安装Java Development ...

    Libgdx开发丛书之 Learning LibGDX Game Development, 2nd Edition

    5. **Scene2D**:这是一个轻量级的2D场景图库,提供了舞台、演员、动作和动画等功能,让开发者能快速构建复杂的2D游戏界面。 6. **Box2D整合**:LibGDX集成了流行的物理引擎Box2D,使得开发者可以轻松实现物理模拟...

    libgdx之演员与演出

    在libGDX中,“演员(Actor)与演出(Stage)”是其Scene2D库的核心概念,用于实现2D用户界面和游戏场景的构建。让我们深入了解这两个关键概念及其应用。 首先,我们来谈谈“演员(Actor)”。在libGDX的Scene2D中...

    libgdx学习文档

    ### libgdx学习文档知识点详解 #### 一、libgdx概述 libgdx是一款功能强大的跨平台游戏开发框架,支持2D与3D游戏的创建。它旨在为开发者提供一套全面的API,覆盖从图形渲染到物理模拟的广泛领域。libgdx的亮点在于...

    libgdx 演员类的使用 mario的小例子

    LibGDX是一个强大的开源游戏开发框架,用于创建跨平台的游戏。在这个“Mario的小例子”中,...演员类的灵活性和易用性使得在LibGDX中实现这样的游戏变得相对简单,同时也提供了足够的扩展性来支持更复杂的游戏设计。

    libgdx学习总结

    libgx学习过程总结,记录本人所遇到的问题和心得

    libgdx游戏

    **LibGDX游戏开发详解** LibGDX是一个强大的开源Java框架,专为跨平台2D和3D游戏开发设计。这个框架允许开发者使用单一代码库创建游戏,可以在Android、iOS、Windows、Mac OS X和Linux等多个平台上运行。"libgdx...

    Libgdx专题系列 地图移动

    通过这个“Libgdx专题系列 地图移动”的学习,你将掌握如何在Libgdx环境中构建可交互、可探索的游戏世界,并为玩家提供流畅的地图导航体验。无论是初学者还是经验丰富的开发者,都能从中获得宝贵的知识和技巧。记得...

    libgdx_wiki学习文档

    libGdx是一个跨平台的2D/3D的游戏开发框架,它由Java/C/C++语言编写而成。libgdx兼容Windows、Linux、Max OS X、Java Applet、Javascript/WebGL与Android(1.5版本+)平台。该文档为libgdx在wiki上的官方学习文档。

    libGDX 1.10.0 开发包

    LibGDX 是一个开源的游戏开发框架,主要用于构建跨平台的2D和3D游戏。它为开发者提供了丰富的功能,使得游戏开发变得更加高效和便捷。在提供的"libGDX 1.10.0 开发包"中,包含了以下几个关键组件: 1. **gdx-1.10.0...

    LibGDX Game Development Essentials

    综上所述,这本“LibGDX Game Development Essentials”是想要学习LibGDX框架并制作游戏的读者的宝贵资料。通过阅读本书,读者将能够了解LibGDX游戏开发的核心概念和实践技能,从而具备开发基本游戏项目的能力。

    libGDX学习记录(二)完整源码 水果落地

    **libGDX学习记录(二)完整源码 水果落地** libGDX是一个开源的游戏开发框架,专为跨平台游戏设计,支持Windows、Linux、Mac OS X、Android以及HTML5。它提供了丰富的功能,包括图形渲染、音频处理、输入管理、...

Global site tag (gtag.js) - Google Analytics