2017-06-29 9 views
4

私のトップダウンゲームでは、敵が近くにいることを検出する敵探知機を持っています。私の問題は、どのように私のメーターバーをアニメーション化することですか?私はこのフレームワークを初めて使う人です。さんに感謝し、libgdxで敵メーター検出器を作る方法は?

プレイヤーの近くに敵を検出すると、メーターバーは敵なしでちょうど

When enemy is near the player

怒鳴る画像のスクリーンショットのようにアニメーション化します

Without enemy enter image description here

アドバンスマイコード:

//detector 
    meter_bar = new Texture("meter_bar.png"); 
    myTextureRegion = new TextureRegion(meter_bar); 
    myTexRegionDrawable = new TextureRegionDrawable(myTextureRegion); 
    actormeter_bar = new Image(myTexRegionDrawable); 
    actormeter_bar.setPosition(200,1005); 
    stage.addActor(actormeter_bar); 

    meter = new Texture("meter.png"); 
    myTextureRegion = new TextureRegion(meter); 
    myTexRegionDrawable = new TextureRegionDrawable(myTextureRegion); 
    actormetter = new Image(myTexRegionDrawable); 
    actormetter.setPosition(190,990); 
    stage.addActor(actormetter); 

プレーヤー運動(前方):

//right_control 
    right_paw = new Texture(Gdx.files.internal("right_paw.png")); 
    myTextureRegion = new TextureRegion(right_paw); 
    myTexRegionDrawable = new TextureRegionDrawable(myTextureRegion); 
    moveForward = new ImageButton(myTexRegionDrawable); //Set the button up 
    moveForward.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("right_paw.png")))); 
    //the hover 
    moveForward.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("right_paw-hover.png")))); 
    moveForward.setPosition(520,110); 
    stage.addActor(moveForward); //Add the button to the stage to perform rendering and take input. 
    Gdx.input.setInputProcessor(stage); 
    moveForward.addListener(new InputListener(){ 
     @Override 
     public void touchUp (InputEvent event, float x, float y, int pointer, int button) { 
      System.out.println("Right Button Pressed"); 
      progressKnobX = progressKnobX + 4; 

      actorprogressknob.setX(progressKnobX); // x-position to move to 
      if(progressKnobX > 418) progressKnobX= 418 ; 
      music.play(); 
      motionState=MotionState.NONE; 
     } 
     @Override 
     public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { 
      motionState=MotionState.UP; 
      return true; 
     } 
    }); 
    stage.addActor(moveForward); 

EnemySpriteムーブメント:

zombie = new Texture(Gdx.files.internal("enemy/ZombieSprite.png")); 
    zombiesprite = new Sprite(zombie); 
    zombieenemy = new Rectangle(); 
    zombieenemy.setWidth(zombiesprite.getWidth()); 

    zombieenemy = zombiesprite.getBoundingRectangle(); 
    zombieenemy.x = zombieX; 
    zombieenemy.y = zombieY; 
    TextureRegion[][] zom = TextureRegion.split(zombie, zombie.getWidth()/Zombie_FRAME_COLS, zombie.getHeight()/Zombie_FRAME_ROWS); 
    TextureRegion[] zwalkFrames = new TextureRegion[Zombie_FRAME_COLS * Zombie_FRAME_ROWS]; 
    index = 0; 
    for (int i = 0; i < Zombie_FRAME_ROWS; i++) { 
     for (int j = 0; j < Zombie_FRAME_COLS; j++) { 
      zwalkFrames[index++] = zom[i][j]; 
     } 
    } 
    zombiewalkAnimation = new Animation<TextureRegion>(0.120f, zwalkFrames); 

MoveForwardボタン機能:

