2014-04-04 22 views
0

我已经问过question关于这个相同的程序。我解决了当时的问题,现在我已经找到了一个不同的问题。当我运行代码时,它会在屏幕上显示一个小蓝框。当你按下箭头键时,它应该移动,我发现如果你点击这个字符并按住一个箭头键一会儿,它就会移动。我需要的是自动刷新屏幕,我相信我需要一个update()方法,但我不确定。如果有人能够帮助我解决这个问题,或者以某种有益的方式改进我的代码。我根据我在上一个问题上收到的一些评论做了一些更改。在java中使用update和repaint

CharacterTest.java:

import javax.swing.JFrame; 
import java.awt.Graphics; 
import javax.swing.JPanel; 
import java.awt.Color; 
import javax.swing.JLabel; 
import javax.swing.ImageIcon; 
import java.awt.BorderLayout; 
import java.awt.Canvas; 
//import java.awt.event.KeyEvent; 
import java.awt.event.*; 

public class CharacterTest extends JFrame{ 

public CharacterTest() 
{ 
    super("Character Test");        //instantiate a window to draw the character in 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //this will stop the program when it closes 

    setSize(800, 800);     //create the window 

    MCharacter C = new MCharacter(); //call the box so that it can be affected 

    getContentPane().add(C);   //draws the character on the window 

    setVisible(true);     //show the window 

    while(C.determine(C.getX(), C.getY()) == false)  //as long as the character is witin a particular area 
    { 
     if(C.getUpKey() == true)    //if the up arrow key is pressed 
     { 
      C.up();        //set the y variable to a higher position 
     } 
     if(C.getDownKey() == true)    //if the down arrow key is pressed 
     { 
      C.down();       //set the y variable to a lower positon 
     } 
     if(C.getRightKey() == true)    //if the right arrow key is pressed 
     { 
      C.right();       //set the x variable ro a more right position 
     } 
     if(C.getLeftKey() == true)    //if the left key is pressed 
     { 
      C.left();       //set the x variable to a more left position 
     } 
     repaint();        //repaint the character at a new position 
     try { 
       Thread.sleep(20); 
      } 
      catch (InterruptedException ex){ 
      } 
    } 
} 



public static void main(String[] args) { 
    CharacterTest test = new CharacterTest(); //calls the method which creates the screeen, the character, and checks for key srokes 
} 
} 

MCharacter.java:

import javax.swing.JFrame; 
import java.awt.Graphics; 
import javax.swing.JPanel; 
import java.awt.Color; 
import javax.swing.JLabel; 
import javax.swing.ImageIcon; 
import java.awt.BorderLayout; 
import java.awt.Canvas; 
//import java.awt.event.KeyEvent; 
import java.awt.event.*; 

public class MCharacter extends Canvas{ 

//these will be the instance variables for the character's parameters- its size and its location 
private int width; 
private int height; 
private int x; 
private int y; 


//these will be turned true if the corresponding key is pressed - defined in the private class line 132 
private boolean leftKey = false; 
private boolean rightKey = false; 
private boolean upKey = false; 
private boolean downKey = false; 


//some constructors that would easily be called 
public MCharacter() 
{ 
    setBackground(Color.WHITE); 
    setWidth(10); 
    setHeight(10); 
    setX(400); 
    setY(400); 
    addKeyListener(new MyKeyListener());  //adds a key listener as the private class below (line 152) 
} 

public MCharacter(int xPos, int yPos) 
{ 
    setBackground(Color.WHITE); 
    setWidth(10); 
    setHeight(10); 
    setX(xPos); 
    setY(yPos); 
    addKeyListener(new MyKeyListener());  //adds a key listener as the private class below (line 152) 
} 

public MCharacter(int wth, int hgt, int xPos, int yPos) 
{ 
    setBackground(Color.WHITE); 
    setWidth(wth); 
    setHeight(hgt); 
    setX(xPos); 
    setY(yPos); 
    addKeyListener(new MyKeyListener());  //adds a key listener as the private class below (line 152) 
} 

//setters for each of the variables 
public void setWidth(int wth) 
{ 
    width = wth; 
} 

public void setHeight(int hgt) 
{ 
    height = hgt; 
} 

public void setX(int xPos) 
{ 
    x = xPos; 
} 

public void setY(int yPos) 
{ 
    y = yPos; 
} 

//getters for each of the varaibles 
public int getWidth() 
{ 
    return width; 
} 

public int getHeight() 
{ 
    return height; 
} 

public int getX() 
{ 
    return x; 
} 

public int getY() 
{ 
    return y; 
} 

//used to determine if the character should move 
public void setUpKey(boolean setUp) 
{ 
    upKey = setUp; 
} 
public void setDownKey(boolean setDown) 
{ 
    downKey = setDown; 
} 
public void setRightKey(boolean setRight) 
{ 
    rightKey = setRight; 
} 
public void setLeftKey(boolean setLeft) 
{ 
    leftKey = setLeft; 
} 

public boolean getUpKey() 
{ 
    if(upKey == true) 
    { 
     return true; 
    } 
    return false; 
} 
public boolean getDownKey() 
{ 
    if(downKey == true) 
    { 
     return true; 
    } 
    return false; 
} 
public boolean getRightKey() 
{ 
    if(rightKey == true) 
    { 
     return true; 
    } 
    return false; 
} 
public boolean getLeftKey() 
{ 
    if(leftKey == true) 
    { 
     return true; 
    } 
    return false; 
} 

//the following class is goign to be used to determine if an arrow key is being pressed 
private class MyKeyListener extends KeyAdapter{ 

