我以前问过一个关于同一个程序的问题。我解决了当时的问题,现在我又铲除了一个不同的问题。 当我运行代码时,它在屏幕上显示一个小的蓝色框。 当你按下箭头键时,它应该会移动,我发现如果你点击这个角色并按住箭头键一会儿,那么它就会移动。 我需要的是让它自动刷新屏幕,我相信我需要一种update()
的方法,但我不确定。 如果有人可以帮助我解决这个问题或以某种方式改进我的代码,那将是有帮助的。 我根据我收到的对上一个问题的一些评论进行了一些更改。
字符测试.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);
}
}
为了顺利完成此操作,您必须将 while 循环移出CharacterTest
构造函数并在单独的线程上执行。还要将leftKey
、rightKey
、upKey
和downKey
字段定义为volatile
,以防止 AWT/Swing 事件线程和渲染线程之间的同步问题(因为事件线程和渲染线程可能同时访问这些字段)。
如果您从自己的单独线程执行画布的repaint()
,则还应setIgnoreRepaint(true)
MCharacter 的构造函数,以防止 Swing 重新绘制您的画布。
此外,为了使您的代码更具可读性,我建议您在MCharacter
中定义一个名为 move()
的方法,并在那里执行 while 循环的内容("移动"字符是有意义的)。 带有循环的run()
方法将如下所示:
@Override public void run() {
while (character.determine()) {
character.move();
}
}