Java游戏超级玛丽的代码优化

代码来源:https://blog.csdn.net/loveliveluo/article/details/125445852?ops_request_misc=&request_id=&biz_id=102&utm_term=java小项目可改进&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-5-125445852.142v101pc_search_result_base5&spm=1018.2226.3001.4187(具体信息可阅读链接的csdn的博客)

由于该项目代码量过大,我只对其中的一个Java类进行了优化和改进。

程序运行环境:
1.操作系统:Windows系统
2.调试软件名称:IntelliJ IDEA
3.调试软件版本号:IntelliJ IDEA 2024版
运行截图
我只优化了里面的Obstacle.java类(该类主要是将障碍物的坐标,类型,图片定下来,以及用于判断马里奥是否到达旗子处)
原始代码如下:
``public class Obstacle implements Runnable {
// 用于表示坐标
private int x;
private int y;
// 用于记录障碍物类型
private int type;
// 用于显示图像
private BufferedImage show = null;
// 定义当前的场景对象
private BackGround bg = null;
// 定义一个线程对象
private Thread thread=new Thread(this);
public Obstacle(int x, int y, int type, BackGround bg){
this.x = x;
this.y = y;
this.type=type;
this.bg = bg;
show=StaticValue.obstacle.get(type);
// 如果是旗子的话,启动线程
if(type==8){
thread.start();
}
}

public int getType() {
    return type;
}

public BufferedImage getShow() {
    return show;
}

public int getX() {
    return x;
}

public int getY() {
    return y;
}

@Override
public void run() {
    while(true){
        if(this.bg.isReach()){
            if(this.y<374){
                this.y+=5;
            }else {
                this.bg.setBase(true);
            }
        }
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

}``
对于这段代码,我发现存在以下几个问题:
1.线程创建与资源浪费:在类定义时就创建了线程对象 private Thread thread=new Thread(this);,不管障碍物类型是不是旗子,线程对象都会被创建。但实际上只有当 type == 8 时才需要启动线程,这可能会造成不必要的资源浪费。

2.缺乏线程停止机制:代码中使用了 while(true) 这样的无限循环,没有提供停止线程的方法。这会导致线程一旦启动,就无法从外部停止,可能会造成资源泄漏,尤其是在游戏结束或者障碍物不再需要移动时。

3.代码的可读性和可维护性较差:代码中缺乏必要的常量定义和注释,使得代码的可读性和可维护性较差。例如,type == 8 代表旗子,但是没有使用常量来表示,后续如果需要修改旗子的类型编号,就需要在多个地方修改代码。

针对上述问题,我进行了代码的优化和改进:
1.线程创建和启动优化:源代码中在类定义时就创建了线程对象 private Thread thread=new Thread(this),不管障碍物类型如何都会创建线程对象;而在新代码,我将线程对象的创建移到了构造函数中,只有当 type == 8 时才创建并启动线程。这样的好处是避免了不必要的线程对象创建,减少了资源浪费,提高了资源的使用效率。

2.引入线程停止机制:源代码使用 while(true) 构建无限循环,没有提供停止线程的方法;而新代码引入了 isRunning 标志和 stopRunning 方法,用于控制线程的运行和停止。这样的好处是使得线程可以在需要时被安全地停止,避免了资源泄漏,增强了程序的健壮性。

3.通过定义常量增强代码的可读性和可维护性:如源代码中使用硬编码的数值 374 和 50 分别表示旗子移动的最大 Y 坐标和线程休眠时间,这种直接写死的数值在代码中难以理解其具体含义,且后续修改时需要在代码多处查找和修改;而新代码将这些数值定义为常量 FLAG_MAX_Y 和 SLEEP_TIME,从常量名就能清晰知道其代表的含义,而且后续如果需要修改,只需要修改常量定义处即可。

经过优化后,项目仍然能够正常运行。虽然项目运行后与原来相比没有什么不同,但是在代码层面上,我提高了代码的可读性和可维护性,并且减少了内存等资源的浪费,解决了可能出现的死循环问题。

难点
1.由于本项目较为大,代码量较多,耦合性较强,并且不同模块的开发人员也不一样,因此阅读起来较为困难。
2.我引入了volatile 关键字来保证可见性,防止sRunning 可能会被多个线程同时访问和修改,但是这只是解决了部分问题。在 stopRunning 方法中修改 isRunning 并调用 thread.interrupt() 时,这两个操作不是原子的,可能会导致线程状态不一致。

思考:
1.通过逆向工程,我深入理解 Obstacle 类的功能,包括障碍物的坐标表示、类型记录、图像显示以及线程控制等。这有助于发现代码中隐藏的逻辑和设计意图,例如为什么使用 type == 8 来判断是否为旗子,以及线程的作用和运行机制。
2.基于逆向工程的结果,可以制定合理的代码重构策略。例如,将硬编码的数值提取为常量,引入更完善的线程管理机制等。这些重构措施可以提高代码的可读性、可维护性和可扩展性。

posted @ 2025-02-27 20:40  叶陵枫  阅读(28)  评论(0)    收藏  举报