0
嗨,大家好,我是新手,這是我第一次發佈到編碼論壇(抱歉我的英語不好XD)我決定做一個菜單開始遊戲但是當我通過使用JFrame setContentPane()我的菜單類添加它,keylistener不能做任何事情,雖然當我通過直接添加我的坦克類測試,它正常運行,我該如何解決這個問題?謝謝:dKeyListener在通過ActionListener使用getContentPane()後不會做任何事情
我的菜單類:
public class Menu extends JPanel {
private JButton jb1=new JButton("Start game"),
jb2=new JButton("Exit");
private JFrame frame;
public Menu(JFrame x){
this.frame=x;
setLayout(new FlowLayout());
add(jb1);
add(jb2);
jb1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
frame.setContentPane(new Tank(frame));
frame.pack();
}
});
jb2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
frame.dispose();
System.exit(0);
}
});
}
public Dimension getPreferredSize(){
return new Dimension(1200,600);
}}
我的坦克類:
public class Tank extends JPanel implements ActionListener,KeyListener{
private int xTank=0,
yTank=0,
xTankMotion=0,
yTankMotion=0;
private int xAlien=800,
yAlien=0,
xAlienMotion=0,
yAlienMotion=0;
private Image tank=new ImageIcon("Tank.jpg").getImage(),
alien= new ImageIcon("Alien.jpg").getImage();
private int tankWidth=tank.getWidth(this),
tankHeight=tank.getHeight(this);
private int fire=0,
xRocket=0,
yRocket=0,
xRocketMotion=0,
yRocketMotion=0;
private int alienWidth=alien.getWidth(this),
alienHeight=alien.getHeight(this);
private int key=1;
private Timer time=new Timer(1,this);
private int angle;
private int truot=0,trung=0;
private boolean banduoc=true;
private JFrame frame;
private void gameOver(JFrame jf){
jf.setContentPane(new Victory());
}
public Tank(JFrame frame){
this.frame=frame;
time.start();
setFocusable(true);
setFocusTraversalKeysEnabled(false);
requestFocus();
addKeyListener(this);
}
@Override
public void actionPerformed(ActionEvent e){
if(xTank<=0) xTank=0;
if(xTank>=400) xTank=400;
if(yTank<=0) yTank=0;
if(yTank>=600-tankHeight) yTank=600-tankHeight;
if(truot==0){
if(xAlien<=1200-alienWidth) {
xAlienMotion=1;
yAlienMotion=0;}
if(xAlien>=1200-alienWidth){
xAlienMotion=0;
yAlienMotion=1;}
if(yAlien>=600-alienHeight){
xAlienMotion=-1;
yAlienMotion=0;}
if(xAlien<=800&&yAlien>=0){
xAlienMotion=0;
yAlienMotion=-1;}}
else {
if(trung==0&&((xTank<=xAlien+alienWidth&&xTank+tankWidth>=xAlien+alienWidth&&((yTank>=yAlien&&yTank<=yAlien+alienHeight)||(yTank+tankHeight>=yAlien&&yTank+tankHeight<=yAlien+alienHeight)))||
(yTank<=yAlien+alienHeight&&yAlien+alienHeight<=yTank+tankHeight&&((xTank>=xAlien&&xTank<=xAlien+alienWidth)||(xTank+tankWidth>=xAlien&&xTank+tankWidth<=xAlien+alienWidth)))||
(xTank+tankWidth>=xAlien&&xAlien>=xTank&&((yTank>=yAlien&&yTank<=yAlien+alienHeight)||(yTank+tankHeight>=yAlien&&yTank+tankHeight<=yAlien+alienHeight)))||
(yTank+tankHeight<=yAlien&&yAlien>=yTank&&((xTank>=xAlien&&xTank<=xAlien+alienWidth)||(xTank+tankWidth>=xAlien&&xTank+tankWidth<=xAlien+alienWidth)))))
{time.stop(); frame.setContentPane(new Defeated(frame)); frame.pack(); return;}
else{
if(yAlien>yTank){
yAlienMotion=-1;
if(xAlien>xTank) xAlienMotion=-1;
else if(xAlien<xTank) xAlienMotion=1;
else xAlienMotion=0;
}
else if(yAlien<yTank){
yAlienMotion=1;
if(xAlien>xTank) xAlienMotion=-1;
else if(xAlien<xTank) xAlienMotion=1;
else xAlienMotion=0;
}
else{
yAlienMotion=0;
if(xAlien>xTank) xAlienMotion=-1;
else if(xAlien<xTank) xAlienMotion=1;
}
}
}
xTank+=xTankMotion;
yTank+=yTankMotion;
xRocket+=xRocketMotion;
yRocket+=yRocketMotion;
xAlien+=xAlienMotion;
yAlien+=yAlienMotion;
if((xRocket>=1200||xRocket<0||yRocket<0||yRocket>600)&&truot==0) {truot=1; banduoc=true;}
if(xRocket>=xAlien&&xRocket<=xAlien+alienWidth&&yRocket>=yAlien&&yRocket<=yAlien+alienHeight) {trung=1; frame.setContentPane(new Victory()); frame.pack();}
repaint();
}
@Override
public Dimension getPreferredSize(){
return new Dimension(1200,600);
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
AffineTransform at= AffineTransform.getTranslateInstance(xTank,yTank);
at.rotate(Math.toRadians(angle),tankWidth/2,tankHeight/2);
Graphics2D g2d=(Graphics2D) g;
g2d.drawImage(tank,at,null);
g.drawImage(alien, xAlien, yAlien, this);
if(fire==1) {
g.setFont(new Font("Monospaced",Font.BOLD,20));
g.setColor(Color.yellow);
g.fillOval(xRocket,yRocket, 5, 5);
}
if(truot==1) {
g.setColor(Color.red);
g.drawString("Noooooo! :(", xTank, yTank-50);
}
}
public static void main(String[] args) {
JFrame frame=new JFrame("Tank");
frame.setContentPane(new Menu(frame));
frame.setContentPane(new Tank(frame));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setResizable(false);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
int i=e.getKeyCode();
if(i==KeyEvent.VK_UP) {
key=2;
xTankMotion=0;
yTankMotion=-1;
angle=90;}
else if(i==KeyEvent.VK_DOWN) {
key= 4;
xTankMotion=0;
yTankMotion=1;
angle=-90;}
else if(i==KeyEvent.VK_RIGHT) {
key=3;
xTankMotion=1;
yTankMotion=0;
angle=180;}
else if(i==KeyEvent.VK_LEFT) {
key=1;
xTankMotion=-1;
yTankMotion=0;
angle=0;}
if(i==KeyEvent.VK_SPACE&&banduoc) {
fire=1;
if(key==1) {
xRocket=xTank;
yRocket=yTank+tankHeight/2;
xRocketMotion=-2;
yRocketMotion=0;
}
if(key==2) {
xRocket=xTank+tankWidth/2;
yRocket=yTank;
yRocketMotion=-2;
xRocketMotion=0;
}
if(key==3) {
xRocket=xTank+tankWidth;
yRocket=yTank+tankHeight/2;
xRocketMotion=2;
yRocketMotion=0;
}
if(key==4) {
xRocket=xTank+tankWidth/2;
yRocket=yTank+tankHeight;
yRocketMotion=2;
xRocketMotion=0;
}
banduoc=false;
}
}
@Override
public void keyReleased(KeyEvent e) {
xTankMotion=0;
yTankMotion=0;
}}
不要使用'KeyListener',它們只能響應組件中的關鍵事件y被註冊爲可調焦且具有焦點。這是一個衆所周知的文件問題。相反,您應該使用旨在解決此限制的鍵綁定API。請參閱[如何使用密鑰綁定](http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html)以獲取更多詳細信息 – MadProgrammer
Omg您回覆了我! XD謝謝!我會嘗試,但我不知道爲什麼我不能集中注意力,你能告訴我我的錯誤嗎?:D我使用setFocusable和requestFocus,但它仍然無法獲得焦點 –
這可能是一些其他控制盜取焦點和您的組件(帶'KeyListener'的那個)從來沒有拿回過 – MadProgrammer