From be5f00c313b064e3a901cff66891b95b3a0e7fba Mon Sep 17 00:00:00 2001 From: wangsj <3305688534@qq.com> Date: Thu, 25 Sep 2025 16:50:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../uno/mloluyu/characters/SimpleFighter.java | 115 ++++++++++-------- .../java/uno/mloluyu/desktop/GameScreen.java | 39 ++++-- .../mloluyu/versatile/FighterController.java | 32 +++-- .../mloluyu/characters/SimpleFighter.class | Bin 7112 -> 7573 bytes .../uno/mloluyu/desktop/GameScreen.class | Bin 5317 -> 6255 bytes .../mloluyu/versatile/FighterController.class | Bin 2332 -> 2433 bytes 6 files changed, 116 insertions(+), 70 deletions(-) diff --git a/src/main/java/uno/mloluyu/characters/SimpleFighter.java b/src/main/java/uno/mloluyu/characters/SimpleFighter.java index 0bf8617..26fc221 100644 --- a/src/main/java/uno/mloluyu/characters/SimpleFighter.java +++ b/src/main/java/uno/mloluyu/characters/SimpleFighter.java @@ -32,30 +32,35 @@ public class SimpleFighter { private boolean isAttacking = false; // 是否正在攻击(攻击状态标志) - private SimpleFighter fighter; // 添加 fighter 的声明 - private Iterable pressedKeys = new HashMap().keySet(); // 初始化 pressedKeys public SimpleFighter(String name) { this.name = name; // 构造函数,初始化角色名称 - this.fighter = this; // 初始化 fighter 为当前实例 + } + + private void processPressedKeys(float deltaTime) { + for (int keycode : pressedKeys) { + float currentDuration = keyPressDuration.getOrDefault(keycode, 0f); + currentDuration += deltaTime; + keyPressDuration.put(keycode, currentDuration); + handleInput(keycode, true, currentDuration); + } } public void update(float deltaTime) { - updateAttackbox(); + updateAttackbox("light"); // 默认使用普通攻击的攻击盒更新 // 攻击只持续一帧 if (isAttacking) { isAttacking = false; changeAction(Action.IDLE); } - for (int keycode : pressedKeys) { - keyPressDuration.put(keycode, keyPressDuration.getOrDefault(keycode, 0f) + deltaTime); // 更新持续时间 - fighter.handleInput(keycode, true); // 持续按下的键 - } + + processPressedKeys(deltaTime); + // 垂直移动(跳跃或重力) if (!isGrounded) { - verticalSpeed -= 980 * deltaTime; // 简单重力模拟 + verticalSpeed -= 2500 * deltaTime; // 简单重力模拟 hitbox.y += verticalSpeed * deltaTime; if (hitbox.y <= 0) { @@ -78,7 +83,7 @@ public class SimpleFighter { if (isAttacking) { shapeRenderer.setColor(Color.RED); // 设置颜色为红色 - shapeRenderer.rect(attackbox.x, attackbox.y, attackbox.width, attackbox.height); // 绘制攻击盒 + shapeRenderer.rect(attackbox.x, attackbox.y, attackbox.width, attackbox.height); // 绘制攻击框 } shapeRenderer.end(); // 结束 ShapeRenderer 渲染 @@ -86,31 +91,29 @@ public class SimpleFighter { } 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()); // 向右移动 + 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(""); // 防御(暂未实现防御逻辑) + if (isPressed && !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.SPACE || keycode == Input.Keys.UP || keycode == Input.Keys.W) { + jump(); + } } - if (keycode == Input.Keys.SPACE || keycode == Input.Keys.UP || keycode == Input.Keys.W) { - System.out.println("点击了跳跃"); - jump(); - } - } else { - // 松开防御键时恢复待机状态 - if ((keycode == Input.Keys.SHIFT_LEFT || keycode == Input.Keys.SHIFT_RIGHT) && - getCurrentAction() == Action.DEFEND) { + keyPressDuration.remove(keycode); + 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 +123,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 +133,9 @@ public class SimpleFighter { public void jump() { if (isGrounded) { - verticalSpeed = 600f; + verticalSpeed = 1000f; isGrounded = false; + System.out.println("跳跃高度: " + verticalSpeed); changeAction(Action.JUMP); } } @@ -156,9 +150,40 @@ 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; + changeAction(Action.ATTACK); + updateAttackbox(attackType); // 根据攻击类型更新攻击盒位置 } public void takeHit(int damage) { @@ -174,12 +199,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; // 获取碰撞盒 diff --git a/src/main/java/uno/mloluyu/desktop/GameScreen.java b/src/main/java/uno/mloluyu/desktop/GameScreen.java index 733a7ea..0d7d13f 100644 --- a/src/main/java/uno/mloluyu/desktop/GameScreen.java +++ b/src/main/java/uno/mloluyu/desktop/GameScreen.java @@ -3,9 +3,11 @@ 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.glutils.ShapeRenderer; import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector3; import java.util.HashMap; import java.util.Map; @@ -22,6 +24,7 @@ public class GameScreen extends ScreenAdapter { private SpriteBatch batch; private ShapeRenderer shapeRenderer; + private OrthographicCamera camera; // 添加摄像机 public GameScreen(MainGame game, SimpleFighter player) { this.player = player; @@ -30,6 +33,10 @@ 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(); Gdx.input.setInputProcessor(controller); @@ -46,17 +53,25 @@ public class GameScreen extends ScreenAdapter { NetworkManager.getInstance().sendPosition(player.getHitbox().x, player.getHitbox().y); } + // 更新摄像机位置 + camera.position.lerp(new Vector3(player.getHitbox().x, player.getHitbox().y, 0), 0.1f); + camera.update(); + batch.setProjectionMatrix(camera.combined); + shapeRenderer.setProjectionMatrix(camera.combined); + shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); renderFighter(player, Color.BLUE); - if (player.isAttacking()) renderAttackBox(player, Color.RED); + 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; + if (pos == null) + continue; SimpleFighter remote = otherPlayers.computeIfAbsent(id, k -> new SimpleFighter("Remote-" + k)); remote.setPosition(pos[0], pos[1]); remote.update(delta); @@ -65,6 +80,12 @@ public class GameScreen extends ScreenAdapter { } shapeRenderer.end(); + + // 绘制地图边界 + shapeRenderer.begin(ShapeRenderer.ShapeType.Line); + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.rect(0, 0, 1000, 1000); // 假设地图边界为1000x1000的区域 + shapeRenderer.end(); } private void renderFighter(SimpleFighter fighter, Color color) { @@ -80,14 +101,14 @@ public class GameScreen extends ScreenAdapter { } // 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/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/SimpleFighter.class b/target/classes/uno/mloluyu/characters/SimpleFighter.class index 64decccbc947aa5d865ca9ef791391e098b0e69a..723464ab56de91d88325a04875ee368403498b1c 100644 GIT binary patch literal 7573 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 P?cKRtb*g=;8_WL>3i5X) diff --git a/target/classes/uno/mloluyu/desktop/GameScreen.class b/target/classes/uno/mloluyu/desktop/GameScreen.class index 8403f289d16989b0f9c2c5025ca99130249eb954..d97d28baf2fff090056561a9d4da057defa7aa77 100644 GIT binary patch literal 6255 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 RrB&Ma$M0#}C+)tn{{nl}ybS;V delta 2388 zcma)7d0bRg6#nik@6Nor42uE|C~6?VI69D~L2iX0Xdr1(Xr&`eFh(;5gFt4ZZKmyB zGne*7+Y6H+#P-E@ZPRwscGGONT|0Lk+E44(uRq>>=bdxUcg{WMyXWoAdoEXhY5#`D z0gPtOcKseE_ps?>lLZoy!eGwHt>WmzkT}~n*XL~x2O7MkzNY$e-y9vONVbC^UBC`q zN&N(@&^Y?bMJA6e0|OPxQL@{V$Fk&Z(;_xRK4=}<%VYTE3B;^C&&d_IV+a0X#<_(k*uQ>6FJHlvgDJdEJ}D1iWs!!Ikmp9Uq=Qe>Zm{^$7E^e zN1IQ^6gi9+WLMx6fm2b%;0QDog@QqUP1s)>tI9NmdAdL~rpZl~;o2EEi{nhmtXah~ zFq46`(of$gl3K~h3makv+G5nhESuxT(rpB>|U)+;C#%JTkSJW zD#d((3wus*LOATJIVTXTv!e+M1Qw!&&N8KVyiUElSl|-OV~B60#QcrM-V;NuD(TAv z7U6QaP#>JW1Xprg!4UU1ABYPASK(^8NgtSgEtYazcbI*upL!y(Oqw0p+H$PmxIuay zspgefCCeNG>TYD{br@P!aWLH2=D=#)EN}}}QK#zs;Yt2Bj@uX#VtX5W!8-5Ma3h^Y zZM;L^PPNfS8>@T`&3=wG45sNNNkr_s1@6JUa*M-bTY~!q9>9arBBoJs9u{a<-EcJd z!v~w8it~uTdQ}|jgek?v6%H&%RG?Fpk=Og0D*UZsMbs{V4Y5l?6_dGfALvT?g20P- zNp2Izj8olzMc`G{eQQggHe9bXn+3KgjaKgu)YZp;-Vk^bZ!uUJiC`3i$e`#T-Of?A zQoJYdKCvw5?4Rnvc7YF(q5^GKo!Key2~y;p&eJ)*5cm>bNppNLIeo3J-fmeLKbhlu z{K)ZxToa#d!B5yHx5RHZ;XB!$;7-Rcs`tMOe2UNFHT;%<&vYDMj5El62{{~JG84lJ zxg&m-+!$w**CggyvERn5^4Y{3W|w;s-4+K!hWs`$Llz{Zk>Ql2{0Jw|L?qGLi|QYO z1!j5=ba$e+yBn$1op5y^&F$$xU;56d_H<%E2Qu4flL>=pO`$;oq>*DX&4G0EMqdm- zKV*}3fB}Z1kwaeui(I%Vl#*!t5JH4uFhLm6t7*G3W>O>%MIPD#FNygi4(q`1br|7Z zkIXKNG7%RJ#!sTi3eSO~2q=@*tXOPeK=s6CI1xog7?bj_kMxwYV26kz= z=Xtbvy0Dm`3)e6dTGrxBm!%7l>lvQJ>WU#9jQ9P>ZWr_8xiuwfV zhen-nBBH841pP4-1;o@M3?r%zr!hDJvuUCSaU2$tWf=@|Z+#bvKi#1l}ka zCL8BZ(A5x&0nZ09$hh^+Zj@HLH{f&7{ND92#WDtrDierz*|ZukPV6Dtfc(Cp)r7tH qmflGu{Y<)F@dy57gvl&SBYhg_0?224oQv6*&IDZa8(PBRH2YtIg6w+$ diff --git a/target/classes/uno/mloluyu/versatile/FighterController.class b/target/classes/uno/mloluyu/versatile/FighterController.class index cf8407e91bf71f3724c975237406644f1135dc77..8e8f706a3cdc25fd2ec87c2cdfa2450829e80545 100644 GIT binary patch delta 863 zcmZvZOHUI~7>1weOleEUKoqUog2fgr5G-Oupp=`XQUz30P*8DzmW!p3re#Y^T)S{g zOo)3nEFhW&R=Q*74>A4&7x>MT5*BXG<-5Jld(PMM?=S4tsqPN$>U7g%{!p9hW5iwb zDb%bQn?^Ki1B`yIuA+6eWO^YW}HVZCKSTvM`yTM=P^$dyvs&zF`G{1q(q@A zlA1}jOnGVJsm?Q=n;EsEwq~K2&!=;RL@{p^R@QUoXEo%mV@~HShWSU0R4wQ%k~Xhu zkzgImIx845I-g!!-%Q&~7R@`IENf=K+4*h5`9azGjfN9gYW+^b5!$}&z7ow7JB+s< z(yH*2juM@5i3b7)ba@ZxJ!C+Yc&x-ox8~DA^W9n{?bGahN@d!b7?5;{F_|=}uzkF@ zFH$N&S)1|5x)s1hJ#MZ^Fh~!L3~-%ELcEq(h9-$Xt56D~WJ0oArzxgUq$AD?UgD6> zFf$U0)+!0Jw8b;4jo?$uth>;4e&@WkUZxL~w&Uk(2Uc9>qFjR|dB==z0s kfIdM=GHlZZ%i^aGKY9Y&$PIGx+zw{VU+!B<@{=d<54$>?5dZ)H delta 783 zcmYk2NmCPH5Qd*GGa=i!f(s@f0gVaBB3OU|f(wZ#prQmtK}Q)jhp-4-(JFs|bE7QF z6J9t-X-&b+o8|xTKX}BRVX0iYzwUm!zo+{{>F1N*%e0avSk$(`I49 zw)zSSE6a*tx^Fa-k5NaL!40~dalOg;swcxu+%@Rqo|DinhRf(T7+}!(qo+$A8a!gi z`KPBVh8YQwR~(x)SItJ-EKD_K?Rj(A>wM~rYvu7#UW9nAIN~c-mS^n70dv7%jB)3a z*55VED+80)is+=*nK$hfOQEGR*(ha97+4Gn^pZ6k?pdX{Ex-pN453^4IOBy{Ym9-^eypcTvCJID6ik4R`H7_m*y_7 zp3q%dCEKZ3-~GEKZ5mZ#&ru>aL5K>%oR?e`8S%|jlaxx8=;RBDYQ%f59&Vx}zZT&Z zw+V1Z(xqtOU83kAR6vH+!6{Mok`;Sg1n*@|Kzzd|xBjFa$i zV%t2~;h84K8+Liwd%z`_Z$>2WMLSFe#_+<*_yw2QBG5`f^v)FGs(`i%TbmHJ(@BS% nqqFF!xkJ|6K5LQ`1v#(W)M<%asp#?5hLA&WU#(b_D8SNxuh)ZC