2017-07-03 2 views
0

Wie man mit verschiedenen Größen von Rahmen umgehen? Wenn ichBounds (0, 0, 100, 100) im Konstruktor setze, sind einige Frames kleiner, aber wenn ich sie aktualisiere, werden Frames nach links und nach oben verschoben. Wie kann man sicherstellen, dass jeder Frame an der gleichen Stelle steht?Java libGDX verschiedene Größen von Animationsrahmen

mayby ​​können Sie sehen, es http://imgur.com/a/AN8Gc

public class Player extends Sprite{ 

//floats 
private float animationTimer; 

//box2d variables 
public World world; 
public Body body; 

//enums 
public enum State{STANDING, MOVING, SHOOTING, RELOAD, MALEE_ATTACK} 
public State currentState; 
public State previousState; 

//booleans 
boolean shoot; 
boolean reload; 
boolean maleeAttack; 

private TextureRegion region; 

public PlayScreen playScreen; 

public Player(PlayScreen playScreen){ 
    this.playScreen = playScreen; 
    this.world = playScreen.getWorld(); 
    definePlayer(); 

    animationTimer = 0; 

    region = Assets.instance.playerAssets.idleAniamtion.getKeyFrame(animationTimer); 

    setRegion(region); 
    setBounds(0, 0, getRegionWidth()/Constants.PPM, getRegionHeight()/Constants.PPM); 
    setPosition(0, 0); 

    currentState = State.STANDING; 
    previousState = State.STANDING; 

    shoot = false; 
    reload = false; 
    maleeAttack = false; 
} 

public void definePlayer(){ 
    BodyDef bodyDef = new BodyDef(); 
    bodyDef.position.set(100/Constants.PPM, 100/Constants.PPM); 
    bodyDef.type = BodyDef.BodyType.DynamicBody; 
    body = world.createBody(bodyDef); 

    FixtureDef fixtureDef = new FixtureDef(); 
    CircleShape shape = new CircleShape(); 
    shape.setRadius(50/Constants.PPM); 
    fixtureDef.shape = shape; 
    body.createFixture(fixtureDef).setUserData(this); 

    body.setLinearDamping(Constants.LINEAR_DAMPING); 
} 

public void update(float delta){ 
    region = Assets.instance.playerAssets.idleAniamtion.getKeyFrame(animationTimer); 
    setRegion(getFrame(delta)); 
    moving(); 
    //rotate(); 

} 

public void moving(){ 
    setPosition(body.getPosition().x - getWidth()/2, body.getPosition(). y - getHeight()/2); 
//setBounds(0, 0, getRegionWidth()/Constants.PPM, getRegionHeight()/Constants.PPM); update bounds 
    if (input.isKeyPressed(Input.Keys.W) && body.getLinearVelocity().y < 5){ 
     body.applyLinearImpulse(new Vector2(0, 1), body.getWorldCenter(), true); 
    } 
    if (input.isKeyPressed(Input.Keys.S) && body.getLinearVelocity().y > -5){ 
     body.applyLinearImpulse(new Vector2(0, -1), body.getWorldCenter(), true); 
    } 
    if (input.isKeyPressed(Input.Keys.D) && body.getLinearVelocity().x < 5){ 
     body.applyLinearImpulse(new Vector2(1, 0), body.getWorldCenter(), true); 
    } 
    if (input.isKeyPressed(Input.Keys.A) && body.getLinearVelocity().x > -5){ 
     body.applyLinearImpulse(new Vector2(-1, 0), body.getWorldCenter(), true); 
    } 
    if (Gdx.input.isKeyPressed(Input.Keys.R)){ 
     reload = true; 
    } 

    if (Gdx.input.isKeyPressed(Input.Keys.F)){ 
     maleeAttack = true; 
    } 
    if (Gdx.input.isButtonPressed(Input.Buttons.LEFT)){ 
     shoot = true; 
    } 

} 

public TextureRegion getFrame(float delta){ 
    TextureRegion region; 

    currentState = getState(); 

    switch (currentState){ 
     case MOVING: 
      region = Assets.instance.playerAssets.moveAnimation.getKeyFrame(animationTimer); 
      break; 
     case SHOOTING: 
      maleeAttack = false; 
      region = Assets.instance.playerAssets.shootAniamtion.getKeyFrame(animationTimer); 
      if (Assets.instance.playerAssets.shootAniamtion.isAnimationFinished(animationTimer)){ 
       shoot = false; 
      } 
      break; 
     case RELOAD: 
      region = Assets.instance.playerAssets.reloadAnimation.getKeyFrame(animationTimer); 
      if (Assets.instance.playerAssets.reloadAnimation.isAnimationFinished(animationTimer)){ 
       reload = false; 
      } 
      break; 
     case MALEE_ATTACK: 
      region = Assets.instance.playerAssets.maleeAttackAnimation.getKeyFrame(animationTimer); 
      if (Assets.instance.playerAssets.maleeAttackAnimation.isAnimationFinished(animationTimer)) { 
       maleeAttack = false; 
      } 
      break; 
     default: 
      region = Assets.instance.playerAssets.idleAniamtion.getKeyFrame(animationTimer); 
      break; 
    } 

    animationTimer = currentState == previousState ? animationTimer + delta : 0; 
    previousState = currentState; 

    return region; 
} 

public State getState(){ 
    if ((body.getLinearVelocity().x > 1 || body.getLinearVelocity().x < -1 || body.getLinearVelocity().y > 1 || body.getLinearVelocity().y < - 1) && !reload && !shoot && !maleeAttack){ 
     return State.MOVING; 
    } 
    if (shoot && !reload){ 
     return State.SHOOTING; 
    } 
    if (reload && !maleeAttack){ 
     return State.RELOAD; 
    } 
    if (maleeAttack){ 
     return State.MALEE_ATTACK; 
    } 
    else { 
     return State.STANDING; 
    } 
} 

public Vector2 getMousePosition(){ 
    Vector2 mousePosition; 
    mousePosition = playScreen.getViewport().unproject(new Vector2(Gdx.input.getX(), Gdx.input.getY())); 
    return mousePosition; 
} 

public float getMouseAngle(){ 
    float angle = (float) Math.atan2(getMousePosition().y - body.getPosition().y, getMousePosition().x - body.getPosition().x); 
    return angle; 
} 

public void rotate(){ 
    setOrigin(getWidth()/2, getHeight()/2); 
    setRotation((float) (getMouseAngle() * (180/Math.PI))); 
    body.setTransform(body.getPosition(), getMouseAngle()); 
} 

}

