分类: libGDX

  • Ashley使用实例

    上一篇文章提到了Ashley,但是没给出具体的例子,加之wiki资料不全,可能使用上有些困难。

    superjumper是Libgdx的一个demo,siondream使用Ashley改造了整个项目,特别适合学习入门。

    地址是:https://github.com/siondream/ashley-superjumper

    组件

    components是entity system的主要构成,这里就成为组件吧。

    组件只包含具体的值,比如宽度,高度,状态等等。

    比如我们的主角Bob

    publicclass BobComponent extends Component {
    publicstaticfinalint STATE_JUMP =0;
    publicstaticfinalint STATE_FALL =1;
    publicstaticfinalint STATE_HIT =2;
    publicstaticfinalfloat JUMP_VELOCITY =11;
    publicstaticfinalfloat MOVE_VELOCITY =20;
    publicstaticfinalfloat WIDTH =0.8f;
    publicstaticfinalfloat HEIGHT =0.8f;
    
    publicfloat heightSoFar =0.0f;
    }

    而对于金币Coin…

  • libGDX的实体框架Ashley

    游戏开发之中有时候会使用实体框架,比如Artemis。

    在游戏开发中使用实体框架可以极大的提升项目层次和可测试性。

    比如利用Artemis,你的游戏代码可能是

    publicclass MyGame {
    
    publicvoidMyGame() {
    world =new World();
    
    world.setSystem(new MovementSystem());
    world.setSystem(new RotationSystem());
    world.setSystem(new RenderingSystem());
    
    world.initialize();
    
    while(true) {
    world.setDelta(MyGameTimer.getDelta());
    world.process();
    }
    }
    }

    Ashley

    Ashley并没有提供特别的功能,它是一个很简单的实体框架。

    它属于Libgdx大家族,但它并不是选用的,你可以继续使用Ash或者Artemis。

    使用的时候在你的gradle配置中加上

    dependencies {
    compile"com.badlogicgames.ashley:ashley:1.0.1"
    }

    就行了。

    具体的使用方法稍后Wiki也会放出的。

    最核心的类是EntitySystem。

    参考资料

    实体系统的好处
    API

  • libGDX中的手势识别

    看到群里面很多人在自己做手势识别的东西,其实Libgdx提供了一个GestureDetector来专门处理这个问题。

    常用的情况有以下几种:

    • touchDown 用户触碰屏幕
    • longPress 用户长按屏幕
    • tap 快速触碰
    • pan 平移
    • zoom 双指的缩放行为

    很明显,GestureDetector是事件驱动的。使用的时候需要实现一个GestureListener,然后将其作为参数传入GestureDetector。

    publicclass GListener implements GestureListener{
    
    @Override
    publicbooleantouchDown(float x,float y,int pointer,int button) {
    
    returnfalse;
    }
    
    @Override
    publicbooleantap(float x,float y,int count,int button) {
    
    returnfalse;
    }
    
    @Override
    publicbooleanlongPress(float x,float 
  • libGDX的多语言和国际化

    Android自身提供了多语言解决方案,但是使用Libgdx开发游戏的时候应该尽量避免使用平台特殊的代码。
    如果使用Android提供的方案那么在桌面的调试就有困难,使用Libgdx自身提供的是最方便的。
    Libgdx目前已经Locale来解决这个问题。

    简介

    从技术上将多语言国际化是指在开发设计上能够实现增加对语言的支持而不需要大规模修改代码。国际化主要解决游戏和应用在不同语言区域的适应性问题。
    Libgdx提供了一套解决方案,以I18NBundle类为中心。
    宏观来看它的操作和Android原生解决方案类似,也是后缀语言代码来处理的。

    结构

    语言文件时一个个独立的配置文件,其名称是由基本名称加上语言代码组成。比如游戏superjump它的语言文件如下:

    • superjump
    • superjump_de
    • superjump_en_GB
    • superjump_fr_CA_VAR1

    一定确保拥有一个默认配置,即superjump.properties,而其他的语言文件根据自身的需要增加吧。
    语言文件的格式很随意,使用键值方式组合,比如:

    gameName=SuperJump
    newMission={0}, you have a new mission. Reach level {1}.
    highScoreTime=High score achievedon {0,date}at {0,time}

    语言文件本身支持按序号赋值和按名称赋值。
    而中文化的语言文件可以写做:

    gameName=超级跳跳人
    newMission={0},,你有一个新任务,完成管卡{1}。
    highScoreTime=最高分为{0,time},获得时间{0,date} 。

    替换规则使用的是java.text.MessageFormat

  • 利用Packr打包Libgdx游戏到PC端

    平时最常用的是Java语言,写出的Java程序一般用Gradle Application插件打包一下。这样就有不同平台的启动文件,基本也算不错的解决方案。

    但这样求用户本身有Java环境,而且这个条件不一定能够满足,还需要自己打包一下环境。

    因为Libgdx框架做出来的东西也有这个需求,所以它专门提供了一个packr工具来解决这个问题。

    命令行直接操作

    packr提供一个with-dependencies包,可以直接运行,在命令行使用即可。

    java -jar packr-1.0-SNAPSHOT-jar-with-dependencies.jar 
    -platform mac 
    -jdk"openjdk-1.7.0-u45-unofficial-icedtea-2.4.3-macosx-x86_64-image.zip" 
    -executable myapp 
    -appjar myapp.jar 
    -mainclass"com/my/app/MainClass" 
    -vmargs"-Xmx1G" 
    -resources pom.xml;src/main/resources 
    -minimizejretrue 
    -outdir out

    因为打包一般针对不同的平台,所以platform的选项为windows,linux或者mac。

    jdk最后指定本地文件,当然网络地址也可以。

    executable是可以执行文件的名称,不包含后缀。

    appjar是你打包好的jar文件,mainclass是启动主类。

    如果需要的话可以通过vmargs指定vm参数,比如-Xms512m -Xmx1024m

    minimizejre可以缩小一点暂用空间。

    Json配置

    如果自动打包的话Json配置稍微好一下,比拼解好看多了。

    {
    "platform":"linux",
    "jdk":"/Users/badlogic/Downloads/openjdk-1.7.0-u45-unofficial-icedtea-2.4.3-linux-x86_64-image.zip",
    "executable":"superjump",
    
  • Libgdx内存管理和对象池

    Libgdx是跨平台的,而一般为了开发方便我们是在PC端调试,同时周期性地在Android平台测试。

    通常而言,PC端的性能远高于Android平台,特别是对于模拟器而言,所以内存和效率开销是一个需要重点注意的问题。

    游戏也是一种重资源应用。图片、音效、动画等等都会占用相当客观的内存,但同时它们又是被JAVA的GC所管理的,而有时候这不是很好的选择。

    可以手动释放的资源

    Libgdx中定义了Disposable接口,实现了该接口的所有类都可以在生命周期结束时手动控制。

    以BitmapFont为例,它使用Batch进行绘制,而所有文字都缓存于BitmapFontCache中。那么在声明周期结束时需要手动释放掉它所用的资源。

    publicvoiddispose () {
    if (ownsTexture) {
    for (int i =0; i < regions.length; i++)
    regions[i].getTexture().dispose();
    }
    }

    其他常用的实现了Disposable接口的类有

    • AssetManager
    • Bitmap
    • BitmapFont
    • BitmapFontCache
    • DecalBatch
    • ETC1Data
    • Mesh
    • FrameBuffer
    • Pixmap
    • PixmapPacker
    • ShaderProgram
    • Skin
    • Texture
    • Stage
    • TextureAtlas
    • TileMapRenderer
  • Libgdx使用Gradle构建速度慢的问题

    Libgdx正式推出1.0版本,其中最重要的一个变化就是正式启用Gradle模板支持。

    填写必要信息后会自动生成Gradle配置文件,通过Gradle可以创建Idea和Eclipse的项目文件,更可以快速升级和添加依赖。

    但是很多人再使用的时候,特别是第一次接触Gradle,会遇到很多问题,最关键的一个就是速度慢。本文会介绍这个问题的原因和解决方法。

    Gradle Wrapper

    Gradle的Wrapper很多文章翻译为包装器。包装器的出现是基于这样的需求,即让没有装Gradle的机器上也能正常的构建你的项目。

    它和Groovy里的Grape类似。如果目标机器上没有Gradle,包装器将先下载安装合适版本的Gradle,然后再运行相应的任务。如果有,但是版本不同,它也可以保证构建工具本身的版本相同。

    出发点是好的,但是现实确实复杂的。因为默认下载的地址http://services.gradle.org/在中国访问速度很慢很慢,而且需要下载的文件大小还很大,一般有40+M,基本上是不能下载成功的。

    对于这个问题有两种解决方法:

    • 使用本地Gradle
    • 修改下载地址

    使用本地Gradle

    这种方法实质上是不使用包装器,而是通过各种方法安装Gradle,然后直接执行。注意,执行的时候不要调用gradlew [command]而是使用gradle [command]

    这种方法简单,但是不能享受到包装器的优势。

    修改下载地址

    访问Gradle Distributions的速度慢,我们可以使用一个快的。

    Wrapper任务有一个名为distributionUrl的属性,直接修改它指定新的下载地址就行了。

    可以在build.gradle中修改,比如

    task prepareWrapper(type: Wrapper) {
    gradleVersion ='1.12'
    distributionUrl ='alternative.location'
    }
  • libGDX 1.0发布了

    也许很多人觉得这一天不会来到,但是Libgdx 1.0 今天正式发布了。

    我从2011年开始使用Libgdx,然后一直在0.9.2的某一个分支上奋斗,不断的等待正式版的发布,以便迁移过去。

    然后终于等到了。

    新特性

    其实1.0版相比0.9.9版的变化不多,主要集中在周边的支持上。

    首先是Gradle的支持。通过Gradle来初始化并管理项目就不再需要下载二进制包了,而且版本的升级也会好很多。

    Libgdx曾经使用过Maven来管理项目,也尝试过Gradle,还一度停止了Gradle模板的支持,不过正式版本确定了对Gradle的支持。

    另外一个更新就是文档上的改变,原来的文档是零散的,现在终于重新组织了。不仅包含Wiki和文章等等,还有对应的视频文件。不过视频都在Youtube上,需要科学上网一下。

    其他的都是小问题,比如移除了OpenGL ES 1.x的支持,添加了3.x的支持。参考目前的硬件支持情况,平时还是使用2.x吧。

    Box2D的绑定一直属于Libgdx的核心模块,始终和Libgdx主库在一起,这一次移动到扩展中去了。

    同时,对已以后项目的发展,也定下了一个大致的发布周期,2周到1个月一次。接下来的重点将集中在3D的支持和应用内购买扩展等等。

    Libgdx的历史

    有趣的是,这次发布说明作者回顾了Libgdx的发展历史和4年来的感受。

    项目起源于2009年中期,作者因为开发Android游戏的需要,对OpenGL ES作为封装并命名为AFX,第一个游戏名为Newton,地址是https://play.google.com/store/apps/details?id=com.badlogic.newtonfull

    作者加入了audio的支持,C#等等,这也是早期Libgdx发布到iOS平台的解决方案。

    正式的开源是在2010年3月6号,分布在Google Code上。第一个贡献者Christoph Widulle是在4月,并在5月引入了Box2D绑定。

    在2011年进入0.9版本阶段,我就是在那之后入坑的。随着部分游戏的走红,Libgdx的影响力也在扩大,比如Apparatus

    慢慢有了Freetype支持,iOS支持等。Nate加入的scene2D是我使用的最多的部分。

    Google使用Libgdx算得上一个里程碑,充分证明了外部的认可。

    其他事项

    Libgdx有了新的Setup工具,但是默认使用中央仓库,可以用oschina的镜像替换之。

    用Gradle管理项目可以直接打包到不同平台了,不需要太关心环境。

    参考资料

    libGDX 1.0 released
    Libgdx goes Gradle:

  • 在Libgdx中修正物理引擎Box2d时间步长

    在Libgdx中修正物理引擎Box2d时间步长

    文章翻译并修改自原文David Saltares。博主经验丰富,他的很多关于Libgdx的文章都值得一读,再此特作推荐。

    Fix your Timestep是Glenn Fiedler所写的一篇关于处理物理模拟的文章。这篇文章是2006年的,但是其中大部分内容在今天仍然具有启发性。

    这篇文章涉及了处理物理引擎中的时间增量的不同方法。这个问题很复杂,但是不可否认它对游戏行为和表现的影响。

    我认为将这些内容迁移到使用Box2D物理引擎的Libgdx应用中是非常好的点子。这些也可以应用到Bullet中,它是另外一款优秀的物理引擎,而且迁移的改动非常小。

    简单却错误的方法

    将时间步长设定为1/60每秒,这是非常常见而且简单的方法。它可以让物理模拟稳定运行,但是当游戏运行FPS降到60以下时,物理引擎的表现会非常糟。而这在移动设备上非常常见。

    最合乎逻辑的方案是计算现在时点在最后一帧后经过的时间,并传递给物理引擎。这样做显然会让每一帧的表现不同,整个物理引擎会表现的很不稳定。不同设备之间的表现会由于设备自身的不同(比如内存、运算器)产生变化。很明显,这不是我们期待的方案。

    固定的时间步长

    如果物理引擎以一个固定的步长,如1/60秒去运行,那么有些设备可能会运行的过快并达到120FPS。而同时有些设备可能运行过于缓慢,达到30FPS,那么物理引擎每两帧才前进一次。

    如果游戏以50FPS运行,会出现什么情况
    

    我们需要一个累加器来保存时间,然后尽可能的保持物理引擎和渲染一致。当这一帧时间过多时,我们可以将多余时间保留给下一帧。

    publicclass SionGame extends ApplicationListener {
    private World world;
    privatedouble accumulator;
    privatedouble currentTime;
    privatefloat step =1.0f /60.0f;
    
    publicvoidrender() {
    
  • libGDX基于RoboVM对IOS平台的支持

    libGDX基于RoboVM对IOS平台的支持

    Libgdx这款跨平台的游戏开发引擎,我之前的很多文章都介绍过了,可以点击Libgdx查看。

    Libgdx在0.99版本正式加入对IOS的支持。

    Libgdx之前其实也是支持IOS的,只是需要先转化成C#,然后使用收费的工具实现。

    而现在Libgdx使用了RoboVM,这是开源免费的。目前已经有超过百款的Libgdx游戏发布到App Store了。

    RoboVM

    RoboVM将Java的字节码转为本地代码,并封装了UI和各种API。这样可以最大程度重用你原有的Java代码。

    RoboVM需要一个Mac OS X,虽然在其他平台,比如ubuntu,也是可以使用的。不过为了更好的集成和开发,最好还是入手一个Mac吧。

    RoboVM提供了Eclipse插件,安装地址:http://download.robovm.org/eclipse/

    插件安装

    在安装完成后复制以下代码测试以下:

    import org.robovm.cocoatouch.coregraphics.*;
    import org.robovm.cocoatouch.foundation.*;
    import org.robovm.cocoatouch.uikit.*;
    
    publicclass IOSDemo extends UIApplicationDelegate.Adapter {
    
    private UIWindow window =null;
    privateint clickCount =0;
    
    @Override
    publicbooleandidFinishLaunching(UIApplication application,
    NSDictionary launchOptions) {