2017-01-05 9 views
1

私はLibGdxを教えていて、シンプルなゲームのチュートリアルに従っていましたが、残念なことに大部分のコードは1つのクラスに含まれています。コードをリファクタリングして、乱数に基づく雨のために複数のテクスチャを使用することができます。Libgdxテクスチャを持つクラスをリファクタリングする

メインプログラムのコードを添付してから、クラスを開始します。

これまでのところRainのテクスチャ以外はすべて機能していました。/ imgは画面に表示されません。

public class GameScreen implements Screen { 
    public static FruitHarvest game; 
    protected final Texture dropImage; 
    //protected final Texture dropImage2; 
    private final Texture bucketImage; 
    public static Rectangle bucket; 
    public static Sound dropSound; 
    //private static Music rainMusic; 
    private final OrthographicCamera camera; 
    public static Array<Rectangle> raindrops; 
    private long lastDropTime; 
    public static int dropsGathered; 
    // private int random = MathUtils.random(0,1); 
    private Drops drop; 
    //Iterator<Rectangle> iterator = raindrops.iterator(); 

    public GameScreen(final FruitHarvest game) { 
     this.game = game; 


     // load the images for the droplet and the bucket, 64x64 pixels each 
     dropImage = new Texture(Gdx.files.internal("droplet.png")); 
     //dropImage2 = new Texture(Gdx.files.internal("droplet1.png")); 
     bucketImage = new Texture(Gdx.files.internal("bucket.png")); 

     // load the drop sound effect and the rain background "music" 
     dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav")); 
     //rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3")); 
     //rainMusic.setLooping(true); 

     // create the camera and the SpriteBatcher 
     camera = new OrthographicCamera(); 
     camera.setToOrtho(false, 800, 480); 

     // create a Rectangle to logically represent the bucket 
     bucket = new Rectangle(); 
     bucket.x = 800/2 - 64/2; // Center the bucket horizontally 
     bucket.y = 20; // Bottom left corner of the bucket is 20 pixels above the bottom screen edge; 
     bucket.width = 64; 
     bucket.height = 64; 

     // Create the raindrops array and spawn the first raindrop 
     raindrops = new Array<Rectangle>(); 

     long delta = 0; 
     drop = new Drops(dropImage, 64, 64, raindrops, delta); 
    } 

    @Override 
    public void render(float delta) { 
     // clear the screen with a dark blue color. The arguments to glClearColor are the 
     // red, green, blue, and alpha component in the range [0,1] of the color to be 
     // used to clear the screen 
     Gdx.gl.glClearColor(0, 0, .5f, 1); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 

     // tell the camera to update its matrices. 
     camera.update(); 

     // tell the SpriteBatch to render in the coordinate system specified by the camera. 
     game.batch.setProjectionMatrix(camera.combined); 

     // begin a new batch and draw the bucket and all drops 
     game.batch.begin(); 
     game.font.draw(game.batch, "Drops collected: " + dropsGathered, 0, 480); 
     game.batch.draw(bucketImage, bucket.x, bucket.y, bucket.width, bucket.height); 

     // Draws the Items Falling 
     for (Rectangle raindrop : raindrops) { 
      game.batch.draw(dropImage, raindrop.x, raindrop.y); 
     } 
     game.batch.end(); 

     // process user input 
     if (Gdx.input.isTouched()) { 
      Vector3 touchPos = new Vector3(); 
      touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0); 
      camera.unproject(touchPos); 
      bucket.x = touchPos.x - 64/2; 
     } 
     if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) bucket.x -= 200 * Gdx.graphics.getDeltaTime(); 
     if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) bucket.x += 200 * Gdx.graphics.getDeltaTime(); 

     // make sure the bucket stays within the screen bounds 
     if (bucket.x < 0) bucket.x = 0; 
     if (bucket.x > 800 - 64) bucket.x = 800 - 64; 

     // check if we need to create a new raindrop 
     if (TimeUtils.nanoTime() - drop.getLastDropTime() > 1000000000) { 
      drop.spawnRaindrop(); 
     } 

     // move the raindrops, remove any that are beneath the bottom edge of the screen 
     // or that hit the bucket. In the later case we increase the value our drops counter 
     // and add a sound effect. 
     Iterator<Rectangle> iter = raindrops.iterator(); 
     drop.update(delta); 
