diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
new file mode 100644
index 0000000..183fe52
--- /dev/null
+++ b/dependency-reduced-pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+ uno.mloluyu
+ game
+ game
+ 1.0-SNAPSHOT
+ LibGDX Desktop Game
+
+
+
+ maven-compiler-plugin
+ 3.13.0
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+ ${maven.compiler.source}
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.2.0
+
+ ${exec.mainClass}
+
+
+
+ maven-shade-plugin
+ 3.5.3
+
+
+ package
+
+ shade
+
+
+ true
+ false
+
+
+
+ ${exec.mainClass}
+
+
+
+
+
+
+
+ maven-jar-plugin
+ 3.3.0
+
+
+
+ ${maven.build.timestamp}
+
+
+
+
+
+
+
+ uno.mloluyu.desktop.DesktopLauncher
+ 17
+ 17
+ 1.12.1
+ yyyy-MM-dd'T'HH:mm:ss
+ UTF-8
+
+
diff --git a/src/main/java/uno/mloluyu/characters/AdvancedFighter.java b/src/main/java/uno/mloluyu/characters/AdvancedFighter.java
index 5d64a71..a029733 100644
--- a/src/main/java/uno/mloluyu/characters/AdvancedFighter.java
+++ b/src/main/java/uno/mloluyu/characters/AdvancedFighter.java
@@ -12,15 +12,15 @@ public class AdvancedFighter extends SimpleFighter {
switch (attackType.toLowerCase()) {
case "light":
changeAction(Action.ATTACK);
- System.out.println(getName() + " 发起轻攻击!");
+ // System.out.println(getName() + " 发起轻攻击!");
break;
case "heavy":
changeAction(Action.ATTACK);
- System.out.println(getName() + " 发起重攻击!");
+ // System.out.println(getName() + " 发起重攻击!");
break;
case "special":
changeAction(Action.ATTACK);
- System.out.println(getName() + " 发动特殊技能!");
+ // System.out.println(getName() + " 发动特殊技能!");
break;
default:
super.attack(attackType); // 默认调用父类攻击逻辑
diff --git a/src/main/java/uno/mloluyu/characters/SimpleFighter.java b/src/main/java/uno/mloluyu/characters/SimpleFighter.java
index 0bf8617..9b5519d 100644
--- a/src/main/java/uno/mloluyu/characters/SimpleFighter.java
+++ b/src/main/java/uno/mloluyu/characters/SimpleFighter.java
@@ -1,7 +1,9 @@
package uno.mloluyu.characters;
-import java.util.HashMap;
-import java.util.Map;
+// 注意:本类使用的是包 uno.mloluyu.characters 下的 Action (IDLE, JUMP, MOVE, ATTACK, DEFEND, HIT, DEAD)
+// 避免与 uno.mloluyu.characters.character.Action (ATTACK1/2/3...) 混淆
+
+// 简化:去除内部按键时长跟踪,统一由 FighterController 负责
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
@@ -16,7 +18,6 @@ import com.badlogic.gdx.math.Rectangle;
public class SimpleFighter {
private String name; // 角色名称
- private final Map keyPressDuration = new HashMap<>();
private Action currentAction = Action.IDLE; // 当前动作状态(待机、攻击、受击等)
private float verticalSpeed = 0f; // 垂直速度(可用于跳跃或下落)
@@ -28,36 +29,60 @@ public class SimpleFighter {
private float speed = 300f; // 移动速度(像素/秒)
private int health = 100; // 当前生命值
- private int attackPower = 10; // 攻击力(暂未使用)
private boolean isAttacking = false; // 是否正在攻击(攻击状态标志)
+ private boolean attackJustStarted = false; // 攻击刚开始的标记,避免第一帧被减掉
+ private int attackInvokeCount = 0; // 调试:attack()调用次数
- private SimpleFighter fighter; // 添加 fighter 的声明
+ // 攻击持续时间(秒)
+ private float attackTimer = 0f;
+ private static final float ATTACK_DURATION = 0.15f; // 攻击判定显示时间
- private Iterable pressedKeys = new HashMap().keySet(); // 初始化 pressedKeys
+ private static boolean debugEnabled = true; // F3 开关
+
+ public static void toggleDebug() {
+ debugEnabled = !debugEnabled;
+ }
+
+ public static boolean isDebugEnabled() {
+ return debugEnabled;
+ }
public SimpleFighter(String name) {
this.name = name; // 构造函数,初始化角色名称
- this.fighter = this; // 初始化 fighter 为当前实例
}
public void update(float deltaTime) {
- updateAttackbox();
+ // 自愈:动作是 ATTACK 但标记丢失
+ if (currentAction == Action.ATTACK && attackTimer > 0f && !isAttacking) {
+ isAttacking = true;
+ attackJustStarted = false;
+ }
- // 攻击只持续一帧
+ // 攻击计时
if (isAttacking) {
- isAttacking = false;
- changeAction(Action.IDLE);
+ if (attackJustStarted) {
+ attackJustStarted = false; // 第一帧不扣时间
+ } else {
+ attackTimer -= deltaTime;
+ }
+ if (attackTimer <= 0f) {
+ isAttacking = false;
+ attackTimer = 0f;
+ if (currentAction == Action.ATTACK)
+ changeAction(Action.IDLE);
+ if (debugEnabled)
+ System.out.println("[ATTACK-END]");
+ }
+ } else {
+ // 空闲/移动状态下保持一个默认攻击盒(便于调试观察)
+ updateAttackbox("light");
}
- for (int keycode : pressedKeys) {
- keyPressDuration.put(keycode, keyPressDuration.getOrDefault(keycode, 0f) + deltaTime); // 更新持续时间
- fighter.handleInput(keycode, true); // 持续按下的键
- }
- // 垂直移动(跳跃或重力)
- if (!isGrounded) {
- verticalSpeed -= 980 * deltaTime; // 简单重力模拟
- hitbox.y += verticalSpeed * deltaTime;
+ // 垂直运动 & 重力
+ if (!isGrounded) {
+ verticalSpeed -= 2500 * deltaTime;
+ hitbox.y += verticalSpeed * deltaTime;
if (hitbox.y <= 0) {
hitbox.y = 0;
verticalSpeed = 0;
@@ -67,50 +92,59 @@ public class SimpleFighter {
}
}
+ @Deprecated
public void render(SpriteBatch batch, ShapeRenderer shapeRenderer) {
- batch.end(); // 暂停 SpriteBatch 渲染,切换到 ShapeRenderer
- System.out.println("人物状态" + currentAction);
- boolean isAttacking = currentAction == Action.ATTACK;
- shapeRenderer.begin(ShapeRenderer.ShapeType.Line); // 开始绘制线框
+ batch.end();
+ shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
+ renderDebug(shapeRenderer);
+ shapeRenderer.end();
+ batch.begin();
+ }
- shapeRenderer.setColor(Color.BLUE); // 设置颜色为蓝色
- shapeRenderer.rect(hitbox.x, hitbox.y, hitbox.width, hitbox.height); // 绘制碰撞盒
+ public void renderSprite(SpriteBatch batch) {
+ /* 预留贴图渲染入口 */ }
+ public void renderDebug(ShapeRenderer sr) {
+ if (!debugEnabled)
+ return;
+ sr.setColor(Color.BLUE);
+ sr.rect(hitbox.x, hitbox.y, hitbox.width, hitbox.height);
if (isAttacking) {
- shapeRenderer.setColor(Color.RED); // 设置颜色为红色
- shapeRenderer.rect(attackbox.x, attackbox.y, attackbox.width, attackbox.height); // 绘制攻击盒
+ // 只画轮廓;填充在 GameScreen 专门的 Filled pass 中画
+ sr.setColor(Color.RED);
+ sr.rect(attackbox.x, attackbox.y, attackbox.width, attackbox.height);
}
-
- shapeRenderer.end(); // 结束 ShapeRenderer 渲染
- batch.begin(); // 恢复 SpriteBatch 渲染
+ // 朝向箭头
+ float arrowX = isFacingRight ? hitbox.x + hitbox.width + 5 : hitbox.x - 15;
+ sr.setColor(Color.YELLOW);
+ sr.line(arrowX, hitbox.y + hitbox.height * 0.7f, arrowX + (isFacingRight ? 10 : -10),
+ hitbox.y + hitbox.height * 0.7f);
}
public void handleInput(int keycode, boolean isPressed, float duration) {
- // 根据按键和按下状态处理输入行为
if (isPressed) {
if (keycode == Input.Keys.LEFT || keycode == Input.Keys.A) {
- move(-1, Gdx.graphics.getDeltaTime()); // 向左移动
+ move(-1, Gdx.graphics.getDeltaTime());
} else if (keycode == Input.Keys.RIGHT || keycode == Input.Keys.D) {
- move(1, Gdx.graphics.getDeltaTime()); // 向右移动
- }
- if (keycode == Input.Keys.Z || keycode == Input.Keys.J) {
- attack(""); // 普通攻击
- } else if (keycode == Input.Keys.X || keycode == Input.Keys.K) {
- attack(""); // 重攻击(暂未区分)
- } else if (keycode == Input.Keys.SPACE || keycode == Input.Keys.UP || keycode == Input.Keys.W) {
- attack(""); // 跳跃(暂未实现跳跃逻辑)
- } else if (keycode == Input.Keys.SHIFT_LEFT || keycode == Input.Keys.SHIFT_RIGHT) {
- attack(""); // 防御(暂未实现防御逻辑)
+ move(1, Gdx.graphics.getDeltaTime());
}
if (keycode == Input.Keys.SPACE || keycode == Input.Keys.UP || keycode == Input.Keys.W) {
- System.out.println("点击了跳跃");
jump();
}
-
+ // 攻击按键
+ if (!isAttacking) {
+ if (keycode == Input.Keys.Z || keycode == Input.Keys.J) {
+ attack("light");
+ } else if (keycode == Input.Keys.X || keycode == Input.Keys.K) {
+ attack("heavy");
+ } else if (keycode == Input.Keys.SHIFT_LEFT || keycode == Input.Keys.SHIFT_RIGHT) {
+ attack("special");
+ }
+ }
} else {
- // 松开防御键时恢复待机状态
- if ((keycode == Input.Keys.SHIFT_LEFT || keycode == Input.Keys.SHIFT_RIGHT) &&
- getCurrentAction() == Action.DEFEND) {
+ if ((keycode == Input.Keys.LEFT || keycode == Input.Keys.RIGHT || keycode == Input.Keys.A
+ || keycode == Input.Keys.D) &&
+ getCurrentAction() == Action.MOVE) {
changeAction(Action.IDLE);
}
}
@@ -120,16 +154,6 @@ public class SimpleFighter {
handleInput(keycode, isPressed, 0f); // 调用已有方法,补充默认持续时间
}
- public void handleRelease(int keycode, float duration) {
- // 处理按键释放逻辑
- System.out.println("按键释放: " + keycode + ", 持续时间: " + duration);
- keyPressDuration.remove(keycode);
- if (keycode == Input.Keys.LEFT || keycode == Input.Keys.RIGHT || keycode == Input.Keys.A
- || keycode == Input.Keys.D) {
- changeAction(Action.IDLE);
- }
- }
-
public Action getCurrentAction() {
return currentAction; // 获取当前动作状态
}
@@ -140,8 +164,9 @@ public class SimpleFighter {
public void jump() {
if (isGrounded) {
- verticalSpeed = 600f;
+ verticalSpeed = 1000f;
isGrounded = false;
+ System.out.println("跳跃高度: " + verticalSpeed);
changeAction(Action.JUMP);
}
}
@@ -156,9 +181,45 @@ public class SimpleFighter {
}
}
+ private void updateAttackbox(String attackType) {
+ float offsetX;
+ float offsetY = 20; // 默认偏移量
+ float width = 80;
+ float height = 80;
+
+ switch (attackType) {
+ case "heavy":
+ offsetX = isFacingRight ? hitbox.width : -100;
+ offsetY = 40;
+ width = 100;
+ height = 100;
+ break;
+ case "light":
+ offsetX = isFacingRight ? hitbox.width - 10 : -attackbox.width + 10;
+ break;
+ case "special":
+ offsetX = isFacingRight ? hitbox.width + 20 : -attackbox.width - 20;
+ offsetY = 50;
+ width = 120;
+ height = 60;
+ break;
+ default:
+ offsetX = isFacingRight ? hitbox.width - 10 : -attackbox.width + 10;
+ }
+
+ attackbox.setPosition(hitbox.x + offsetX, hitbox.y + offsetY);
+ attackbox.setSize(width, height);
+ }
+
public void attack(String attackType) {
- isAttacking = true; // 设置攻击状态
- changeAction(Action.ATTACK); // 切换为攻击动作
+ isAttacking = true;
+ attackTimer = ATTACK_DURATION;
+ attackJustStarted = true;
+ changeAction(Action.ATTACK);
+ updateAttackbox(attackType);
+ attackInvokeCount++;
+ if (debugEnabled)
+ System.out.println("[ATTACK] type=" + attackType + " count=" + attackInvokeCount);
}
public void takeHit(int damage) {
@@ -174,12 +235,6 @@ public class SimpleFighter {
return isAttacking; // 判断是否处于攻击状态
}
- private void updateAttackbox() {
- // 根据朝向更新攻击盒位置,使其位于角色前方
- float offsetX = isFacingRight ? hitbox.width - 10 : -attackbox.width + 10;
- attackbox.setPosition(hitbox.x + offsetX, hitbox.y + 20);
- }
-
// 常用访问器
public Rectangle getHitbox() {
return hitbox; // 获取碰撞盒
@@ -200,4 +255,21 @@ public class SimpleFighter {
public void setPosition(float x, float y) {
hitbox.setPosition(x, y); // 设置角色位置
}
+
+ public void debugPrintState() {
+ if (debugEnabled)
+ System.out.println("[STATE] action=" + currentAction + ", atk=" + isAttacking + ", t=" + attackTimer);
+ }
+
+ public float getAttackTimer() {
+ return attackTimer;
+ }
+
+ public float getAttackTimerPercent() {
+ return isAttacking ? attackTimer / ATTACK_DURATION : 0f;
+ }
+
+ public int getAttackInvokeCount() {
+ return attackInvokeCount;
+ }
}
diff --git a/src/main/java/uno/mloluyu/characters/character/Fighter.java b/src/main/java/uno/mloluyu/characters/character/Fighter.java
index 1c69a55..d9812d2 100644
--- a/src/main/java/uno/mloluyu/characters/character/Fighter.java
+++ b/src/main/java/uno/mloluyu/characters/character/Fighter.java
@@ -92,7 +92,7 @@ public abstract class Fighter implements Disposable {
return;
switch (currentAction) {
- case ATTACK1, ATTACK2, ATTACK3, SPECIAL1, SPECIAL2, HIT -> changeAction(Action.IDLE);
+ case ATTACK1, ATTACK2, ATTACK3, ATTACK4, SPECIAL1, SPECIAL2, HIT -> changeAction(Action.IDLE);
case JUMP -> changeAction(Action.FALL);
default -> {
}
diff --git a/src/main/java/uno/mloluyu/characters/character/Reimu.java b/src/main/java/uno/mloluyu/characters/character/Reimu.java
index e8d4564..0a6eb86 100644
--- a/src/main/java/uno/mloluyu/characters/character/Reimu.java
+++ b/src/main/java/uno/mloluyu/characters/character/Reimu.java
@@ -3,11 +3,9 @@ package uno.mloluyu.characters.character;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
-import uno.mloluyu.characters.character.Fighter.Action;
-
public class Reimu extends Fighter {
public Reimu() {
- super(new TextureAtlas(Gdx.files.internal("src\\main\\resources\\character\\reimu\\reimu.atlas")));
+ super("Reimu", new TextureAtlas(Gdx.files.internal("src/main/resources/character/reimu/reimu.atlas")));
// 设置角色属性
speed = 350f; // 更快的移动速度
@@ -18,27 +16,27 @@ public class Reimu extends Fighter {
@Override
protected void loadAnimations() {
- // TODO Auto-generated method stub
- // 加载基础动作动画
- loadAnimationFromAtlas(Action.IDLE, "other/stand", 9, true);
- loadAnimationFromAtlas(Action.WALK, "other/walkFront", 9, true);
- loadAnimationFromAtlas(Action.JUMP, "other/jump", 8, false);
- loadAnimationFromAtlas(Action.FALL, "other/hitSpin", 5, false);
+ // 基础动作 (looping)
+ animationManager.loadLooping(Action.IDLE, "other/stand", 9);
+ animationManager.loadLooping(Action.WALK, "other/walkFront", 9);
+ // 一次性动作 (one-shot)
+ animationManager.loadOneShot(Action.JUMP, "other/jump", 8);
+ animationManager.loadOneShot(Action.FALL, "other/hitSpin", 5);
- // 加载攻击动作动画
- loadAnimationFromAtlas(Action.ATTACK1, "attackAa/attackAa", 6, false);
- loadAnimationFromAtlas(Action.ATTACK2, "attackAb/attackAb", 6, false);
- loadAnimationFromAtlas(Action.ATTACK3, "attackAc/attackAc", 6, false);
- loadAnimationFromAtlas(Action.ATTACK4, "attackAd/attackAd", 6, false);
+ // 攻击动作
+ animationManager.loadOneShot(Action.ATTACK1, "attackAa/attackAa", 6);
+ animationManager.loadOneShot(Action.ATTACK2, "attackAb/attackAb", 6);
+ animationManager.loadOneShot(Action.ATTACK3, "attackAc/attackAc", 6);
+ animationManager.loadOneShot(Action.ATTACK4, "attackAd/attackAd", 6);
- // 加载受击动画
- loadAnimationFromAtlas(Action.HIT, "hitSpin/hitSpin", 5, false);
+ // 受击
+ animationManager.loadOneShot(Action.HIT, "hitSpin/hitSpin", 5);
- // 设置帧间隔(动作速度)
- setFrameDuration(Action.IDLE, 0.04f);
- setFrameDuration(Action.WALK, 0.08f);
- setFrameDuration(Action.ATTACK1, 0.07f);
- setFrameDuration(Action.SPECIAL2, 0.06f);
+ // 帧间隔
+ animationManager.setFrameDuration(Action.IDLE, 0.04f);
+ animationManager.setFrameDuration(Action.WALK, 0.08f);
+ animationManager.setFrameDuration(Action.ATTACK1, 0.07f);
+ animationManager.setFrameDuration(Action.SPECIAL2, 0.06f);
}
@Override
diff --git a/src/main/java/uno/mloluyu/desktop/GameScreen.java b/src/main/java/uno/mloluyu/desktop/GameScreen.java
index 733a7ea..0513b67 100644
--- a/src/main/java/uno/mloluyu/desktop/GameScreen.java
+++ b/src/main/java/uno/mloluyu/desktop/GameScreen.java
@@ -3,9 +3,13 @@ package uno.mloluyu.desktop;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.ScreenAdapter;
import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
+import com.badlogic.gdx.graphics.GL20;
+import uno.mloluyu.characters.Action;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Rectangle;
+import com.badlogic.gdx.math.Vector3;
import java.util.HashMap;
import java.util.Map;
@@ -22,6 +26,8 @@ public class GameScreen extends ScreenAdapter {
private SpriteBatch batch;
private ShapeRenderer shapeRenderer;
+ private OrthographicCamera camera; // 添加摄像机
+ private com.badlogic.gdx.graphics.g2d.BitmapFont debugFont; // 添加 debugFont 字段
public GameScreen(MainGame game, SimpleFighter player) {
this.player = player;
@@ -30,8 +36,13 @@ public class GameScreen extends ScreenAdapter {
@Override
public void show() {
+ camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
+ camera.position.set(player.getHitbox().x, player.getHitbox().y, 0); // 初始化摄像机位置
+ camera.update();
+
batch = new SpriteBatch();
shapeRenderer = new ShapeRenderer();
+ debugFont = new com.badlogic.gdx.graphics.g2d.BitmapFont(); // 初始化 debugFont
Gdx.input.setInputProcessor(controller);
}
@@ -39,55 +50,109 @@ public class GameScreen extends ScreenAdapter {
public void render(float delta) {
new ClearScreen();
+ // 输入 / 逻辑
player.update(delta);
controller.update(delta);
-
if (NetworkManager.getInstance().isConnected()) {
NetworkManager.getInstance().sendPosition(player.getHitbox().x, player.getHitbox().y);
- }
-
- shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
-
- renderFighter(player, Color.BLUE);
- if (player.isAttacking()) renderAttackBox(player, Color.RED);
-
- Map positions = NetworkManager.getInstance().getPlayerPositions();
- if (positions != null) {
- for (Map.Entry entry : positions.entrySet()) {
- String id = entry.getKey();
- float[] pos = entry.getValue();
- if (pos == null) continue;
- SimpleFighter remote = otherPlayers.computeIfAbsent(id, k -> new SimpleFighter("Remote-" + k));
- remote.setPosition(pos[0], pos[1]);
- remote.update(delta);
- renderFighter(remote, Color.GREEN);
+ Map positions = NetworkManager.getInstance().getPlayerPositions();
+ if (positions != null) {
+ for (Map.Entry entry : positions.entrySet()) {
+ float[] pos = entry.getValue();
+ if (pos == null)
+ continue;
+ SimpleFighter remote = otherPlayers.computeIfAbsent(entry.getKey(),
+ k -> new SimpleFighter("Remote-" + k));
+ remote.setPosition(pos[0], pos[1]);
+ remote.update(delta);
+ }
}
}
+ // F3 调试切换
+ if (Gdx.input.isKeyJustPressed(com.badlogic.gdx.Input.Keys.F3)) {
+ SimpleFighter.toggleDebug();
+ }
+
+ // 摄像机跟随
+ camera.position.lerp(new Vector3(player.getHitbox().x, player.getHitbox().y, 0), 0.1f);
+ camera.update();
+ batch.setProjectionMatrix(camera.combined);
+ shapeRenderer.setProjectionMatrix(camera.combined);
+
+ // 混合
+ Gdx.gl.glEnable(GL20.GL_BLEND);
+ Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
+
+ // -------- Filled pass --------
+ shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
+ drawHitbox(player, Color.BLUE);
+ boolean showPlayerAttack = player.isAttacking()
+ || (player.getCurrentAction() == Action.ATTACK && player.getAttackTimer() > 0);
+ if (showPlayerAttack)
+ drawAttackBox(player, 1f, 0f, 0f, 0.35f);
+ for (SimpleFighter remote : otherPlayers.values()) {
+ drawHitbox(remote, Color.GREEN);
+ if (remote.isAttacking())
+ drawAttackBox(remote, 1f, 0f, 0f, 0.25f);
+ }
shapeRenderer.end();
+
+ // -------- Sprite / HUD pass --------
+ batch.begin();
+ player.renderSprite(batch);
+ if (SimpleFighter.isDebugEnabled()) {
+ debugFont.setColor(Color.WHITE);
+ debugFont.draw(batch,
+ "ACTION:" + player.getCurrentAction() +
+ " atk=" + player.isAttacking() +
+ " timer=" + String.format("%.2f", player.getAttackTimer()) +
+ " atkInvoke=" + player.getAttackInvokeCount(),
+ 10, Gdx.graphics.getHeight() - 10);
+ }
+ batch.end();
+
+ // -------- Debug line pass --------
+ if (SimpleFighter.isDebugEnabled()) {
+ shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
+ player.renderDebug(shapeRenderer);
+ for (SimpleFighter remote : otherPlayers.values())
+ remote.renderDebug(shapeRenderer);
+ shapeRenderer.setColor(Color.WHITE);
+ shapeRenderer.rect(0, 0, 1000, 1000);
+ shapeRenderer.end();
+ }
+
+ // 控制台状态输出(保持以便继续诊断)
+ player.debugPrintState();
+ if (SimpleFighter.isDebugEnabled() && player.isAttacking()) {
+ Rectangle ab = player.getAttackbox();
+ System.out.println("[DEBUG] AttackBox: x=" + ab.x + ", y=" + ab.y + ", w=" + ab.width + ", h=" + ab.height
+ + ", timer=" + player.getAttackTimer());
+ }
}
- private void renderFighter(SimpleFighter fighter, Color color) {
+ private void drawHitbox(SimpleFighter fighter, Color color) {
shapeRenderer.setColor(color);
Rectangle r = fighter.getHitbox();
shapeRenderer.rect(r.x, r.y, r.width, r.height);
}
- private void renderAttackBox(SimpleFighter fighter, Color color) {
- shapeRenderer.setColor(color);
- Rectangle a = fighter.getAttackbox();
- shapeRenderer.rect(a.x, a.y, a.width, a.height);
+ private void drawAttackBox(SimpleFighter fighter, float r, float g, float b, float a) {
+ shapeRenderer.setColor(r, g, b, a);
+ Rectangle box = fighter.getAttackbox();
+ shapeRenderer.rect(box.x, box.y, box.width, box.height);
}
// private void checkPlayerAttacks() {
- // if (!player.isAttacking()) return;
+ // if (!player.isAttacking()) return;
- // for (SimpleFighter target : otherPlayers.values()) {
- // if (target.isAlive() && player.getAttackbox().overlaps(target.getHitbox())) {
- // target.takeHit(player.getAttackPower()); // 使用访问器方法
- // System.out.println("命中远程玩家:" + target.getName());
- // }
- // }
+ // for (SimpleFighter target : otherPlayers.values()) {
+ // if (target.isAlive() && player.getAttackbox().overlaps(target.getHitbox())) {
+ // target.takeHit(player.getAttackPower()); // 使用访问器方法
+ // System.out.println("命中远程玩家:" + target.getName());
+ // }
+ // }
// }
@Override
diff --git a/src/main/java/uno/mloluyu/desktop/StartScreen.java b/src/main/java/uno/mloluyu/desktop/StartScreen.java
index d013e7e..f7b9cb9 100644
--- a/src/main/java/uno/mloluyu/desktop/StartScreen.java
+++ b/src/main/java/uno/mloluyu/desktop/StartScreen.java
@@ -33,10 +33,10 @@ public class StartScreen implements Screen {
public void render(float delta) {
deltaSum += delta;
- if (deltaSum >= 3.0F) {
+ if (deltaSum >= .01F) {
if (mainGame != null) {
mainGame.showGameScreen();
- System.out.println("已经切换到主菜单");
+ System.out.println("已经切换到主菜单");
return;
}
}
diff --git a/src/main/java/uno/mloluyu/versatile/ButtonActions.java b/src/main/java/uno/mloluyu/versatile/ButtonActions.java
deleted file mode 100644
index 82d927b..0000000
--- a/src/main/java/uno/mloluyu/versatile/ButtonActions.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package uno.mloluyu.versatile;
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.g2d.TextureAtlas;
-import com.badlogic.gdx.graphics.g2d.TextureRegion;
-
-/**
- * 按钮资源管理类:统一管理按钮枚举和图集资源
- */
-public class ButtonActions {
-
- private static TextureAtlas atlas;
-
- // 初始化图集(建议在游戏启动或Screen加载时调用一次)
- public static void loadAtlas(String atlasPath) {
- if (atlas == null) {
- atlas = new TextureAtlas(Gdx.files.internal(atlasPath));
- }
- }
-
- // 获取图集区域
- public static TextureRegion getRegion(Button button) {
- if (atlas == null) {
- throw new IllegalStateException("按钮图集尚未加载,请先调用 ButtonActions.loadAtlas()");
- }
- TextureRegion region = atlas.findRegion(button.getRegionName());
- if (region == null) {
- throw new IllegalArgumentException("图集中未找到区域: " + button.getRegionName());
- }
- return region;
- }
-
- // 释放资源(建议在Screen dispose时调用)
- public static void dispose() {
- if (atlas != null) {
- atlas.dispose();
- atlas = null;
- }
- }
-
- /**
- * 按钮枚举:统一定义所有按钮区域名
- */
- public enum Button {
- CONFIRM("confirm"), // 确认按钮
- BACK("back"), // 返回按钮
- WARRIOR("warrior"), // 战士角色按钮
- MAGE("mage"), // 法师角色按钮
- ARCHER("archer"); // 弓箭手角色按钮
-
- private final String regionName;
-
- Button(String regionName) {
- this.regionName = regionName;
- }
-
- public String getRegionName() {
- return regionName;
- }
- }
-}
diff --git a/src/main/java/uno/mloluyu/versatile/FighterController.java b/src/main/java/uno/mloluyu/versatile/FighterController.java
index e984509..283579f 100644
--- a/src/main/java/uno/mloluyu/versatile/FighterController.java
+++ b/src/main/java/uno/mloluyu/versatile/FighterController.java
@@ -29,36 +29,42 @@ public class FighterController extends InputAdapter {
return;
for (int keycode : pressedKeys) {
- fighter.handleInput(keycode, true); // 持续按下的键
+ float currentDuration = keyPressDuration.getOrDefault(keycode, 0f);
+ currentDuration += deltaTime;
+ keyPressDuration.put(keycode, currentDuration);
+ fighter.handleInput(keycode, true, currentDuration); // 持续按下的键,传递持续时间
}
}
@Override
public boolean keyDown(int keycode) {
+ // System.out.println("按键按下: " + keycode);
if (fighter == null)
return false;
if (!pressedKeys.contains(keycode, false)) {
pressedKeys.add(keycode);
+ keyPressDuration.put(keycode, 0f); // 初始化按键持续时间
}
- fighter.handleInput(keycode, true); // 按下事件
+ fighter.handleInput(keycode, true, 0f); // 按下事件,初始持续时间为 0
return true;
}
- @Override
- public boolean keyUp(int keycode) {
- if (fighter == null)
- return false;
+ @Override
+ public boolean keyUp(int keycode) {
+ // System.out.println("按键松开: " + keycode);
- float duration = keyPressDuration.getOrDefault(keycode, 0f);
- pressedKeys.removeValue(keycode, false);
- keyPressDuration.remove(keycode);
+ if (fighter == null)
+ return false;
- // 传给角色:按键松开 + 按下时长
- fighter.handleRelease(keycode, duration);
- return true;
- }//松开事件
+ float duration = keyPressDuration.getOrDefault(keycode, 0f);
+ pressedKeys.removeValue(keycode, false);
+ keyPressDuration.remove(keycode);
+
+ fighter.handleInput(keycode, false, duration); // 按键松开事件,传递持续时间
+ return true;
+ }// 松开事件
public SimpleFighter getFighter() {
return fighter;
diff --git a/target/classes/uno/mloluyu/characters/AdvancedFighter.class b/target/classes/uno/mloluyu/characters/AdvancedFighter.class
index 8d7e798..5c05aba 100644
Binary files a/target/classes/uno/mloluyu/characters/AdvancedFighter.class and b/target/classes/uno/mloluyu/characters/AdvancedFighter.class differ
diff --git a/target/classes/uno/mloluyu/characters/SimpleFighter.class b/target/classes/uno/mloluyu/characters/SimpleFighter.class
index 64deccc..67835e6 100644
Binary files a/target/classes/uno/mloluyu/characters/SimpleFighter.class and b/target/classes/uno/mloluyu/characters/SimpleFighter.class differ
diff --git a/target/classes/uno/mloluyu/characters/character/Fighter.class b/target/classes/uno/mloluyu/characters/character/Fighter.class
index 29f2886..b0f71cd 100644
Binary files a/target/classes/uno/mloluyu/characters/character/Fighter.class and b/target/classes/uno/mloluyu/characters/character/Fighter.class differ
diff --git a/target/classes/uno/mloluyu/characters/character/Reimu.class b/target/classes/uno/mloluyu/characters/character/Reimu.class
index 8499472..dc55e6c 100644
Binary files a/target/classes/uno/mloluyu/characters/character/Reimu.class and b/target/classes/uno/mloluyu/characters/character/Reimu.class differ
diff --git a/target/classes/uno/mloluyu/desktop/GameScreen.class b/target/classes/uno/mloluyu/desktop/GameScreen.class
index 8403f28..cf1b703 100644
Binary files a/target/classes/uno/mloluyu/desktop/GameScreen.class and b/target/classes/uno/mloluyu/desktop/GameScreen.class differ
diff --git a/target/classes/uno/mloluyu/desktop/StartScreen.class b/target/classes/uno/mloluyu/desktop/StartScreen.class
index 3bd5e02..a184ca4 100644
Binary files a/target/classes/uno/mloluyu/desktop/StartScreen.class and b/target/classes/uno/mloluyu/desktop/StartScreen.class differ
diff --git a/target/classes/uno/mloluyu/versatile/ButtonActions$Button.class b/target/classes/uno/mloluyu/versatile/ButtonActions$Button.class
deleted file mode 100644
index a2bf178..0000000
Binary files a/target/classes/uno/mloluyu/versatile/ButtonActions$Button.class and /dev/null differ
diff --git a/target/classes/uno/mloluyu/versatile/ButtonActions.class b/target/classes/uno/mloluyu/versatile/ButtonActions.class
deleted file mode 100644
index 91fd8a4..0000000
Binary files a/target/classes/uno/mloluyu/versatile/ButtonActions.class and /dev/null differ
diff --git a/target/classes/uno/mloluyu/versatile/FighterController.class b/target/classes/uno/mloluyu/versatile/FighterController.class
index cf8407e..8e8f706 100644
Binary files a/target/classes/uno/mloluyu/versatile/FighterController.class and b/target/classes/uno/mloluyu/versatile/FighterController.class differ
diff --git a/target/game-1.0-SNAPSHOT.jar b/target/game-1.0-SNAPSHOT.jar
index 7ae4f19..197191f 100644
Binary files a/target/game-1.0-SNAPSHOT.jar and b/target/game-1.0-SNAPSHOT.jar differ
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
index be72bc6..ab0a50d 100644
--- a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -1,13 +1,3 @@
-uno\mloluyu\network\ConnectServer$1$1.class
-uno\mloluyu\network\ConnectServer$1.class
-uno\mloluyu\network\CreateServer$1.class
-uno\mloluyu\characters\FighterList.class
-uno\mloluyu\network\CreateServer.class
-uno\mloluyu\desktop\Launcher.class
-uno\mloluyu\characters\Fighter$Action.class
-uno\mloluyu\desktop\GameCore.class
-uno\mloluyu\characters\Fighter.class
-uno\mloluyu\characters\Alice.class
-uno\mloluyu\Controller\FighterController.class
uno\mloluyu\network\ConnectServer.class
+uno\mloluyu\characters\character\Fighter$1.class
uno\mloluyu\util\SimpleFormatter.class
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
index 4306e4b..d049ed5 100644
--- a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -1,10 +1,23 @@
-C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\Alice.java
-C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\Fighter.java
-C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\FighterList.java
-C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\Controller\FighterController.java
-C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\desktop\GameCore.java
-C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\desktop\Launcher.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\Action.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\AdvancedFighter.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\character\Action.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\character\Alice.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\character\Fighter.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\character\FighterAnimationManager.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\character\FighterList.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\character\Reimu.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\characters\SimpleFighter.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\desktop\CharacterSelectScreen.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\desktop\DesktopLauncher.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\desktop\GameScreen.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\desktop\MainGame.java
C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\desktop\MainMenuScreen.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\desktop\NetworkSettingsScreen.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\desktop\StartScreen.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\network\ConnectClient.java
C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\network\ConnectServer.java
-C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\network\CreateServer.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\network\NetworkManager.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\util\ClearScreen.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\util\Font.java
C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\util\SimpleFormatter.java
+C:\Users\www\Documents\Game\Game\src\main\java\uno\mloluyu\versatile\FighterController.java
diff --git a/target/original-game-1.0-SNAPSHOT.jar b/target/original-game-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..f2b8e03
Binary files /dev/null and b/target/original-game-1.0-SNAPSHOT.jar differ