- 浏览: 28691 次
- 性别:
- 来自: 北京
最新评论
-
max_eye:
archy123 写道max_eye 写道期待楼主继续更新,我 ...
libgdx学习笔记系列(九)了解物理引擎box2D -
archy123:
max_eye 写道期待楼主继续更新,我也是刚学习libgdx ...
libgdx学习笔记系列(九)了解物理引擎box2D -
max_eye:
期待楼主继续更新,我也是刚学习libgdx.觉得你谢的挺不错的 ...
libgdx学习笔记系列(九)了解物理引擎box2D
看下如何使用MVC中的控制层来控制演员的动作。
首先需要修改下演员类,演员类中我们没有定义演员的速度等相关信息。
也没定义如何改变它的位置等等信息。
修改如下:
重点说下update方法。
这是实时改变演员位置的代码。
这里涉及到二维向量的加运算,因为这里主要是x轴的运算,y轴为0,所以实际上就x坐标的相加。具体可参考上篇推荐的向量在游戏中的应用那篇博文。
velocity.scl(deltaTime)。我们看下Vector2 scl方法的源码
很简单的运算,当前的x,y的值乘以帧时间间隔。
假设x为2f,那么在0.016秒内(参考前几篇内容),它的值就是2f*0.016=0.032f,我们再乘以实际每单位屏幕像素数,就可以推算出它每刷新一次屏幕移动的距离。
0.032*80=2.56 也就是说,每刷新一次屏幕坐标x的值增加2.56像素。记得前几篇介绍帧率的概念吧。上次计算出每秒大概刷新62.5次,2.56*62.5=160,这是每秒移动的距离。
我们前面假设的是2f的速度。2f*80=160。两个值相等。
所以这段代码的意思就是把速度值跟屏幕刷新次数结合起来,实现平滑增加x,y的值。
这里Y值为0所以实际上是增加x的值。如果实现跳,飞等空中效果就需要改变Y的值了。
有兴趣的可以先试试。
接下来在control包下新建GirlControl类。
state()方法不停判断当前的输入状态,实时修改演员的,行动状态,朝向和位置信息。
向左移动使用负值不停减少x的值,当没有任何按键的时候,设置人物为站立状态,移动速度为0.
别的代码注释写的很清楚了,这里就不解释了。一定要有这么一个概念。游戏屏幕是个无限循环,我们改变状态也好,获取状态也好,要想实时获取,那么这个方法必须在这个循环中。
修改我们的MyGame方法
我们实现了InputProcessor,这个是监听输入事件的。
我们看下说明
/** An InputProcessor is used to receive input events from the keyboard and the touch screen (mouse on the desktop). For this it
* has to be registered with the {@link Input#setInputProcessor(InputProcessor)} method. It will be called each frame before the
* call to {@link ApplicationListener#render()}. Each method returns a boolean in case you want to use this with the
* {@link InputMultiplexer} to chain input processors.
*
* @author mzechner */
其中
has to be registered with the {@link Input#setInputProcessor(InputProcessor)} method
我们必须使用setInputProcessor注册下。
它的方法中包含一些keydown等的,这是实体按键和pc按键。暂时不用理会。我们看下它的实现类。
其实就9个,其中有个手势类,里边实现了一些复杂的手势操作的方法,例如,缩放,滑动等,这么我不使用手势类,暂时还用不上那么复杂的操作。
touchDown方法前两个就是当前点击的位置信息。pointer点击了几个点,比如说3个手指同时点击屏幕,它的值一般为0,1,2这三个值。button是跟键盘有关的。忽略它。
我们根据点击的位置信息来判断让演员往那边走。
运行下看看效果吧。
演员的控制其实就是这么简单。
下篇来实现演员的跳动飞行等动作,有兴趣的可以自己先试试怎么实现。
源码因为今天更新maven的项目依赖库卡住了。所以今天没有编译新的源文件。并且今天改动也不大。源码就不提供了。
首先需要修改下演员类,演员类中我们没有定义演员的速度等相关信息。
也没定义如何改变它的位置等等信息。
修改如下:
package com.me.mygdxgame.actor; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; public class GirlActor { //定义一个演员状态的枚举方法 //这里我们只定义两种状态,站立状态,跑动状态 public enum State { IDLE, RUNING } //演员的位置 private Vector2 position = new Vector2(); //这个演员的大小,因为纹理是方形或长方形的 private Rectangle bounds = new Rectangle(); //默认状态是跑动的 private State state = State.RUNING; private float stateTime = 0; //演员的朝向 private boolean facingRight = true; //演员的x,y移动速度 private float speed_x = 2f; private float speed_y = 0; //演员在二维空间中的x,y速度向量值 //这里是为了便于进行向量的加减乘除运算,所以定义个向量速度 public Vector2 velocity = new Vector2(); /** * 演员的构造器 * 我们初始化的时候需要指定演员的位置和大小 * * @param position 位置 * @param size 演员大小 */ public GirlActor(Vector2 position, Vector2 size) { this.position = position; //演员的大小 this.bounds.width = size.x; this.bounds.height = size.y; } /** * 改变当前演员状态的方法 * * @param deltaTime 帧间隔时间 */ public void update(float deltaTime) { stateTime += deltaTime; //根据时间和速度来运算当前的演员位置信息。 position.add(velocity.scl(deltaTime)); } //get set 方法,是不是很像我们的JavaBean public float getSpeed_x() { return speed_x; } public void setSpeed_x(float speed_x) { this.speed_x = speed_x; } public float getSpeed_y() { return speed_y; } public void setSpeed_y(float speed_y) { this.speed_y = speed_y; } public Vector2 getVelocity() { return velocity; } public void setVelocity(Vector2 velocity) { this.velocity = velocity; } public Vector2 getPosition() { return position; } public void setPosition(Vector2 position) { this.position = position; } public Rectangle getBounds() { return bounds; } public void setBounds(Rectangle bounds) { this.bounds = bounds; } public State getState() { return state; } public void setState(State state) { this.state = state; } public float getStateTime() { return stateTime; } public void setStateTime(float stateTime) { this.stateTime = stateTime; } public boolean isFacingRight() { return facingRight; } public void setFacingRight(boolean facingRight) { this.facingRight = facingRight; } }
重点说下update方法。
position.add(velocity.scl(deltaTime));
这是实时改变演员位置的代码。
这里涉及到二维向量的加运算,因为这里主要是x轴的运算,y轴为0,所以实际上就x坐标的相加。具体可参考上篇推荐的向量在游戏中的应用那篇博文。
velocity.scl(deltaTime)。我们看下Vector2 scl方法的源码
public Vector2 scl (float scalar) { x *= scalar; y *= scalar; return this; }
很简单的运算,当前的x,y的值乘以帧时间间隔。
假设x为2f,那么在0.016秒内(参考前几篇内容),它的值就是2f*0.016=0.032f,我们再乘以实际每单位屏幕像素数,就可以推算出它每刷新一次屏幕移动的距离。
0.032*80=2.56 也就是说,每刷新一次屏幕坐标x的值增加2.56像素。记得前几篇介绍帧率的概念吧。上次计算出每秒大概刷新62.5次,2.56*62.5=160,这是每秒移动的距离。
我们前面假设的是2f的速度。2f*80=160。两个值相等。
所以这段代码的意思就是把速度值跟屏幕刷新次数结合起来,实现平滑增加x,y的值。
这里Y值为0所以实际上是增加x的值。如果实现跳,飞等空中效果就需要改变Y的值了。
有兴趣的可以先试试。
接下来在control包下新建GirlControl类。
package com.me.mygdxgame.control; import com.me.mygdxgame.actor.GirlActor; import com.me.mygdxgame.actor.World; /** * control层,演员的控制 */ public class GirlControl { private World<GirlActor> world; private GirlActor girl; /** * 枚举类型的按键状态 */ public enum KEY { LEFTDOWN, LEFTUP, RIGHTDOWN, RIGHTUP, NON } /** * 构造器 * * @param world 游戏世界 */ public GirlControl(World<GirlActor> world) { this.world = world; girl = world.getActors("girl"); } /** * 默认状态为什么都没做 */ private KEY keyState = KEY.NON; public KEY getKeyState() { return keyState; } public void setKeyState(KEY keyState) { this.keyState = keyState; } /** * 不断执行的方法 * 在MyGame的render方法中调用来不断判断和更新演员状态 */ public void update() { state(); //边界检查,是否超出屏幕右边。世界的宽度-人物纹理的宽度 //这里就体现出我们定义世界网格的好处了。我根本不需要知道屏幕纹理的具体大小。 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; } } /** * 判断当前按下的按键状态 */ private void state() { switch (getKeyState()) { case LEFTDOWN: girl.setState(GirlActor.State.RUNING); girl.setFacingRight(false); girl.getVelocity().x = -girl.getSpeed_x(); break; case LEFTUP: break; case RIGHTDOWN: girl.setState(GirlActor.State.RUNING); girl.setFacingRight(true); girl.getVelocity().x = girl.getSpeed_x(); break; case RIGHTUP: break; case NON: girl.setState(GirlActor.State.IDLE); girl.getVelocity().x = 0; default: break; } } }
state()方法不停判断当前的输入状态,实时修改演员的,行动状态,朝向和位置信息。
向左移动使用负值不停减少x的值,当没有任何按键的时候,设置人物为站立状态,移动速度为0.
别的代码注释写的很清楚了,这里就不解释了。一定要有这么一个概念。游戏屏幕是个无限循环,我们改变状态也好,获取状态也好,要想实时获取,那么这个方法必须在这个循环中。
修改我们的MyGame方法
package com.me.mygdxgame; import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.math.Vector2; import com.me.mygdxgame.actor.GirlActor; import com.me.mygdxgame.actor.World; import com.me.mygdxgame.control.GirlControl; import com.me.mygdxgame.view.GirlView; public class MyGame implements ApplicationListener, InputProcessor { private World<GirlActor> world; private GirlView girlView; private GirlControl control; @Override public void create() { world = new World<GirlActor>(); GirlActor girlsActor = new GirlActor(new Vector2(0, 0), new Vector2(2, 2)); world.addActors("girl", girlsActor); girlView = new GirlView(world); control = new GirlControl(world); //游戏输入注册当前这个界面 Gdx.input.setInputProcessor(this); } @Override public void render() { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); Gdx.gl.glClearColor(0.57f, 0.41f, 0.55f, 1.0f); girlView.render(); control.update(); } @Override public void dispose() { girlView.dispose(); } @Override public void resize(int width, int height) { world.setPixelsXY(width, height); } @Override public void pause() { } @Override public void resume() { } @Override public boolean keyDown(int keycode) { return false; } @Override public boolean keyUp(int keycode) { return false; } @Override public boolean keyTyped(char character) { return false; } @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { //点击屏幕左半边就左移,右半边就右移 if (screenX < world.getWidth() / 2) { control.setKeyState(GirlControl.KEY.LEFTDOWN); } else { control.setKeyState(GirlControl.KEY.RIGHTDOWN); } return false; } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { control.setKeyState(GirlControl.KEY.NON); return false; } @Override public boolean touchDragged(int screenX, int screenY, int pointer) { return false; } @Override public boolean mouseMoved(int screenX, int screenY) { return false; } @Override public boolean scrolled(int amount) { return false; } }
我们实现了InputProcessor,这个是监听输入事件的。
我们看下说明
/** An InputProcessor is used to receive input events from the keyboard and the touch screen (mouse on the desktop). For this it
* has to be registered with the {@link Input#setInputProcessor(InputProcessor)} method. It will be called each frame before the
* call to {@link ApplicationListener#render()}. Each method returns a boolean in case you want to use this with the
* {@link InputMultiplexer} to chain input processors.
*
* @author mzechner */
其中
has to be registered with the {@link Input#setInputProcessor(InputProcessor)} method
我们必须使用setInputProcessor注册下。
Gdx.input.setInputProcessor(this);
它的方法中包含一些keydown等的,这是实体按键和pc按键。暂时不用理会。我们看下它的实现类。
其实就9个,其中有个手势类,里边实现了一些复杂的手势操作的方法,例如,缩放,滑动等,这么我不使用手势类,暂时还用不上那么复杂的操作。
touchDown方法前两个就是当前点击的位置信息。pointer点击了几个点,比如说3个手指同时点击屏幕,它的值一般为0,1,2这三个值。button是跟键盘有关的。忽略它。
我们根据点击的位置信息来判断让演员往那边走。
运行下看看效果吧。
演员的控制其实就是这么简单。
下篇来实现演员的跳动飞行等动作,有兴趣的可以自己先试试怎么实现。
源码因为今天更新maven的项目依赖库卡住了。所以今天没有编译新的源文件。并且今天改动也不大。源码就不提供了。
发表评论
-
libgdx学习笔记系列(十)libgdx1.0版的flappybird实现
2014-04-24 10:00 01.0变化较大,特别说明下。 1.0以后版本使用的是Grad ... -
libgdx学习笔记系列(九)了解物理引擎box2D
2014-04-10 12:45 5275注意:在1.0正式版中box2d被作为一个扩展独立了出来。因为 ... -
libgdx学习笔记系列(八)地图的生成、加载、绘制
2014-03-28 13:18 4443在开始地图之前,先了解下地图的概念。 大家都见过瓷砖吧,有 ... -
libgdx学习笔记系列(七)控制演员的动作(二)
2014-03-26 16:55 2783昨天在编译以前的代码的时候发现Stage类发生了变化,编译出错 ... -
libgdx学习笔记系列(四) Action动作及游戏开发的“MVC”
2014-03-19 16:16 1958这篇笔记少写点。 因为学习到现在我发现了一个重要的问题。 问题 ... -
libgdx学习笔记系列(五)游戏的MVC结构
2014-03-21 16:29 2970先看看游戏的mvc结构 ... -
libgdx学习笔记系列(三)会动的小人
2014-03-18 09:51 3266(重要提示:Stage类在3.19号被作者更新后初始化方法已经 ... -
libgdx学习笔记系列(二)hello libgdx 文字工具类的使用
2014-03-14 15:11 3538今天了解了下项目 ... -
libgdx学习笔记系列(一)初识libgdx
2014-03-13 16:50 2253注意:1.0正式版中,项 ...
相关推荐
演员之间可以通过父子关系进行组织,形成层次结构,这样可以方便地控制一组相关演员的属性。 **舞台与演员的关系** 舞台是演员表演的场所,演员在舞台上进行各种活动。舞台会负责渲染和更新所有在其上的演员。当一...
在“Libgdx专题系列第一篇 第一节”中,我们将着重介绍Libgdx的基础知识和环境搭建。首先,你需要下载并安装Java Development Kit (JDK) 和Eclipse或IntelliJ IDEA这样的Java集成开发环境(IDE)。接着,通过Libgdx的...
LibGDX是一个强大的开源Java框架,专为跨平台游戏开发设计。它允许开发者使用单一代码库创建游戏,这些游戏可以在Android、iOS、HTML5、Windows、Linux和Mac等多个平台上运行。这个“libgdx学习资料”压缩包包含了...
libGDX学习记录(一)源码,搭建一个桌面端和android端的libGDX框架,展示图片。 详细地址:https://blog.csdn.net/weixin_47450795/article/details/110003413
在"Libgdx专题系列 第一篇 第七节"中,我们将深入探讨Libgdx中的文本渲染和处理技术。 首先,让我们了解一下Libgdx中的文本渲染基础。Libgdx提供了`BitmapFont`类来处理游戏中的文本显示。`BitmapFont`是基于位图的...
通过学习和实践这个"Libgdx专题系列 UI篇",你将掌握如何利用TWL库和TableLayout在Libgdx中创建出高效、美观的用户界面,为你的游戏或应用增添更多互动性和吸引力。记得不断尝试和迭代,让UI设计适应你的项目需求,...
本篇将深入探讨Libgdx专题系列的第一篇第六节中的核心知识点,主要关注文本渲染。 在Libgdx中,文本渲染是一个关键功能,因为游戏和应用程序往往需要显示各种各样的文字信息。在第六节中,我们可能会学习到以下关键...
在游戏开发领域,LibGDX 是一个非常流行的开源框架,尤其适用于创建2D游戏。本专题将深入探讨如何使用LibGDX实现斜45°视角的地图系统,这种视角在许多经典游戏中常见,如《马里奥兄弟》和《塞尔达传说》等。斜45°...
在libGDX的Scene2D中,每个可视或交互性的元素都被视为一个演员。这可以是简单的文本框、按钮、图片,甚至是复杂的自定义组件。演员具备位置、大小、旋转、缩放等属性,并且可以包含子演员。演员有一个重要的特性,...
5. **Scene2D**:这是一个轻量级的2D场景图库,提供了舞台、演员、动作和动画等功能,让开发者能快速构建复杂的2D游戏界面。 6. **Box2D整合**:LibGDX集成了流行的物理引擎Box2D,使得开发者可以轻松实现物理模拟...
### libgdx学习文档知识点详解 #### 一、libgdx概述 libgdx是一款功能强大的跨平台游戏开发框架,支持2D与3D游戏的创建。它旨在为开发者提供一套全面的API,覆盖从图形渲染到物理模拟的广泛领域。libgdx的亮点在于...
本节是Libgdx专题系列的第一篇第一节,主要探讨的是在Libgdx中处理文本的技巧和方法。 在Libgdx中,处理文本通常涉及到两个核心组件:`BitmapFont`和`Label`。`BitmapFont`是用于渲染位图字体的类,它将字符集转换...
LibGDX是一个强大的开源游戏开发框架,用于创建跨平台的游戏。在这个“Mario的小例子”中,我们将探讨如何利用LibGDX中的Actor类来构建游戏场景,特别是如何模拟经典的马里奥游戏元素。Actor类是LibGDX舞台(Stage)...
通过这个“Libgdx专题系列 地图移动”的学习,你将掌握如何在Libgdx环境中构建可交互、可探索的游戏世界,并为玩家提供流畅的地图导航体验。无论是初学者还是经验丰富的开发者,都能从中获得宝贵的知识和技巧。记得...
在这一系列的教程中,你将逐步学习如何使用上述技术和工具,从创建基本的Game类开始,搭建游戏结构,到设计游戏逻辑,直至完成一个功能完备的游戏。每个文档(game1至game11)都将深入讲解一个具体主题,帮助你逐步...
libGDX学习记录(二)阶段源码 展示TexturePacker合成的图片,详细地址: https://blog.csdn.net/weixin_47450795/article/details/110037945
LibGDX是一个强大的开源Java框架,专为跨平台2D和3D游戏开发设计。这个框架允许开发者使用单一代码库创建游戏,可以在Android、iOS、Windows、Mac OS X和Linux等多个平台上运行。"libgdx游戏"这个标题暗示我们将深入...
libgx学习过程总结,记录本人所遇到的问题和心得
6. **场景管理**:Scene2D提供了一套易于使用的2D场景管理工具,包含演员(Actor)、舞台(Stage)和动作(Action),简化了游戏逻辑的组织。 7. **文件I/O**:方便的数据存储和读取机制,使得游戏数据的保存和加载...