//  while (iter.hasNext()) { 
//   Rectangle raindrop = iter.next(); 
//   raindrop.y -= 200 * Gdx.graphics.getDeltaTime(); 
//   if (raindrop.y + 64 < 0) iter.remove(); 
//   if (raindrop.overlaps(bucket)) { 
//    dropsGathered++; 
//    dropSound.play(); 
//    iter.remove(); 
//   } 
//  } 
    } 

    private void spawnRaindrop() { 
     Rectangle raindrop = new Rectangle(); 
     raindrop.x = MathUtils.random(0, 800 - 64); 
     raindrop.y = 480; 
     raindrop.width = 64; 
     raindrop.height = 64; 
     raindrops.add(raindrop); 
     lastDropTime = TimeUtils.nanoTime(); 
    } 

// public void randomDrop(int value, float dropX, float dropY) { 
//  switch (value) { 
//   case 0: 
//    game.batch.draw(dropImage, dropX, dropY); 
//    break; 
//   case 1: 
//    //game.batch.draw(dropImage2, dropX, dropY); 
//    break; 
//   default: 
//    game.batch.draw(dropImage, dropX, dropY); 
//    break; 
//  } 
// } 

    @Override 
    public void resize(int width, int height) { 

    } 

    @Override 
    public void show() { 
     // start the playback of the background music when the screen is shown 
     //rainMusic.play(); 
    } 

    @Override 
    public void hide() { 
    } 

    @Override 
    public void pause() { 
    } 

    @Override 
    public void resume() { 
    } 

    @Override 
    public void dispose() { 
     dropImage.dispose(); 
     bucketImage.dispose(); 
     dropSound.dispose(); 
     //rainMusic.dispose(); 
    } 
} 

相続人は、あなたのドロップクラスでArray<Rectangle> raindrops;に滴を追加drop.spawnRaindrop();ではなく、あなたが

for (Rectangle raindrop : raindrops) { 
     game.batch.draw(dropImage, raindrop.x, raindrop.y); 
    } 

がループトラフraindrop配列リストを使用して描画するための滴

public class Drops { 
    private Rectangle raindrop; 
    private int imageHeight, imageWidth, x, y; 
    private Array<Rectangle> raindrops; 
    private long lastDropTime; 
    private Texture dropImage = new Texture(Gdx.files.internal("droplet.png")); 
    Iterator<Rectangle> iter = GameScreen.raindrops.iterator(); 
    private float runTime = 0; 

    public Drops(Texture img, int imageHeight, int imageWidth, Array<Rectangle> drop, float delta) { 
     this.imageHeight = imageHeight; 
     this.imageWidth = imageWidth; 
     this.raindrops = drop; 
     this.dropImage = img; 
    } 

    public void update(float delta) { 
     while (iter.equals(true)) { 
      raindrop = iter.next(); 
      raindrop.y -= 200 * Gdx.graphics.getDeltaTime(); 
      if (raindrop.y + 64 < 0) iter.remove(); 
      onCollision(); 
     } 

    } 

    public void onCollision() { 
     if (raindrop.overlaps(bucket)) { 
      GameScreen.dropsGathered++; 
      GameScreen.dropSound.play(); 
      iter.remove(); 
     } 
    } 

    public void spawnRaindrop() { 
     Rectangle raindrop = new Rectangle(); 
     raindrop.x = MathUtils.random(0, 800 - 64); 
     raindrop.y = 480; 
     raindrop.width = imageWidth; 
     raindrop.height = imageHeight; 
     raindrops.add(raindrop); 
     lastDropTime = TimeUtils.nanoTime(); 

    } 

    public long getLastDropTime() { 
     return lastDropTime; 
    } 

} 
+1

実際に何が間違っているかを明確にする必要があります。 「テクスチャが読み込まれていません」とは、検証可能な特定の問題のようには聞こえません。ところで、コンストラクタの前にロードしている最初の 'dropImage'がリークしています。 – Tenfour04

+0

Rainテクスチャは画面に表示されません。コンストラクタの前に "dropImage"がどのように漏れているかを明確にすることはできますか?私はまだJavaとLibGdxでプログラミングするのが初めてです – crazydaze

+0

Dropsクラスのドロップ方法のレンダリング方法はどこですか? DropsクラスにDropsのテクスチャを描画する必要があります。 – Aryan

答えて

0

のための私のクラスあなたのGameScreenは空です。

