[libGDX] Android向けの完全なゲームを作成しています。 パート2

こんにちは 記事の最初の部分が公開されてからまだ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



  //   create() public BackgroundActor background; @Override public void create() { ... background = new BackgroundActor(); background.setPosition(0, 0); ... }
      
      







次に、新しい画面ごとにシーンに追加する必要があります。



 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; //  .     xml  . public void setNote(String note) { this.note = note; } public String getNote() { return this.note; } //    ,        public void setDelay(String delay) { this.delay = Float.parseFloat(delay); } public float getDelay() { return this.delay; } //   --  public void setStar(Star star) { this.star = star; } public Star getStar() { return this.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 { // ,    private Sound sound, wrong; //     private String note; //   private Sprite img; private Texture img_texture; //  .   ,     private Level level; public Star(String str_img, String str_sound) { img_texture = new Texture("images/stars/" + str_img + ".png"); img_texture.setFilter(TextureFilter.Linear, TextureFilter.Linear); img = new Sprite(img_texture); //     ,          img.setSize(Gdx.graphics.getHeight() * 15 / 100, Gdx.graphics.getHeight() * 15 / 100); this.note = str_sound; this.sound = Gdx.audio.newSound(Gdx.files.internal("sounds/bells/" + str_sound + ".mp3")); this.wrong = Gdx.audio.newSound(Gdx.files.internal("sounds/bells/wrong.mp3")); //        ,            addListener(new ClickListener() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { img.setScale(1.2f); if (note.equals(level.getCurrentNoteStr())) { level.setCurrentNote(); Gdx.input.vibrate(25); //   ,         getSound().play(); } else { //   ,   .       .    ,     . level.setCurrentNote(0); level.setEndNote(true); level.setPlayMusic(); getWrongSound().play(); Gdx.input.vibrate(80); } return true; } @Override public void touchUp(InputEvent event, float x, float y, int pointer, int button) { img.setScale(1.0f); //      ,     ,    } }); setTouchable(Touchable.enabled); //       } public void setLevel(Level level) { this.level = level; } //      ,        @Override public void setBounds(float x, float y, float width, float height) { super.setBounds(x, y, this.img.getWidth(), this.img.getHeight()); this.img.setPosition(x, y); } //    ,    .  . @Override public void act(float delta) { img.rotate(0.05f); } //     @Override public void draw(Batch batch, float alpha) { this.img.draw(batch); } public Sound getSound() { return this.sound; } public Sound getWrongSound() { return this.wrong; } public String getNote() { return this.note; } public Sprite getImg() { return this.img; } }
      
      







次に、レベルクラスを作成します。 彼は、すべての女優と俳優を作成し、曲を演奏し、あなたの勝利を祝福する責任があります。 オブジェクトパッケージに追加しましたが、マネージャーとしてより適しているので、自分でそこに転送できます。



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")); //    public Level(String level) { xml_parse = new XMLparse(); Array<Star> xml_stars = xml_parse.XMLparseStars(); //       notes = xml_parse.XMLparseNotes(level); //     starsPos = xml_parse.getPos(level); //      endNote = 3; delay = 0; this.win = false; setPlayMusic(); for (Note n : this.notes) { for (Star s : xml_stars) { if (n.getNote().equals(s.getNote()) && !this.stars.contains(s, true)) { //    xml       ,     this.stars.add(s); } if (n.getNote().equals(s.getNote())) n.setStar(s); //          } } for (Star s : this.stars) { s.setLevel(this); s.setBounds( //    ,              (            ) Gdx.graphics.getWidth() * Float.parseFloat(starsPos.get(s.getNote()).get(0)) / 100, Gdx.graphics.getHeight() * Float.parseFloat(starsPos.get(s.getNote()).get(1)) / 100 - s.getImg().getHeight() / 2, s.getImg().getWidth(), s.getImg().getHeight() ); } } public boolean isWin() { return this.win; } //    public void setEndNote() { if (this.endNote < this.notes.size - 1) { this.endNote += 4; } } //    ,   ,   ,    . //      ,     . ! ! public void setEndNote(boolean begin) { if (begin) { this.endNote = 3; } } public void setCurrentNote(int note) { this.currentNote = note; } //    public void setCurrentNote() { if (this.currentNote < this.notes.size - 1) { this.currentNote++; if (currentNote - 1 == endNote) { currentNote = 0; setEndNote(); //    4    setPlayMusic(); //       } } else { //     ,    this.endNote = notes.size - 1; this.currentNote = 0; this.win = true; this.winner.play(); } } public int getCurrentNote() { return this.currentNote; } public String getCurrentNoteStr() { return this.notes.get(this.currentNote).getNote(); } public Array<Note> getNotes() { return this.notes; } public Array<Star> getStars() { return this.stars; } public void setPlayMusic() { if (playMusic) { playMusic = false; } else { playMusic = true; } } //      public void playStars() { if (playMusic) { for (Star s : stars) { s.setTouchable(Touchable.disabled); //      ,    } if (getCurrentNote() < notes.size) { if (getCurrentNote() <= endNote) { Note note = notes.get(getCurrentNote()); delay += note.getDelay(); // delay         if (delay >= 0.9f) note.getStar().getImg().setScale(1.2f); //        ,     if (delay >= 1.0f) { delay = 0; setCurrentNote(currentNote + 1); note.getStar().getSound().play(); note.getStar().getImg().setScale(1f); } } else { setPlayMusic(); setCurrentNote(0); } } else { delay = 0; setCurrentNote(0); setPlayMusic(); } } else { for (Star s : stars) { s.setTouchable(Touchable.enabled); //        } } } }
      
      







