2014-06-08 34 views
-1

我正在制作一款汽车游戏,我刚刚遇到了屏幕大小问题,它不允许汽车移动(它应该能够在所有屏幕上移动) ,也许jpanel的大小不是正确的大小。JFrame和JPanel大小在java中没有变化

主要和JPanel的:

public class MyCarGame extends JPanel implements Runnable { 

CarPlayer Player; 

public MyCarGame(GUI frame) { 
    Player = new CarPlayer(0, 0); 

    this.setSize(WidthFrame,HeightFrame); 
    this.addKeyListener(new KeyListener()); 

} 

public void draw(Graphics g) { 
    Player.draw(g); 
    repaint(); 
} 

/** 
* @param args the command line arguments 
*/ 
@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); //To change body of generated methods, choose Tools | Templates. 
    draw(g); 

} 

@Override 
public void run() { 
    while (true) { 
     Player.move(); 
     try { 
      Thread.sleep(10); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(MyCarGame.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

private class KeyListener extends KeyAdapter{ 

@Override 
public void keyPressed(KeyEvent e) { 
    switch (e.getKeyCode()) { 
     case KeyEvent.VK_RIGHT: 
      Player.xVel = 3; 
      break; 
     case KeyEvent.VK_LEFT: 
      Player.xVel = -3; 
      break; 
     case KeyEvent.VK_UP: 
      Player.yVel = -3; 
      break; 
     case KeyEvent.VK_DOWN: 
      Player.yVel = 3; 
      break; 
    } 
} 

@Override 
public void keyReleased(KeyEvent e) { 
    switch (e.getKeyCode()) { 
     case KeyEvent.VK_RIGHT: 

     case KeyEvent.VK_LEFT: 
      Player.xVel = 0; 
      break; 
     case KeyEvent.VK_UP: 
     case KeyEvent.VK_DOWN: 
      Player.yVel = -1; 
      break; 

    } 
} 
} 

public static int WidthFrame = 0; 
public static int HeightFrame = 0; 

public static void main(String[] args) { 
    // TODO code application logic here 
    new GUI().setVisible(true); 
} 

} 

Player类:

public class CarPlayer { 
int x; 
int y; 
Image img; 
public int xVel; 
public int yVel; 
public CarPlayer(int x,int y){ 

img= new ImageIcon("images/PlayerCar.png").getImage(); 
this.x=x; 
this.y=y; 
xVel=0; 
yVel=-1; 
} 

public int getX() { 
    return x; 
} 

public int getY() { 
    return y; 
} 


public void move(){ 
    if(x+xVel<(MyCarGame.WidthFrame-50) && x+xVel>0) 
x+=xVel; 
    if(y+yVel<(MyCarGame.HeightFrame-100) && y+yVel>0) 
y+=yVel; 
if(x<0){ 
xVel=0; 
} 
if(y<0){ 
    yVel=0; 

} 
if(y>(MyCarGame.HeightFrame-100)){ 
yVel=0; 
} 
if(x>(MyCarGame.WidthFrame-50)){ 
    xVel=0; 
} 
} 



public void draw(Graphics g){ 

g.drawImage(img, x, y,50,100, null); 

} 

} 

Frame类:

public class GUI extends javax.swing.JFrame { 

/** 
* Creates new form GUI 
*/ 
MyCarGame g; 
public GUI() { 
    this.setFocusable(false); 
    this.setResizable(false); 
    this.setExtendedState(JFrame.MAXIMIZED_BOTH); 
    MyCarGame.WidthFrame=this.getWidth(); 
    MyCarGame.HeightFrame=this.getHeight(); 
    g=new MyCarGame(this); 
    this.add(g); 
    g.setLocation(0, 0); 
    g.requestFocusInWindow(); 
    Thread t= new Thread(g); 
    t.start(); 
    } 
} 
+1

1)为了更好地帮助越早,后期一个[MCVE](http://stackoverflow.com/help/mcve)(最小完整和可验证示例)。 2)对代码块使用一致的逻辑缩进。代码的缩进旨在帮助人们理解程序流程。 –

+0

使用Swing'Timer'进行动画。 –

+0

'WidthFrame'和'HeightFrame'是'0'?你能指望什么。不要为此使用'static'字段,传递'Player'需要知道的信息,即组件的实际大小... – MadProgrammer

回答

1

你依靠“神奇”的价值观,或者试图...

public GUI() { 
    this.setFocusable(false); 
    this.setResizable(false); 
    this.setExtendedState(JFrame.MAXIMIZED_BOTH); 
    MyCarGame.WidthFrame = this.getWidth(); 
    MyCarGame.HeightFrame = this.getHeight(); 

此时,帧大小仍然0x0,因为直到您尝试使其可见时,该框架并不真正知道它将显示在哪个屏幕上。

这些值也没有考虑到框线可能具有可能的插图,和他们的平台之间的变化,外观和感觉(甚至可以在同一平台的不同实例更改)

简单的解决方案,摆脱它。 static是不是一个很好的选择,更好的解决办法是改变你的move方法需要调用者在宽度和可用空间的高度来传递......

例如...

public void move(int width, int height) { 

然后,当你需要调用它,你可以使用类似...

Player.move(getWidth(), getHeight()); 

避免KeyListener,它只是麻烦,可以考虑使用key bindings API代替。它提供了更好地控制触发关键事件所需的焦点级别...

不要直接或间接地从任何paint方法中调用repaint,这只会继续引发paint事件,这最终会消耗你的CPU

在我的系统,setResizable没有很好地与setExtendedState玩......你可能要考虑摆脱setResizable选项...

+0

我现在工作了,谢谢。但我不明白,那么我不应该使用repaint()?我将添加一些其他图像也移动,是的,我会通过宽度和高度方法移动 – HkGDota

+0

您可以使用'repaint',但不是在'paint'方法的上下文中。 Swing使用被动渲染器引擎,这意味着可能由于任何数量的原因触发绘画,其中许多您无法控制。 – MadProgrammer

0

首先,有个小小的建议,为变量的名称,使用较低 - 字母。

其次,如果您已经绘画,请勿重新绘制MyCarGame类的draw()方法。移动车后,你应该问这个问题。而你的游戏循环需要更多的控制。 关于游戏循环,使用此链接:https://www.google.pt/#q=java+game+loop

+0

所以你的意思是我应该使用重新运行的方法吗? – HkGDota

+0

是的,我的意思是。 一个简单的游戏循环有:1st updateGame(),2nd renderGame()(或repaint()),3rd sleep()。 此链接显示:http://www.java-gaming.org/index.php?topic=24220.0 – saclyr

+0

好吧谢谢。 – HkGDota