//button functions 
MotionState motionState=MotionState.NONE; 
enum MotionState { 
    NONE { 
     @Override 
     public boolean update(Rectangle player) { 
      return true; 
     } 
    }, 
    UP { 
     @Override 
     public boolean update(Rectangle player) { 
      player.y += 300 * Gdx.graphics.getDeltaTime(); 
      return false; 
     } 
    }, 
    DOWN{ 
     @Override 
     public boolean update(Rectangle player) { 
      player.y -= 300 * Gdx.graphics.getDeltaTime(); 
      return false; 
     } 
    }, 
    LEFT{ 
     @Override 
     public boolean update(Rectangle player) { 
      player.x -= 100 * Gdx.graphics.getDeltaTime(); 
      return false; 
     } 
    }, 
    RIGHT{ 
     @Override 
     public boolean update(Rectangle player) { 
      player.x += 100 * Gdx.graphics.getDeltaTime(); 
      return false; 
     } 
    }; 
    public abstract boolean update(Rectangle player); 
} 
私は物事がどのように見える道は非常に厄介であり、あなたが維持するために一生懸命になりますので、あなたが Libgdx extension Ashleyを使用することを学ぶお勧めしたいと思い、あなたの最初の質問に答える前に

if(Gdx.input.isKeyPressed(Input.Keys.DOWN)) motionState = MotionState.DOWN; 
    if(Gdx.input.isKeyPressed(Input.Keys.UP)) motionState=MotionState.UP; 
    if(Gdx.input.isKeyPressed(Input.Keys.LEFT)) motionState=MotionState.LEFT; 
    if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)) motionState=MotionState.RIGHT; 

    if(motionState.update(player)) motionState=MotionState.NONE; 


    if(player.y> 1910){ 
     zombieenemy.y -= 60 * Gdx.graphics.getDeltaTime(); 
    } 

答えて

3

をレンダリングします。

私の答え:

は、内のすべてのあなたのゲームの敵とArrayListの<>または類似したデータモデルを保持し、その後、私たちは、それぞれ1を反復処理し、それが位置だ取得し、プレイヤーに距離を計算します。

Enemy closestEnemy = null; 
float closestEnemyDist = -1; 

for(Enemy enemy : ListOfEnemies){ 
    /* here we find the distance to the player */ 
    float distToPlayer = Math.sqrt((enemy.y-player.x)^2 + (enemy.y-player.y)^2); 

    /* initiate closestEnemyDist for the first time */ 
    if(closestEnemyDist == -1){ 
     closestEnemyDist = distToPlayer; 
    } 

    /* we find the closest distance to the player */ 
    float minDist = Math.min(closestEnemyDist, distToPlayer); 

    /* we make sure it is the closest and save the closest enemy as well */ 
    if(minDist <= closestEnemyDist){ 
     closestEnemyDist = minDist; 
     closestEnemy = enemy; 
    } 
} 

これはあなたに最も近い敵とそれの距離を与える、あなたが希望ならば、あなたはすべてのゲームの更新このコードを実行することができ、それの方法を作るか、単に距離を得ることができます。

距離計は:

ここで我々はつもりのあなたのメーターが割合を示しているとしましょう... 0%から100%まで、小さな数学を行う、あなたは最大距離を選択する必要があり、あなたのメーターが0%を考慮して(敵がそれをmaxDistanceと呼んでいることを意味します)、これは距離が100であることを容易に理解し、この方法を見てください。これはあなたを助け

public int calcMeter(float closestEnemyDist, float maxDistance) { 
    int meter = 0; 

    /* calculate only if enemy is in range */ 
    if(closestEnemyDist < maxDistance){ 
     /* using rounding and multiply by 100f because we wanted 
     * values from 0 - 100, you can can modify this to work just 
     * with float from 0 - 1f 
     */ 
     meter = Math.round(
      /* 
      * here we flip the percentage so if the enemy is very 
      * close then your meter will be higher 
      */ 
      (1f - (closestEnemyDist/maxDistance)) * 100f 
     ); 
    } 
    return meter; 
} 

希望、グッドラック:)

+0

