¿Cómo hacer detector de contador enemigo en libgdx?

En mi juego de arriba abajo, tengo un detector de enemigos para detectar el enemigo está cerca. Mi problema es ¿cómo puedo crear animar mi barra de medidor con la transición? Soy nuevo en este marco. Gracias y Avance

Cuando el jugador detecta al enemigo cerca, la barra del medidor se animará igual que la imagen que se muestra abajo

Cuando el enemigo está cerca del jugador

Sin enemigo

Sin enemigo Introduzca aquí la descripción de la imagen

Mi código:

//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); 

Movimiento del jugador (adelante):

 //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 Movimiento:

  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); 

Botón MoveForward Función:

 //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); } 

Hacer

  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(); } 

Antes de responder a su pregunta inicial, me gustaría sugerirle que aprenda a usar la extensión de Libgdx, Ashley, porque la forma en que se ven las cosas es muy complicada y le resultará difícil de mantener.

Mi respuesta:

Mantenga un ArrayList <> o un modelo de datos similar con todos sus enemigos de juego dentro, entonces vamos a iterar a través de cada uno y obtener su posición y calcular la distancia al jugador.

 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; } } 

Esto le da el enemigo más cercano y su distancia, puede hacer un método de la misma o obtener sólo la distancia si lo desea, puede ejecutar este código cada actualización del juego.

El medidor de distancia:

Aquí vamos a hacer una pequeña matemática, digamos que su medidor muestra porcentajes … de 0% a 100%, debe elegir la distancia máxima que su medidor considera 0% (lo que significa que el enemigo está muy lejos llamarlo maxDistance), para que usted Fácilmente entender esto imaginar que la distancia es de 100 y mirar a este método.

 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; } 

Espero que esto te ayude, buena suerte 🙂

Utilizo la clase Stack para crear la clase Meter. La imagen del medidor necesita ser transparente y la imagen de la barra debe ser una animación. Stack Actor puede superponer las imágenes y hacer que una encima de la otra. Aquí está la clase Meter:

 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() ); } } 

Clase de escenario que utiliza la piel para establecer los actores.

 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 ); } } 

La mejor práctica es crear una piel y poner todos los recursos de ui allí. Cargar desde el archivo en un objeto TextureAtlas y pasar ese objeto a la piel. He creado una animación simple esto no escala correctamente su sólo como un ejemplo. En el objeto de pantalla o objeto de juego:

 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; 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.