Libgdx上的情人节申请

每年都有很多关于情人节的文章。 我还决定参与这个话题,并创造一些原创和不寻常的东西。 这个想法是用心脏创建一个简单的Android应用程序,该应用程序将具有其物理模型并彼此交互。 然后我添加了文字,声音,粒子和其他一些效果。 生成的应用程序正在运行并且非常原始! 在本文中,我将描述libgdx库的创建过程以及功能和陷阱。


情人节那天的心


目录内容



程序和工具


为了实现这个想法,我使用了以下程序和库:


  1. IntelliJ IDEA-用于跨平台应用程序的IDE。 或者,您可以使用Android StudioEclipse
  2. libgdx-用于开发游戏和其他图形应用程序的跨平台(PC,Mac,Linux,Android)Java库。 该库根据Apache License 2.0分发。 使用JNI对某些代码段进行了优化(例如Box2d)。
  3. box2d- libgdx用于创建物理引擎libgdx使用的物理模型的编辑器,该引擎内置于libgdx 。 在这里,它将用于匹配心脏的图像与其物理模型。
  4. Hiero位图字体生成器 -一种将矢量字体转换为光栅的程序(因为在libgdx仅支持光栅字体)。
  5. 粒子编辑器 -由libgdx的创建者开发的用于创建粒子系统的编辑器。 它用于心脏破坏过程中具有“爆炸”效果的颗粒。
  6. Paint.NET-图像编辑器,用于编辑心脏的图像并创建背景。

所有这些程序和组件都可以自由分发,这是一大优势。 我选择libgdx是因为,首先,我已经有了一些经验,其次,使用libgdx不需要使用速度较慢的Android仿真器,因为它是跨平台的,可以在本机Java环境中测试应用程序,然后进行编译适用于Android。


世界你好


首先,我将简单介绍几个如何创建libgdx项目。 使用gdx-setup.jar ,生成一个项目模板(基于Gradle),该模板指定目标平台。 当前,支持DesktopAndroidIosHtml 。 老实说,由于我没有iOS设备,因此我无法尝试其中的最后两个,而且HTML尚有一些问题尚未解决。


项目设置


您也可以选择要使用的扩展名。 在我们的例子中,这是Box2d物理库。


但是,所有这些都在Wiki中进行了描述: 创建一个libgdx项目


生成后,将创建三个文件夹:


  • 核心
  • 台式机
  • 安卓

在最后两个中,分别放置了DesktopLauncherAndroidLauncher ,如下所示:


 public class DesktopLauncher { public static void main (String[] arg) { LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); config.width = 800; config.height = 480; new LwjglApplication(new ValentinesDayHeartsApp(), config); } } 

 public class AndroidLauncher extends AndroidApplication { @Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); initialize(new ValentinesDayHeartsApp(), config); } } 

不再有专门用于Android平台的代码,这是所选库的巨大优势。 它仅在AndroidManifest.xml配置中保留为允许振动并禁用睡眠模式(以防止重置应用程序状态)。 并设置景观方向,以使世界不会倒过来:


 <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> 


 android:screenOrientation="landscape" 

通用代码存储在core文件夹中。 名为ValentinesDayHeartsApp的主类实现ApplicationListener接口(用于处理初始化事件,渲染,完成和其他状态)和InputProcessor接口(用于处理用户输入)。


仅此而已,骨架已准备就绪! 现在,我们的应用程序将同时在PC和Android上运行。


一般


该项目具有简单的结构:在ValentinesDayHeatsApp类中, createrenderdisposetouchDown方法被覆盖。 create方法初始化所有资源(纹理,字体,粒子,声音)并创建物理世界。 在render方法中,将渲染世界上所有对象:


 @Override public void render() { updatePhysics(); updateBackground(); updateSprites(); updateParticles(); refresh(); renderBackground(); renderHearts(); renderFonts(); renderParticles(); } 

dispose方法中,所有资源都被释放。 是的,是的,尽管Java具有自动垃圾收集功能,但仍需要手动释放非托管资源(Box2d对象和其他一些资源)。 touchDown方法由触摸或鼠标单击触发。 它的工作原理是:如果触摸点与心脏相交,则心脏将被删除。 否则,将在接触点中产生新的心脏。 Heart对象具有以下属性:


  • Body -物理模型。
  • Sprite图形模型(Sprite)。
  • String -在心脏上显示的文本。
  • Font -一种字体。
  • ParticleEffect破坏心脏时产生的ParticleEffect
  • BreakSound破坏心脏的声音。

接下来,我将更详细地描述应用程序的组件。


贴图


首先,我需要找到或吸引人的心。 幸运的是,我轻松地对其进行了搜索,然后对其进行了一些编辑:添加了光晕和透明背景。 要在libgdx加载纹理,我使用了Texture类。 由于相同的纹理可以使用多次,因此使用了其他Sprite对象。 它们是使用render方法绘制的。 精灵的位置和角度是渲染的参数和心脏的物理模型。 为了做出改变,我决定用不同的阴影画出心。 我使用了HSL调色板,该调色板允许操作色相,饱和度和亮度,而不是RGB等颜色分量。 可以轻松找到RGB-> HSL和HSL-> RGB转换的公式,我使用了在Java上的.NET中操纵颜色一文中的方法。 所有转换都在prepareHeartsTexturesprepareHslDatagenerateHeartTexture方法中。 这是示例:


 Pixmap pixmap = new Pixmap(fileHandle); float[][][] result = new float[pixmap.getWidth()][pixmap.getHeight()][4]; for (int i = 0; i < pixmap.getWidth(); i++) for (int j = 0; j < pixmap.getHeight(); j++) { int color = pixmap.getPixel(i, j); float r = (float)((color >> 24) & 0xFF) / 255.0f; float g = (float)((color >> 16) & 0xFF) / 255.0f; float b = (float)((color >> 8) & 0xFF) / 255.0f; float a = (float)(color & 0xFF) / 255.0f; result[i][j] = ColorUtils.RgbToHsl(r, g, b, a); } return result; 

