2013-02-27 4 views
2

Привет, я только что возился о полигонах и awt. Я создал Jframe и могу нарисовать многоугольники в порядке, и один из них перемещается с помощью нажатия клавиш.create game loop thread

Мне интересно, как начать поток gameloop (и где его поместить!), Который будет обновлять jframe независимо.

Из-за googling im поверили, что у меня должен быть один поток для ввода пользователем и один для самой игры.

В настоящее время я реализовал KeyListener на классе платы (код, показанный ниже), должен ли я поместить это в свой класс и сделать его реализуемым runnable? Когда код стоит, я перерисовываю JFrame в методе keypressed() так что я вижу, что он правильно перемещается.

Будучи на нем большую часть дня, и я очень сильно смущен :) Как всегда, любая помощь очень ценится!

Кроме того, в то время как им при использовании онлайн-тюнинга следует использовать JPanel вместо JFrame и paintComponent() вместо 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(); 
    } 
} 

ответ

4

Эти ответы в определенной степени зависят от того, какую игру вы пытаетесь создать.

От googling Я убежден, что у меня должен быть один поток для ввода пользователем, а другой - для самой игры.

Вы создаете один основной игровой цикл, который запускается в своей собственной теме. В psudeocode

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

Ваш пользовательский ввод обновит модель игры напрямую. Игровой цикл обновляет игровую модель, если компьютер должен делать ходы или реагировать на ваши ходы. Затем игровой цикл читает модель игры и рисует игру на основе значений в модели.

На данный момент я реализовал KeyListener на классе платы (код, показанный ниже), следует ли я его вынести в свой класс и сделать его реализуемым runnable?

Да, вы должны поставить KeyListener в свой класс. Нет, вам не нужно делать отдельный поток.

Чтобы сохранить ваши будущие проблемы, ваши компоненты Swing должны быть определены и использованы в потоке отправки событий.

Вот как вы это делаете.

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

Должен ли я использовать JPanel вместо JFrame и paintComponent() вместо краски()?

Да.

У вас должна быть JPanel внутри JFrame. JPanel - это место, где вы выполняете плейдокод с ничьей, используя метод paintComponent.

Некоторые люди будут не согласны со мной, но я нашел, что лучше всего, если каждый объект в игре имеет метод рисования, чтобы нарисовать себя.

public void draw(Graphics g) 

Модель игры также будет иметь метод draw, который рисует все объекты в модели.

Метод JPanel paintComponent будет выглядеть следующим образом:

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    gameModel.draw(g); 
} 
+0

Спасибо Гилберт, ночи отдыха и Ваш ответ получил это работает. – SocialistPig