年度归档: 2011 年

  • android游戏开发框架libgdx的使用(九)—在libgdx中使用Box2d

    android游戏开发框架libgdx的使用(九)—在libgdx中使用Box2d

    在游戏开发中难免会需要模拟现实情况,一般常见的就是模拟物理世界。

    比如物体碰撞,车辆前进,物体下落等。也许有人会觉得原来有实现过一些效果没有看到用什么物理知识呢。

    在我看来引入物理引擎并不是必须的,但是这样可以让游戏更逼真。物理引擎的话首选Box2d,但是它是C++写的,直接用不方便。

    在Android游戏开发中使用物理引擎一般有三个比较好的选择:

    1.JBox2d

    Box2d的Java移植版本,速度有点慢。不过对于不熟悉C++的朋友而言这个可以拿来看看原理。

    2.Havok

    这个就不多说了,我怎么没有用过。

    3.Libgdx

    libgdx用了jni封装了box2d,速度和易用性都不错。

    下面我们来看看一个示例,原来没有接触过box2d的朋友最好先找资料看看。

    代码如下:

    package com.cnblogs.htynkn.listener;
    
    import com.badlogic.gdx.ApplicationListener;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL10;
    import com.badlogic.gdx.graphics.OrthographicCamera;
    import com.badlogic.gdx.math.Vector2;
    import com.badlogic.gdx.physics.box2d.Body;
    import com.badlogic.gdx.physics.box2d.BodyDef;
    import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
    import com.badlogic.gdx.physics.box2d.CircleShape;
    import com.badlogic.gdx.physics.box2d.World;
    import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
    
    publicclass DemoGame implements ApplicationListener 
  • 是sourceForge还是google code?

    是sourceForge还是google code?

    最近写了一点小东西,想把代码放到网上。最先想到的是google code,没有其他什么说的,界面简单,使用方便。

    svn服务器速度也不错,校园网这个渣速也可以跑到40K/S。用着用着就觉得有点纠结了,因为仔细研究了一下sourceForge,觉得也不错,有点像移动到sourceForge上去。

    但是sourceForge的速度有点纠结了,还有满屏的英语…看着有点困难。而且建立项目的界面改了,有点不知所云。(可以切换到老界面创建项目)。

    仔细比较了一下觉得二者各有优劣,遂把随感随想写成博文,一方面给后来人参考,一方面想听听其他朋友的看法。

    1.google code

    优点:

    *毫无悬念,速度快,特别是SVN服务器,提交代码时感觉很爽。

    *界面简单,极其一般的英语水准都可以胜任。

    *上手容易,快速体验。

    劣势:

    *功能较弱,一般的需求没有问题,但是SVN权限划分,wiki的支持上都有不是很强。

    *没有统计,虽然Google Code集合自家产品的统计,但是我觉得Google Analytics是做网站统计,对于svn库没有统计,对于下载等的统计没有单独划分出来。

    *稳定性不够.有时候会访问不起。(我觉得是被盾了)

    2.sourceForge

    优点:

    *老牌,用户量,各方面的操作和管理方式都经过了时间的考验。

    *功能服务,只要你能够想到的,都会有提供,实在没有的你还可以在Hosted Apps里面找找。

    *提供了web空间,可以更随意的表现。

    缺点:

    *因为功能丰富,所以上手有点困难。

    *速度,速度,有时候确实有点慢。

     

    其实依我来看,Google Code拿来做点简单的还是可以的,特别是你的项目本身就有网站什么的,不足的功能可以自己架。偶尔的无法访问也没有大的影响。

    如果你需要强大的功能,而且可以接受有点慢的速度,那就推荐sourceForge了。

    我在两者上面都建立了一个项目,监控了几天在线率,结果如下:

    gs2

    Google Code的无法访问一般就是几分钟的事情。

    gs1

  • android游戏开发框架libgdx的使用(八)–相机和观察点

    android游戏开发框架libgdx的使用(八)–相机和观察点

    本文使用的libgdx是0.92版本,和现在的最新版可能有一些不一样的地方。全文内容仅供参考。

    相机也可以成为观察者,最简单的例子就是魂斗罗。

    魂斗罗

    玩家操作角色前进,后退,跳跃等,显示的世界(就是后面的背景)会不停变化。其实就是相机的观察点(视角)的改变引起的。

    也许游戏的世界(背景地图)很大,比如10240480,而设备的分辨率是800480。现在游戏的角色在地图的最左侧,那么它的观察点就是(400,240)。

    随着角色的向前移动,观察点也变化,通常是y值变大。

    角色后退时x值变小。

    角色跳跃时,y值变化。(其实地图可能要稍微高一点,比如500,这样角色的跳跃才会有效果)。

    可以说相机是游戏开发的一个基本组件。而Libgdx的Stage类中就默认包含了一个Camera。

    Camera类按照功能而言也有很多种,最常用的是OrthographicCamera(正投影相机),Stage中默认Camera的实现类为该类。

    OrthographicCamera实现以下功能:

    1.移动和旋转镜头

    2.放大和缩小

    3.改变观察点(视角)

    4.窗体和世界的点的转化

    相机的最大好处就是无需手动操作矩阵就可以移动游戏世界,所有的矩阵投影和观察点运算就是对开发者隐藏的。

    相机的使用一般配合着mesh。mesh绘制一个矩形区域,然后将地图贴图在其上。

    接下来的例子将使用一张图:

    xk

    大小2048*2048.

    代码如下:

    package com.cnblogs.htynkn.listener;
    
    import com.badlogic.gdx.ApplicationListener;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL10;
    import com.badlogic.gdx.graphics.Mesh;
    import com.badlogic.gdx.graphics.OrthographicCamera;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.VertexAttribute;
    import com.badlogic.gdx.graphics.VertexAttributes;
    import 
  • android游戏开发框架libgdx的使用(七)–开发框架总观

    android游戏开发框架libgdx的使用(七)–开发框架总观

    本文使用的libgdx是0.92版本,和现在的最新版可能有一些不一样的地方。全文内容仅供参考。

    上几篇文章介绍了libgdx框架的一些基本类的用法,也夹杂着浏览了一下部分源代码,但是如果使用libgdx进实际开发,
    仅仅了解几个类是不够的,还需要对框架有具体和宏观的了解。

    1.应用的生命周期

    游戏应该高效和稳定,特别是对于android平台。目前的开发都是面向手机和平板。如果有效的管理资源,如何高效的运行都是非常重要的。

    试想一个制作优美,可玩性高的游戏运行于你的android手机上却10秒钟崩溃一次,运行时卡的如同在看漫画,这样的游戏是有合格的吗?

    application_lifecycle_diagram

    Android一般不用管resize(),我们在create中实例化所需的对象,在render()中进行绘制。pause()时可以保持当前的灵活数据。dispose()报销对象。

    而在resume()中根据保持的数据对游戏进行还原。

    其实说不负责一点,dispose()你可以不管,android系统会自动回收一些,用户对于退出后的短暂停滞也是有接受能力的。

    create()你也可以水一些,大不了进入游戏或者初始化相关场景时速度慢一些罢了。

    但是pause()和resume()你必须认真处理。电话是最常见的意外性中断,不会有用户偏爱一个电话就可以让记录或者进度消失的游戏的。

    2.游戏构架

    对于是否该称架构我一直有所疑惑,你可以理解为游戏的组成。一个游戏不论大小,不论复杂程度都应该具有的大致框架。

    架构

    这里稍微解释一下。

    输入只是用户的响应,可以使点击(Touch)或者点击(Click),拖拽(Drag)等。

    输出一般是图片和声音或者影像,当时也有文件或者其他数据(比如网络的存储)。

    而在输入中的文件一般为图片和声音,逻辑由数学逻辑和物理逻辑构成。

    而libgdx对于物理上处理是Box2D的封装,可以满足一般需求了。对于数学的封装了一些常见的结构和少量算式,不过可以基于此开发自己需要的算法。

    libgdx对于图像和声音等文件的处理比较好,可以直接使用。

    3.游戏容器

    最原始的容器自然是Application了。

    图表2

    然后是Game,它管理着若干个Screen,比如游戏场景,积分场景,帮助场景,高分榜场景。而场景之下有着若干舞台,舞台之中是演员。…

  • android游戏开发框架libgdx的使用(六)–演员和演出

    android游戏开发框架libgdx的使用(六)–演员和演出

    本文使用的libgdx是0.92版本,和现在的最新版可能有一些不一样的地方。全文内容仅供参考。

    上一篇说到UI,然后之前说到舞台,现在我们可以很轻松的构建一出戏了。

    因为actor类在绘制是以x,y值为基准,所以我们可以通过控制x,y值变化演员的位置,但是演员的其他效果需要配合Action类进行操作。

    Action类是一个抽象类,所有的具体实现都在com.badlogic.gdx.scenes.scene2d.actions包中。

    actions

    而包中的类依功能而言可以分为两类:

    1. 控制Action
    2. 表现Action

    控制Action没有直接表现效果,它操作的对象是表现Action。

    比如Delay。

    表现Action就是直接的表现效果,继承自AnimationAction,操作对象是Actor。

    比如MoveTo。

    现在挨着说吧:

    控制类:

    Delay $ (Action action,float duration)

    延迟duration秒执行action。

    Forever $ (Action action)

    一直执行action。

    Parallel $ (Action... actions)

    并行(同时)执行actions。

    Repeat $ (Action action,int times)

    重复action times次。

    Sequence $ (Action... actions)
  • android游戏开发框架libgdx的使用(五)–舞台和常用UI类

    android游戏开发框架libgdx的使用(五)–舞台和常用UI类

    本文使用的libgdx是0.92版本,和现在的最新版可能有一些不一样的地方。全文内容仅供参考。

    常用的UI类包括标签,按钮,勾选框,下拉框,图片,输入框,列表,滑动面板,滑条,分割面板。它们都在com.badlogic.gdx.scenes.scene2d.ui包中,都属于Actor,可以方便的纳入舞台的管理中。

    其实仔细看看UI类的实现代码不难发现其实它们都是大部分继承自Widget或者Table,如果需要自定义UI可以继承以上两个类(它们继承自Actor),这里要说明一下libgdx的布局部分使用了TWL,有兴趣的朋友可以去看看。

    在介绍每个控件之前我们先来看一下NinePatch,这是最近的一个比较重大的更新。

    何为NinePatch?其实android原生即有NinePatch类,常在按钮中使用。

    NinePatch

    如图,将图片分成九份。中间部分可以根据需要扩大,使按钮的大小内容变动不受图片的限制。

    而在libgdx的NinePatch其实就是九个TextureRegion对象。

    常用的实例化方法有两个:

    publicNinePatch (Texture texture,int left,int right,int top,int bottom)
    
    publicNinePatch (TextureRegion region,int left,int right,int top,int bottom)

    关于其中的四个int型参数如何取值我们可以参考一下源码:

    publicNinePatch (TextureRegion region,int left,int right,int top,int bottom) {
    int middleWidth = region.getRegionWidth() - left - 
  • android游戏开发框架libgdx的使用(四)–舞台和演员

    android游戏开发框架libgdx的使用(四)–舞台和演员

    本文使用的libgdx是0.92版本,和现在的最新版可能有一些不一样的地方。全文内容仅供参考。

    我们先看几个游戏截图再来理解何为舞台。

    12942M3Q423F-45025

    请仔细观察图片中的元素,有些东西是不能动,有些可以动,有些有特效,有些没有。有些是按钮,有些是图片,但是其实它们都可以统一称为演员(Actor)。

    而整个游戏界面就是我们的舞台。

    12942M3Q423F-45025 - 副本

    再看一个射击类游戏

    f2316c3c29ce2660f93dce72a0944453

    而其中的演员是

    f2316c3c29ce2660f93dce72a0944453

    演员是游戏设计中常用的一个对象,它接受舞台的统一管理,拥有一些公共的事件,比如触摸,点击,但是同时还有自身的响应和属性。

    而舞台就是容纳演员的场所。它统一管理所有演员,接受输入,同时提供一个方便的框架操作演员的时间变化。

    我们来看一下Stage类:

    protectedfinal Group root;
    protectedfinal SpriteBatch batch;
    protected Camera camera;

    它拥有一个Group,一个SpriteBatch,还有一个相机。

    SpriteBatch我们在前几篇说过,这里就不再重复了。

    Group是一个类,用于容纳和控制演员。但是这里要注意Group本身其实也是继承自Actor。

    相机我们这里跳过,以后再说,可以暂时理解成一个控制观察视角和指标转化的工具。

    当我们拥有一个演员后就可以调用addActor方法加入舞台。

    舞台可以获取输入,但是需要设置。

    Gdx.input.setInputProcessor(stage);

    下面来个列子,控制一个人物前进。

    actor1

    控制人物的按钮:

    narrow

    将所需的图片放到assert中

    所需资源

    新建三个类:

    FirstGame,实现接口ApplicationListener

    FirstActor,继承Actor

    NarrowButton,继承Actor

    先看一下FirstGame

    声明一个Stage,然后实例化FirstActor和NarrowButton,将二者加入舞台中,最后设置输入响应为Stage。

    package com.cnblogs.htynkn.listener;
    
    import java.util.Date;
    import java.util.Random;
    
    
  • android游戏开发框架libgdx的使用(三)–中文显示与汉字绘制

    android游戏开发框架libgdx的使用(三)–中文显示与汉字绘制

    本文使用的libgdx是0.92版本,和现在的最新版可能有一些不一样的地方。全文内容仅供参考。

    本来这篇想写场景的,但是昨天和群里一个朋友讨论了一下libgdx显示汉字的问题。以前没有注意到这个问题,发现还是蛮严重的,要是不支持中文,libgdx用着就有点不愉快了。

    我们来看看BitmapFont类,这是有关文字绘制的。看一下源码:

    publicBitmapFont () {
    this(Gdx.files.classpath("com/badlogic/gdx/utils/arial-15.fnt"),
    Gdx.files.classpath("com/badlogic/gdx/utils/arial-15.png"),false,true);
    }

    这是默认的构造函数,可以看出它加载了两个文件arial-15.fnt和arial-15.png。

    arial-15.fnt文件的部分内容:

    infoface="Arial"size=15bold=0italic=0charset=""unicode=0stretchH=100smooth=1aa=1padding=0,0,0,0spacing=1,1commonlineHeight=18base=14scaleW=256scaleH=256pages=1packed=0pageid=0file="arial-15.png"charscount=189charid=32x=0y=0width=0height=0xoffset=0yoffset=14xadvance=4page=0chnl=0 charid=255x=0y=0width=8height=19xoffset=-1yoffset=0xadvance=7page=0chnl=0 charid=254x=8y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=253x=17y=0width=8height=19xoffset=-1yoffset=0xadvance=7page=0chnl=0 charid=252x=25y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=251x=34y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=250x=43y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=249x=52y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=248x=61y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=247x=70y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=246x=79y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=245x=88y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=244x=97y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=243x=106y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=242x=115y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=241x=124y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=240x=133y=0width=9height=19xoffset=1yoffset=0xadvance=8page=0chnl=0 charid=239x=142y=0width=5height=19xoffset=0yoffset=0xadvance=3page=0chnl=0 …kerningscount=374kerningfirst=49second=49amount=-1kerningfirst=121second=44amount=-1kerningfirst=121second=46amount=-1kerningfirst=119second=44amount=-1kerningfirst=119second=46amount=-1kerningfirst=118second=44amount=-1kerningfirst=118second=46amount=-1kerningfirst=114second=44amount=-1kerningfirst=114second=46amount=-1kerningfirst=89second=44amount=-2kerningfirst=89second=45amount=-1kerningfirst=89second=46amount=-2kerningfirst=89second=58amount=-1kerningfirst=89second=59amount=-1kerningfirst=89second=65amount=-1kerningfirst=89second=97amount=-1kerningfirst=89second=101amount=-1…

     

    再看看arial-15.png:

    arial-15

    可以很明显看出,libgdx的文字绘制是根据fnt文件获取对应文字的在png中的坐标位置,然后截取图片的相应部分进行绘制。

    那么要让libgdx支持中文思路就很简单了,我们自己构造fnt和png文件,其中包含我们要使用的中文即可。

    作者给我们提供了一个对应的工具:Hiero

    下载后双击运行,在右侧列表中选择一个可以用的字体,然后输入需要的中文,最好保留自动生成的英文和符号。

    hiero界面

    在右侧的Effects中可以设置效果:

    hiero界面效果

    点File—Save …

  • android游戏开发框架libgdx的使用(一)–环境搭建

    android游戏开发框架libgdx的使用(一)–环境搭建

    本文使用的libgdx是0.92版本,和现在的最新版可能有一些不一样的地方。全文内容仅供参考。

    Libgdx是一款支持2D与3D游戏开发的游戏类库,兼容大多数微机平台(标准JavaSE实现,能运行在Mac、Linux、Windows等系统)与Android平台(Android1.5以上即可使用,Android2.1以上可满功率发挥)。

    logo:logo

    地址:http://code.google.com/p/libgdx/

    首先下载最新的jar,我下载的是libgdx-0.9.2。

    SpxImage

    新建一个Android项目,File -> New -> Project -> Android Project。我选的SDK是1.6的,最低选择应该是1.5.

    新建一个文件夹libs(这个名字是固定的,不能随意改),将下载到的jar复制进去,android平台只需要复制gdx.jar和gdx-backend-android.jar。

    增加引用,然后将armeabi和armeabi-v7a两个文件夹复制到libs文件夹中。

    SpxImage

    然后写个小东西测试一下环境有没有问题。

    新建类HelloGameActivity,继承AndroidApplication类。

    package com.cnblogs.htynkn;
    
    import com.badlogic.gdx.backends.android.AndroidApplication;
    
    import android.os.Bundle;
    
    publicclass HelloGameActivity extends AndroidApplication {
    @Override
    publicvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initialize(new FirstGame(),false);
    }
    }

     

    initialize(new 
  • android游戏开发框架libgdx的使用(二)–图形绘制

    android游戏开发框架libgdx的使用(二)–图形绘制

    本文使用的libgdx是0.92版本,和现在的最新版可能有一些不一样的地方。全文内容仅供参考。

    首先了解一下何为texture。按照英文解释来理解:一个图片从原始格式解码并上传到GPU就被称为纹理。(说实话我不是很清楚这个的定义哈,求指点)

    为了绘制texture,常常使用几何来描述,通过几何对应的顶点来描述纹理。比如要描述一个矩形,可以通过描述每个顶点来描述矩形。

     

    要绘图时,首先要绑定纹理,然后传递一个几何描述给OpenGL进行绘制。而绘图的大小和位置由几何描述和OpenGL的viewport的设置共同决定。

    当然大部分的游戏都会让viewport的大小和屏幕一致。这就意味使用像素更容易让纹理绘制在合适的大小和位置。

     

    绘制一个矩形的几何图形是非常常见的,同样让同一个纹理在不同位置以不同大小位置也是非常常见的,比如漫天的弹幕。但是每次都传递每个形状到GPU进行绘制的效率是较低的。

    所以许多相同纹理可以一起描述并一起送入GPU,这就是SpriteBatch类所要做的。

     

    SpriteBatch被赋予了纹理和坐标以便每个图形的绘制。它(SpriteBatch)汇集了很多图形而没有直接提交给GPU。如果它被赋予的纹理不同于原有的,它将保持原有的图形,并获取新的图形。

    上一篇文章其实就使用了SpriteBatch,但是没有绘制图形,现在我们来试试绘制。

    先找张图片来,分辨率必须是2的次方(如3232,256512)。

    我截取了我的桌面的一部分,分辨率调成512*512。

    image1

    拷贝到assets文件夹中,图片文件最好都是放在这个里面哈。

    SpxImage

    然后修改代码

    private Texture texture;
    实例化texture,texture=new Texture(Gdx.files.internal("image1.jpg"));
    然后来说一下为什么要将图片放在assets文件夹中。
    Gdx.files是libgdx的文件模块,主要提供以下5大功能。
    • 读取文件
    • 写文件
    • 复制文件
    • 移动文件
    • 列出文件和目录

    而获取操作文件的FileHandle有4种方法。

    1.Classpath路径相对于classpath,文件通常为只读。

    2.Internal内部文件路径相对于程序根目录或者android 的assets文件夹。

    3.External外部文件路径是相对于SD卡根目录

    4.Absolute

    assets文件夹本身就是存储资源的文件夹,而且相比resource文件夹,它其中的资源不会生成R中的ID,用来放图片很是合适。

    所以用Gdx.files.internal(“image1.jpg”)获取图片,然后调用batch.draw(texture,20,10);绘制图形,20,10是坐标,笛卡尔座标,以左下角为原点。

    完整代码:…