+0

Verwenden Sie Ansichtsfenster oder virtuellen Bildschirm? –

+0

Ja, ich verwende ExtendViewport. – misza

Antwort

0

Sie benötigen die zusätzliche Dateninformationen ein TextureAtlas bietet als AtlasRegion zu verwenden.

  1. Eine vollständige Animation sollte die gleiche Größe (Breite/Höhe) für jeden Keyframe haben. Wählen Sie eine Größe, in die die größte Schlüsselfarm passt. Beachten Sie auch die korrekte Positionierung. Haben Sie denselben Drehpunkt für jeden Keyframe.

  2. Um Platzverschwendung zu vermeiden, wenn Sie Ihre TextureAtlas packen, aktivieren Sie die Funktion "trimmen". Sollte von keinem TexturePacker Tool unterstützt werden.

  3. Die Texturdaten-Datei (für Libgdx) hat dann Einträge wie folgt aus:

walk_animation 
    rotate: false 
    xy: 794, 235 
    size: 86, 109 
    orig: 160, 170 
    offset: 37, 22 
    index: 5 
  1. Verwenden Sie die AtlasRegion Dinge auf die zeichnen korrekte Größe und Position:
float width = 400; // pick your size here 
float height = 300; 

float offsetPctX = atlasRegion.offsetX/atlasRegion.originalWidth; 
float offsetPctY = atlasRegion.offsetY/atlasRegion.originalHeight; 

float scaleWidth = (float) atlasRegion.packedWidth/atlasRegion.originalWidth; 
float scaleHeight = (float) atlasRegion.packedHeight/atlasRegion.originalHeight; 

float drawWidth = width * scaleWidth; 
float drawHeight = height * scaleHeight; 

float regionOffsetX = offsetPctX * width; 
float regionOffsetY = offsetPctY * height; 

float drawScaleX = 1; // adjust to your needs 
float drawScaleY = 1; 


float drawOriginX = 0; // adjust to tour needs 
float drawOriginY = 0; 

float drawRotation = false; 

float x = 100 + offsetX + regionOffsetX; // adjust to your needs 
float y = 100 + offsetY + regionOffsetY; 

spriteBatch.draw(atlasRegion, x, y, drawOriginX, drawOriginY, drawWidth, drawHeight, drawScaleX, drawScaleY, drawRotation); 
+0

was ist rc., Ich habe einen Fehler damit. Kann ich das verwenden, wenn ich zwei Animationen aber unterschiedliche Größe habe? Einer ist größer und "springt" ein bisschen nach oben links. – misza

+0

Ich entfernte die RC. Teil. offsetX/Y ist nur eine Offset-Nummer, die Sie für Ihr Sprite festgelegt haben. Belassen Sie es bei Nichtgebrauch auf 0. Dies ist der Code eines meiner Projekte mit Animationen, bei denen Animationsrahmen manchmal unterschiedliche Größen haben. –

0

Um die Größenänderung der Textur zu vermeiden, erstellen Sie einfach eine variable Größe, die zum Festlegen der Grenzen verwendet wird. Die Grenze muss jeden Rahmen setzen.

public class Player extends Sprite { 

    private Body body; 
    private Vector2 size; 

    public Player(){ 

     this.size = new Vector2(getRegionWidth()/Constants.PPM, getRegionHeight()/Constants.PPM); 
    } 

    public void update(float delta){ 

     Vector2 position = body.getPosition(); 

     setRegion(getFrame(delta)); 
     setRotation(MathUtils.radDeg * body.getAngle()); 
     setBounds(position.x, position.y, size.x, size.y); 
     setOriginCenter(); 
    } 

    public void rotate(){ 

     this.body.setTransform(body.getPosition(), getMouseAngle()); 
    } 
} 
+0

Wenn ich jeden Rahmen festlege, dann sind Frames "springend" (setbouds (posistion.x, position.y, getWidth, getHeight)) und wenn ich dich mag, werden die Frames immer noch skaliert, da die Grenzen immer noch die gleiche Größe haben. – misza

+0

Ich habe versucht, Sprite-Klasse vor, aber irgendwie wird es nicht richtig rendern. Es schafft eine Menge Overhead, die Sie nicht wirklich brauchen. Verwenden Sie einfach die batch.draw() stattdessen ist es so viel einfacher zu debuggen als sprite.draw(). – Tejay

Verwandte Themen