したがって、配列リストをドロップして描画するか、GameScreenで配列リストを作成してください。

+0

あなたの提案をありがとう。私はそれを考慮に入れます。 – crazydaze

0

リファクタリング時にはさらに注意する必要があります。スクリーンクラスの元の配列のドロップした四角形を残して、それを描画しています(空の状態です)。あなたのDropsクラスでは、画面クラスで現在は役に立たない配列のイテレータを参照しています。そして、画面のrenderメソッドで空の配列を更新しています。

基本的に、ドロップは1か所で処理する必要がありますが、2つの異なるクラスのドロップの冗長な配列を処理し、それらをすべて混在させることになります。

バケツとの衝突を処理しようとするDropsというクラスがあるのは私には分かりません。トップレベルのゲームロジックを別のクラスに移動する理由はありません。コードを複雑にするだけです。もっと複雑なゲームをしていた場合は、ゲームのさまざまな側面を追跡して更新するための別々のクラスを持つことが理にかなっています。あなたは、コンストラクタで別のもので、参照を交換する前に、それを処分することはありませんので、

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

ところで、あなたは、この行で読み込むテクスチャをリークしています。 LibGDXでは、Disposableを実装しているオブジェクトは、その参照が失われる前に処理する必要があります。そうしないと、ネイティブメモリがリークします。

ストレートフォワードな方法

は、複数のドロップ画像を許可する:

1)画面クラス内のすべてのゲームロジックとバックあなたの元の単一のクラスに移動します。

2)簡単にアクセスできるように、ドロップイメージをアレイに読み込みます。

private final Array<Texture> dropImages = new Array<Texture>(); // replaces your dropImage declaration 

//... 

// in constructor: 
dropImages.add(new Texture(Gdx.files.internal("droplet.png"))); 
dropImages.add(new Texture(Gdx.files.internal("droplet1.png"))); 
// etc. as many variations as you like 

// don't forget to dispose of them: 
@Override 
public void dispose() { 
    for (Texture dropImage : dropImages) dropImage.dispose(); 
    bucketImage.dispose(); 
    dropSound.dispose(); 
} 

3)Rectを拡張し、画像タイプの追加パラメータを持つDropクラスを作成します。また、TextureAtlasを使用していないのでバッチフラッシュを発生させるので、それらを描画するときにテクスチャを複数回スワップするのを避けるために、これらをイメージインデックスでソート可能にしたいと思うかもしれません。

public class Drop extends Rectangle implements Comparable<Drop>{ 

    public int imageIndex; 

    public Drop(){ 
     super(); 
    } 

    public int compareTo(Drop otherDrop) { 
     return (int)Math.signum(imageIndex - otherDrop.imageIndex); 
    } 

} 

4)あなたのArray<Rectangle>Array<Drop>に変更してください。

private void spawnRaindrop() { 
    Drop raindrop = new Drop(); 
    raindrop.x = MathUtils.random(0, 800 - 64); 
    raindrop.y = 480; 
    raindrop.width = 64; 
    raindrop.height = 64; 
    raindrop.imageIndex = MathUtils.random(dropImages.size); // <-- HERE 
    raindrops.add(raindrop); 
    lastDropTime = TimeUtils.nanoTime(); 
} 

5)あなたの滴を描くとき、​​正しいテクスチャを引っ張って、ドロップのパラメータ:imageIndexを使用する:あなたがドロップを起動すると、また、それをランダムな画像のインデックスを与えます。テクスチャを前後に入れ替えるのを避けるために、最初に並べ替えることができます。

// Draws the Items Falling 
raindrops.sort(); 
for (Drop raindrop : raindrops) { 
    game.batch.draw(dropImages.get(raindrop.imageIndex), raindrop.x, raindrop.y); 
} 
+0

あなたの有益なポストをありがとう、私は間違いなくあなたが作った提案を検討します。 私がこのクラスをリファクタリングする理由は、より大きく複雑なゲームを作る計画を立てているからです。しかし、私は経験やリファクタリングコードを単純なもので最初にやっていたので、私にとってはまったく混沌とはなりませんより大きなプロジェクトで作業してください。 – crazydaze

+0

わかりやすくするために、私は既にDrops()クラスを持っています。 「Drop()クラスを作成する」と言うと、新しいクラスをまとめて参照するか、現在のDrops()クラスを参照しています。 – crazydaze

関連する問題