すべてが明確であることを願っています。 私は可能な限りコードにコメントしようとしました。 質問を引き起こす唯一のものは遅れです。 少し説明します。 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); //   pref = new GamePreferences(); level = new Level(strLevel); stars = level.getStars(); level.setCurrentNote(0); for (final Star s : stars) { stage.addActor(s); //    ()   } LabelStyle labelStyle = new LabelStyle(); labelStyle.font = game.font; // Skin  ,       Skin skin = new Skin(); TextureAtlas buttonAtlas = new TextureAtlas(Gdx.files.internal("images/game/images.pack")); skin.addRegions(buttonAtlas); TextButtonStyle textButtonStyle = new TextButtonStyle(); textButtonStyle.font = game.font; textButtonStyle.up = skin.getDrawable("button-up"); textButtonStyle.down = skin.getDrawable("button-down"); textButtonStyle.checked = skin.getDrawable("button-up"); //      ,        table = new Table(); table.padTop(20); table.center().top(); table.setFillParent(true); // label     Label label = new Label(game.langStr.get("Constellation"), labelStyle); table.add(label); table.row().padBottom(30); label = new Label(game.langStr.get("level_" + strLevel), labelStyle); table.add(label); table.setVisible(false); stage.addActor(table); table2 = new Table(); table2.center().bottom(); table2.setFillParent(true); table2.row().colspan(2).padBottom(30); label = new Label(game.langStr.get("YouWin"), labelStyle); table2.add(label).bottom(); table2.row().padBottom(20); TextButton button = new TextButton(game.langStr.get("Again"), textButtonStyle); //         () //  ,  ,    button.addListener(new ClickListener() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { Gdx.input.vibrate(20); return true; }; @Override public void touchUp(InputEvent event, float x, float y, int pointer, int button) { game.setScreen(new PlayScreen(game, sL, nL)); dispose(); }; }); table2.add(button); //          button = new TextButton(game.langStr.get("Levels"), textButtonStyle); button.addListener(new ClickListener() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { Gdx.input.vibrate(20); return true; }; @Override public void touchUp(InputEvent event, float x, float y, int pointer, int button) { game.setScreen(new LevelScreen(game)); dispose(); }; }); table2.add(button); table2.setVisible(false); stage.addActor(table2); Gdx.input.setInputProcessor(stage); Gdx.input.setCatchBackKey(true); stage.setHardKeyListener(new OnHardKeyListener() { @Override public void onHardKey(int keyCode, int state) { if (keyCode == Keys.BACK && state == 1){ game.setScreen(new LevelScreen(game)); } } }); } @Override public void render(float delta) { //        Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); //      act()    ,      (  ,   ) stage.act(delta); stage.draw(); level.playStars(); //   ,      , label'   if (level.isWin()) { table.setVisible(true); table2.setVisible(true); pref.setLevel(nL); //    .  . for (Star s : stars) { s.setTouchable(Touchable.disabled); //          } } } @Override public void resize(int width, int height) {} @Override public void show() {} @Override public void hide() {} @Override public void pause() {} @Override public void resume() {} //        MyGame @Override public void dispose() { stage.dispose(); game.dispose(); } }
      
      









