Java Swing Horse模拟

时间:2015-11-15 01:16:35

标签: java multithreading swing 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);
        }
    }
}

1 个答案:

答案 0 :(得分:3)

您的代码问题:

  • 你永远不会给startRace JButton一个ActionListener,那么按钮将如何影响,以及比赛将如何开始?请注意,您将StartRace ActionListener对象添加到stopRace JButton,我猜这是错误的。
  • 即使您将该监听器添加到startRace按钮,动作监听器也只会使所有匹马前进一步&#34;步骤&#34;而且没有 - 你的后台线程中没有循环来重复执行操作。
  • 你似乎在不必要地创造新的Horse2D对象。为什么不简单地推进现有Horse2D对象的位置?
  • 我自己,我使用单个Swing Timer而不是一堆线程来简化代码。