2012-08-05 22 views
0

所以我一直在嘗試着在Java中製作非常簡單的遊戲。當我在一堂課中製作整個課程時,我一直都很成功,但每當我嘗試添加面向對象原則時,一切都會崩潰。我想要的是從我的好人那裏發射一顆子彈,這或多或少是一個炮塔。我可以輕鬆地設置這樣的東西,但是當我嘗試用類代表好人和子彈時,所有東西都會分崩離析。 這是我到目前爲止。 設置了主程序框架:令人難以置信的簡單的Java遊戲任務使用OOP

import javax.swing.JFrame; 

public class Shooter 
{ 
    public static void main (String[] args) 
    { 
     JFrame frame = new JFrame("Car"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     ShooterPanel panel = new ShooterPanel(); 

     frame.getContentPane().add(panel); 
     frame.pack(); 
     frame.setVisible(true); 
    } 
} 

ShooterPanel類:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class ShooterPanel extends JPanel 
{ 
    final int WIDTH = 200, HEIGHT = 100; 
    GoodGuy hero; 

    public ShooterPanel() 
    { 
     hero = new GoodGuy(0, HEIGHT-20, 20); 
     addKeyListener(new MoveListener()); 
     setPreferredSize(new Dimension (WIDTH, HEIGHT)); 
     setFocusable(true); 
    } 
    public void paintComponent(Graphics page) 
    { 
     super.paintComponent(page); 
     hero.draw(page); 
    } 
    private class MoveListener implements KeyListener 
    { 

     public void keyPressed (KeyEvent event) 
     { 
      switch (event.getKeyCode()) 
      { 
       case KeyEvent.VK_SPACE: 
        hero.shoot(); 
        break; 
      } 
     } 
     //-------------------------------------------------------------- 
     //Provide empty definitions for unused event methods. 
     //-------------------------------------------------------------- 
     public void keyTyped (KeyEvent event) {} 
     public void keyReleased (KeyEvent event) {} 
    } 
} 

我們的主角:

import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

public class GoodGuy 
{ 
    private int x, y, size; 
    private Bullet bullet; 

    public GoodGuy(int x, int y, int height) 
    { 
     size = height; 
     this.x = x; 
     this.y = y; 
    } 
    public int getSize() 
    { 
     return size; 
    } 
    public void draw(Graphics page) 
    { 
     page.drawRect(x, y, size, size); 
    } 
    public void shoot() 
    { 
     bullet = new Bullet(x+size, y); 
    } 
} 

而他的子彈:

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.Timer; 

public class Bullet 
{ 
    private int x, y; 
    final int LENGTH = 5, DELAY =200; 
    private Timer timer; 
    Graphics page1; 

    public Bullet(int x, int y) 
    { 
     this.x = x; 
     this.y = y; 
     timer = new Timer(DELAY, new BulletListener()); 
     timer.start(); 
    } 
    public void draw(Graphics page) 
    { 
     page.drawLine (x, y, x+LENGTH, y); 
    } 

