تطبيق عيد الحب على Libgdx

كل عام هناك الكثير من المقالات المخصصة لعيد الحب. قررت أيضًا المشاركة في هذا الموضوع وإنشاء شيء أصلي وغير عادي. كانت الفكرة هي إنشاء تطبيق Android بسيط مع قلوب من شأنها أن تحتوي على نماذجها المادية وتتفاعل مع بعضها البعض. ثم أضفت النص والأصوات والجسيمات وبعض الآثار الأخرى. التطبيق الناتج كان يعمل وأصلي للغاية! في هذه المقالة سوف أصف عملية الإنشاء ، وكذلك إمكانيات مكتبة libgdx ومخاطرها .


عيد الحب قلوب .


المحتويات



البرامج والأدوات


لتطبيق هذه الفكرة ، استخدمت البرامج والمكتبات التالية:


  1. IntelliJ IDEA - هو IDE للتطبيقات عبر الأنظمة الأساسية. بدلاً من ذلك ، يمكنك استخدام Android Studio ، Eclipse .
  2. libgdx - مكتبة جافا (كمبيوتر شخصي ، Mac ، Linux ، Android) ، مكتبة جافا لتطوير الألعاب والتطبيقات الرسومية الأخرى. يتم توزيع هذه المكتبة تحت رخصة أباتشي 2.0. تم تحسين بعض مقتطفات الشفرة باستخدام JNI (على سبيل المثال ، Box2d).
  3. box2d-editor - محرر لإنشاء النماذج المادية المستخدمة في box2d المحرك box2d ، والتي بنيت في libgdx . هنا سيتم استخدامه لمطابقة صورة القلب مع نموذجها المادي.
  4. Hiero bitmap font generator - برنامج لتحويل خطوط الخطوط المتجهة إلى خطوط المسح (حيث في libgdx يتم دعم الخطوط النقطية فقط).
  5. محرر الجسيمات - محرر لإنشاء أنظمة الجسيمات ، التي طورها خالق libgdx . يتم استخدامه للجزيئات في تأثير "الانفجار" أثناء تدمير القلب.
  6. Paint.NET - محرر صور ، تم استخدامه لتحرير صورة القلب ولإنشاء الخلفية.

يتم توزيع جميع هذه البرامج والمكونات بحرية ، وهذه ميزة كبيرة. لقد اخترت libgdx ، لأنه ، أولاً ، لدي بالفعل بعض الخبرة في ذلك ، وثانياً ، باستخدام libgdx ، libgdx بحاجة إلى محاكي Android بطيء ، حيث إنه نظام أساسي مشترك ويسمح باختبار التطبيقات في بيئة Java الأصلية ثم تجميع لهم لالروبوت.


مرحبا العالم


أولاً ، سوف أخبركم بكلمات قليلة عن كيفية إنشاء مشاريع libgdx. باستخدام gdx-setup.jar ، قم بإنشاء قالب مشروع (يعتمد على Gradle) ، والذي يحدد الأنظمة الأساسية الهدف. حاليا ، ويدعم Desktop ، Android ، Ios ، Html . لكي أكون أمينًا ، فشلت في تجربة الأخيرين ، حيث أنني لا أمتلك جهازًا يعمل بنظام iOS ، وهناك بعض الصعوبات في HTML التي لم أحلها بعد.


Projectsetup


يمكنك أيضًا تحديد الامتدادات التي ستستخدمها. في حالتنا ، هذه هي مكتبة الفيزياء Box2d.


ومع ذلك ، يتم وصف كل هذا في الويكي: إنشاء مشروع libgdx .


بعد الإنشاء ، يتم إنشاء ثلاثة مجلدات:


  • الأساسية
  • سطح المكتب
  • الروبوت

في اليومين الأخيرين ، يتم وضع AndroidLauncher و AndroidLauncher على التوالي ، والتي تبدو كما يلي:


 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 (لمعالجة إدخال المستخدم).


هذا كل شيء ، الهيكل العظمي جاهز! الآن سيتم تشغيل تطبيقنا على كل من أجهزة الكمبيوتر الشخصية وأجهزة Android.


