This commit is contained in:
2025-09-25 18:22:28 +08:00
parent be5f00c313
commit e67428431f
20 changed files with 284 additions and 176 deletions

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>uno.mloluyu</groupId>
<artifactId>game</artifactId>
<name>game</name>
<version>1.0-SNAPSHOT</version>
<description>LibGDX Desktop Game</description>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<release>${maven.compiler.source}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<mainClass>${exec.mainClass}</mainClass>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<minimizeJar>false</minimizeJar>
<shadedArtifactSet />
<transformers>
<transformer>
<mainClass>${exec.mainClass}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<exec.mainClass>uno.mloluyu.desktop.DesktopLauncher</exec.mainClass>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<gdx.version>1.12.1</gdx.version>
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss</maven.build.timestamp.format>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -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); // 默认调用父类攻击逻辑

View File

@@ -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<Integer, Float> keyPressDuration = new HashMap<>();
private Action currentAction = Action.IDLE; // 当前动作状态(待机、攻击、受击等)
private float verticalSpeed = 0f; // 垂直速度(可用于跳跃或下落)
@@ -28,41 +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 Iterable<Integer> pressedKeys = new HashMap<Integer, Float>().keySet(); // 初始化 pressedKeys
// 攻击持续时间(秒)
private float attackTimer = 0f;
private static final float ATTACK_DURATION = 0.15f; // 攻击判定显示时间
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; // 构造函数,初始化角色名称
}
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("light"); // 默认使用普通攻击的攻击盒更新
// 攻击只持续一帧
if (isAttacking) {
isAttacking = false;
changeAction(Action.IDLE);
// 自愈:动作是 ATTACK 但标记丢失
if (currentAction == Action.ATTACK && attackTimer > 0f && !isAttacking) {
isAttacking = true;
attackJustStarted = false;
}
processPressedKeys(deltaTime);
// 攻击计时
if (isAttacking) {
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");
}
// 垂直移动(跳跃或重力
// 垂直运动 & 重力
if (!isGrounded) {
verticalSpeed -= 2500 * deltaTime; // 简单重力模拟
verticalSpeed -= 2500 * deltaTime;
hitbox.y += verticalSpeed * deltaTime;
if (hitbox.y <= 0) {
hitbox.y = 0;
verticalSpeed = 0;
@@ -72,45 +92,56 @@ 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());
} else if (keycode == Input.Keys.RIGHT || keycode == Input.Keys.D) {
move(1, Gdx.graphics.getDeltaTime());
}
if (isPressed && !isAttacking) {
if (keycode == Input.Keys.SPACE || keycode == Input.Keys.UP || keycode == Input.Keys.W) {
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.SPACE || keycode == Input.Keys.UP || keycode == Input.Keys.W) {
jump();
}
}
} else {
keyPressDuration.remove(keycode);
if ((keycode == Input.Keys.LEFT || keycode == Input.Keys.RIGHT || keycode == Input.Keys.A
|| keycode == Input.Keys.D) &&
getCurrentAction() == Action.MOVE) {
@@ -182,8 +213,13 @@ public class SimpleFighter {
public void attack(String attackType) {
isAttacking = true;
attackTimer = ATTACK_DURATION;
attackJustStarted = true;
changeAction(Action.ATTACK);
updateAttackbox(attackType); // 根据攻击类型更新攻击盒位置
updateAttackbox(attackType);
attackInvokeCount++;
if (debugEnabled)
System.out.println("[ATTACK] type=" + attackType + " count=" + attackInvokeCount);
}
public void takeHit(int damage) {
@@ -219,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;
}
}

View File

@@ -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 -> {
}

View File

@@ -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

View File

@@ -5,6 +5,8 @@ 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;
@@ -25,6 +27,7 @@ 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;
@@ -39,6 +42,7 @@ public class GameScreen extends ScreenAdapter {
batch = new SpriteBatch();
shapeRenderer = new ShapeRenderer();
debugFont = new com.badlogic.gdx.graphics.g2d.BitmapFont(); // 初始化 debugFont
Gdx.input.setInputProcessor(controller);
}
@@ -46,58 +50,98 @@ 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);
Map<String, float[]> positions = NetworkManager.getInstance().getPlayerPositions();
if (positions != null) {
for (Map.Entry<String, float[]> 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();
renderFighter(player, Color.BLUE);
if (player.isAttacking())
renderAttackBox(player, Color.RED);
// -------- 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();
Map<String, float[]> positions = NetworkManager.getInstance().getPlayerPositions();
if (positions != null) {
for (Map.Entry<String, float[]> 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);
}
// -------- 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();
}
shapeRenderer.end();
// 绘制地图边界
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.setColor(Color.WHITE);
shapeRenderer.rect(0, 0, 1000, 1000); // 假设地图边界为1000x1000的区域
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() {

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

Binary file not shown.

View File

@@ -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

View File

@@ -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

Binary file not shown.