通过多线程的并发方法



我正在尝试用Java制作一个游戏,这是我第一次处理多线程(好吧,除了通过Clip类同时播放音乐之外。)我有一个Canvas类,它扩展了JPanel,但在Canvas类中,我也有一个KeyListener来接受输入,如下所示:

private class myKeyListener implements KeyListener
{
    public void keyPressed(KeyEvent keyEvent)
    {
        if(keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE){System.exit (0);}
        Thread thread3 = new Thread() 
            {
                public void run() {
                    if(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT){moveX(5, player1);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_LEFT){moveX(-5, player1);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_UP){moveY(-5, player1);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_DOWN){moveY (5, player1);}
                }
            };
        Thread thread4 = new Thread() 
            {
                public void run() {
                    if(keyEvent.getKeyCode() == KeyEvent.VK_D){moveX(5, player2);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_A){moveX(-5, player2);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_W){moveY(-5, player2);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_S){ moveY(5, player2);}
                }
            };
        Thread thread5 = new Thread() 
            {
                public void run() {
                    repaint();
                }
            };
        thread3.start();
        thread4.start();
        thread5.start();
        try{
            thread3.join();
            thread4.join();
            thread5.join();
        }
        catch (Exception e){System.out.println(e);}
        repaint();
    }
    public void keyReleased(KeyEvent keyEvent)
    {
    }
    public void keyTyped(KeyEvent keyEvent)
    {
    }
}

我的目标是拥有它,这样一个人就可以在画布上同时移动两个玩家(矩形)。目前,一次只能移动一个,但决不能同时移动两个。这是我第一次处理多线程,所以如果我犯了一个新手错误,我提前道歉。

这是代码。

你只需要一个线程,就可以完成"游戏循环"。

