From 566d570074ebc227ac126de12e3b14ad178c8fd9 Mon Sep 17 00:00:00 2001 From: wangsj <3305688534@qq.com> Date: Fri, 19 Sep 2025 15:36:50 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=92=8C=E5=BE=85=E6=9C=BA?= =?UTF-8?q?=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/uno/mloluyu/desktop/GameCore.java | 5 + .../uno/mloluyu/desktop/character/Alice.java | 171 ++++++++++++------ .../uno/mloluyu/util/SimpleFormatter.java | 19 ++ .../uno/mloluyu/desktop/GameCore.class | Bin 1087 -> 1458 bytes .../uno/mloluyu/desktop/character/Alice.class | Bin 4444 -> 6439 bytes .../uno/mloluyu/util/SimpleFormatter.class | Bin 0 -> 1397 bytes 6 files changed, 143 insertions(+), 52 deletions(-) create mode 100644 src/main/java/uno/mloluyu/util/SimpleFormatter.java create mode 100644 target/classes/uno/mloluyu/util/SimpleFormatter.class diff --git a/src/main/java/uno/mloluyu/desktop/GameCore.java b/src/main/java/uno/mloluyu/desktop/GameCore.java index db55da6..ce02cd9 100644 --- a/src/main/java/uno/mloluyu/desktop/GameCore.java +++ b/src/main/java/uno/mloluyu/desktop/GameCore.java @@ -16,11 +16,16 @@ public class GameCore implements ApplicationListener { @Override public void create() { alice1.create(); + } @Override public void render() { + Gdx.gl.glClearColor(150, 150, 150, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + alice1.update(Gdx.graphics.getDeltaTime()); alice1.render(); } diff --git a/src/main/java/uno/mloluyu/desktop/character/Alice.java b/src/main/java/uno/mloluyu/desktop/character/Alice.java index 8f47777..a88613c 100644 --- a/src/main/java/uno/mloluyu/desktop/character/Alice.java +++ b/src/main/java/uno/mloluyu/desktop/character/Alice.java @@ -1,112 +1,179 @@ package uno.mloluyu.desktop.character; +import uno.mloluyu.util.SimpleFormatter; + import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.Animation; import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.Array; public class Alice { private SpriteBatch batch; - private Sprite playerSprite; - private Texture playerTexture; + private Animation walkAnimation; // 行走动画 + private Animation idleAnimation; // idle动画 + private TextureRegion currentFrame; // 当前显示的帧 + private float stateTime; // 动画播放时间 + private String path = "character/alice/"; - private String textureFileName = "attackAa000.png"; private final float MOVEMENT_SPEED = 200f; private Vector2 position; + private float width; // 角色宽度 + private float height; // 角色高度 + private boolean isMoving = false; // 是否在移动 + private boolean isFacingRight = true; // 是否面朝右 - public void create(){ + public void create() { batch = new SpriteBatch(); - - // 验证文件是否存在 - String fullPath = path + textureFileName; - if (!Gdx.files.internal(fullPath).exists()) { - Gdx.app.error("Alice", "图片文件不存在: " + fullPath); - Gdx.app.error("Alice", "请检查文件是否放在 assets/" + fullPath); - return; - } - - try { - // 加载纹理并添加错误处理 - playerTexture = new Texture(Gdx.files.internal(fullPath)); - Gdx.app.log("Alice", "成功加载纹理: " + fullPath); - } catch (Exception e) { - Gdx.app.error("Alice", "加载纹理失败: " + e.getMessage()); - e.printStackTrace(); - return; - } - - // 从纹理创建精灵 - playerSprite = new Sprite(playerTexture); - - // 初始化位置向量 position = new Vector2(); - setSpriteToCenter(playerSprite); - - // 设置精灵的原点为中心 - playerSprite.setOriginCenter(); + + // 加载动画帧 + loadAnimations(); + + // 初始化位置(屏幕中心) + setToCenter(); } - private void setSpriteToCenter(Sprite sprite) { - if (sprite == null) return; // 防止空指针 - - float x = (Gdx.graphics.getWidth() - sprite.getWidth()) / 2f; - float y = (Gdx.graphics.getHeight() - sprite.getHeight()) / 2f; - sprite.setPosition(x, y); + /** + * 加载动画帧序列 + */ + private void loadAnimations() { + try { + // 1. 加载静止动画 + Array idleFrames = new Array<>(); + for (int i = 0; i < 16; i++) { + Texture texture = new Texture(Gdx.files.internal(path + "stand" + SimpleFormatter.addLeadingZeros(i,3) + ".png")); //文件路径 + System.out.println(texture); + idleFrames.add(new TextureRegion(texture)); + } + + idleAnimation = new Animation<>(0.1f, idleFrames, Animation.PlayMode.LOOP); // 每帧时间 + + // 2. 加载行走动画 + Array walkFrames = new Array<>(); + for (int i = 0; i < 5; i++) { + Texture texture = new Texture(Gdx.files.internal(path + "walkFront" + SimpleFormatter.addLeadingZeros(i,3) + ".png")); + System.out.println("调试代码"+texture); + walkFrames.add(new TextureRegion(texture)); + } + walkAnimation = new Animation<>(0.1f, walkFrames, Animation.PlayMode.LOOP); + + // 设置角色尺寸 + width = idleFrames.get(0).getRegionWidth(); + height = idleFrames.get(0).getRegionHeight(); + + Gdx.app.log("Alice", "动画加载成功"); + + } catch (Exception e) { + Gdx.app.error("Alice", "动画加载失败: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 设置角色到屏幕中心 + */ + private void setToCenter() { + float x = (Gdx.graphics.getWidth() - width) / 2f; + float y = (Gdx.graphics.getHeight() - height) / 2f; position.set(x, y); } + /** + * 更新逻辑和动画 + */ public void update(float deltaTime) { - if (playerSprite == null) return; // 资源未加载则不更新 - + if (idleAnimation == null) return; + + stateTime += deltaTime; + + handleMovement(deltaTime); + + if (isMoving) { + currentFrame = walkAnimation.getKeyFrame(stateTime); + } else { + currentFrame = idleAnimation.getKeyFrame(stateTime); + } + + if ((isFacingRight && currentFrame.isFlipX()) || + (!isFacingRight && !currentFrame.isFlipX())) { + currentFrame.flip(true, false); + } + } + + /** + * 处理移动逻辑 + */ + private void handleMovement(float deltaTime) { float moveX = 0; float moveY = 0; + isMoving = false; + // 方向键控制 if (Gdx.input.isKeyPressed(Input.Keys.UP)) { moveY += MOVEMENT_SPEED * deltaTime; + isMoving = true; } if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) { moveY -= MOVEMENT_SPEED * deltaTime; + isMoving = true; } if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) { moveX += MOVEMENT_SPEED * deltaTime; + isMoving = true; + isFacingRight = true; // 朝右 } if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) { moveX -= MOVEMENT_SPEED * deltaTime; + isMoving = true; + isFacingRight = false; // 朝左 } + // 更新位置并限制在屏幕内 position.add(moveX, moveY); clampPosition(); - playerSprite.setPosition(position.x, position.y); } + /** + * 限制在屏幕范围内 + */ private void clampPosition() { - if (playerSprite == null) return; - - float maxX = Gdx.graphics.getWidth() - playerSprite.getWidth(); - float maxY = Gdx.graphics.getHeight() - playerSprite.getHeight(); + float maxX = Gdx.graphics.getWidth() - width; + float maxY = Gdx.graphics.getHeight() - height; position.x = Math.max(0, Math.min(position.x, maxX)); position.y = Math.max(0, Math.min(position.y, maxY)); } + /** + * 渲染角色和动画 + */ public void render() { - if (batch == null || playerSprite == null) return; // 资源未准备好则不渲染 - + if (batch == null || currentFrame == null) return; batch.begin(); - playerSprite.draw(batch); + batch.draw(currentFrame, position.x, position.y); batch.end(); } + /** + * 释放资源 + */ public void dispose() { if (batch != null) { batch.dispose(); batch = null; } - if (playerTexture != null) { - playerTexture.dispose(); - playerTexture = null; + if (idleAnimation != null) { + for (TextureRegion region : idleAnimation.getKeyFrames()) { + region.getTexture().dispose(); + } + } + if (walkAnimation != null) { + for (TextureRegion region : walkAnimation.getKeyFrames()) { + region.getTexture().dispose(); + } } - playerSprite = null; } } diff --git a/src/main/java/uno/mloluyu/util/SimpleFormatter.java b/src/main/java/uno/mloluyu/util/SimpleFormatter.java new file mode 100644 index 0000000..74b697b --- /dev/null +++ b/src/main/java/uno/mloluyu/util/SimpleFormatter.java @@ -0,0 +1,19 @@ +package uno.mloluyu.util; +public class SimpleFormatter { + /** + * 简化版:数字补前导零 + * @param number 要格式化的数字(如1, 10) + * @param digits 保留的位数(如3位) + * @return 带前导零的字符串(1→"001",10→"010") + */ + public static String addLeadingZeros(int number, int digits) { + return String.format("%0" + digits + "d", number); + } + + // 测试 + public static void main(String[] args) { + for (int i = 1; i <= 15; i++) { + System.out.println(addLeadingZeros(i, 3)); + } + } +} diff --git a/target/classes/uno/mloluyu/desktop/GameCore.class b/target/classes/uno/mloluyu/desktop/GameCore.class index d97bbc1a053b6580f27c2a60c379f97e26f16cb4..67bd9622ca3609c8e0ceaffa8169729e73a4721c 100644 GIT binary patch delta 585 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 UFetXLU7okFM9dc#ibW{-4{tnxO#lD@ literal 4444 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 diff --git a/target/classes/uno/mloluyu/util/SimpleFormatter.class b/target/classes/uno/mloluyu/util/SimpleFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..8c9bab284d3bcffee27ab65067e6d86784c2e7c9 GIT binary patch literal 1397 zcmah}>rN9v6#j-57V2WTSP)P|1ufnd?_$AQ6=_n$qy(e>8rrdpYJ&YYQZzVn^S^xMzRUjZy)*+Lh?ROl(E1Rk>YAZvL3&c(V#pL{*BP>9)et#k&}X9? zJq-D(^u(jEwITd9zTpanp{lBLcb)sv=*eMLZ_0q-MD>3>N(9LpjjG@c={27TUy<8L zu~M0>?vbl$pDs&7l;EI^Aq+E&w)mDPE3eM=6R9_87ijKjaxN4*`Q}i-sD%-R!9CoH zr$tlvHV$Kq!P@3-C{|xY@zdcGvr-NdIBMa@zQV=aY)s-9RqsVqUxxYO-}IlSj^c8c z(ovEm3B-%a%fKq6G-Oknw6ZNOJwq)GllaW8_u&+Z7EbS{wi9U4vN4M@)K3*sdkZlK zshr1DQceDXwk^wnhcu(H;eL}i4|m{7 zX-S6un&$Pb72ZzfC0A3SUl&W#Ow^%2X7z%hLYduDN(b8K?G>RnRU^oughdMr4AXl( zmEN}65>8y1ctDnTT`PabOb!k9>on)YItEEE2(qpWS`^OPFr*^ zPiNnu;R!^UyKYTtQOft=W-snit7qm|gTbzNp76^q4+0TbxX&>2SDKxOTUcV4{I@9$ zR-7e{Q|~kMus|y_Z=6<(G>0T3*?r~{df(Hg3prZNwb>t_)s78F_LJ6U=7&y@e3v@Ai}81Kkp{~}U?Z^urihXG6mTNq)`ydrPGFnF(ZG&p7v5s< z17;?Ac5(J2&c9-8Vj%zK*LOoS6A>LkmiBofGC