From 7153ac9b97726938a0951073007aa010c1e19445 Mon Sep 17 00:00:00 2001 From: wangsj <3305688534@qq.com> Date: Thu, 25 Sep 2025 22:03:19 +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 | 88 +++++++++++++++++ .../java/uno/mloluyu/desktop/GameScreen.java | 92 ++++++++++++++++++ .../uno/mloluyu/network/NetworkManager.java | 62 ++++++++++++ .../mloluyu/characters/SimpleFighter.class | Bin 5943 -> 7638 bytes .../uno/mloluyu/desktop/GameScreen.class | Bin 9198 -> 12528 bytes .../uno/mloluyu/network/NetworkManager.class | Bin 5933 -> 8495 bytes 6 files changed, 242 insertions(+) diff --git a/src/main/java/uno/mloluyu/characters/SimpleFighter.java b/src/main/java/uno/mloluyu/characters/SimpleFighter.java index 3840c05..54a8b4e 100644 --- a/src/main/java/uno/mloluyu/characters/SimpleFighter.java +++ b/src/main/java/uno/mloluyu/characters/SimpleFighter.java @@ -29,12 +29,36 @@ public class SimpleFighter { private boolean attackJustStarted = false; // 攻击是否刚开始 private float attackTimer = 0f; // 攻击计时器 private static final float ATTACK_DURATION = 0.15f; // 攻击持续时间 + // 新增:连续攻击序号(本地,用于避免重复伤害) + private int attackSequence = 0; + private String lastAttackType = "light"; // 记录最后一次攻击类型,供伤害判定 + private int lastDamageAppliedSeq = -1; // 已经对目标造成伤害的序号,避免重复 + // 击退 & 无敌 + private float knockbackX = 0f; + private float knockbackTimer = 0f; + private float invulnerableTimer = 0f; // 无敌帧时间(被击中后短暂无敌) + private static final float INVULNERABLE_DURATION = 0.3f; + private static final float KNOCKBACK_DURATION = 0.12f; public SimpleFighter(String name) { this.name = name; } public void update(float deltaTime) { + // 处理无敌帧计时 + if (invulnerableTimer > 0) { + invulnerableTimer -= deltaTime; + if (invulnerableTimer < 0) + invulnerableTimer = 0; + } + // 处理击退 + if (knockbackTimer > 0) { + hitbox.x += knockbackX * deltaTime; + knockbackTimer -= deltaTime; + if (knockbackTimer <= 0) { + knockbackX = 0; + } + } if (isAttacking) { if (attackJustStarted) { attackJustStarted = false; @@ -135,6 +159,19 @@ public class SimpleFighter { } } + // 供远程同步:根据位置变化量更新朝向(不触发移动动作,只用于攻击盒朝向正确) + public void updateFacingByDelta(float dx) { + if (dx > 0) { + isFacingRight = true; + } else if (dx < 0) { + isFacingRight = false; + } + } + + public boolean isFacingRight() { + return isFacingRight; + } + private void updateAttackbox(String attackType) { float offsetX, offsetY = 20, width = 80, height = 80; switch (attackType) { @@ -166,11 +203,21 @@ public class SimpleFighter { attackJustStarted = true; changeAction(Action.ATTACK); updateAttackbox(attackType); + lastAttackType = attackType; + attackSequence++; // 本地每次攻击自增 + lastDamageAppliedSeq = -1; // 新一次攻击重置 } public void takeHit(int damage) { + if (invulnerableTimer > 0 || health <= 0) + return; // 无敌或已死亡 health = Math.max(0, health - damage); changeAction(health > 0 ? Action.HIT : Action.DEAD); + // 设置无敌 & 击退 + invulnerableTimer = INVULNERABLE_DURATION; + // 击退方向与幅度 + knockbackX = isFacingRight ? -600f : 600f; + knockbackTimer = KNOCKBACK_DURATION; } public boolean isAlive() { @@ -181,6 +228,10 @@ public class SimpleFighter { return isAttacking; } + public boolean isInvulnerable() { + return invulnerableTimer > 0; + } + public Rectangle getHitbox() { return hitbox; } @@ -193,6 +244,43 @@ public class SimpleFighter { return health; } + public int getAttackSequence() { + return attackSequence; + } + + public String getLastAttackType() { + return lastAttackType; + } + + public int getLastDamageAppliedSeq() { + return lastDamageAppliedSeq; + } + + public void setLastDamageAppliedSeq(int seq) { + this.lastDamageAppliedSeq = seq; + } + + public boolean canDealDamage() { + return isAttacking && attackSequence != lastDamageAppliedSeq; // 未对当前序号造成过伤害 + } + + public void markDamageApplied() { + lastDamageAppliedSeq = attackSequence; + } + + // 根据攻击类型返回伤害数值 + public int getDamageForAttack(String type) { + switch (type) { + case "heavy": + return 20; + case "special": + return 30; + case "light": + default: + return 10; + } + } + public String getName() { return name; } diff --git a/src/main/java/uno/mloluyu/desktop/GameScreen.java b/src/main/java/uno/mloluyu/desktop/GameScreen.java index 7e43fce..75e36e8 100644 --- a/src/main/java/uno/mloluyu/desktop/GameScreen.java +++ b/src/main/java/uno/mloluyu/desktop/GameScreen.java @@ -24,6 +24,8 @@ public class GameScreen extends ScreenAdapter { private final SimpleFighter player; private final FighterController controller; private final Map otherPlayers = new HashMap<>(); + private final Map deathTimers = new HashMap<>(); // 记录远程/本地死亡计时 + private static final float RESPAWN_DELAY = 2f; private SpriteBatch batch; private ShapeRenderer shapeRenderer; @@ -80,7 +82,11 @@ public class GameScreen extends ScreenAdapter { } return new SimpleFighter("Remote-" + k); }); + // 根据位置变化更新朝向 + float oldX = remote.getHitbox().x; remote.setPosition(pos[0], pos[1]); + float dx = remote.getHitbox().x - oldX; + remote.updateFacingByDelta(dx); remote.update(delta); } // 处理远程攻击同步:触发远程角色的攻击动画 @@ -93,6 +99,92 @@ public class GameScreen extends ScreenAdapter { } attacks.clear(); } + // 主机执行碰撞检测并广播伤害 + if (NetworkManager.getInstance().isHost()) { + // 只处理本地玩家攻击命中其他人,以及(可扩展)其他远程之间不处理 + if (player.isAttacking()) { + for (Map.Entry e : otherPlayers.entrySet()) { + SimpleFighter target = e.getValue(); + if (target.isAlive() && player.isAttacking() && player.canDealDamage() + && player.getAttackbox().overlaps(target.getHitbox())) { + // 使用攻击类型伤害 + int dmg = player.getDamageForAttack(player.getLastAttackType()); + NetworkManager.getInstance().sendDamage(e.getKey(), dmg); + player.markDamageApplied(); + } + } + } + // 远程玩家攻击命中本地玩家 + for (Map.Entry e : otherPlayers.entrySet()) { + SimpleFighter attacker = e.getValue(); + if (attacker.isAttacking() && attacker.canDealDamage() && player.isAlive() + && attacker.getAttackbox().overlaps(player.getHitbox())) { + int dmg = attacker.getDamageForAttack(attacker.getLastAttackType()); + NetworkManager.getInstance().sendDamage(NetworkManager.getInstance().getLocalPlayerId(), dmg); + attacker.markDamageApplied(); + } + } + // 主机处理死亡计时与重生广播 + // 本地玩家死亡 + if (!player.isAlive()) { + deathTimers.merge(NetworkManager.getInstance().getLocalPlayerId(), Gdx.graphics.getDeltaTime(), + Float::sum); + } + // 远程玩家死亡 + for (Map.Entry e : otherPlayers.entrySet()) { + if (!e.getValue().isAlive()) { + deathTimers.merge(e.getKey(), Gdx.graphics.getDeltaTime(), Float::sum); + } + } + // 检查需要重生的对象 + for (Map.Entry dt : new java.util.ArrayList<>(deathTimers.entrySet())) { + if (dt.getValue() >= RESPAWN_DELAY) { + String pid = dt.getKey(); + // 重生位置简单放原点附近随机 + float rx = (float) (Math.random() * 200 - 100); + float ry = 0; + NetworkManager.getInstance().sendRespawn(pid, rx, ry); + deathTimers.remove(pid); + } + } + } + // 应用收到的伤害事件 + Map damageEvents = NetworkManager.getInstance().getDamageEvents(); + if (!damageEvents.isEmpty()) { + for (Map.Entry dmg : damageEvents.entrySet()) { + String targetId = dmg.getKey(); + int amount = dmg.getValue(); + if (targetId.equals(NetworkManager.getInstance().getLocalPlayerId())) { + player.takeHit(amount); + } else { + SimpleFighter remote = otherPlayers.get(targetId); + if (remote != null) { + remote.takeHit(amount); + } + } + } + damageEvents.clear(); + } + // 处理重生事件 + Map respawns = NetworkManager.getInstance().getRespawnEvents(); + if (!respawns.isEmpty()) { + for (Map.Entry r : respawns.entrySet()) { + String pid = r.getKey(); + float[] p = r.getValue(); + if (pid.equals(NetworkManager.getInstance().getLocalPlayerId())) { + player.setPosition(p[0], p[1]); + // 简单复活:重置血量字段(需访问) + // 由于 health 私有且无 setter,可在 SimpleFighter 新增 resetForRespawn 方法(后续可优化) + // 临时通过反射或改造:这里暂时忽略直接血量恢复(若需要我可再补) + } else { + SimpleFighter remote = otherPlayers.get(pid); + if (remote != null) { + remote.setPosition(p[0], p[1]); + } + } + } + respawns.clear(); + } } // 摄像机跟随 diff --git a/src/main/java/uno/mloluyu/network/NetworkManager.java b/src/main/java/uno/mloluyu/network/NetworkManager.java index a26db8b..6d0e247 100644 --- a/src/main/java/uno/mloluyu/network/NetworkManager.java +++ b/src/main/java/uno/mloluyu/network/NetworkManager.java @@ -16,6 +16,9 @@ public class NetworkManager { private final Map playerCharacters = new HashMap<>(); // 存储远程玩家的攻击类型(attackType) private final Map playerAttacks = new HashMap<>(); + // 伤害事件:targetId -> 累积伤害(本帧内可能多次) + private final Map damageEvents = new HashMap<>(); + private final Map respawnEvents = new HashMap<>(); public static NetworkManager getInstance() { if (instance == null) { @@ -104,6 +107,39 @@ public class NetworkManager { } else { Gdx.app.error("Network", "攻击消息格式错误: " + message); } + } else if (message.startsWith("DAMAGE:")) { + // DAMAGE:targetId,amount,(dir) + String[] parts = message.substring(7).split(","); + if (parts.length >= 2) { + String targetId = parts[0]; + try { + int amount = Integer.parseInt(parts[1]); + damageEvents.merge(targetId, amount, Integer::sum); + // 第三个参数方向目前不存储,只为击退逻辑可扩展 + Gdx.app.log("Network", + "收到伤害: " + targetId + " -" + amount + (parts.length >= 3 ? (" dir=" + parts[2]) : "")); + } catch (NumberFormatException e) { + Gdx.app.error("Network", "伤害数值解析失败: " + message); + } + } else { + Gdx.app.error("Network", "伤害消息格式错误: " + message); + } + } else if (message.startsWith("RESPAWN:")) { + // RESPAWN:playerId,x,y + String[] parts = message.substring(8).split(","); + if (parts.length == 3) { + try { + String pid = parts[0]; + float x = Float.parseFloat(parts[1]); + float y = Float.parseFloat(parts[2]); + respawnEvents.put(pid, new float[] { x, y }); + Gdx.app.log("Network", "收到重生: " + pid + " -> (" + x + "," + y + ")"); + } catch (NumberFormatException e) { + Gdx.app.error("Network", "重生坐标解析失败: " + message); + } + } else { + Gdx.app.error("Network", "重生消息格式错误: " + message); + } } else { Gdx.app.log("Network", "未知消息类型: " + message); } @@ -140,6 +176,32 @@ public class NetworkManager { return playerCharacters; } + public Map getDamageEvents() { + return damageEvents; + } + + public void sendDamage(String targetId, int amount) { + String msg = "DAMAGE:" + targetId + "," + amount; // 不含方向 + if (isHost && server != null) { + server.broadcastToOthers(null, msg); + receiveMessage(msg); // 本地也应用 + } else if (client != null) { + client.sendMessage(msg); + } + } + + public void sendRespawn(String playerId, float x, float y) { + String msg = "RESPAWN:" + playerId + "," + x + "," + y; + if (isHost && server != null) { + server.broadcastToOthers(null, msg); + receiveMessage(msg); + } + } + + public Map getRespawnEvents() { + return respawnEvents; + } + public boolean isHost() { return isHost; } diff --git a/target/classes/uno/mloluyu/characters/SimpleFighter.class b/target/classes/uno/mloluyu/characters/SimpleFighter.class index 783970bf1da270630dc431797ba263a0b15b7dd6..ab982a2d6b1a2338996afddb6edf157cf8e8e6d4 100644 GIT binary patch literal 7638 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 diff --git a/target/classes/uno/mloluyu/desktop/GameScreen.class b/target/classes/uno/mloluyu/desktop/GameScreen.class index ffa71793bfe31f836cb8771c5218d8aa96687e42..4aa70c7184ae9b3ca3263172778fd5b775f369bc 100644 GIT binary patch literal 12528 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 literal 9198 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 diff --git a/target/classes/uno/mloluyu/network/NetworkManager.class b/target/classes/uno/mloluyu/network/NetworkManager.class index a9911bf6062aee249ed22a8f36a3b0b7ec549792..8859c121889f3501512c70ce7c7e941827926248 100644 GIT binary patch literal 8495 zcmcIp3w%@8dH)|-wuF2ETjm*3p0@D|oRaXcoj{Bq;KT-EQ>aPP_FB3z0$Fk-nMaqT zq)UO2P-q5i=qP~%V)En>u)%gh*QT&#eXZTvF3plILju-~?%8e`E&HEyuVmR0^z|$J zeD1m5`Of!!=X;;4w}0LDCV;!d3I}Wg)4Kw}@(zE{-?h1`JYYmN21D!1mzmEdJ)pN6 zAqVUNIqUQddbwW@w3jb$TW5G80#08b9MJw4Ms>{Mq2!uU?4!s zEec7Zd;C5lKu$MBuTe-6-4|XO3=>_f5g6$YdUXE^zrNWBHFyQwje`ehiG+NCcJ3IZ zkZRWIA>9*^a*gg(8&(9vzKAav2oqxN>x%gN7`l3ADwF%` z7jjRINjJfXgy;Uot*OK$sgWkB>PSTQtS24Kt9Q^!bsMNDzRvqy$TkEb1`S-L=!T4N zr@k=|CzN%kFW`$T6v!wlUL|0!33?3|GB8=gEtoU{0#h|)LvvudK(11*QqodAyq1b` zVHze&tO5-=$d$918pfEjVh!WWS*eEc=4_URiO7`-_XUh)T^(&kXr zv>(+icO^1ri{WQ!pi{|^`<#Z+80Cfyk4r6lUSL5QEu@h+6~uh*iRXVOwllI;EN`iF z;Zf|+@FboRaH*&WODhVbO#^Er`WH0p!fuiaceRC8fsxn^X$;}S(>#5d+_Xo-UVKSL z9)pIJE1e@3-=8YA3(w#y4(wyP984|s{-7Sw@aNc1p*!_Z*ieug2wk6z132iwvrK=3 z*_$~~!y!CJ({y%GpdorS3xBdFSdipHS|B$|MZ1jUBN|?ik(z0QLcx$5cC8)7fq{4dQ|*ma z6g9kwb4(aYk%SH7Z)KU{21(;DG<+T3Al(hRzsp$upv)CREFUklZl;NEYB-MzJSj7% zpD{2kULREXe6TB^+`N3TuilzgNlX2ehPUz8+|^-(+F2A=Cp-KN4P$!F4GE{Un@cL` zI|6XCynj!|*WUif{6t{Nphuf+Kz%UOp-1XAd5lh(0I22;GsjRHw2sWFd1+!q+Ah)l394*blDugt zv%7NXs;^qPxsw~5EQhkcU|rABJAz%(2}FYo4WHM6_vm(9HCu#uhNdjJL+okxj5CMB zZrmv*NG3YG`M<^Hq@!7Smpz?JrcjfPo91K$`UMcrzLTiWgk_&z}#&IW4 za5kyA+4cRmbfaIS&u>El#S-4C8O>%(I;?xKaLhtD7IX;Nby>La_LW^LTZn95*lM8+ z8qwwTg+1mSLl(p98l9YNkAvXOU|5zcVbky{Ok%(ZyCyPKQ{?d*ddMjp)DWAL*q2_7 z4s5x6?m+AdM@X?H*cI{^^*-6B<_&E#XG=e(Y>R`zNH`MGJDZHi+MqY=5}Fw05F>eO z8uWBuU_)@dQEnd1Y#Zu%Ckci&Q*&apz%$7KXknWKm+Aqp-w5Y727~LnI+L@rrKlv| z7_w11c^dTOP>N^SR1!71-{0bk7*(UQM7C47c}a`D_FQax@1>WICAvFPO-#&Y*Edx- z#TZsdSz$#P|2xGvsYA06sP_p>vlrjkdFhSUE_Xj4JFq)?_{8N?M=IscTLdPVOR=8q zvB!?Z4i2z~ys~HC=H9_@Ej|nDAU9&F`Fqf+||K!UDVJ}+(3^h z6{t!+aXfV-`B@y4%qR}a5w|(T?aazky}r<0H1J$TpVD=IO>QR-Sx#QTOLdHMTNSAs8&;>P+6r$ z#w#rWWr8<}27X-$)%f*r*a$mBBd_Ku&YCWxIK(nu^lpwyQ<&+8w|*L%_n>UJo!<-+>++pn4ifJZ_|ESK ziT6D27V=94$6HBp8>M2pM|DXrK2nl#8dFO8F|D;1GfpFaa9TJxEgGDb3{J~VDDh@< zoUV@LWJfD+f1}AT2U93U31@RL7I$;KoOqha7`G{PjKD`R#}cZJ2bKTEoW$)HFtQ(l z0?mCLxAXlt;Te#8Mk$3(;O>d!FiFvr`{pSOkwaqhvA`m^kR;_|R!Qk;R16C1QqU>1 z$y7yPoQY)#MSN6|5&Ik5iMuRXCEIEY=DUVIblSMEvBk63J78!ws35BnvUL@Y^ z61%DFMXkAI=Xz0n8nykXZzavzUM%gwy(h8Ez0$qvEIyurL4n6nRA45@B057c9jgSh zP@2Sbc7p3C6UR4*FOOdkH}R)hOBGxFG`xyYX&)X0hB1@Z5{k;ru98}sk>7_7U>WCA_F79;oh2M1-Eb4&J&$bp zAY`LFwQ1|g3>M%H`pjH9?>uUGKF_~^9#erznn(&&VzNsJRfW&sPn52!@GxgK?k>k8 z%5S8PjDYPLN*#Dq+ILGrRY%EEM(QHzDUVT<3aaK$fhJCe%U&jB=P*omLXu=R<6$9{ zxQKpwHzuQ+_FIfH)bJ#=^o@EY|5TH0LjFbAs+5{zNo`Y}t)wouq~;d}Q`?yt^i*aQ z+XJQUZ9RBmAJ&&Tda%>|#UA`wQ`wtY2eG6qW6rWN`aYR9s4b~MEr zPs8@%hY2Yvm&G~$D8aEX4*GEdlotp6y|wcMJ#;d?wE^$&w}k!TSw26oO}7=`9j?fn ze3h{X+{4(qmkFbhvD(BP%Tb6GT)&Tdo4L}0`|&Y+5~~ov#~G!q^z=1&iqPHse7P47 z;5n|I;-|7+d>R+fh9AI#_u<9QVBnWbRKMbVP4EVg#czsvSSJdwUKGJE7Vz3ri%ziu z4~bO>i8Y9bHgt)N*eD*xCh=uH_hYj-gwKc*cvzgmBjPQ7X!{->6Yt`4;sZP`V*GG+ z6|GVNV|b>2 zz1?zH?&s=6o#S@!S zWvHxk7`fMJcDn9ILxUZp(FiyrNX4kP2naSw)o2}A6s|F{zSmzHf)_au!%|>LfSpO`E z$iJizDH={>e_A5{8c)s45oSSYX5y&00Q(8~WKFrsnxZ1CtPel8B8*GFSB)uAE#&j8 zl84z{9bsqi0&8S9%k@$Ez>BOrFVTE2GXh^#(weoVIqtKJO6f(sEf7;yNVC@PcP-~N zRL~r9?cZ*ymcrp`Ii6N6|DHtTKT>pCGMvb%v_$@s*}!aHU!ZPflQF;a);|2#AKYM^ zq4Lf$ockD7{S2}JhUps&fOAR=v%#33P}+PIX0n-^ufoix8rxwF#!O3lzr_DoGVi0z zvWF`!%`fP~{{pH$((Jd;`nBhgCm&*>UG^4oj10CxX7l%T8v7eeA8)bM{wCX?3re~> zOriDS&<>YNuipkfXx$GiALEJ z!;HTlGX8$V==m|@=pEL+pRhZBm$mObiuXSA!B0`gJTH4yGv(ALiE4)}k3S9wbtM!d zguD{&z&I(t$W>#W8po<}yc#E}agrK8qQ)s|oF^@^VGONjg@M= hQ;iGNc()oCtFcy%^=e!y?x8&VT}#|6n#6KU{C~*rN&x@> literal 5933 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