import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
import java.util.ArrayList;
public class Canvas2 extends JPanel {
    // attributes
    private Rectangle player1;
    private Rectangle player2;
    private ArrayList<KeyEvent> log;
    private boolean player1left = false;
    private boolean player1right = false;
    private boolean player1up = false;
    private boolean player1down = false;
    private boolean player2left = false;
    private boolean player2right = false;
    private boolean player2up = false;
    private boolean player2down = false;
    // constructor
    public Canvas2() {
        // initialize object
        player1 = new Rectangle(50, 50, 50, 50);
        player2 = new Rectangle(50, 50, 50, 50);
        log = new ArrayList<KeyEvent>();
        // set canavs background colour
        setBackground(Color.white);
        // add the key listener in the constructor of your canavas/panel
        addKeyListener(new myKeyListener());
        // ensure focus is on this canavas/panel for key operations.
        setFocusable(true);
        Thread gameLoop = new Thread() {
            public void run() {
                while (true) {
                    updatePlayers();
                    repaint();
                    pause(10);
                }
            }
        };
        gameLoop.start();
    }
    private void updatePlayers() {
        if (player1left) {
            moveX(-5, player1);
        }
        if (player1right) {
            moveX(5, player1);
        }
        if (player1up) {
            moveY(-5, player1);
        }
        if (player1down) {
            moveY(5, player1);
        }
        if (player2left) {
            moveX(-5, player2);
        }
        if (player2right) {
            moveX(5, player2);
        }
        if (player2up) {
            moveY(-5, player2);
        }
        if (player2down) {
            moveY(5, player2);
        }
    }
    // painting
    public void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);
        Graphics2D graphics2d = (Graphics2D) graphics;
        graphics.setColor(Color.blue);
        graphics2d.fill(player1);
        graphics2d.fill(player2);
    }
    // function which essentially re-creates rectangle with varying x
    // orientations. (x-movement)
    public void moveX(int mutationDistance, Rectangle sampleObject) {
        sampleObject.setBounds(sampleObject.x + mutationDistance,
                sampleObject.y, sampleObject.width, sampleObject.height);
    }
    // function which essentially re-creates rectangle with varying y
    // orientations. (y-movement)
    public void moveY(int mutationDistance, Rectangle sampleObject) {
        sampleObject.setBounds(sampleObject.x, sampleObject.y
                + mutationDistance, sampleObject.width, sampleObject.height);
    }
    // listener
    private class myKeyListener implements KeyListener {
        // implement all the possible actions on keys
        public void keyPressed(final KeyEvent keyEvent) {
            if (keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE) {
                System.exit(0);
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
                player1right = true;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_LEFT) {
                player1left = true;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_UP) {
                player1up = true;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN) {
                player1down = true;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_D) {
                player2right = true;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_A) {
                player2left = true;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_W) {
                player2up = true;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_S) {
                player2down = true;
            }

        }
        public void keyReleased(KeyEvent keyEvent) {
            if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
                player1right = false;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_LEFT) {
                player1left = false;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_UP) {
                player1up = false;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN) {
                player1down = false;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_D) {
                player2right = false;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_A) {
                player2left = false;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_W) {
                player2up = false;
            }
            if (keyEvent.getKeyCode() == KeyEvent.VK_S) {
                player2down = false;
            }
        }
        public void keyTyped(KeyEvent keyEvent) {
        }
    }
    public static void pause(int secs) {
        try {
            Thread.sleep(secs);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
import java.util.ArrayList;
/**
 * This code was originally by the user "UniBrain" from the website:
 * http://forum.codecall.net/topic/74377-moving-graphics-across-up-and-down-a-jpanel/?p=652384
 * 
 * but has been modified by me for my own purposes
 */
public class Canvas2 extends JPanel
{
//attributes
private Rectangle player1;
private Rectangle player2;
private ArrayList<KeyEvent> log;
//constructor
public Canvas2()
{
    //initialize object
    player1 = new Rectangle (50, 50, 50, 50);
    player2 = new Rectangle (50, 50, 50, 50);
    log = new ArrayList<KeyEvent>();
    //set canavs background colour
    setBackground (Color.white);
    //add the key listener in the constructor of your canavas/panel
    addKeyListener(new myKeyListener());
    //ensure focus is on this canavas/panel for key operations.
    setFocusable(true);
}
//painting
public void paintComponent(Graphics graphics)
{
    super.paintComponent(graphics);
    Graphics2D graphics2d =(Graphics2D)graphics;
    graphics.setColor(Color.blue);
    graphics2d.fill(player1);
    graphics2d.fill(player2);
}
//function which essentially re-creates rectangle with varying x orientations. (x-movement)
public void moveX(int mutationDistance, Rectangle sampleObject)
{
    sampleObject.setBounds(sampleObject.x + mutationDistance, sampleObject.y, sampleObject.width, sampleObject.height);
}
//function which essentially re-creates rectangle with varying y orientations. (y-movement)
public void moveY(int mutationDistance, Rectangle sampleObject)
{
    sampleObject.setBounds(sampleObject.x, sampleObject.y + mutationDistance, sampleObject.width, sampleObject.height);
}
public void move(){
    /*
     * This method of keeping track of key events and using a loop is taken from the user Michael Meyers at
     * http://stackoverflow.com/questions/752999/how-do-i-handle-multiple-key-presses-in-java
     */
    Thread thread1 = new Thread() 
        {
            public void run() {
                for(KeyEvent keyEvent: log){
                    if(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT){moveX(5, player1);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_LEFT){moveX (-5, player1);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_UP){moveY (-5, player1);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_DOWN){moveY (5, player1);}
                }
            }
        };
    Thread thread2 = new Thread() 
        {
            public void run() {
                for(KeyEvent keyEvent: log){
                    if(keyEvent.getKeyCode() == KeyEvent.VK_D){moveX(5, player2);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_A){moveX(-5, player2);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_W){moveY(-5, player2);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_S){moveY(5, player2);}
                }
            }
        };
    //Starts the threads
    thread1.start();
    thread2.start();
    //Waits for them to finish
    try{
        thread1.join();
        thread2.join();
        log = new ArrayList<KeyEvent>();
    }
    catch (Exception e){System.out.println(e);}
}
//listener
private class myKeyListener implements KeyListener
{
    //implement all the possible actions on keys
    public void keyPressed(KeyEvent keyEvent)
    {
        if(keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE){System.exit (0);}
        Thread thread3 = new Thread() 
            {
                public void run() {
                    if(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT){moveX(5, player1);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_LEFT){moveX(-5, player1);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_UP){moveY(-5, player1);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_DOWN){moveY (5, player1);}
                }
            };
        Thread thread4 = new Thread() 
            {
                public void run() {
                    if(keyEvent.getKeyCode() == KeyEvent.VK_D){moveX(5, player2);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_A){moveX(-5, player2);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_W){moveY(-5, player2);}
                    if(keyEvent.getKeyCode() == KeyEvent.VK_S){ moveY(5, player2);}
                }
            };
        Thread thread5 = new Thread() 
            {
                public void run() {
                    repaint();
                }
            };
        thread3.start();
        thread4.start();
        thread5.start();
        try{
            thread3.join();
            thread4.join();
            thread5.join();
        }
        catch (Exception e){System.out.println(e);}
        repaint();
    }
    public void keyReleased(KeyEvent keyEvent)
    {
    }
    public void keyTyped(KeyEvent keyEvent)
    {
    }
}
public static void pause(int secs){
    try{Thread.sleep(secs*0);} catch(Exception e){}
}
}

然后由该类执行

import javax.swing.JFrame;
import java.awt.Dimension;
/**
 * This code was taken from the user "UniBrain" from the website:
 * http://forum.codecall.net/topic/74377-moving-graphics-across-up-and-down-a-jpanel/?p=652384
 */
public class Display
{   
public static void main ( String [ ] arguments )
{
    JFrame frame = new JFrame("key listener demo");
    Canvas2 panel = new Canvas2();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(panel);
    frame.setContentPane(panel);
    frame.setPreferredSize(new Dimension(800, 600));
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.pack();
}
}

最新更新