月度归档: 2011 年 11 月

  • 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是坐标,笛卡尔座标,以左下角为原点。

    完整代码:…

  • C#使用NSoup解析HTML的乱码解决

    NSoup是JSoup的Net移植版本。使用方法基本一致。

    如果项目涉及HTML的处理,强烈推荐NSoup,毕竟字符串截断太苦逼了。

    下载地址:

    http://nsoup.codeplex.com/

    简单用法如下:

    NSoup.Nodes.Document doc = NSoup.NSoupClient.Parse(HtmlString);

    处理网络上的页面:

    NSoup.Nodes.Document doc = NSoup.NSoupClient.Connect("http://www.cnblogs.com/htynkn/").Get();

    但是遗憾的是NSoup默认的编码是UTF-8,处理中文有乱码(对于编码是UTF-8的自然不会有乱码,但是有些GB2312的就可能有乱码,谢谢 forhells的提醒)。

    目前我找到两种解决办法:

    1.下载网页源代码再处理

    WebClient webClient =new WebClient();
    String HtmlString=Encoding.GetEncoding("utf-8").GetString(webClient.DownloadData("http://www.cnblogs.com/htynkn/"));
    NSoup.Nodes.Document doc = NSoup.NSoupClient.Parse(HtmlString);

    2.获得网页的流

    WebRequest webRequest=WebRequest.Create("http://www.cnblogs.com/htynkn/");
    NSoup.Nodes.Document doc = NSoup.NSoupClient.Parse(webRequest.GetResponse().GetResponseStream(),"utf-8");

    第二种用着比较方便,但是我觉得第一种比较合适,毕竟NSoup是个Html解析类,下载网页代码这种事情本来不应该交给它。…

  • Android自动匹配电子邮件地址,网址,电话–谈Linkify的使用

    Android自动匹配电子邮件地址,网址,电话–谈Linkify的使用

    翻看Android Api,无意看到了Linkify。按照Api的说明,Linkify可以转化符合匹配规则的文字为可点击的连接。

    感觉这个还是有点用处,下面来试一试。

    1.新建一个项目

    SpxImage

    2.修改样式文件

    为了方便查看效果,添加一个EditText和一个TextView

    SpxImage

    代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:weightsum="1">
    <edittext android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/inputText">
    <requestfocus></requestfocus>
    </edittext>
    <textview android:layout_height="wrap_content" android:textappearance="?android:attr/textAppearanceLarge" android:layout_width="fill_parent" android:layout_weight="0.08" android:id="@+id/viewText" android:text="请输入内容"></textview>
    </linearlayout>

    3.修改AndroidLearnActivity.java

    看一下关键部分的说明

    SpxImage

    在本例子中我们使用第一个。再看一看Linkify默认支持识别什么。

    SpxImage

    MAP_ADDRESSES我没有理解到…

    下面看一下完整的代码:

    package cn.ghy.sdx;
    import android.app.Activity;
    import 
  • Android中使用Ormlite实现持久化(二)–持久化类的详细配置

    上一篇文章简单的使用了Ormlite一下,但是我觉得Ormlite出色之处就是对于需要字段,表等等的配置设计的比较好。

    下面来说说类的配置:

    如果我们开发的Android应用需要保持用户信息,那么现在新建一个类:UserAccount

    该类有六个变量:

    privateint id;private String username;private String password;private Date regTime;private String tellphone;private String email;

    用eclipse生成get和set方法:

    publicintgetId() {return id; }publicvoidsetId(int id) {this.id = id; }public StringgetUsername() {return username; }publicvoidsetUsername(String username) {this.username = username; }public StringgetPassword() {return password; }publicvoidsetPassword(String password)