0

为了更加熟悉线程,我一直在从事 Java 的一个辅助项目。它是一个 cookie clicker 克隆,它使用不同的线程用于 clicker、counter 和其他所有内容。在尝试运行最终构建时,我得到一个无限递归错误,导致我的一个类初始化时堆栈溢出。我已经尝试将类移动到它自己的文件中,但这似乎并没有改变任何东西。这是代码:

游戏.java

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.Dimension;

public class Game { // main class
    // Integer
    int total = 0;
    int perSec = 0;
    int perClick = 1;
    int upgradeIndex = 0;
    // Boolean
    boolean running = false;
    // JFrame
    JFrame window;
    // JTextField
    JTextField totalDisplay;
    // JButton
    JButton clickArea;
    JButton upgrade1;
    JButton upgrade2;
    JButton upgrade3;
    JButton nextPage;
    JButton prevPage;
    // JPanel
    JPanel clickWindow;
    JPanel upgrades;
    JPanel navigation;
    // Upgrades
        // Click upgrade
    PerClickUpgrade exclamation; // amount 1 cost 10
    PerClickUpgrade at; // amount 10 cost 100
    PerClickUpgrade hashtag; // amount 100 cost 1000
    PerClickUpgrade dollar; // amount 1000 cost 10000
        // Sec upgrade
    PerSecUpgrade percent; // amount 10 cost 1000
    PerSecUpgrade carrot; // amount 100 cost 10000
    PerSecUpgrade and; // amount 1000 cost 100000
        // Click multiplier
    PerClickMultiplier asterisk; // amount 2x cost 1000000
        // Sec multiplier
    PerSecMultiplier tilde; // amount 2x cost 10000000

    Game() {
        window = new JFrame(); // main window
        clickWindow = new JPanel(); // panel for click button
        upgrades = new JPanel(); // panel for upgrades
        upgrade1 = new JButton();
        upgrade2 = new JButton();
        upgrade3 = new JButton();
        navigation = new JPanel(); // navigate upgrade menu
        nextPage = new JButton();
        prevPage = new JButton();
        exclamation = new PerClickUpgrade("!", 1, 10, upgrade1);
        at = new PerClickUpgrade("@", 10, 100, upgrade2);
        hashtag = new PerClickUpgrade("#",100,1000,upgrade3);
        dollar = new PerClickUpgrade("$",1000,10000,upgrade1);
        percent = new PerSecUpgrade("%",10,1000,upgrade2);
        carrot = new PerSecUpgrade("^",100,10000, upgrade3);
        and = new PerSecUpgrade("&", 1000,100000, upgrade1);
        asterisk = new PerClickMultiplier("*",2,1000000, upgrade2);
        tilde = new PerSecMultiplier("~", 2, 10000000, upgrade3);
        window.setSize(new Dimension(800, 600));
        window.setResizable(false);
        window.setLocationRelativeTo(null);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setTitle("ASCII Clicker");
        window.setLayout(new BorderLayout());
        clickWindow.setPreferredSize(new Dimension((800 / 2), 600));
        upgrades.setPreferredSize(new Dimension((800 / 2), 600));
        navigation.setPreferredSize(new Dimension((800 / 2), (600 / 4)));
        clickWindow.setLayout(new BorderLayout());
        navigation.setLayout(new BorderLayout());
        window.add(clickWindow, BorderLayout.WEST);
        window.add(upgrades, BorderLayout.EAST);
        clickWindow.add(totalDisplay, BorderLayout.PAGE_START);
        clickWindow.add(clickArea, BorderLayout.CENTER);
        upgrades.add(upgrade1);
        upgrades.add(upgrade2);
        upgrades.add(upgrade3);
        upgrades.add(navigation);
        navigation.add(nextPage, BorderLayout.EAST);
        navigation.add(prevPage, BorderLayout.WEST);
        window.pack();
        Thread clickDetection = new Thread(new Clicker()); // detects clicks
        Thread counter = new Thread(new Counter()); // counts total
        clickDetection.start();
        counter.start();
        window.setVisible(true);
        exclamation.update(); // sets exclamation, at, and hashtag as displayed upgrades
        at.update();
        hashtag.update();
        upgrade1.addActionListener(e -> {
            switch (upgradeIndex) {
                case 0 -> exclamation.buy();
                case 1 -> dollar.buy();
                case 2 -> and.buy();
            }
        });
        upgrade2.addActionListener(e -> {
            switch (upgradeIndex) {
                case 0 -> at.buy();
                case 1 -> percent.buy();
                case 2 -> asterisk.buy();
            }
        });
        upgrade3.addActionListener(e -> {
            switch (upgradeIndex) {
                case 0 -> hashtag.buy();
                case 1 -> carrot.buy();
                case 2 -> tilde.buy();
            }
        });
        prevPage.addActionListener(e -> {
            if (upgradeIndex != 0) {
                upgradeIndex--;
                switch (upgradeIndex) {
                    case 0 -> {
                        exclamation.update();
                        at.update();
                        hashtag.update();
                    }
                    case 1 -> {
                        dollar.update();
                        percent.update();
                        carrot.update();
                    }
                    case 2 -> {
                        and.update();
                        asterisk.update();
                        tilde.update();
                    }
                }
            }
        });
        nextPage.addActionListener(e -> {
            if (upgradeIndex != 2) {
                upgradeIndex++;
                switch (upgradeIndex) {
                    case 0 -> {
                        exclamation.update();
                        at.update();
                        hashtag.update();
                    }
                    case 1 -> {
                        dollar.update();
                        percent.update();
                        carrot.update();
                    }
                    case 2 -> {
                        and.update();
                        asterisk.update();
                        tilde.update();
                    }
                }
            }
        });
    }

