2012-09-15 22 views
0

我應該做一個小遊戲模擬。在這個遊戲中有三個按鈕。當用戶點擊關閉按鈕坦克時,用戶點擊啓動坦克和汽車將相互關閉90度,將汽車拋出子彈。如何通知擺動遊戲上的多線程事件

我爲此做了一個模擬。坦克扔子彈到汽車,但當子彈碰撞車我不能這樣。我只需要增加坦克打車的次數。

這裏是源代碼

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 

import javax.swing.JPanel; 

public class Vehicle extends Thread { 
    private JPanel box; 

    private int XSIZE; 

    private int YSIZE; 

    private int time; 

    private int x; 

    private int y; 

    private int dx = 5; 

    private int dy = 5; 

    private int dim; 

    public Vehicle(JPanel b, int i) { 
     box = b; 
     this.dim = i; 
     if (i == 0) { 
      x = 0; 
      y = 100; 
      time = 1000; 
      XSIZE = 9; 
      YSIZE = 20; 
     } else { 
      time = 200; 
      y = box.getSize().height; 
      x = box.getSize().width/2; 
      XSIZE = 6; 
      YSIZE = 10; 
     } 
    } 

    public void draw() { 
     Graphics g = box.getGraphics(); 
     g.fillOval(x, y, XSIZE, YSIZE); 
     g.dispose(); 
    } 

    public void moveHorizontal() { 
     if (!box.isVisible()) 
      return; 
     Graphics g = box.getGraphics(); 
     g.setColor(Color.BLUE); 
     g.setXORMode(box.getBackground()); 
     g.fillOval(x, y, XSIZE, YSIZE); 
     x += dx; 

     Dimension d = box.getSize(); 
     if (x < 0) { 
      x = 0; 
      dx = -dx; 
     } 
     if (x + XSIZE >= d.width) { 
      x = d.width - XSIZE; 
      dx = -dx; 
     } 

     g.fillOval(x, y, XSIZE, YSIZE); 
     g.dispose(); 
    } 

    public JPanel getBox() { 
     return box; 
    } 

    public void setBox(JPanel box) { 
     this.box = box; 
    } 

    public void moveVertical() { 
     if (!box.isVisible()) 
      return; 
     Graphics g = box.getGraphics(); 
     g.setXORMode(box.getBackground()); 
     g.fillOval(x, y, XSIZE, YSIZE); 
     y += dy; 
     Dimension d = box.getSize(); 
     if (y < 0) { 
      y = 0; 
      dy = -dy; 
     } 
     if (y + YSIZE >= d.height) { 
      y = d.height - YSIZE; 
      dy = -dy; 
     } 

     g.fillOval(x, y, XSIZE, YSIZE); 
     g.dispose(); 
    } 

    public void move(int i) { 

     if (i == 0) { 

      moveHorizontal(); 
     } else { 
      moveVertical(); 
     } 
    } 

    public int getYSIZE() { 
     return YSIZE; 
    } 

    public void setYSIZE(int ySIZE) { 
     YSIZE = ySIZE; 
    } 

    public int getX() { 
     return x; 
    } 

    public void setX(int x) { 
     this.x = x; 
    } 

    public int getY() { 
     return y; 
    } 

    public int getXSIZE() { 
     return XSIZE; 
    } 

    public void setXSIZE(int xSIZE) { 
     XSIZE = xSIZE; 
    } 

    public void setY(int y) { 
     this.y = y; 
    } 

    public void run() { 
     try { 
      draw(); 
      for (;;) { 
       move(dim); 
       sleep(time); 
      } 
     } catch (InterruptedException e) { 
     } 
    } 

} 

    import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 

import javax.swing.JPanel; 

public class Bullet extends Thread { 
    private JPanel box; 

    private int XSIZE = 3; 

    public int getXSIZE() { 
     return XSIZE; 
    } 

    public void setXSIZE(int xSIZE) { 
     XSIZE = xSIZE; 
    } 

    public int getX() { 
     return x; 
    } 

    public void setX(int x) { 
     this.x = x; 
    } 

    private int YSIZE = 1; 

    private int x; 

    private int y; 

    private int dx = 3; 

    public Bullet(JPanel b, Vehicle tank, Vehicle car) { 
     box = b; 

     x = tank.getX() + tank.getXSIZE(); 
     if (x >= tank.getBox().getSize().width/2) 
      dx = -dx; 

     y = tank.getY() + tank.getYSIZE()/2; 
     ; 

    } 

    public void draw() { 
     Graphics g = box.getGraphics(); 
     g.fillOval(x, y, XSIZE, YSIZE); 
     g.dispose(); 
    } 

    public void move() { 
     if (!box.isVisible()) 
      return; 
     Graphics g = box.getGraphics(); 
     g.setColor(Color.RED); 
     g.setXORMode(box.getBackground()); 
     g.fillOval(x, y, XSIZE, YSIZE); 
     x += dx; 

     Dimension d = box.getSize(); 

     if (x < 0) { 
      x = 0; 

     } 
     if (x + XSIZE >= d.width) { 
      x = d.width - XSIZE; 

     } 
     g.fillOval(x, y, XSIZE, YSIZE); 
     g.dispose(); 

    } 

    public void run() { 
     try { 
      draw(); 
      for (;;) { 
       move(); 

       sleep(20); 
      } 
     } catch (InterruptedException e) { 
     } 
    } 

} 

    import java.awt.Container; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JLabel; 