あなたにサー@Ariel Yustをありがとう、私はあなたを助けるために喜んで、あなたのコードとlibgdxのアシュリーのAPI – jaZzZ

+0

@jaZzZを試してみてくださいウィル!これがあなたの問題を解決するならば、答えとしてマークしてください。 –

0

私はメータークラスを作成するStackクラスを使用します。メーター画像は透明でなければならず、バー画像はアニメーションである必要があります。スタックアクタは画像を重ねて重ねて表示できます。メータークラスは次のとおりです。

public class Meter extends Stack { 

    private Animation<Drawable> animation; 
    private Image bar; 

    public Meter(Skin skin){ 

     Array<Drawable> drawables = new Array<Drawable>(); 

     for (int i = 0; i < TestScreen.LENGTH; ++i){ 
      drawables.add(skin.getDrawable(TestScreen.BAR + Integer.toString(i))); 
     } 

     animation = new Animation<Drawable>(1f, drawables); 
     bar = new Image(animation.getKeyFrame(0f)); 
     addActor(bar); 
     addActor(new Image(skin.getDrawable(TestScreen.METER))); 
     setTouchable(Touchable.disabled); 
    } 

    /** 
    * Set the "hotness" of the meter. 
    * @param value float between 0 and 1 
    */ 
    public void setValue(float value){ 

     // actions are the default way to animate simple effects to the actors 
     // this is just to add a pop in effect when you have a really smooth animation this isn't really necessary 
     bar.addAction(Actions.sequence(
      Actions.alpha(0), 
      Actions.fadeIn(0.01f, Interpolation.smooth) 
     )); 

     // set the new image to the value percentage 
     bar.setDrawable(animation.getKeyFrame(value * animation.getAnimationDuration())); 
     bar.setSize(bar.getPrefWidth(), bar.getPrefHeight()); 
    } 
} 

アクターを設定するためにスキンを使用するステージクラスです。

public class MyStage extends Stage { 

    public Meter meter; 

    public MyStage(Skin skin){ 

     super(); 

     meter = new Meter(skin); 

     Table table = new Table(skin); 
     table.setFillParent(true); 
     table.setOrigin(Align.top); 
     table.add(meter).width((1/10f) * Gdx.graphics.getWidth()); 

     addActor(table); 
    } 
} 

スキンを作成し、そこにすべてのUIリソースを配置することをお勧めします。 TextureAtlasオブジェクトのファイルからロードし、そのオブジェクトをスキンに渡します。私はシンプルなアニメーションを作成しましたが、これはちょうど例として正しくスケールされません。画面オブジェクトやゲームオブジェクトでは:

private MyStage myStage; 

@Override 
public void show(){ 

    Skin skin = new Skin(); 
    skin.add(METER, new TextureRegionDrawable(new TextureRegion(meter_texture)), Drawable.class); 

    float w = meter_bar_texture.getWidth()/(float) LENGTH; 

    for (int i = 0; i < LENGTH; ++i){ 
     TextureRegion region = new TextureRegion(meter_bar_texture, 0, 0, (int)(i * w), meter_bar_texture.getHeight()); 

     skin.add(BAR + Integer.toString(i), new TextureRegionDrawable(region), Drawable.class); 
    } 

    this.myStage = new MyStage(skin); 
} 

@Override 
public void hide() { 

    super.hide(); 

    this.meter_bar_texture.dispose(); 
    this.meter_texture.dispose(); 
} 

@Override 
public void update(float delta) { 

    if (dangerIncreased() && value < 100){ 
     danger += 5; 

     this.myStage.meter.setValue(danger/100f); 
    } else if (dangerDecreased() && danger > 0){ 
     danger -= 5; 

     this.myStage.meter.setValue(danger/100f); 
    } 

    this.myStage.act(delta); 
} 

public static final String METER = "meter"; 
public static final String BAR = "bar"; 
public static final int LENGTH = 10; 
関連する問題