(实例)使用libgdx创建开发一个Android游戏

介绍

在过去几年大量的跨平台游戏的框架已经出现。这些框架来填补缺口,由于手机游戏及平台的多样性越来越大的兴趣保持越来越大。今天比以往任何时候都采用游戏引擎和开发你的第一场比赛更容易。最困难的部分是选择合适的游戏框架。然而,从所有可用的选项有一个明确突出:libgdx这些都是一些libgdx的,使其成为一个独一无二的特点:

 

跨平台:部署在桌面,Android的,HTLM5iOS(用的辅助RoboVM

你可以调试,并在桌面环境中测试你的游戏,然后将其部署为Android平台几乎为零的努力。

强大的性能

良好的文档,优良的社区支持

许多功能的2D3D游戏。

友好的开源许可证(Apache 2.0中)。它可以自由用于商业用途。

 

<!--EndFragment-->

在这篇文章中我将提供libgdx的概述。一个简单的2D游戏,称为“水果捕手”将被用作例子。在这个游戏中果实脱落的天空。你随身携带一个篮子,你移动它,或者通过触摸屏幕或滑动您的手机,以赶上他们。为了使它更有趣的时令水果值得更多的积分。当然,你知道,你必须喜欢时令水果!因为,正如我所说,libdgx文档很不错的,我不打算在这里介绍的基本信息。你可以阅读如何设置和运行一个项目的维基您还可以阅读如何创建一个简单的游戏,以及如何扩展它使用的游戏画面在这里,我将介绍一些重要的游戏概念,并提供技巧,将帮助你从一个样品的游戏移动到一个准备部署在市场。虽然libgdx是一个跨平台的框架,重点将部署Android平台发出。

但是在开始编写代码之前,我们必须包括两方面内容,这对于游戏设计的重要。

游戏资源

我猜想,你最该读的是开发商,而不是设计师。在我看来不过创造一个游戏是艺术多于一个发展的过程。伟大的游戏通常是站立,因为他们的良好的图形和漂亮的声音和音乐了。这并不意味着一个单一的开发者有没有运气创建一个游戏。这是困难的开发人员从头开始创建的所有资源,但是它是非常容易在网上找到合适的资源,然后使用适当的工具来适应他们。而且因为没有人,上面写着这是一个律师,这是提供资源,你可以在游戏中自由使用的URL列表:

 

图片:Openclipart。公共领域的SVG图形。

声音:Freesound上。创作共用许可声音。注重个人的声音许可证。

字体:字体松鼠。它可能会作为一个惊喜,但你不能在游戏中使用本地字体。字体松鼠提供的字体都是免费的商业用途。libgdx提供了一个工具,可以让你轻松地集成这些字体。

<!--EndFragment-->

 

这份名单是当然并非详尽无遗。还有其他的资源中心,以及。然而,当搜索,注意牌照。不要只用你在网上找到的第一张图像。你需要确保你有使用它的权利。另外,上面的列表不包括其他类型的资源,如3D模型。

工具

当你在网上找到(或已经支付的设计师为您创建它们)相应的资源,你还没有准备好开始编码。时代的大多数资源将需要一些编辑。有设计,你能避免做一个基本的水平。令人欣慰的是,这种设计实际上是有趣的,而且都是免费的工具,你可以使用:

 

Inkscape中:专业矢量图形编辑器。这是很好的设计在矢量格式的所有图像。这将允许您轻松地调整它们用于任何当前或未来的屏幕分辨率。

GIMP:图像处理程序。它具有类似的功能到Photoshop。大多数游戏引擎需要的位图(通常是PNG)的图像。从Inkscape中导出图像后,你可能需要纳入到你的游戏之前,做一些最后的感动。GIMP的界面是不是用户友好的,需要一些时间来习惯。不过GIMP是功能全,有许多教程和视频提供在线。

大言不惭:跨平台软件录制和编辑声音。

<!--EndFragment-->

 

上述所有工具都是免费的,开源的专业水平和。他们是绰绰有余你会需要的任何任务。除了上述通用工具,也有很多游戏的具体工具。有用于包装许多小图像来一个大单,工具,用于创建瓦片地图创建位图字体,工具的工具。libgdx具有的工具,这个国王和他们中的一些将在本文稍后将提交很好的支持。

游戏主循环

游戏的确有一些自己的软件设计模式。最普遍的人,当然是游戏循环。我相信你已经听说过它。游戏循环实际上是一个while循环,所有的处理正在发生。在这个循环中你显示所有图像,播放声音,应用物理和游戏逻辑。你尝试这样做,尽可能快。当循环完成后,它会立即启动了一遍。循环在一秒钟内执行的次数等于“每秒帧”(FPS)。最高的FPS,越流畅的游戏中会出现的人。

大多数游戏框架通过提供一个函数(或方法)实现游戏循环。这个方法做所有的处理和框架需要调用它尽可能快的照顾。让我们称这种方法为“循环法”。在伪代码中的“循环法”载列如下:

 

void gameMain(float delta) {

    renderWorld();

    getUserInput();

    update(delta);
}

这种伪代码还涉及著名的MVC模式,这也是受欢迎的游戏开发。在“循环法”接受一个float参数。这就是所谓的增量,实际上是自上一次循环方法被调用传递的时间。你可以把它看作是FPS的倒数。那就是:三角= 1 / FPS。

该renderWorld方法呈现在屏幕上的所有图像。这是绘制所有图像在适当的位置游戏的“查看”。所有的图像绘制每次循环运行时间,即使他们的立场没有改变。下一个循环读取用户输入。这可能来自于触摸屏,键盘,鼠标,它的accelerormeter,游戏垫… 虽然上面这似乎是循环方法的一部分,它更常见的是被实现为更新“标准”一个单独的类(“控制器”)。最后一部分应用物理和游戏逻辑。这是需要的增量信息。游戏可能需要一个完整的物理引擎或只是一些简单的物体的运动和碰撞检测。在任何情况下,实现这个定时信息是必要的。在这部分的东西,如更新分数,并检查游戏结束条件将发生。如果你已经使用XNA或MonoGame工作,你可能会发现这部分相似的Update方法。这种方法实际上会更新“标准”游戏或状态。在MonoGame特殊考虑采取这样的Update方法被调用在固定的时间间隔,无论渲染多长时间服用执行。换句话说,框架始终调用update方法,它应该用不了多长时间来执行,每秒钟一个特定的号码,然后使用剩余的时间来呈现世界尽可能经常。libgdx不支持单独的更新方法。因此,你应该实现这个模式自己。如果renderWorld时间过长执行(低端设备,太多的对象来呈现),它不应该被称为在每个循环中,以便更新方法被称为定期和比赛状态保持一致。如果你不这样做,你可能会发现自己的处境,物体通过障碍物飞及各种奇怪的事情发生。

libgdx支持游戏主循环模式通过ApplicationListener接口。这个接口定义了以下方法:

void create() / / 当第一次创建。应用程序调用
void dispose() / / 当应用程序被销毁时调用。
void pause() / / 当应用程序被暂停时调用。
void render() / / 调用,当应用程序应该呈现自身。
void resize(int width, int height) / / 当应用程序被调整大小时调用。
void resume() / / 当应用程序从暂停状态恢复时调用。

上述方法提供了切入点您将需要处理的一个游戏的生命周期中的所有事件。render方法是在主循环的方法,我们在上面描述。libgdx提供静态构造读取增量时间(Gdx.graphics.getDeltaTime() 和处理用户输入(Gdx.input)。虽然你可以直接从render方法内处理输入,libgdx还提供了更高级的机制,让您实现一个单独的控制器类(InputProcessor)。不提供,你需要实现这个模式自己如上一个单独的更新方法说明。

从另一个ApplicationListener方法创建和处置方法是针对游戏资源的处理非常重要。因为在你的游戏中,你要处理大量的与OpenGL的资源,垃圾回收也不会帮助你,你会需要手动处理掉。我们通常分配资源,为游戏中的create方法。这就是所谓的只有一次,当游戏开始。在Dispose方法中,我们有我们的机会来处理这些资源。资源处理,当然是通常比这更复杂。为了快速启动游戏,并避免内存不足的错误,更复杂的资源处理是必要的。您可能需要预先分配一些资源,去分配他们中的一些在早期内存不足的情况​​。我们将在后面讨论更多关于这个。

游戏画面

下图显示一个典型的游戏画面。游戏包括各种屏幕。正在显示每次只有一个屏幕。当开发一个游戏是很方便的就能够想到在这些屏幕方面。首先实现初始菜单画面,那么游戏开始画面,游戏主画面(通常是最困难的),游戏结束画面等。

libgdx支持这种模式通过游戏抽象类和屏幕界面。

这是一个非常薄的结构,你需要既为游戏和画面对象提供的实现。Game类无非是一个ApplicationListener,代表们渲染到一个或多个画面对象。这使得它更容易想到在屏幕方面。这也使得资源处理更容易。屏幕界面提供了Dispose方法,但是它不会自动调用。你应该把它自己,以出售本屏幕的资源。这是一件好事,因为它允许更灵活的资源处理。一个屏幕可保持预加载,使得它可以快速重新使用。一般来说这种模式可以让你实现一个资源处理服务。这项服务将预先加载资源,它会处理那些不打算在短期内使用的资源。例如从1级去2级的时候,你需要处理的第1级的资源和预加载2级的人,而仍在级别的屏幕。一个单独的服务类将负责装卸的资源。游戏画面模式可以很容易地在适当的时候调用这个服务。

如果你看看游戏画面,你一定会发现,他们大多是很简单的。除了 ​​动作画面,所有画面只显示一条消息,并提供了几个行动点为用户。他们只是简单的用户界面。libgdx提供Scene2d以利于创造这样的画面。复制从libgdx维基:

scene2d设备完善,布局,绘图和处理输入的游戏菜单,HUD覆盖,工具和其他用户界面。该scene2d.ui包提供许多演员和其他公用设施专门用于构建用户界面。

我没有亲自使用Scene2d在果实的守望者,但我相信,你应该考虑它自己的应用程序。

渲染图片

下面的代码片段显示你需要做的,以图像呈现到屏幕(这是从简单的游戏,例如在libgdx维基)。首先,你需要创建的创建方法一个摄像头和一个SpriteBatch的对象。在那里,您还可以创建您在它们加载的图像纹理对象。在render方法使用的SpriteBatch对象来绘制纹理。你一定不要忘记在处理Dispose方法的纹理和SpriteBatch的对象。

Texture bucketImage;

OrthographicCamera camera;
SpriteBatch batch;

@Override
public void create() {
    camera = new OrthographicCamera();
    camera.setToOrtho(false, 800, 480);

    batch = new SpriteBatch();
    dropImage = new Texture(Gdx.files.internal("droplet.png"));
    ...

}

@Override
public void render() {
    Gdx.gl.glClearColor(0, 0, 0.2f, 1);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    batch.draw(bucketImage, bucket.x, bucket.y);
    batch.end();
}

@Override
public void dispose() {
    bucketImage.dispose();
    batch.dispose();
    ...
}

绘制图像libgdx很容易。(如果你认为上面的代码很复杂,你应该做一个关于画图用OpenGL图像没有一个框架的帮助下研究)。然而,上面的代码只适用于非常简单的游戏。在现实情况下,您将需要几个抽象层添加到您的图像绘制代码。

首先,如果你有很多的小图像,你不应该由一个加载它们。相反,你应该“打包”成一个大的图像,加载这个图片到一个纹理,然后从中选择区域。下图描绘了果实的守望者的小图片全部集成在一个单一的。

libgdx使得它很容易创建打包的图像。你可以做到这一点直接从桌面项目。所有您需要做的是添加GDX-tools.jar中的类路径中,写几行代码。这就是我如何做到这一点的水果捕手。我定义的最大高度和宽度为1024。如果图像不适合在一个1024×1024的图像,一个以上的将被创建。这将是完全透明的,你作为代码来选择一个区域不会改变。该TexturePacker2.process需要的所有图像从一个特定的文件夹中,它们并复制图像压缩包到Android项目资产的文件夹。它还创建了一个“图集”的文件。这是一个简单的文本文件,其中包含单个图像的位置到合并之一。在水果捕手三个“地图集”的创建方式:一为小图像,一个用于文本图像的英语,和一个文本图像的德语。

Settings settings = new Settings();
settings.maxWidth = 1024;
settings.maxHeight = 1024;
TexturePacker2.process(settings, "images", "../FruitCatcher-android/assets", "game");
TexturePacker2.process(settings, "text-images", "../FruitCatcher-android/assets", "text_images");
TexturePacker2.process(settings, "text-images-de", "../FruitCatcher-android/assets", "text_images_de");

当你调用上面的代码,你需要刷新的Android项目,以使更改被拾起。此外,你应该注意的命名约定的TexturePacker2实用程序使用,以支持动画。您可以命名了一系列这样的图像:image_n.png,其中n是一个整数。数n实际上代表的是帧索引。如果你有一个精灵,它由多个帧,该公约将可以很容易地加载这些帧。

 / / 创建一个图集对象
TextureAtlas atlas = new TextureAtlas(Gdx.files.internal("game.atlas"));

/ / 加载星架1
TextureRegion startTexture1 =  atlas.findRegion("star", 1);

/ / 加载星架2
TextureRegion startTexture2 =  atlas.findRegion("star", 2);

/ / 载入图像按钮
TextureRegion buttonTexture = atlas.findRegion("button");

在复杂的游戏,用大量的图片,可能需要相当长的时间来加载所有的图像。什么游戏通常做的是在开头显示“加载”屏幕,并开始加载图像和其他必需的资产。当一切都被加载,游戏就可以开始。有一个延迟开始,该用户可以忍受,然后游戏运行流畅。libgdx支持这种模式与援助AssetManager

正如您所看到的图像加载是不是在实际应用中那么简单。您可能需要使用一个AssetManager,一个TexturePacker或两者兼而有之。您可能还需要实现一个运行在两者之间的屏幕你的游戏的自定义装载和卸载方案。基于这些原因,我相信,这将是最好创建一个单独的服务,将提供所有影像到其他代码层。我把这种服务ImageProvider在果实的守望者。有了这个服务将让您体验不同的装卸技术,而不会影响整个源基地。它真的会还清,如果你设计你的游戏像这样从一开始。

文字渲染

如果你以前从来没有开发出一个游戏,特别考虑是必要的,以显示文字,它可能会作为一个惊喜。但是,你应该明白,出于性能原因游戏框架使用OpenGL和没有办法用,可以使用系统字体的本地代码结合起来。幸运的是,libgdx可以很容易地创建一个位图字体,然后用它在你的应用程序。libgdx已采纳Hiero位图字体工具。这是一个开放源码的工具。以前是很难找到它的一个工作版本。现在libgdx保持它作为一个工具,你可以直接从libgdx二进制文件运行它。Hiero可以加载任何系统字体和转换成位图字体,在libgdx理解的格式。它也可以直接加载TTF字体,而无需安装它们。当Hiero工作要注意许可证。只使用,你必须这样做的权利字体。在创建位图字体,这是很容易装入,然后用它来 ​​显示文本。

/ / 加载位图字体  
BitmapFont font = new BitmapFont(Gdx.files.internal("fonts/poetsen.fnt"),
                                 Gdx.files.internal("fonts/poetsen.png"), false);

/ / 绘制字符串用的SpriteBatch对象
font.draw(spriteBatch, line_string, lineX, lineY);

一些你可能没有从一开始就意识到,那是你的游戏必须能够存储它的状态,然后从中恢复。这是在可从电话呼叫中断的移动设备尤其重要。当玩家在中断后返回到比赛中,她希望找到它在她离开时的状态。如果她正要达到了很高的分数,并发​​现她已经从年初开始,她会生气,你应该期待一些非常负面的评论。

你的游戏必须能够从一开始就与从一个众所周知的状态开始为好。本场比赛必须不断更新其状态,必须在适当的时候坚持它在一个非易失性位置。libgdx提供了JSON的实用工具,可以让你在一个跨平台的方式序列化和反序列化的类。在水果捕手有两个独立的状态类:GameScreenState用来存储当前游戏的状态(数字采集点,剩余时间,水果中的天空)和GameState,其中包含有关游戏的会话信息。它们都被保存在电子游戏的暂停方法。如果您有需要大量的时间来序列化更复杂的状态对象,你应该定期对其进行序列化,而 ​​不是等待暂停的方法。

调用Android原生代码

调用Android原生代码可能有必要在某些情况下:

 

显示广告

应用内购买

使用本机的用户输入

连接与排行榜

<!--EndFragment-->

 

维基您可以阅读如何与AdMob的整合libgdx游戏。我已经使用了上述技术在水果捕手显示AdMob的广告。不过,我需要本地代码也用于获取用户的名字,当高分达标,用于显示前5分数。与本机代码的集成实际上正在发生的内部AndroidApplication类。这是libgdx扩展一个Android活动提供了一个类。为了调用从libgdx本地代码,你应该做到以下几点:

创建一个方法定义为切入点,需要调用本机代码的操作界面。你的实现AndroidApplication将实现此接口。我把这个接口GameEventListener。此接口是Android项目的libgdx,而不是一部分。这也是以及可从桌面项目。

你的实现com.badlogic.gdx.Game将接受GameEventListener作为参数的构造函数。这可以通过为null,表示你不在乎实现本机的功能平台。我需要水果捕手的桌面版本,以便快速调试和测试。我不需要然而,显示广告和高分吧。我简单地传递一个空GameEventListener它。在我的游戏类我检查null,调用GameEventListener方法之前。

以上后,你将拥有在AndroidApplication类的入口点方法。这些方法将被libgdx引擎调用。因为libgdx不会在UI线程中运行你不能从他们那里访问UI。相反,你需要使用一个消息处理函数来发布消息,将触发相应的UI操作。

<!--EndFragment-->

编译指令

在文章顶部的zip文件不包含libgdx二进制文件(这将所做的zip文件过大)。然而,这是很容易的添加它们。下载libgdx并运行GDX – 设置 – ui.jar。这使您可以创建一个新的项目或更新现有的。点击“更新”,选择位置,您解压缩zip文件和所需的文件将被添加。有一件事,那会不会被添加为GDX-tools.jar文件。你需要手动将它添加到桌面项目的libs文件夹。

我也取得了在代码中使用GitHub上你可以从那里复制的存储库。所有必需的二进制文件都包括在内。最后,您可以从下载游戏谷歌播放请注意,这个版本的游戏会显示广告。在页面顶部的APK是免费广告。

总结

如果这篇文章太长,为您和您立即播种滚动至底部,这是一个总结。

libgdx是一个跨平台的开源游戏框架,您可以在商业应用中自由使用。

libgdx实现游戏主循环模式与ApplicationListener接口。它还实现了游戏画面的模式。

libgdx可以很容易地呈现在屏幕上的图像。它还提供工具,包装小图像成一个大的,并在后台加载图像,同时显示一个启动画面。

随着libgdx你可以嵌入一个位图字体用一个单一的代码行。您可以创建一个位图字体用所提供的实用工具安装在你的系统中的任何字体。

调用本地代码通常需要(显示广告,应用内购买,原生输入文本,与领先的服务集成)。

有必要定期保存你的游戏的状态。libgdx使得这个容易使用一个跨平台的JSON序列化。

源码下载地址:水果捕手源(无libgdx二进制文件) – 4.4 MB.rar

                         水果捕手APK – 2.5 MB.rar

<!--EndFragment-->

猜你喜欢

转载自ilixin.iteye.com/blog/2001008