不幸的是,由于生成具有不同阴影的纹理,因此Android应用程序开始时会有一些延迟。


字型


由于libgdx仅能使用光栅字体,因此我使用了Hiero位图字体生成器 (版本5)和FNT文件,该生成器以PNG格式创建所有字符的图像,该文件包含有关图像中每个字符坐标的信息。 这是该程序的屏幕截图:


位图字体工具


生成必要的文件后,可以在libgdx应用程序中按如下方式使用字体:


 font = new BitmapFont( Gdx.files.internal("data/Jura-Medium.fnt"), Gdx.files.internal("data/Jura-Medium.png"), false); font.setColor(Color.WHITE); 

然后像这样渲染它:


 font.draw(spriteBatch, heart.String, screenPosition.x, screenPosition.y); 

在渲染时,我遇到了一些困难:例如,无法以某种角度渲染字体,因为可以使用精灵来完成。 要解决此问题,您需要更改SpriteBatch的投影矩阵,然后按如下所示呈现字体:


 Matrix4 projection = spriteBatch.getProjectionMatrix(); projection.setToOrtho2D(0, 0, WorldWidth, WorldHeight); projection.translate(tmpVector1.x, tmpVector1.y, 0); projection.rotate(0, 0, 1, body.getAngle() / (float)Math.PI * 180); projection.translate(-tmpVector1.x, -tmpVector1.y, 0); Vector2 stringSize = heart.getStringSize(); tmpVector1.add(heart.Size.x / PhysWorldWidth * WorldWidth * CenterDisplacement.x - stringSize.x * 0.5f, heart.Size.y / PhysWorldHeight * WorldHeight * CenterDisplacement.y + stringSize.y); spriteBatch.begin(); BitmapFont.BitmapFontData fontData = font.getData(); fontData.setScale(heart.Size.x * FontSizeHeartSizeCoef.x, heart.Size.y * FontSizeHeartSizeCoef.y); font.draw(spriteBatch, heart.String, tmpVector1.x, tmpVector1.y); fontData.setScale(1, 1); spriteBatch.end(); 

物理学


作为物理引擎,使用了box2d


为了使心脏的图像与其物理模型匹配,我使用box2d-editor


物理身体编辑器


使用此程序,我创建了心脏的多边形,该多边形自动被分解为凸多边形。 物理模型是JSON格式的这些多边形的一组坐标。


此外,此文件在我们的应用程序中使用(加载在addHeart方法中进行)。 libgdx只能以二进制格式加载文件。 幸运的是,找到了BodyEditorLoader.java类,该类也可用于从JSON(即文本表示形式)加载模型。


不要忘记设置身体的密度,摩擦和弹性:


 FixtureDef fdef = new FixtureDef(); fdef.density = 0.75f; fdef.friction = 1.0f; fdef.restitution = 0.4f; bodyLoader.attachFixture(body, "Heart", fdef, newWidth); body.resetMassData(); 

现在我们的心有了肉壳!


为了使心脏不会从屏幕上飞走,我们可以在我们的小世界的侧面添加四个静态矩形。 在移动设备上,建议根据设备方向设置重力:


 if (Gdx.app.getType() == ApplicationType.Android) { gravity.x = -Gdx.input.getPitch() / 90.0f; gravity.y = Gdx.input.getRoll() / 90.0f; gravity.mul(gravityCoef); world.setGravity(gravity); } 

粒子系统


libgdx ,使用可以在编辑器中生成的特殊文件来指定粒子系统:


粒子编辑器


如您所见,此编辑器具有许多设置:您可以加载不同的纹理,更改生命周期,展开的形式,透明度和其他参数。 我制作了心形的粒子,当您点击屏幕并摧毁一颗大的物理心脏时,该粒子会出现。 在该应用程序中,使用粒子的过程如下:


初始化


 ParticleEffect effect = new ParticleEffect(); effect.load(Gdx.files.internal("data/destroy.p"), Gdx.files.internal("data")); 

生命周期的开始


重要的是不要忘记start没有start就不会显示粒子:


 effect.setPosition(.., ..); effect.start(); 

声音


声音加载如下:


 sound = Gdx.audio.newSound(Gdx.files.internal("path/to/file")); 

然后像这样播放:


 sound.play(1); 

有什么会更容易? 但是,也有陷阱。 由于某些原因,只能以OGG格式和96 kbit / s的比特率加载文件。


结论


我希望本文中介绍的技术对使用libgdx开发游戏的许多人有用。 您可以使用源代码和资源。 将情人节的申请发送给您的爱人:)


值得注意的是,可以在data/words.txt文件中更改显示在心脏上的文本。 即使没有重新编译,它也可以工作。


源代码和可执行文件


Source: https://habr.com/ru/post/zh-CN440298/


All Articles