2015-12-01 55 views
0

儘管有類似的問題,但我認爲我的代碼設置稍有不同。我的主要方法中有一個JFrame。不過,我的構造函數中只有JPanel。我試圖讓我的一些變量是靜態的,這樣我就可以在主要方法中訪問它們,並且說,例如,如果此圖形的x座標加上其寬度大於frame.getWidth()..但是贏得'由於某種原因工作。我不想轟炸任何有代碼的人,所以我只會嘗試提供主要信息,如果您需要更多信息,我會更新它。不讓圖形超出JFrame邊界

package finalProj; 

    import javax.swing.JFrame; 
    import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.geom.Ellipse2D; 

public class nonaMaingamePractice extends JPanel implements ActionListener, KeyListener { 
    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    private static Ellipse2D ellipse; 
    static Toolkit tools = Toolkit.getDefaultToolkit(); 
    static int screenWidth = (int)(Math.round(tools.getScreenSize().getWidth())); 
    static int screenHeight = (int)(Math.round(tools.getScreenSize().getHeight())); 
    private static Rectangle paddleRect; 
    JLabel text = new JLabel("cool"); 
    Timer timeMove = new Timer(1, this); 
    Timer timeBall = new Timer(10, new timeBall()); 
    private static double x = screenWidth/2, y = (screenHeight*0.8), xx = 0, yy = 0, score = 0, Ox = screenWidth/2, Oy = screenHeight/2, Oyy = 0, width = 100, height = 30; 
    public nonaMaingamePractice(){ 
      setLayout(new BorderLayout()); 
      timeBall.start();    
      timeMove.start(); 
      addKeyListener(this); 
      setFocusable(true); 

      JPanel panelNorth = makePanel(); 
      panelNorth.setBackground(Color.CYAN); 
      add(panelNorth, BorderLayout.NORTH); 

      JLabel scoreLabel = new JLabel("Score: " + score); 
      panelNorth.add(scoreLabel); 


    } 
    public void paintComponent(Graphics g){ 

      super.paintComponent(g); 
      g.setColor(Color.BLUE); 
      paddleRect = new Rectangle((int)x, (int)y, (int)width, (int)height); 
      ellipse = new Ellipse2D.Double(Ox, Oy+Oyy, 50, 50); 
      Graphics2D graphics = (Graphics2D)g; 
      graphics.fill(paddleRect);    
      graphics.fill(ellipse); 

    } 
    @Override 
    public void actionPerformed(ActionEvent e) { 
      x = x + xx; 
      y = y + yy; 

      if(x<0){ 
        x=0; 
        xx=0; 
      } 


      repaint(); 

    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
      // TODO Auto-generated method stub 

    } 
    @Override 
    public void keyPressed(KeyEvent e) { 
      int c = e.getKeyCode(); 
      if(c==KeyEvent.VK_RIGHT){ 
        xx=1; 
      }else if(c==KeyEvent.VK_LEFT){ 
        xx=-1; 
      } 

    } 
    @Override 
    public void keyReleased(KeyEvent e) { 
      xx=0; 

    } 
    protected JPanel makePanel() { 
      @SuppressWarnings("serial") 

        JPanel pane = new JPanel() { 

       @Override 
       public Dimension getPreferredSize() { 
        return new Dimension(100, 30); 
       } 
      }; 
      pane.setBackground(Color.CYAN); 
      return pane; 
     } 

    protected class timeBall implements ActionListener{ 
     Timer timeWhateva = new Timer(100, this); 

      @Override 
      public void actionPerformed(ActionEvent e) { 

        try{ 
         System.out.println(paddleRect.getX()); 
         if(ellipse.intersects(paddleRect)){ 
          timeWhateva.start(); 
           Oy+=-1; 
           System.out.println(ellipse.getX() + " " + ellipse.getY()); 

         }else if(!ellipse.intersects(paddleRect)){ 
          Oyy+=1; 
         } 
       }catch(RuntimeException NullPointerException){ 
         System.out.println(NullPointerException.getMessage()); 
       } 
        repaint(); 
      } 



    } 


      public static void main(String[] args){ 

        nonaMaingamePractice main = new nonaMaingamePractice(); 
        JFrame frame = new JFrame(); 
        frame.add(main); 
        frame.setVisible(true); 
        frame.setTitle("Project 4 game"); 
        frame.setSize(screenWidth, screenHeight); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

      } 
} 
+0

什麼是你的問題?您是否問如何使用不大於屏幕的自定義繪畫創建JPanel? – VGR

+0

對不起@VGR,問題是:我怎樣才能讓圖形不會離開JFrame的外部? – Tyler

+0

請記住,框架的裝飾被繪製在可見框架區域的邊界內,因此,從技術上講,試圖將框架限制在框架內需要考慮這些因素。話雖如此,我真的不知道你在問什麼。什麼圖形?我能想到的最簡單的事情就是簡單地使用另一個'JPanel',將其添加到BorderLayout的中心位置,並使用它來顯示任何自定義圖形 – MadProgrammer

回答

1

好的,所以似乎有一些事情是錯誤的。

首先,不要依賴static進行交叉對象通信,這是一個非常糟糕的主意,它會回來咬你。相反,將信息傳遞給需要它的類。其次,我將重點關注有一個Timer(或「主循環」),它負責更新遊戲的當前狀態並調度重繪。這是Model-View-Controller範式的基本概念

,我要做的第一件事就是把你的代碼完全分開,並重建它...

首先,我想某種接口,提供信息關於遊戲和當前的狀態,我可以通過對遊戲的其他部分情況,以便他們做出決定並更新遊戲的狀態...

