Question

Hi I have just been messing about polygons and awt. I have created a Jframe and can draw the polygons ok and have one of them move with keypresses.

I'm wondering how to start a gameloop thread(and where to put it!) that will update the jframe independently.

From googling im led to believe that I should have one thread for user input and one for the game itself.

At the moment I have implemented KeyListener on the board class(code shown below),should I put that out into its own class and make it implement runnable?As the code stands I repaint the JFrame in the keypressed() method just so i can see that it moves correctly

Being at it most of the day and I have myself very very confused :) As always any help much appreciated!

Also while im at it from online tutourials should I use JPanel instead of JFrame and paintComponent() instead of paint()?

    import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;

import javax.swing.JFrame;

public class Board extends JFrame implements KeyListener{
    AffineTransform identity = new AffineTransform();
    Graphics2D g2d;

    Ship ship = new Ship();

    public static final int ALIENS = 3;
    Alien[] alien = new Alien[ALIENS];


    Board(){
        super("The Board");
        setSize(1280,1024);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setBackground(Color.BLACK);
        for(int x=0;x<ALIENS;x++){
            alien[x]=new Alien();
        }
    }

    public void paint(Graphics g){
        super.paint(g);
        addKeyListener(this);
        //draw ship
        g2d = (Graphics2D)g;    
        g2d.setTransform(identity);
        g2d.translate(ship.getxPos(),ship.getyPos());
        g2d.scale(2,2);
        g2d.setColor(Color.ORANGE);
        g2d.fill(ship.getShape());
        g2d.setColor(Color.BLACK);
        g2d.draw(ship.getShape());

        // draw aliens
        for(int x=0;x<ALIENS;x++){
            //if alien alive
            if(alien[x].isAlive()){
                //draw alien
                g2d = (Graphics2D)g;    
                g2d.setTransform(identity);
                g2d.translate(alien[x].getxPos(),alien[x].getyPos());
                g2d.scale(2,2);
                g2d.setColor(Color.BLUE);
                g2d.fill(alien[x].getShape());
                g2d.setColor(Color.BLACK);
                g2d.draw(alien[x].getShape());
            }
        }
    }//end paint


    /*****************************************************
     * key listener events
     *****************************************************/
    public void keyReleased(KeyEvent k) { }
    public void keyTyped(KeyEvent k) { }
    public void keyPressed(KeyEvent k) {
        int keyCode = k.getKeyCode();

        switch (keyCode) {

        case KeyEvent.VK_A:
            //move ship left
            if(ship.getxPos()<20){
                ship.setxPos(20);
            }else
            ship.setxPos(ship.getxPos()-1);
            break;
        case KeyEvent.VK_D:
            if(ship.getxPos()>1260){
                ship.setxPos(1260);
            }else
            ship.setxPos(ship.getxPos()+1);
        }
       repaint();
    }//end keypressed event

    public static void main(String[] args){
        new Board();
    }
}
Was it helpful?

Solution

These answers depend somewhat on what kind of game you're trying to create.

From googling I'm led to believe that I should have one thread for user input and one for the game itself.

You create one main game loop, which runs in its own thread. In psudeocode

while (running) {
    update game model
    draw game
    wait x milliseconds
} 

Your user input would update the game model directly. The game loop updates the game model if the computer is required to make moves or react to your moves. Then, the game loop reads the game model and draws the game based on the values in the model.

At the moment I have implemented KeyListener on the board class(code shown below),should I put that out into its own class and make it implement runnable?

Yes, you should put KeyListener into its own class. No, you don't have to make it a separate thread.

To save yourself future trouble, your Swing components should be defined and used on the Event Dispatch thread.

Here's how you do that.

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new Board();
        }
    });
}

Should I use JPanel instead of JFrame and paintComponent() instead of paint()?

Yes.

You should have a JPanel inside of a JFrame. The JPanel is where you perform the draw game psudeocode, using the paintComponent method.

Some people are going to disagree with me, but I've found it best if every object in the game has a draw method to draw itself.

public void draw(Graphics g)

The game model would also have a draw method, which draws all of the objects in the model.

The JPanel paintComponent method would look like this:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    gameModel.draw(g);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top