こんにちは 記事の
最初の部分が公開されてからまだ1日も経っていません。未完成のビジネスがあり、記事を追加する必要があるため、眠れません。 始めましょう。
また予約します。 私はJavaについてあまり詳しくないので、次のコードは多くの人にとって混乱を招く可能性がありますが、1週間も経たないうちにゲームを作成し、コードの美しさと品格よりも結果に重点を置きました。 コメントには、プロジェクトのコードと構造を完成させるのを手伝ってくれる人がいて、完璧ではないにしても、少なくとも見栄えにつながり、私や他の人がより良いプログラマになる機会を与えることを願っています。 さて、十分な歌詞、「ハードコア」を続けましょう。
新しい
パッケージを作成し、
objectsという名前を付け
ます 。 その中にバックグラウンドクラスを作成し、次のコードを追加します。
BackgroundActor.javaファイルpackage ru.habrahabr.songs_of_the_space.objects; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.scenes.scene2d.Actor; public class BackgroundActor extends Actor { private Texture backgroundTexture; private Sprite backgroundSprite; public BackgroundActor() { backgroundTexture = new Texture("images/sky.jpg"); backgroundSprite = new Sprite(backgroundTexture); backgroundSprite.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); } @Override public void draw(Batch batch, float alpha) { backgroundSprite.draw(batch); } }
複雑なことは何もありません。 これは、ユーザーの画面に合わせて設定され、ゲームをより星空のようにする「俳優」です。 次のようになります。
次のすべての画面で作成しないように、
MyGame.javaに追加し、外部からアクセスできるようにします。 これはちらつきから私たちを救います。
ファイルMyGame.java
次に、新しい画面ごとにシーンに追加する必要があります。
stage.addActor(game.background);
次に、
オブジェクトパッケージでも、ノートクラスを作成します。 彼はすべてのノートを必要な順序で保存します。
ファイルNote.java package ru.habrahabr.songs_of_the_space.objects; public class Note { private String note; private float delay; private Star star;
メモを作成したので、宇宙シーンの主役となるスターを作成する必要があります。 彼女は明滅し、将来のユーザーのために素晴らしいメロディーを歌います。
続行する前に、メモとスター用に別のクラスが必要な理由を少し説明します。 メロディーは音符を繰り返すことができ、各星は単一のコピーにある必要があります。 ゲームのアイデアについて考えていたとき、私はすべてのメモを星の中に入れました。 その結果、メロディーが単純すぎるか、空に星が多すぎて、8音を繰り返してもレベルを渡すことが困難でした。
だから、星を作成します。
Star.javaファイル
package ru.habrahabr.songs_of_the_space.objects; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureFilter; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Touchable; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; public class Star extends Actor {
次に、レベルクラスを作成します。 彼は、すべての女優と俳優を作成し、曲を演奏し、あなたの勝利を祝福する責任があります。
オブジェクトパッケージに追加しましたが、マネージャーとしてより適しているので、自分でそこに転送できます。
Level.javaファイル
package ru.habrahabr.songs_of_the_space.objects; import java.util.HashMap; import java.util.Map; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.scenes.scene2d.Touchable; import com.badlogic.gdx.utils.Array; public class Level { private XMLparse xml_parse; private Array<Note> notes = new Array<Note>(); private Array<Star> stars = new Array<Star>(); private Map<String, Array<String>> starsPos = new HashMap<String, Array<String>>(); private int currentNote; private int endNote; private float delay; private boolean playMusic; private boolean win; private final Sound winner = Gdx.audio.newSound(Gdx.files.internal("sounds/win.mp3"));
すべてが明確であることを願っています。 私は可能な限りコードにコメントしようとしました。 質問を引き起こす唯一のものは
遅れです。 少し説明します。
playStars()メソッドは、
PlayScreen.javaクラスの
render()メソッドで呼び出され
ます 。 スレッドで実行されるため、すべての条件が
満たされるたびに、指定された量だけ
遅延が増加します。 したがって、ノートの演奏の遅延がシミュレートされます。 これは、コードで最もよく見られます。 最後にPlayScreen.javaクラスにデータを入力しましょう。 たくさんのコードがあるので、私はそれをネタバレの下に隠すことにしました。
ファイルPlayScreen.java package ru.habrahabr.songs_of_the_space.managers; import ru.habrahabr.songs_of_the_space.MyGame; import ru.habrahabr.songs_of_the_space.objects.GamePreferences; import ru.habrahabr.songs_of_the_space.objects.Level; import ru.habrahabr.songs_of_the_space.objects.PlayStage; import ru.habrahabr.songs_of_the_space.objects.PlayStage.OnHardKeyListener; import ru.habrahabr.songs_of_the_space.objects.Star; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.Screen; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Touchable; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.viewport.ScreenViewport; public class PlayScreen implements Screen { final MyGame game; private GamePreferences pref; private Level level; private String sL, nL; private Array<Star> stars; private PlayStage stage; private Table table, table2; public PlayScreen(final MyGame gam, String strLevel, String strNextLevel) { game = gam; this.sL = strLevel; this.nL = strNextLevel; stage = new PlayStage(new ScreenViewport()); stage.addActor(game.background);
新しい
GamePreferences.javaクラスに気付くように、コードはおそらくいくつかの質問を提起しまし
た 。 このクラスにより、すべてのゲーム設定を便利な形式で保存できます。 Androidアプリケーションの場合、いわゆる
「SharedPreferences」が作成されます。 詳細は
こちら 。 この場合、ユーザーから渡されたレベルを保存します。
まあ何? それを作成して入力しましょう。
GamePreferences.javaファイル package ru.habrahabr.songs_of_the_space.objects; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Preferences; public class GamePreferences { private Preferences pref; private static final String PREFS_NAME = "SONGS_OF_THE_SPACE"; private static final String PREF_LEVEL = "LEVEL_"; public GamePreferences() { pref = Gdx.app.getPreferences(PREFS_NAME); } public boolean getLevel(String level) { pref.putBoolean(PREF_LEVEL + 1, true); pref.flush(); return pref.getBoolean(PREF_LEVEL + level, false); } public void setLevel(String level) { pref.putBoolean(PREF_LEVEL + level, true); pref.flush(); } }
複雑なことは何もありません。 私はドキュメントを複製しません、それへのリンクを下に与えました。 ここで、
XMLparse.javaクラスを
少し更新する必要があり
ます 。 そのため、解析用の星とメモをまだ教えていません。 やってみましょう。
XMLparse.javaファイル package ru.habrahabr.songs_of_the_space.objects; import java.io.IOException; import java.util.HashMap; import java.util.Map; import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.XmlReader; import com.badlogic.gdx.utils.XmlReader.Element; public class XMLparse { private Array<Star> stars = new Array<Star>(); private Array<Note> notes = new Array<Note>(); private Map<String, Array<String>> starsPos = new HashMap<String, Array<String>>();
少し残っています。 真実は。 さて、多言語サポートについて話したので、作成してみましょう。 ユーザーのロケールを基準として使用します。 私たちにとっては、シンボル
ruで始まり、英語では
enで始まります。 アプリケーションを2つの言語に翻訳したので、言語ファイルは次のようになります(したがって、
XMLparseLangsメソッドコードに少し奇妙な条件があります)。
Langs.xmlファイル <?xml version="1.0"?> <langs> <lang key="en"> <string key="Play">Play</string> <string key="Exit">Exit</string> <string key="Again">Again</string> <string key="Levels">Levels</string> <string key="YouWin">You win!</string> <string key="Constellation">Constellation</string> <string key="level_1">Canes Venatici</string> <string key="level_2">Triangulum</string> <string key="level_3">Equuleus</string> <string key="level_4">Apus</string> <string key="level_5">Sagitta</string> <string key="level_6">Musca</string> <string key="level_7">Ursa Minor</string> <string key="level_8">Orion</string> <string key="level_9">Ursa Major</string> <string key="level_10">Eridanus</string> <string key="level_11">Lacerta</string> </lang> <lang key="ru"> <string key="Play"></string> <string key="Exit"></string> <string key="Again"></string> <string key="Levels"></string> <string key="YouWin"> !</string> <string key="Constellation"></string> <string key="level_1"> </string> <string key="level_2"></string> <string key="level_3"> </string> <string key="level_4"> </string> <string key="level_5"></string> <string key="level_6"></string> <string key="level_7"> </string> <string key="level_8"></string> <string key="level_9"> </string> <string key="level_10"></string> <string key="level_11"></string> </lang> </langs>
ご覧のとおり、属性を取得し、その属性に基づいてユーザーに与えるものを決定します。 今、私たちは別のことをする必要があります。 星、メモ、レベルのXMLファイルを作成します。 やってみましょう。
Stars.xmlファイル <?xml version="1.0"?> <stars> <star files="c5" /> <star files="c#5" /> <star files="d5" /> <star files="d#5" /> <star files="e5" /> <star files="f5" /> <star files="f#5" /> <star files="g5" /> <star files="g#5" /> <star files="a5" /> <star files="a#5" /> <star files="b5" /> <star files="c6" /> <star files="c#6" /> <star files="d6" /> <star files="d#6" /> <star files="e6" /> <star files="f6" /> <star files="f#6" /> <star files="g6" /> <star files="g#6" /> <star files="a6" /> <star files="a#6" /> <star files="b6" /> </stars>
このファイルを見ると、各音符に星があると言ったとき、彼は少しずるいことがわかりました。 異なるキーで星の異なる表現を作成しました。 なんで? サウンドを改善するには、多かれ少なかれ面白い星座を取ると、少なくとも8〜9個の星で構成されていることがわかります。別のオクターブを追加して、生活を簡素化します。
ここで、(たとえば)レベルのファイルを提供します。
1.xmlファイル <?xml version="1.0"?> <level> <notes> <note delay="0.02f">d5</note> <note delay="0.05f">a6</note> <note delay="0.05f">d6</note> <note delay="0.05f">f#6</note> <note delay="0.02f">e5</note> <note delay="0.05f">a6</note> <note delay="0.05f">c#6</note> <note delay="0.05f">e6</note> <note delay="0.02f">d6</note> <note delay="0.05f">f#6</note> <note delay="0.05f">a6</note> <note delay="0.05f">d5</note> </notes> <positions> <position note="d5" x="5" y="35" /> <position note="a6" x="20" y="43" /> <position note="d6" x="40" y="50" /> <position note="f#6" x="55" y="45" /> <position note="e5" x="67" y="37" /> <position note="c#6" x="77" y="47" /> <position note="e6" x="90" y="50" /> </positions> </level>
ご覧のとおり、最初に音符のシーケンスとその遅延を決定し、次に各固有音符の位置をパーセンテージで決定します。 それがすべてのようです。 何かを忘れた場合は、コメントを待っています。 また、私は批判とアドバイスを楽しみにしています。 次の記事に興味がある人は、AdMobをゲームに接続するプロセスを説明し、ゲームのサウンドを取得した方法と場所を教えてください。また、Google Playでのゲームのレイアウトについても説明します。 ご清聴ありがとうございました!
プロジェクトファイルと完成したゲームの例。更新 投稿全体に十分な資料がなかったため、新しい投稿を作成しないことにしました。そこで、ここにいくつか修正を残します。
エラーと修正まず第一に、zig1375
habrayuzerはAssetManagerを使用するのが良いと書いています。 レベルを選択した後、ゲームがしばらくフリーズするように見えるため、これは本当に公正な発言です。その結果、ゲームがハングしていたのかロードしていたのかは完全にはわかりません。 この問題を次のように解決しました。 まず、
MyGame.javaクラスで、
AssetManagerタイプのオブジェクトを作成し、公開します。 次に、新しい画面を作成し、LoaderScreen.javaという名前を付けて、次のように書き込みます。
ファイルLoaderScreen.java package ru.habrahabr.songs_of_the_space.managers; import ru.habrahabr.songs_of_the_space.MyGame; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Screen; import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.utils.viewport.ScreenViewport; public class LoaderScreen implements Screen { private MyGame game; private Stage stage; private Table table; private LabelStyle labelStyle; private Label label; public LoaderScreen(MyGame gam) { game = gam;
ここで、
MyGame.javaクラスで、
MainMenuScreen.java画面の代わりにこの画面を呼び出すだけです。 それ
に関するドキュメントはよく書かれています。 そして、ファイルにアクセスする場所を次のように変更する必要があります。
game.manager.get("some/file.png", TextureAtlas.class);
ゲームの開始前にすべての準備が整ったので、画面が表示されます。
また、何らかの種類のアニメーションを追加して、ゲームがロードされており、フリーズしていないことをユーザーに確実に知らせることができます。
次。 1nt3g3r
habrayuzerからのコメントになり
ました 。 彼は、すべてのテクスチャを1つのファイルにまとめる方が良いと書いています。 私はボタンでこれをしましたが、星とするのを忘れましたが、無駄でした。 パッケージについてはlibGDXの
ドキュメントで読むことができますが、このソリューションの利点の一部のみを説明します。 -, , 300 , . -, , , . ? . libGDX - :
java -cp gdx.jar:extensions/gdx-tools/gdx-tools.jar com.badlogic.gdx.tools.texturepacker.TexturePacker inputDir [outputDir] [packFileName]
, region :
starsAtlas = manager.get("images/stars/stars.pack", TextureAtlas.class);
,
sperson , libGDX json :
Skin.get(String, Class<?>);
,
1nt3g3r , xml, json. , , xml . json
.
, AdMob. ,
, «» . . , 16 !
, Google Play. . , , , - , , . , , , Google Play. - , . , . , .
.
, .
FL Studio . , .
Sytrus , ,
. ,
Audacity , - , , .
FreeSound . , , , .
, . ? . - , . , .