public interface GameView { 
    public boolean isKeyRightPressed(); 
    public boolean isKeyLeftPressed(); 
    public Dimension getSize(); 
    public void updateState(); 
} 

這是提供狀態信息右鍵和左鍵的大小,並提供一些基本的功能來請求視圖更新它的當前狀態

接下來,我們需要一些方法來比賽的狀態模型...

import java.awt.Rectangle; 
import java.awt.geom.Ellipse2D; 

public interface GameModel { 
    public Rectangle getPaddle(); 
    public Ellipse2D getBall(); 
    public void ballWasMissed(); 
} 

所以,這基本上維持對球拍和球信息,並提供了這樣一種手段「主遊戲循環」可以提供有關遊戲狀態的通知返回到模型

接下來,我們需要實際的「主遊戲循環」或控制器。這是負責更新模型的狀態,並更新視圖...

import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.Ellipse2D; 

public class MainLoop implements ActionListener { 

    private GameView gameView; 
    private GameModel gameModel; 
    private int ballYDelta = 1; 

    public MainLoop(GameView gameView, GameModel gameModel) { 
     this.gameView = gameView; 
     this.gameModel = gameModel; 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     Rectangle paddle = gameModel.getPaddle(); 
     Ellipse2D ball = gameModel.getBall(); 
     // Update the paddle position... 
     if (gameView.isKeyLeftPressed()) { 
      paddle.x--; 
     } else if (gameView.isKeyRightPressed()) { 
      paddle.x++; 
     } 
     // Correct for overflow... 
     if (paddle.x < 0) { 
      paddle.x = 0; 
     } else if (paddle.x + paddle.width > gameView.getSize().width) { 
      paddle.x = gameView.getSize().width - paddle.width; 
     } 

     // Update the ball position... 
     Rectangle bounds = ball.getBounds(); 
     bounds.y += ballYDelta; 
     if (bounds.y < 0) { 
      bounds.y = 0; 
      ballYDelta *= -1; 
     } else if (bounds.y > gameView.getSize().height) { 
      // Ball is out of bounds... 
      // Notify the gameView so it knows what to do when the ball goes 
      // out of the game view's viewable, ie update the score... 
      // Reset ball position to just out side the top of the view... 
      gameModel.ballWasMissed(); 
      bounds.y = -bounds.height; 
     } else if (paddle.intersects(bounds)) { 
      // Put the ball to the top of the paddle 
      bounds.y = paddle.y - bounds.height; 
      // Bounce 
      ballYDelta *= -1; 
     } 
     ball.setFrame(bounds); 

     // Update the view 
     gameView.updateState(); 
    } 

} 

這基本上是我們在哪裏關於對象的當前位置作出決定,並更新自己的位置。在這裏,我們檢查「超出界限」的位置並適當地更新它們的狀態(例如,球可以「反彈」並改變方向)

增量值非常小,所以你可能想玩這些

最後,我們需要的東西,拉它一起...

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class NonaMaingamePractice extends JPanel implements KeyListener, GameView { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    JLabel text = new JLabel("cool"); 

    private Timer timeBall; 
    private GameModel model; 

    private boolean init = false; 
    private boolean rightIsPressed; 
    private boolean leftIsPressed; 

    public NonaMaingamePractice() { 
     setLayout(new BorderLayout()); 
     addKeyListener(this); 
     setFocusable(true); 

     JPanel panelNorth = makePanel(); 
     panelNorth.setBackground(Color.CYAN); 
     add(panelNorth, BorderLayout.NORTH); 

     JLabel scoreLabel = new JLabel("Score: " + 0); 
     panelNorth.add(scoreLabel); 

     addComponentListener(new ComponentAdapter() { 
      @Override 
      public void componentResized(ComponentEvent e) { 
       if (getWidth() > 0 && getHeight() > 0 && !init) { 
        init = true; 
        model = new DefaultGameModel(getSize()); 
        timeBall = new Timer(40, new MainLoop(NonaMaingamePractice.this, model)); 
        timeBall.start(); 
       } else if (model != null) { 
        model.getPaddle().y = (getHeight() - model.getPaddle().height) - 10; 
       } 
      } 

     }); 

    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(200, 200); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 

     super.paintComponent(g); 
     g.setColor(Color.BLUE); 
     Graphics2D graphics = (Graphics2D) g; 
     if (model != null) { 
      graphics.fill(model.getPaddle()); 
      graphics.fill(model.getBall()); 
     } 

    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     int c = e.getKeyCode(); 
     if (c == KeyEvent.VK_RIGHT) { 
      rightIsPressed = true; 
     } else if (c == KeyEvent.VK_LEFT) { 
      leftIsPressed = true; 
     } 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     int c = e.getKeyCode(); 
     if (c == KeyEvent.VK_RIGHT) { 
      rightIsPressed = false; 
     } else if (c == KeyEvent.VK_LEFT) { 
      leftIsPressed = false; 
     } 
    } 

    protected JPanel makePanel() { 
     @SuppressWarnings("serial") 

     JPanel pane = new JPanel() { 

      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(100, 30); 
      } 
     }; 
     pane.setBackground(Color.CYAN); 
     return pane; 
    } 

    @Override 
    public boolean isKeyRightPressed() { 
     return rightIsPressed; 
    } 

    @Override 
    public boolean isKeyLeftPressed() { 
     return leftIsPressed; 
    } 

    @Override 
    public void updateState() { 
     // Maybe update the score?? 
     repaint(); 
    } 

    public static void main(String[] args) { 

     NonaMaingamePractice main = new NonaMaingamePractice(); 
     JFrame frame = new JFrame(); 
     frame.add(main); 
     frame.setVisible(true); 
     frame.setTitle("Project 4 game"); 
     frame.pack(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    } 
}