    public static void main(String[] args) {
        new Game();
    }
}

class Counter extends Game implements Runnable { // Updates counter

    @Override
    public void run() {
        running = true;
        while (running) {
            total += (perSec / 10);
            totalDisplay.setText(String.valueOf(total));
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Clicker extends Game implements Runnable { // Records clicks

    @Override
    public void run() {
        clickArea.setText("()");
        clickArea.addActionListener(e -> total += perClick);
    }
}

PerClickUpgrade.java


class PerClickUpgrade extends Game {
    private int totalUpgrade = 0;
    private int totalCost;
    private final int upgradeAmount;
    private final int cost;
    private int timesBought = 0;
    private final JButton display;
    private final String symbol;

    PerClickUpgrade(String symbol, int upgradeAmount, int cost, JButton display) {
        this.symbol = symbol;
        this.totalCost = cost;
        this.cost = cost;
        this.upgradeAmount = upgradeAmount;
        this.display = display;
    }

    public void update() {
        this.display.setText(
                this.symbol +
                        "\nOwned: " +
                        this.timesBought +
                        "\nPer Click Increase: " +
                        this.totalUpgrade +
                        "\nCost: " +
                        this.totalCost
        );
    }

    public void buy() {
        if (total >= this.totalCost) {
            this.timesBought++;
            this.totalUpgrade += this.upgradeAmount;
            perClick = this.totalUpgrade;
            total -= this.cost;
            this.totalCost += (this.cost / 2);
            this.update();
        }
    }
}

PerSecUpgrade.java


class PerSecUpgrade extends Game {
    private int totalUpgrade = 0;
    private int totalCost;
    private final int upgradeAmount;
    private final int cost;
    private int timesBought = 0;
    private final JButton display;
    private final String symbol;

    PerSecUpgrade(String symbol, int upgradeAmount, int cost, JButton display) {
        this.symbol = symbol;
        this.totalCost = cost;
        this.cost = cost;
        this.upgradeAmount = upgradeAmount;
        this.display = display;
    }

    void update() {
        this.display.setText(
                this.symbol +
                        "\nOwned: " +
                        this.timesBought +
                        "\nPer Click Increase: " +
                        this.totalUpgrade +
                        "\nCost: " +
                        this.totalCost
        );
    }

    void buy() {
        if (total >= this.totalCost) {
            this.timesBought++;
            this.totalUpgrade += this.upgradeAmount;
            perSec = this.totalUpgrade;
            total -= this.cost;
            this.totalCost += (this.cost / 2);
            this.update();
        }
    }
}

PerSecMultiplier.java


class PerSecMultiplier extends Game {
    private int totalCost;
    private final int upgradeAmount;
    private final int cost;
    private int timesBought = 0;
    private final JButton display;
    private final String symbol;

    PerSecMultiplier(String symbol, int upgradeAmount, int cost, JButton display) {
        this.symbol = symbol;
        this.totalCost = cost;
        this.cost = cost;
        this.upgradeAmount = upgradeAmount;
        this.display = display;
    }

    void update() {
        this.display.setText(
                this.symbol +
                        "\nOwned: " +
                        this.timesBought +
                        "\n" +
                        this.upgradeAmount +
                        "x Per Sec\nCost: " +
                        this.cost
        );
    }

    void buy() {
        if (total >= this.totalCost) {
            this.timesBought++;
            perSec *= this.upgradeAmount;
            total -= this.totalCost;
            this.totalCost += (this.cost / 2);
            this.update();
        }
    }
}

每次点击乘数


public class PerClickMultiplier extends Game {
    private final int upgradeAmount;
    private final int cost;
    private final JButton display;
    private final String symbol;
    private int totalCost;
    private int timesBought = 0;

    PerClickMultiplier(String symbol, int upgradeAmount, int cost, JButton display) {
        this.totalCost = cost;
        this.upgradeAmount = upgradeAmount;
        this.cost = cost;
        this.display = display;
        this.symbol = symbol;
    }

    void update() {
        this.display.setText(
                this.symbol +
                        "\nOwned: " +
                        this.timesBought +
                        "\n" +
                        this.upgradeAmount +
                        "x Per Click\nCost: " +
                        this.cost
        );
    }

    void buy() {
        if (total >= this.totalCost) {
            this.timesBought++;
            perClick *= this.upgradeAmount;
            total -= this.totalCost;
            this.totalCost += (this.cost / 2);
            this.update();
        }
    }
}

任何其他一般性批评也值得赞赏。

4

0 回答 0