ADC2000 ADC2000 - 6 months ago 13
Java Question

Concurrent methods via multithreading

I am trying to make a game in Java and this is my first time dealing with multithreading (well, asides from playing music concurrently via the Clip class.) I have a Canvas class which extends JPanel, but within the Canvas class I also have a KeyListener to take input, shown here:

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)
{
}
}


My goal is to have it so that one can move both players (which are Rectangles) at the same time on the canvas. Currently, one can only move them one at a time, but never both at the same time. This is my first time dealing with multithreading so I apologize in advance if I am making a rookie mistake.

Answer

Here is the code.

You need just one thread, to do the "game loop".

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();
        }
    }
}
Comments