@SuppressWarnings("serial") 
public class Tank_Shut_Car_ThreadFrame extends JFrame { 

    private JPanel canvas; 
    private boolean isOn = false; 
    private Vehicle tank; 
    private Vehicle car; 
    private JLabel score; 
    public static int sc = 0; 

    public Tank_Shut_Car_ThreadFrame() { 
     setResizable(false); 
     setSize(600, 400); 
     setTitle("Tank Shut Car"); 
     addWindowListener(new WindowAdapter() { 
      public void windowClosing(WindowEvent e) { 
       System.exit(0); 
      } 
     }); 

     Container contentPane = getContentPane(); 
     canvas = new JPanel(); 
     contentPane.add(canvas, "Center"); 
     canvas.setLayout(null); 

     score = new JLabel("0"); 
     score.setBounds(527, 11, 36, 14); 
     canvas.add(score); 

     JLabel lblScore = new JLabel("score"); 
     lblScore.setBounds(481, 11, 36, 14); 
     canvas.add(lblScore); 
     JPanel p = new JPanel(); 

     addButton(p, "Start", new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 

       if (!isOn) { 
        tank = new Vehicle(canvas, 0); 
        tank.start(); 
        car = new Vehicle(canvas, 1); 
        car.start(); 
        isOn = true; 
       } 
      } 
     }); 

     addButton(p, "Shut", new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 

       if (isOn) { 
        Bullet bullet = new Bullet(canvas, tank, car); 
        bullet.start(); 
        score.setText("" + sc); 
       } 

      } 
     }); 
     addButton(p, "Close", new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
       canvas.setVisible(false); 
       System.exit(0); 
      } 
     }); 

     contentPane.add(p, "South"); 
    } 

    public void addButton(Container c, String title, ActionListener a) { 
     JButton button = new JButton(title); 
     c.add(button); 
     button.addActionListener(a); 
    } 

} 

    import javax.swing.JFrame; 

public class Test { 
    public static void main(String[] args) { 

     JFrame frame = new Tank_Shut_Car_ThreadFrame(); 
     frame.setVisible(true); 
    } 
} 
+3

'車輛延伸Thread','子彈繼承Thread ',...爲動畫使用'javax.swing.Timer',學習Swing併發規則並減少問題中的代碼+添加實際的具體問題。看看http://sscce.org – Robin

回答

1

好了,所以我有這個(只是爲了好玩)圍繞發揮 BangBang

現在,這遠非一個「正確」或「完整」的遊戲引擎,但它提供一個關於如何將核心線程引擎與UI組件混合的基本概念。

而是然後粘貼整個代碼,我已上載源它Tank.zip

但基本的引擎看起來像這樣...

public class GameEngine extends Thread { 

    public static final Object ASSET_LOCK = new Object(); 
    private List<GameAsset> lstAssets; 
    private GameScreen screen; 

    public GameEngine(GameScreen screen) { 
     // Let the thread die when the JVM closes 
     setDaemon(true); 
     // Want to be below the UI thread (personal preference) 
     setPriority(NORM_PRIORITY - 1); 

     // A list of game assests 
     lstAssets = new ArrayList<GameAsset>(25); 
     // A reference to the screen 
     this.screen = screen; 
     // Add global key listener, this is simpler to the trying to attach a key listener 
     // to the screen. 
     Toolkit.getDefaultToolkit().addAWTEventListener(new EventHandler(), AWTEvent.KEY_EVENT_MASK); 

    } 

    public GameAsset[] getAssets() { 
     synchronized (ASSET_LOCK) { 
      return lstAssets.toArray(new GameAsset[lstAssets.size()]); 
     } 
    } 

    /* 
    * Allows for assets to be added 
    */ 
    public void addAsset(GameAsset asset) { 
     synchronized (ASSET_LOCK) { 
      lstAssets.add(asset); 
     } 
    } 

    @Override 
    public void run() { 

     while (true) { 
      try { 
       sleep(40); 
      } catch (InterruptedException ex) { 
      } 

      synchronized (ASSET_LOCK) { 
       GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]); 
       for (GameAsset asset : assets) { 
        if (lstAssets.contains(asset)) { 
         asset.update(this, screen); 
        } 
       } 
       screen.repaint(new ArrayList<GameAsset>(lstAssets)); 
      } 
     } 
    } 

    /** 
    * Allows the removal of an asset... 
    */ 
    public void removeAsset(GameAsset asset) { 
     synchronized (ASSET_LOCK) { 
      lstAssets.remove(asset); 
     } 
    } 

    /** 
    * Key event handling... 
    */ 
    protected class EventHandler implements AWTEventListener { 

     @Override 
     public void eventDispatched(AWTEvent event) { 
      KeyEvent keyEvent = (KeyEvent) event; 
      if (keyEvent.getID() == KeyEvent.KEY_PRESSED) { 
       synchronized (ASSET_LOCK) { 
        GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]); 
        for (GameAsset asset : assets) { 
         if (lstAssets.contains(asset)) { 
          asset.processKeyPressed(GameEngine.this, screen, keyEvent); 
         } 
        } 
       } 
      } else if (keyEvent.getID() == KeyEvent.KEY_RELEASED) { 
       synchronized (ASSET_LOCK) { 
        GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]); 
        for (GameAsset asset : lstAssets) { 
         if (lstAssets.contains(asset)) { 
          asset.processKeyReleased(GameEngine.this, screen, keyEvent); 
         } 
        } 
       } 
      } 
     } 
    } 
}