عام


يحتوي المشروع على بنية بسيطة: في فئة ValentinesDayHeatsApp ، تم إبطال أساليب touchDown dispose وطرق touchDown . تقوم طريقة create بتهيئة جميع الموارد (القوام ، الخطوط ، الجسيمات ، الأصوات) وتخلق العالم المادي. في طريقة التجسيد ، يحدث تجسيد جميع الكائنات في العالم:


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

في طريقة dispose ، يتم تحرير جميع الموارد. نعم ، نعم ، على الرغم من أن Java لديها مجموعة بيانات غير آلية ، لا تزال هناك حاجة إلى إصدار موارد غير مُدارة (كائنات Box2d وبعضها الآخر) يدويًا. يتم تشغيل طريقة touchDown خلال لمسة أو نقرة بالماوس. تعمل مثل هذه: إذا كانت نقطة اللمس تتقاطع مع القلب ، يتم حذف القلب. خلاف ذلك ، يتم إنشاء قلب جديد في نقطة اللمس. كائن Heart له الخصائص التالية:


  • Body - نموذج البدني.
  • Sprite - نموذج رسومية (العفريت).
  • String - النص المعروض على القلب.
  • Font - الخط.
  • ParticleEffect - الجزيئات التي تنشأ عند تدمير القلب.
  • BreakSound - صوت لتدمير القلب.

بعد ذلك ، سوف أصف مكونات التطبيق بمزيد من التفاصيل.


القوام


بادئ ذي بدء ، كنت بحاجة إلى إيجاد أو رسم القلب. لحسن الحظ ، لقد غوغل بسهولة ثم تحريره قليلاً: إضافة توهج وخلفية شفافة. لتحميل القوام في libgdx ، استخدمت فئة Texture . نظرًا لأنه يمكن استخدام نفس الملمس عدة مرات ، تم استخدام كائنات Sprite إضافية. تم رسمها باستخدام طريقة render . موقف العفريت والزاوية هي معالم التقديم والنموذج المادي للقلب. من أجل التغيير ، قررت أن أرسم القلوب بألوان مختلفة. لقد استخدمت لوحة HSL ، والتي تسمح بمعالجة الصبغة والتشبع والإضاءة ، وليس مكونات الألوان مثل RGB. يمكن العثور بسهولة على صيغة تحويل RGB -> HSL و HSL -> RGB ، واستخدمت الطرق من المقالة " معالجة الألوان في .NET على Java". جميع التحويلات هي في prepareHeartsTextures ، prepareHslData generateHeartTexture أساليب prepareHslData . هنا هو المثال:


 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 Bitmap Font Generator (الإصدار 5) ، الذي ينشئ صورًا لجميع الأحرف بتنسيق PNG وملف FNT ، الذي يحتوي على معلومات حول إحداثيات كل حرف في الصورة. فيما يلي لقطة شاشة لهذا البرنامج:


أداة الخط نقطية


بعد إنشاء الملفات الضرورية ، يمكن استخدام الخط في تطبيق 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 التي بدونها لن يتم عرض الجزيئات:


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

الأصوات


يتم تحميل الأصوات على النحو التالي:


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

ثم لعبت مثل هذا:


 sound.play(1); 

ما يمكن أن يكون أسهل؟ ومع ذلك ، هناك أيضا مطبات. لسبب ما ، يمكن تحميل الملفات فقط بتنسيق OGG ومعدل البت 96 كيلوبت / ثانية .


الخاتمة


آمل أن تكون التقنيات الموضحة في هذه المقالة مفيدة لكثير منكم لتطوير الألعاب باستخدام libgdx . يمكنك استخدام شفرة المصدر والموارد. إرسال طلبات لعيد الحب إلى الأحبة الخاص بك :)


تجدر الإشارة إلى أنه يمكن تغيير النص المعروض على القلوب في ملف data/words.txt . إنه يعمل حتى بدون إعادة التركيب.


شفرة المصدر والتنفيذية


Source: https://habr.com/ru/post/ar440298/


All Articles