Java 摇摆马模拟

Java Swing Horse Simulation

我无法在我的挥杆应用程序中更新我的马匹位置。我尝试了多种方法来更新马匹的 xPosition,因为它们在代表赛道的挥杆面板上刷新。

public class HorseModel{

    /*Horse dimensions*/
    private int x;
    private int y;
    private final int horsePerimeter = 20;

    public HorseModel(int xT, int yT){
    /*Constructor*/
        x = xT;
        y = yT;
    }
    public void setDimensions(int dimX, int dimY){
    /*Sets program dimensions*/
        x = dimX;
        y = dimY;
    }
    public void createHorse(Graphics2D h){
    /*Paints HorseModel on screen as 2 dimensional object*/

        Ellipse2D.Double horseModel = new Ellipse2D.Double(x, y, horsePerimeter, horsePerimeter);
        h.setColor(Color.RED);
        h.fill(horseModel);
        h.setColor(Color.YELLOW);
        h.draw(horseModel);
    }
}
public class HorseMovement implements Runnable{

    public final int xStartPos = 10; //change
    public final int yStartPos = 20;

    private RaceTrack hRaceTrack;
    private HorseModel Horse2D;
    private int xPos, yPos;

    public HorseMovement(RaceTrack r, int yPos_Spacing){
    /*Constructor*/
        xPos = xStartPos;
        yPos = yStartPos * yPos_Spacing;
        Horse2D = new HorseModel(xPos, yPos);
        hRaceTrack = r;
    }
    public HorseModel moveHorse(HorseModel horseObject){
    /*Updates horse positon*/
        horseObject = new HorseModel(xPos++, yPos);
        return horseObject;
    }
    public void paintComponent(Graphics h){
    /*paints the new horse after movement*/
        this.Horse2D = moveHorse(Horse2D);
        Graphics2D hMod = (Graphics2D) h;
        Horse2D.createHorse(hMod);
    }
    public void run(){
    /*Repaints the horse models as they increment movement across the screen*/
        hRaceTrack.repaint();
        hRaceTrack.revalidate();
    }
}
public class RacePanel extends JFrame{

    /*Frame Buttons*/
    private JPanel mPanel;
    private JButton startRace = new JButton("Start Race");
    private JButton stopRace = new JButton("Stop Race");
    private JButton startOver = new JButton("Start Over");


    /*Panel to fill with HorseModels for race*/
    private RaceTrack rTrack;

    /*Window dimensions*/
    public int Window_Height = 1024;
    public int Window_Width = 768;

    public RacePanel(){
    /*Constructor*/

        initGui();
        initRace();
        initQuit();

        setSize(Window_Width, Window_Height);
    }
    public void initGui(){
    /*Initializes the main race panel and sets button positions and layouts*/
        mPanel = new JPanel(new BorderLayout());
        rTrack = new RaceTrack();

        JPanel horsePanel = new JPanel(); //panel to house horse objects before running across screen

        horsePanel.setLayout(new GridLayout(1, 3));

        positionJPanels(horsePanel, mPanel);
    }
    public void initRace(){
    /*implements action listener for start race button*/
        class StartRace implements ActionListener{
            public void actionPerformed(ActionEvent e){
                startRace.setEnabled(true);
                rTrack.initTrack();
            }
        }
        ActionListener event = new StartRace();
        stopRace.addActionListener(event);
    }
    public void initQuit(){
    /*Implements the action listener for stop race button*/
        class StopRace implements ActionListener{
            public void actionPerformed(ActionEvent e){
                System.exit(0);//exits program if race is stopped
            }
        }
        ActionListener event = new StopRace();
        stopRace.addActionListener(event);
    }
    public void positionJPanels(JPanel h, JPanel p){
    /*Handles adding buttons to a JPanel*/
        h.add(startRace);
        h.add(startOver);
        h.add(stopRace);

        p.add(h, BorderLayout.NORTH); //sets the horse panel buttons to the top of the layout
        p.add(rTrack, BorderLayout.CENTER); //sets

        add(p);
    }
}

public class RaceController {

    public static void main(String[] args){
        new RaceController();
    }
    public RaceController(){
    /*Constructor*/
        JFrame mFrame = new RacePanel();
        mFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mFrame.setVisible(true);
    }

}
public class RaceTrack extends JPanel{

    /*Sets horses within race track*/
    private int numOfHorseObjects = 5;// change this to a dynamic
    private int numOfThreads = 25;

    /*Holds horse thread from HorseObject class*/
    private ArrayList<HorseMovement> horses = new ArrayList<>();
    private ArrayList<Thread> threads = new ArrayList(numOfThreads);

    public RaceTrack(){
    /*Constructor*/
        setBackground(Color.black);
        reset();
    }
    public void initTrack(){
    /*Starts the RaceTrack simulation*/
        threads.clear(); //clears the thread arraylist still residing

        for(int i = 0; i < horses.size(); i++){
            Thread T = new Thread(horses.get(i));
            T.start();
            threads.add(T);
        }
    }
    public void reset(){
    /*resets horse position within screen*/
        horses.clear();
        for(int i = 0; i < numOfHorseObjects; i++){
            horses.add(new HorseMovement(this, i + 1));
        }
    }
    public void paintComponent(Graphics g){
    /*overrides graphics paint method in order to paint the horse movements
    * through the arraylist of HorseMovements*/
        super.paintComponent(g);
        for(HorseMovement h : horses){
            h.paintComponent(g);
        }
    }
}

您的代码有问题:

  • 您从来没有给 startRace JButton 一个 ActionListener,那么按钮将如何产生影响,比赛将如何开始?请注意,您正在将 StartRace ActionListener 对象添加到 stopRace JButton,我猜这是错误的。
  • 即使您将该侦听器添加到 startRace 按钮,动作侦听器也只会让所有马匹前进一匹 "step" 而不会更多——您的后台线程中没有循环来重复执行动作。
  • 您似乎在不必要地创建新的 Horse2D 对象。为什么不简单地推进现有 Horse2D 对象的位置?
  • 我自己,为了简化代码,我会使用单个 Swing Timer 而不是一堆线程。