    //***************************************************************** 
    // Represents the action listener for the timer. 
    //***************************************************************** 
    private class BulletListener implements ActionListener 
    { 
     public void actionPerformed (ActionEvent event) 
     { 
      x +=5; 
      draw(page1); 
     } 
    } 
} 

我想即將發生 是爲了按下空格鍵,這個好人出現一顆子彈,並讓它在屏幕上向右移動。我根本無法得到子彈。我嘗試了幾件事,都無濟於事。我相信這很容易。正如我所說,我可以在我的ShooterPanel類中使用變量繪製子彈而不是創建對象,但我希望實現面向對象。有沒有人有我的解決方案?我將不勝感激一些幫助,但我正在尋找解決方案。請,如果你只是給出一個模糊的建議,我寧願沒有迴應。編輯:這是我希望我的程序如何工作:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.util.ArrayList; 

public class ShooterPanel extends JPanel 
{ 
final int WIDTH = 200, HEIGHT = 100; 
GoodGuy hero; 
ArrayList<BadGuy> enemies = new ArrayList<BadGuy>(); 
ArrayList<Bullet> bullets = new ArrayList<Bullet>(); 
private Timer timer, bulletTimer; 

final int DELAY = 200; 
int count=0; 
private boolean bulletOut = false; 

public ShooterPanel() 
{ 
    hero = new GoodGuy(0, HEIGHT-20, 20); 
    addKeyListener(new MoveListener()); 
    timer = new Timer(DELAY, new EnemyListener()); 
    bulletTimer = new Timer(100, new BulletListener()); 
    setPreferredSize(new Dimension (WIDTH, HEIGHT)); 
    //enemies.add(new BadGuy(WIDTH-10, HEIGHT-10)); 
    setFocusable(true); 
    timer.start(); 
} 
public void paintComponent(Graphics page) 
{ 
    super.paintComponent(page); 
    hero.draw(page); 
    for (int i = 0; i < enemies.size(); i++) 
    { 
     enemies.get(i).draw(page); 
    } 
    if (bulletOut) 
     for(Bullet bullet: bullets) 
      bullet.draw(page); 

} 
private class MoveListener implements KeyListener 
{ 
    //-------------------------------------------------------------- 
    //Responds to the user pressing arrow keys by adjusting the 
    //image and image location accordingly. 
    //-------------------------------------------------------------- 
    public void keyPressed (KeyEvent event) 
    { 
     switch (event.getKeyCode()) 
     { 
     case KeyEvent.VK_SPACE: 
      bullets.add(new Bullet(20,95)); 
      bulletOut = true; 
      bulletTimer.start(); 
      break; 
     } 

    } 
    //-------------------------------------------------------------- 
    //Provide empty definitions for unused event methods. 
    //-------------------------------------------------------------- 
    public void keyTyped (KeyEvent event) {} 
    public void keyReleased (KeyEvent event) {} 
} 
//***************************************************************** 
// Represents the action listener for the timer. 
//***************************************************************** 
private class EnemyListener implements ActionListener 
{ 
    //-------------------------------------------------------------- 
    // Updates the position of the image and possibly the direction 
    // of movement whenever the timer fires an action event. 
    //-------------------------------------------------------------- 
    public void actionPerformed (ActionEvent event) 
    { 
     if (count%20==0) 
      enemies.add(new BadGuy(WIDTH-10, HEIGHT-10)); 

     for (BadGuy enemy: enemies) 
     { 
      enemy.move(); 
     } 

     count++; 
     repaint(); 
    } 
} 
private class BulletListener implements ActionListener 
{ 
    //-------------------------------------------------------------- 
    // Updates the position of the image and possibly the direction 
    // of movement whenever the timer fires an action event. 
    //-------------------------------------------------------------- 
    public void actionPerformed (ActionEvent event) 
    { 
     for(Bullet bullet: bullets) 
      bullet.move(); 
     for(int i = 0; i < bullets.size(); i++) 
     { 

      if (enemies.size() != 0) 
      { 
       if (bullets.get(i).getX() > enemies.get(0).getX()) 
       { 
        bullets.remove(i); 
        enemies.remove(0); 
       } 
      } 
      if (bullets.size() != 0) 
      { 
       if (bullets.get(i).getX()>WIDTH) 
        bullets.remove(i); 
      }  
     } 
     repaint(); 
    } 
} 
} 
import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

public class GoodGuy 
{ 
private int x, y, size; 
private Bullet bullet; 

public GoodGuy(int x, int y, int height) 
{ 
    size = height; 
    this.x = x; 
    this.y = y; 
} 
public int getSize() 
{ 
    return size; 
} 
public void draw(Graphics page) 
{ 
    page.drawRect(x, y, size, size); 
} 
public void shoot() 
{ 
    bullet = new Bullet(x+size, y); 

} 
} 

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class BadGuy 
{ 
private int x, y; 
final int RADIUS = 5; 


public BadGuy(int x, int y) 
{ 
    this.x = x; 
    this.y = y; 

} 
public void move() 
{ 
    x -= 5; 

} 
public void draw(Graphics page) 
{ 
    page.drawOval(x, y, RADIUS*2, RADIUS*2); 
} 
public int getX() 
{ 
    return x; 
} 

} 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.Timer; 

public class Bullet 
{ 
private int x, y; 
final int LENGTH = 5, DELAY =200; 

public Bullet(int x, int y) 
{ 
    this.x = x; 
    this.y = y; 
} 
public void draw(Graphics page) 
{ 
    page.drawLine (x, y, x+LENGTH, y); 

} 
public void move() 
{ 
    x += 5; 
} 
public int getX() 
{ 
    return x; 
} 
} 

射手類仍然是一樣的。這就是我希望程序要做的事情,但這不完全是我希望它做到的。我更喜歡它是否更面向對象,並且每個類都照顧好自己。 ShooterPanel已經開始因爲我的口味而變得有點複雜,並且隨着更多的程序添加到遊戲中而變得更糟。我想改變的一件事是每個子彈都有自己的計時器,並在Bullet類中定義了一個ActionListener。但是,我無法弄清楚如何做到這一點,以便每當計時器觸發事件​​時重新繪製子彈。如果有人知道這樣做的方式,請讓我知道。

+0

另請參閱示例[此處](http://stackoverflow.com/q/9849950/230513)和[這裏](http://stackoverflow.com/q/3066590/230513)。 – trashgod 2012-08-05 20:43:37

回答

0

您需要使您的ShooterPanel可以調焦。 Add:

setFocusable(true); 
    requestFocusInWindow(); 

此外,BulletListener的圖形從不設置。這個paint(ing)應該可能發生在ShooterPanel本身。

+0

即使添加了可調焦的線條,我的問題仍然存在。任何人都知道如何讓這幅畫在ShooterPanel中出現?我試着把它添加到paintComponent:if(bulletOut)\t \t \t \t hero.getBullet()。draw(page); bulletOut是一個布爾變量,當按下空格鍵並實例化子彈時,該變量設置爲true。 getBullet()當然是我添加到返回子彈的GoodGuy類的方法。我還更改了BulletListener,只是將x增加了5.不幸的是,這並沒有奏效。 – user1505612 2012-08-05 20:54:51

+0

當然,通過這種方式設置,每次定時器觸發時都不會發生repaint()調用,所以我不認爲它會顯示子彈移動,即使它正在工作。任何人都有解決方案? – user1505612 2012-08-05 21:01:23