LibGDX 如何停止播放器动画拉伸
LibGDX how to stop player animation stretching
为了我在学校的 A 级计算项目,我一直在创建一个类似于洛克人游戏风格的 2D 平台。到目前为止,我已经获得了一些菜单和播放器方法,例如碰撞检测、移动和动画。我所有的播放器动画都在一个大小不同的精灵 sheet 中,因此它们并不完全相同(79x136、118x128、88x136 等)。
这是我的具体问题:
但是在玩游戏和看动画的时候移动和跳跃,动画的尺寸好像被拉伸或压缩成一个特定的尺寸,我认为是118x140.
我这样说是因为当玩家静止不动时,其中一个静止动画以适当的大小正确显示,并且与该分辨率匹配,而且似乎所有其他动画都试图适应相同的尺寸。
我浏览了互联网和这个网站,看看是否有人有类似的问题,但 none 似乎与这个问题直接相关,因此我要寻求解决方案.
这是我的 Player.java 文件中使用的代码,其中定义了我的播放器的所有方面:
package com.ultimate.robot.entities;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.math.Vector2;
public class Player extends Sprite implements InputProcessor {
/** the movement velocity */
private Vector2 velocity = new Vector2();
private float speed = 240 * 2, gravity = 180 * 1.8f, animationTime = 0;
private boolean canJump;
private Animation still, left, right, jump, fall;
private TiledMapTileLayer collisionLayer;
private String blockedKey = "blocked";
public Player(Animation still, Animation left, Animation right,
Animation jump, Animation fall, TiledMapTileLayer
collisionLayer) {
super(still.getKeyFrame(0));
this.still = still;
this.left = left;
this.right = right;
this.jump = jump;
this.fall = fall;
this.collisionLayer = collisionLayer;
}
public void draw(Batch spriteBatch) {
update(Gdx.graphics.getDeltaTime());
super.draw(spriteBatch);
}
public void update(float delta) {
// apply gravity
velocity.y -= gravity * delta;
// clamp velocity
if(velocity.y > speed)
velocity.y = speed;
else if(velocity.y < -speed)
velocity.y = -speed;
// save old position
float oldX = getX(), oldY = getY();
boolean collisionX = false, collisionY = false;
// move on x
setX(getX() + velocity.x * delta);
if(velocity.x < 0) // going left
collisionX = collidesLeft();
else if(velocity.x > 0) // going right
collisionX = collidesRight();
// react to x collision
if(collisionX) {
setX(oldX);
velocity.x = 0;
}
// move on y
setY(getY() + velocity.y * delta * 5f);
if(velocity.y < 0) // going down
canJump = collisionY = collidesBottom();
else if(velocity.y > 0) // going up
collisionY = collidesTop();
// react to y collision
if(collisionY) {
setY(oldY);
velocity.y = 0;
}
// update animation
animationTime += delta;
setRegion(velocity.x < 0 ? left.getKeyFrame(animationTime) :
velocity.x > 0 ? right.getKeyFrame(animationTime) :
velocity.y > 0 ? jump.getKeyFrame(animationTime) :
velocity.y < 0 ? fall.getKeyFrame(animationTime) :
still.getKeyFrame(animationTime));
}
private boolean isCellBlocked(float x, float y) {
Cell cell = collisionLayer.getCell(
(int) (x / collisionLayer.getTileWidth()),
(int) (y / collisionLayer.getTileHeight()));
return cell != null && cell.getTile() != null
&& cell.getTile().getProperties().containsKey(blockedKey);
}
public boolean collidesRight() {
for(float step = 0; step < getHeight();
step += collisionLayer.getTileHeight() / 2)
if(isCellBlocked(getX() + getWidth(), getY() + step))
return true;
return false;
}
public boolean collidesLeft() {
for(float step = 0; step < getHeight();
step += collisionLayer.getTileHeight() / 2)
if(isCellBlocked(getX(), getY() + step))
return true;
return false;
}
public boolean collidesTop() {
for(float step = 0; step < getWidth();
step += collisionLayer.getTileWidth() / 2)
if(isCellBlocked(getX() + step, getY() + getHeight()))
return true;
return false;
}
public boolean collidesBottom() {
for(float step = 0; step < getWidth();
step += collisionLayer.getTileWidth() / 2)
if(isCellBlocked(getX() + step, getY()))
return true;
return false;
}
public Vector2 getVelocity() {
return velocity;
}
public void setVelocity(Vector2 velocity) {
this.velocity = velocity;
}
public float getSpeed() {
return speed;
}
public void setSpeed(float speed) {
this.speed = speed;
}
public float getGravity() {
return gravity;
}
public void setGravity(float gravity) {
this.gravity = gravity;
}
public TiledMapTileLayer getCollisionLayer() {
return collisionLayer;
}
public void setCollisionLayer(TiledMapTileLayer collisionLayer) {
this.collisionLayer = collisionLayer;
}
@Override
public boolean keyDown(int keycode) {
switch(keycode) {
case Keys.SPACE:
if(canJump) {
velocity.y = speed / 3f;
canJump = false;
animationTime = 0;
}
break;
case Keys.LEFT:
velocity.x = -speed;
animationTime = 0;
break;
case Keys.RIGHT:
velocity.x = speed;
animationTime = 0;
}
return true;
}
@Override
public boolean keyUp(int keycode) {
switch(keycode) {
case Keys.LEFT:
case Keys.RIGHT:
velocity.x = 0;
animationTime = 0;
}
return true;
}
@Override
public boolean keyTyped(char character) {
return false;
}
@Override
public boolean touchDown(int screenX, int screenY,
int pointer, int button) {
return false;
}
@Override
public boolean touchUp(int screenX, int screenY,
int pointer, int button) {
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY,
int pointer) {
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
@Override
public boolean scrolled(int amount) {
return false;
}
}
下一个代码用于 playersheet.sprites 文件,该文件充当玩家的纹理图集并包含以下区域:
playersheet.png
format: RGBA8888
filter: Nearest,Nearest
repeat: none
playerstill
rotate: false
xy: 363, 272
size: 118, 140
orig: 59, 70
offset: 0, 0
index: -1
playerstill
rotate: false
xy: 867, 152
size: 118, 128
orig: 59, 64
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 688, 276
size: 79, 136
orig: 39, 68
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 481, 272
size: 92, 140
orig: 46, 70
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 767, 280
size: 132, 132
orig: 66, 66
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 644, 140
size: 88, 136
orig: 44, 68
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 422, 132
size: 98, 140
orig: 49, 70
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 732, 144
size: 135, 132
orig: 67, 66
offset: 0, 0
index: -1
playershoot
rotate: false
xy: 592, 0
size: 116, 136
orig: 58, 68
offset: 0, 0
index: -1
playerjump
rotate: false
xy: 0, 44
size: 74, 184
orig: 74, 184
offset: 0, 0
index: -1
playerjumpshoot
rotate: false
xy: 0, 228
size: 107, 184
orig: 107, 184
offset: 0, 0
index: -1
playerfall
rotate: false
xy: 186, 76
size: 108, 168
orig: 108, 168
offset: 0, 0
index: -1
playerfallshoot
rotate: false
xy: 107, 244
size: 124, 168
orig: 124, 168
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 294, 132
size: 128, 140
orig: 128, 140
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 573, 276
size: 115, 136
orig: 115, 136
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 294, 0
size: 150, 132
orig: 150, 132
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 520, 136
size: 124, 136
orig: 124, 136
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 231, 272
size: 132, 140
orig: 132, 140
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 444, 0
size: 148, 132
orig: 148, 132
offset: 0, 0
index: -1
playerblock
rotate: false
xy: 708, 8
size: 136, 132
orig: 136, 132
offset: 0, 0
index: -1
playerduck
rotate: false
xy: 899, 304
size: 96, 108
orig: 96, 108
offset: 0, 0
index: -1
playerhurt
rotate: false
xy: 844, 48
size: 136, 96
orig: 136, 96
offset: 0, 0
index: -1
playervictory
rotate: false
xy: 74, 48
size: 112, 180
orig: 112, 180
offset: 0, 0
index: -1
最后我的 LevelOne.java 文件中使用了这段代码,其中包含关卡的所有元素并创建了玩家:
package com.ultimate.robot.levels;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.ultimate.robot.entities.Player;
public class LevelOne implements Screen {
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private OrthographicCamera camera;
private Music level1music;
private Sprite desert, blueSky;
private TextureAtlas playerAtlas;
private Player player;
@Override
public void show() {
map = new TmxMapLoader().load("maps/levelone.tmx");
playerAtlas = new TextureAtlas("Sprites/playersheet.sprites");
Animation still, left, right, jump, fall;
still = new Animation(1/2f, playerAtlas.findRegions("playerstill"));
left = new Animation(1 /6f, playerAtlas.findRegions("playerrun"));
right = new Animation(1 /6f, playerAtlas.findRegions("playerrun"));
jump = new Animation(1 /6f, playerAtlas.findRegions("playerjump"));
fall = new Animation(1 /6f, playerAtlas.findRegions("playerfall"));
still.setPlayMode(Animation.PlayMode.LOOP);
left.setPlayMode(Animation.PlayMode.LOOP);
right.setPlayMode(Animation.PlayMode.LOOP);
jump.setPlayMode(Animation.PlayMode.NORMAL);
fall.setPlayMode(Animation.PlayMode.NORMAL);
player = new Player(still, left, right, jump, fall,
(TiledMapTileLayer) map.getLayers().get(0));
player.setPosition(5 * player.getCollisionLayer().getTileWidth(),
4 * player.getCollisionLayer().getTileHeight());
// setting camera
camera = new OrthographicCamera();
// creating background
desert = new Sprite(new Texture(
Gdx.files.internal("Backgrounds/desert.png")));
blueSky = new Sprite(new Texture(
Gdx.files.internal("Backgrounds/bluesky.png")));
// creating music
level1music = Gdx.audio.newMusic(
Gdx.files.internal("Music/level1.ogg"));
// playing music
level1music.setLooping(true);
level1music.play();
Gdx.input.setInputProcessor(player);
renderer = new OrthogonalTiledMapRenderer(map);
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.position.set(player.getX() + player.getWidth() / 2,
player.getY() + player.getHeight() / 2, 0);
camera.update();
renderer.setView(camera);
renderer.getBatch().begin();
renderer.getBatch().draw(blueSky, 0, 0);
renderer.getBatch().draw(desert, 0, 0);
player.draw(renderer.getBatch());
renderer.getBatch().end();
renderer.render();
}
@Override
public void resize(int width, int height) {
camera.viewportWidth = width;
camera.viewportHeight = height;
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
dispose();
}
@Override
public void dispose() {
map.dispose();
renderer.dispose();
level1music.dispose();
playerAtlas.dispose();
desert.getTexture().dispose();
blueSky.getTexture().dispose();
}
}
我希望这可以帮助找到解决方案。
你可以做几件事,一个会做所有相同的图像,如果只有 alpha 通道 "will consume more memory" 以免彼此大小不同,另一方面你可以检查动画是否具有某些分辨率和设施 yourSprite.size (w, h);
后者,
尽管这看起来更容易,但如果更改分辨率然后在设置精灵的大小中,您现在必须创建一个函数来控制精灵中的图像,因此仅在需要时进行更改,如果不更改则不进行设置在尺寸上,希望我明白我的意思。
您的评论示例:
例如打开 Gimp 并创建大小为 118x140 的图像,带 alpha 通道,创建一个新层并将图像粘贴到其中,然后将其导出为您想要的格式,例如 png "you can merge the layers downwards to join them" 但如果您有visible and export it is not necessary.
inicial size before Gimp size base 118x140
texture size 79x136 texture size 118x140 after export gimp
texture size 118x128 texture size 118x140 after export gimp
texture size 88x136 texture size 118x140 after export gimp
yourSprite.size(118, 140);
别担心,我已经设法使用自定义动画 class 解决了这个问题,同时按照另一个教程,它似乎修复了拉伸和压缩的动画。它创建了一个纹理区域,动画必须适合其中,但我已将大小设置为最大的动画,因此它们都适合该区域。我不得不重写很多代码,但我对最终结果很满意。
为了我在学校的 A 级计算项目,我一直在创建一个类似于洛克人游戏风格的 2D 平台。到目前为止,我已经获得了一些菜单和播放器方法,例如碰撞检测、移动和动画。我所有的播放器动画都在一个大小不同的精灵 sheet 中,因此它们并不完全相同(79x136、118x128、88x136 等)。
这是我的具体问题:
但是在玩游戏和看动画的时候移动和跳跃,动画的尺寸好像被拉伸或压缩成一个特定的尺寸,我认为是118x140.
我这样说是因为当玩家静止不动时,其中一个静止动画以适当的大小正确显示,并且与该分辨率匹配,而且似乎所有其他动画都试图适应相同的尺寸。
我浏览了互联网和这个网站,看看是否有人有类似的问题,但 none 似乎与这个问题直接相关,因此我要寻求解决方案.
这是我的 Player.java 文件中使用的代码,其中定义了我的播放器的所有方面:
package com.ultimate.robot.entities;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.math.Vector2;
public class Player extends Sprite implements InputProcessor {
/** the movement velocity */
private Vector2 velocity = new Vector2();
private float speed = 240 * 2, gravity = 180 * 1.8f, animationTime = 0;
private boolean canJump;
private Animation still, left, right, jump, fall;
private TiledMapTileLayer collisionLayer;
private String blockedKey = "blocked";
public Player(Animation still, Animation left, Animation right,
Animation jump, Animation fall, TiledMapTileLayer
collisionLayer) {
super(still.getKeyFrame(0));
this.still = still;
this.left = left;
this.right = right;
this.jump = jump;
this.fall = fall;
this.collisionLayer = collisionLayer;
}
public void draw(Batch spriteBatch) {
update(Gdx.graphics.getDeltaTime());
super.draw(spriteBatch);
}
public void update(float delta) {
// apply gravity
velocity.y -= gravity * delta;
// clamp velocity
if(velocity.y > speed)
velocity.y = speed;
else if(velocity.y < -speed)
velocity.y = -speed;
// save old position
float oldX = getX(), oldY = getY();
boolean collisionX = false, collisionY = false;
// move on x
setX(getX() + velocity.x * delta);
if(velocity.x < 0) // going left
collisionX = collidesLeft();
else if(velocity.x > 0) // going right
collisionX = collidesRight();
// react to x collision
if(collisionX) {
setX(oldX);
velocity.x = 0;
}
// move on y
setY(getY() + velocity.y * delta * 5f);
if(velocity.y < 0) // going down
canJump = collisionY = collidesBottom();
else if(velocity.y > 0) // going up
collisionY = collidesTop();
// react to y collision
if(collisionY) {
setY(oldY);
velocity.y = 0;
}
// update animation
animationTime += delta;
setRegion(velocity.x < 0 ? left.getKeyFrame(animationTime) :
velocity.x > 0 ? right.getKeyFrame(animationTime) :
velocity.y > 0 ? jump.getKeyFrame(animationTime) :
velocity.y < 0 ? fall.getKeyFrame(animationTime) :
still.getKeyFrame(animationTime));
}
private boolean isCellBlocked(float x, float y) {
Cell cell = collisionLayer.getCell(
(int) (x / collisionLayer.getTileWidth()),
(int) (y / collisionLayer.getTileHeight()));
return cell != null && cell.getTile() != null
&& cell.getTile().getProperties().containsKey(blockedKey);
}
public boolean collidesRight() {
for(float step = 0; step < getHeight();
step += collisionLayer.getTileHeight() / 2)
if(isCellBlocked(getX() + getWidth(), getY() + step))
return true;
return false;
}
public boolean collidesLeft() {
for(float step = 0; step < getHeight();
step += collisionLayer.getTileHeight() / 2)
if(isCellBlocked(getX(), getY() + step))
return true;
return false;
}
public boolean collidesTop() {
for(float step = 0; step < getWidth();
step += collisionLayer.getTileWidth() / 2)
if(isCellBlocked(getX() + step, getY() + getHeight()))
return true;
return false;
}
public boolean collidesBottom() {
for(float step = 0; step < getWidth();
step += collisionLayer.getTileWidth() / 2)
if(isCellBlocked(getX() + step, getY()))
return true;
return false;
}
public Vector2 getVelocity() {
return velocity;
}
public void setVelocity(Vector2 velocity) {
this.velocity = velocity;
}
public float getSpeed() {
return speed;
}
public void setSpeed(float speed) {
this.speed = speed;
}
public float getGravity() {
return gravity;
}
public void setGravity(float gravity) {
this.gravity = gravity;
}
public TiledMapTileLayer getCollisionLayer() {
return collisionLayer;
}
public void setCollisionLayer(TiledMapTileLayer collisionLayer) {
this.collisionLayer = collisionLayer;
}
@Override
public boolean keyDown(int keycode) {
switch(keycode) {
case Keys.SPACE:
if(canJump) {
velocity.y = speed / 3f;
canJump = false;
animationTime = 0;
}
break;
case Keys.LEFT:
velocity.x = -speed;
animationTime = 0;
break;
case Keys.RIGHT:
velocity.x = speed;
animationTime = 0;
}
return true;
}
@Override
public boolean keyUp(int keycode) {
switch(keycode) {
case Keys.LEFT:
case Keys.RIGHT:
velocity.x = 0;
animationTime = 0;
}
return true;
}
@Override
public boolean keyTyped(char character) {
return false;
}
@Override
public boolean touchDown(int screenX, int screenY,
int pointer, int button) {
return false;
}
@Override
public boolean touchUp(int screenX, int screenY,
int pointer, int button) {
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY,
int pointer) {
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
@Override
public boolean scrolled(int amount) {
return false;
}
}
下一个代码用于 playersheet.sprites 文件,该文件充当玩家的纹理图集并包含以下区域:
playersheet.png
format: RGBA8888
filter: Nearest,Nearest
repeat: none
playerstill
rotate: false
xy: 363, 272
size: 118, 140
orig: 59, 70
offset: 0, 0
index: -1
playerstill
rotate: false
xy: 867, 152
size: 118, 128
orig: 59, 64
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 688, 276
size: 79, 136
orig: 39, 68
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 481, 272
size: 92, 140
orig: 46, 70
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 767, 280
size: 132, 132
orig: 66, 66
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 644, 140
size: 88, 136
orig: 44, 68
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 422, 132
size: 98, 140
orig: 49, 70
offset: 0, 0
index: -1
playerrun
rotate: false
xy: 732, 144
size: 135, 132
orig: 67, 66
offset: 0, 0
index: -1
playershoot
rotate: false
xy: 592, 0
size: 116, 136
orig: 58, 68
offset: 0, 0
index: -1
playerjump
rotate: false
xy: 0, 44
size: 74, 184
orig: 74, 184
offset: 0, 0
index: -1
playerjumpshoot
rotate: false
xy: 0, 228
size: 107, 184
orig: 107, 184
offset: 0, 0
index: -1
playerfall
rotate: false
xy: 186, 76
size: 108, 168
orig: 108, 168
offset: 0, 0
index: -1
playerfallshoot
rotate: false
xy: 107, 244
size: 124, 168
orig: 124, 168
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 294, 132
size: 128, 140
orig: 128, 140
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 573, 276
size: 115, 136
orig: 115, 136
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 294, 0
size: 150, 132
orig: 150, 132
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 520, 136
size: 124, 136
orig: 124, 136
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 231, 272
size: 132, 140
orig: 132, 140
offset: 0, 0
index: -1
playerrunshoot
rotate: false
xy: 444, 0
size: 148, 132
orig: 148, 132
offset: 0, 0
index: -1
playerblock
rotate: false
xy: 708, 8
size: 136, 132
orig: 136, 132
offset: 0, 0
index: -1
playerduck
rotate: false
xy: 899, 304
size: 96, 108
orig: 96, 108
offset: 0, 0
index: -1
playerhurt
rotate: false
xy: 844, 48
size: 136, 96
orig: 136, 96
offset: 0, 0
index: -1
playervictory
rotate: false
xy: 74, 48
size: 112, 180
orig: 112, 180
offset: 0, 0
index: -1
最后我的 LevelOne.java 文件中使用了这段代码,其中包含关卡的所有元素并创建了玩家:
package com.ultimate.robot.levels;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.ultimate.robot.entities.Player;
public class LevelOne implements Screen {
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private OrthographicCamera camera;
private Music level1music;
private Sprite desert, blueSky;
private TextureAtlas playerAtlas;
private Player player;
@Override
public void show() {
map = new TmxMapLoader().load("maps/levelone.tmx");
playerAtlas = new TextureAtlas("Sprites/playersheet.sprites");
Animation still, left, right, jump, fall;
still = new Animation(1/2f, playerAtlas.findRegions("playerstill"));
left = new Animation(1 /6f, playerAtlas.findRegions("playerrun"));
right = new Animation(1 /6f, playerAtlas.findRegions("playerrun"));
jump = new Animation(1 /6f, playerAtlas.findRegions("playerjump"));
fall = new Animation(1 /6f, playerAtlas.findRegions("playerfall"));
still.setPlayMode(Animation.PlayMode.LOOP);
left.setPlayMode(Animation.PlayMode.LOOP);
right.setPlayMode(Animation.PlayMode.LOOP);
jump.setPlayMode(Animation.PlayMode.NORMAL);
fall.setPlayMode(Animation.PlayMode.NORMAL);
player = new Player(still, left, right, jump, fall,
(TiledMapTileLayer) map.getLayers().get(0));
player.setPosition(5 * player.getCollisionLayer().getTileWidth(),
4 * player.getCollisionLayer().getTileHeight());
// setting camera
camera = new OrthographicCamera();
// creating background
desert = new Sprite(new Texture(
Gdx.files.internal("Backgrounds/desert.png")));
blueSky = new Sprite(new Texture(
Gdx.files.internal("Backgrounds/bluesky.png")));
// creating music
level1music = Gdx.audio.newMusic(
Gdx.files.internal("Music/level1.ogg"));
// playing music
level1music.setLooping(true);
level1music.play();
Gdx.input.setInputProcessor(player);
renderer = new OrthogonalTiledMapRenderer(map);
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.position.set(player.getX() + player.getWidth() / 2,
player.getY() + player.getHeight() / 2, 0);
camera.update();
renderer.setView(camera);
renderer.getBatch().begin();
renderer.getBatch().draw(blueSky, 0, 0);
renderer.getBatch().draw(desert, 0, 0);
player.draw(renderer.getBatch());
renderer.getBatch().end();
renderer.render();
}
@Override
public void resize(int width, int height) {
camera.viewportWidth = width;
camera.viewportHeight = height;
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
dispose();
}
@Override
public void dispose() {
map.dispose();
renderer.dispose();
level1music.dispose();
playerAtlas.dispose();
desert.getTexture().dispose();
blueSky.getTexture().dispose();
}
}
我希望这可以帮助找到解决方案。
你可以做几件事,一个会做所有相同的图像,如果只有 alpha 通道 "will consume more memory" 以免彼此大小不同,另一方面你可以检查动画是否具有某些分辨率和设施 yourSprite.size (w, h);
后者,
尽管这看起来更容易,但如果更改分辨率然后在设置精灵的大小中,您现在必须创建一个函数来控制精灵中的图像,因此仅在需要时进行更改,如果不更改则不进行设置在尺寸上,希望我明白我的意思。
您的评论示例:
例如打开 Gimp 并创建大小为 118x140 的图像,带 alpha 通道,创建一个新层并将图像粘贴到其中,然后将其导出为您想要的格式,例如 png "you can merge the layers downwards to join them" 但如果您有visible and export it is not necessary.
inicial size before Gimp size base 118x140
texture size 79x136 texture size 118x140 after export gimp
texture size 118x128 texture size 118x140 after export gimp
texture size 88x136 texture size 118x140 after export gimp
yourSprite.size(118, 140);
别担心,我已经设法使用自定义动画 class 解决了这个问题,同时按照另一个教程,它似乎修复了拉伸和压缩的动画。它创建了一个纹理区域,动画必须适合其中,但我已将大小设置为最大的动画,因此它们都适合该区域。我不得不重写很多代码,但我对最终结果很满意。