新しい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>>(); //        .    ?    ! public HashMap<String, String> XMLparseLangs(String lang) { HashMap<String, String> langs = new HashMap<String, String>(); try { Element root = new XmlReader().parse(Gdx.files.internal("xml/langs.xml")); Array<Element> xml_langs = root.getChildrenByName("lang"); for (Element el : xml_langs) { if (el.getAttribute("key").equals(lang)) { Array<Element> xml_strings = el.getChildrenByName("string"); for (Element e : xml_strings) { langs.put(e.getAttribute("key"), e.getText()); } } else if (el.getAttribute("key").equals("en")) { Array<Element> xml_strings = el.getChildrenByName("string"); for (Element e : xml_strings) { langs.put(e.getAttribute("key"), e.getText()); } } } } catch (IOException e) { e.printStackTrace(); } return langs; } //      public Array<Star> XMLparseStars() { try { Element root = new XmlReader().parse(Gdx.files.internal("xml/stars.xml")); Array<Element> xml_stars = root.getChildrenByName("star"); for (Element el : xml_stars) { Star star = new Star( el.getAttribute("files"), el.getAttribute("files") ); stars.add(star); } } catch (IOException e) { e.printStackTrace(); } return this.stars; } //     public Array<String> XMLparseLevels() { Array<String> levels = new Array<String>(); Array<Integer> int_levels = new Array<Integer>(); FileHandle dirHandle; if (Gdx.app.getType() == ApplicationType.Android) { dirHandle = Gdx.files.internal("xml/levels"); } else { //  ,   libGDX -        Desktop  dirHandle = Gdx.files.internal(System.getProperty("user.dir") + "/assets/xml/levels"); } for (FileHandle entry : dirHandle.list()) { levels.add(entry.name().split(".xml")[0]); } for (int i = 0; i < levels.size; i++) { int_levels.add(Integer.parseInt(levels.get(i))); } int_levels.sort(); levels.clear(); for (int i = 0; i < int_levels.size; i++) { levels.add(String.valueOf(int_levels.get(i))); } return levels; } //   public Array<Note> XMLparseNotes(String strLevel) { try { Element root = new XmlReader().parse(Gdx.files.internal("xml/levels/" + strLevel + ".xml")).getChildByName("notes"); Array<Element> xml_notes = root.getChildrenByName("note"); for (Element el : xml_notes) { Note note = new Note(); note.setNote(el.getText()); note.setDelay(el.getAttribute("delay")); this.notes.add(note); } } catch (IOException e) { e.printStackTrace(); } return this.notes; } //    .  ,       ,        ,      public Map<String, Array<String>> getPos(String strLevel) { try { Element root = new XmlReader().parse(Gdx.files.internal("xml/levels/" + strLevel + ".xml")).getChildByName("positions"); Array<Element> xml_pos = root.getChildrenByName("position"); for (Element el : xml_pos) { Array<String> xy = new Array<String>(); xy.add(el.getAttribute("x")); xy.add(el.getAttribute("y")); this.starsPos.put(el.getAttribute("note"), xy); } } catch (IOException e) { e.printStackTrace(); } return this.starsPos; } }
      
      









少し残っています。 真実は。 さて、多言語サポートについて話したので、作成してみましょう。 ユーザーのロケールを基準として使用します。 私たちにとっては、シンボル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> <!-- Levels --> <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> <!-- Levels --> <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; //     game.manager.load("some/sounds", Sound.class); game.manager.load("some/textureatlas.pack", TextureAtlas.class); stage = new Stage(new ScreenViewport()); stage.addActor(game.background); game.getHandler().showAds(false); labelStyle = new LabelStyle(); labelStyle.font = game.levels; table = new Table(); table.setFillParent(true); label = new Label(game.langStr.get("Loading"), labelStyle); table.add(label); stage.addActor(table); } @Override public void render(float delta) { Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); stage.act(delta); stage.draw(); if (game.manager.update()) { game.setScreen(new MainMenuScreen(game)); dispose(); } }
      
      









ここで、 MyGame.javaクラスで、 MainMenuScreen.java画面の代わりにこの画面を呼び出すだけです。 それに関するドキュメントはよく書かれています。 そして、ファイルにアクセスする場所を次のように変更する必要があります。



 game.manager.get("some/file.png", TextureAtlas.class); //  TextureAtlas     .          
      
      





ゲームの開始前にすべての準備が整ったので、画面が表示されます。



起動画面
画像





また、何らかの種類のアニメーションを追加して、ゲームがロードされており、フリーズしていないことをユーザーに確実に知らせることができます。



次。 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); //    starsAtlas.findRegion("star1"),
      
      







, sperson , libGDX json :

 Skin.get(String, Class<?>);
      
      





, 1nt3g3r , xml, json. , , xml . json .



, AdMob. , , «» . . , 16 !



, Google Play. . , , , - , , . , , , Google Play. - , . , . , . .



, . FL Studio . , . Sytrus , , . , Audacity , - , , .

FreeSound . , , , .

, . ? . - , . , .




All Articles