在 Java 中使用更新和重绘



我以前问过一个关于同一个程序的问题。我解决了当时的问题,现在我又铲除了一个不同的问题。 当我运行代码时,它在屏幕上显示一个小的蓝色框。 当你按下箭头键时,它应该会移动,我发现如果你点击这个角色并按住箭头键一会儿,那么它就会移动。 我需要的是让它自动刷新屏幕,我相信我需要一种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构造函数并在单独的线程上执行。还要将leftKeyrightKeyupKeydownKey字段定义为volatile,以防止 AWT/Swing 事件线程和渲染线程之间的同步问题(因为事件线程和渲染线程可能同时访问这些字段)。

如果您从自己的单独线程执行画布的repaint(),则还应setIgnoreRepaint(true) MCharacter 的构造函数,以防止 Swing 重新绘制您的画布。

此外,为了使您的代码更具可读性,我建议您在MCharacter中定义一个名为 move() 的方法,并在那里执行 while 循环的内容("移动"字符是有意义的)。 带有循环的run()方法将如下所示:

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

相关内容

  • 没有找到相关文章

最新更新