    public void keyPressed(KeyEvent e){ 
     switch (e.getKeyCode()){ 
      case KeyEvent.VK_LEFT:    //if left key is pressed 
      setLeftKey(true);      //set this boolean to true 
      break; 
      case KeyEvent.VK_RIGHT:    //if right key is pressed 
      setRightKey(true);     //set this boolean to true 
      break; 
      case KeyEvent.VK_UP:    //if the up key is pressed 
      setUpKey(true);      //set this boolean to true 
      break; 
      case KeyEvent.VK_DOWN:    //if the down key is pressed 
      setDownKey(true);      //set this boolean to true 
      break; 
     } 
    } 
    public void keyReleased(KeyEvent e){ 
     switch (e.getKeyCode()){ 
      case KeyEvent.VK_LEFT:    //if left key is released 
      setLeftKey(false);     //set this boolean to false 
      break; 
      case KeyEvent.VK_RIGHT:    //if right key is released 
      setRightKey(false);     //set this boolean to false 
      break; 
      case KeyEvent.VK_UP:    //if up key is released 
      setUpKey(false);      //set this boolean to false 
      break; 
      case KeyEvent.VK_DOWN:    //if down key is released 
      setDownKey(false);     //set this boolean to false 
      break; 
     } 
    } 
} 

//I am going to call the paint method here and create a small box that I will use as the character 
public void paint(Graphics window) 
{ 
    window.setColor(Color.BLUE);    //sets the color of the character 
    window.fillRect(x, y, width, height);  //sets the dimensions of the character 
} 

//this method will be used to keep checking for a key pressed: while this is false check for a keytyped 
public boolean determine(int x, int y) 
{ 
    if(x >= 10 && x <= 790 && y >= 10 && y <= 790) 
    { 
     return false; 
    } 
    return true; 
} 

//the following methods will be to move the character 
public void up() 
{ 
    setY(getY()-2); 
} 
public void down() 
{ 
    setY(getY()+2); 
} 
public void right() 
{ 
    setX(getX()+2); 
} 
public void left() 
{ 
    setX(getX()-2); 
} 
} 
+0

其一,**不要**从你的'paint'方法 –

+0

里面添加键侦听器以及又在哪里我应该加入呢? – user3473563

+0

构造函数看起来像个合适的地方 –

回答

0

要顺利做到这一点,你必须移动,而环出CharacterTest构造并在执行此单独的线程。同时将您的leftKey,rightKey,upKeydownKey字段定义为volatile以防止AWT/Swing事件线程和您的呈现线程(因为事件线程和您的呈现线程可能同时访问这些字段)之间的同步问题。

如果您从您自己单独的线程执行Canvas'repaint(),则还应该在MCharacter的构造函数中使用setIgnoreRepaint(true)以防止Swing重绘您的Canvas。另外,为了让你的代码更具可读性,我建议你在MCharacter中定义一个名为move()的方法,然后在那里执行while循环的内容(“移动”一个字符是有意义的)。该run()方法与循环,然后将这个样子:

@Override public void run() { 
    while (character.determine()) { 
     character.move(); 
    } 
}