为什么我的绘画方法每隔一次只调用一次?

时间:2014-03-22 14:10:27

标签: java image swing file-io paintcomponent

我有一组精灵,我在Java游戏中调用,当我有3个精灵时,它工作正常,但是当我添加第四个精灵时,重绘方法只会每隔一次调用一次。

这是我的最小例子,

主要课程:

public class Maze extends JPanel implements ActionListener{

/**
 * @param args
 */
int stage;
int dir;
int x = 32;
int y = 32;
Rectangle r = new Rectangle(x,y,10,10);
Draw D = new Draw();
public static ArrayList<Rectangle> walls = new ArrayList<Rectangle>();
public ArrayList<Image> spritesl = new ArrayList<Image>();
public ArrayList<Image> spritesd = new ArrayList<Image>();
public ArrayList<Image> spritesr = new ArrayList<Image>();
public ArrayList<Image> spritesu = new ArrayList<Image>();
BufferedImage image;
public Maze() throws IOException{
    setBackground(Color.black);
    setSize(672,672);
    Timer timer = new Timer(2000,this);
    timer.addActionListener(this);
    timer.start();
    //add sprites
    for(int i = 1; i<5; i += 1){
        spritesl.add(image = ImageIO.read(new File("C:/Users/Dave/Desktop/Sprites/left" + i + ".png")));
    }
    for(int i = 1; i<5; i += 1){
        spritesd.add(image = ImageIO.read(new File("C:/Users/Dave/Desktop/Sprites/down" + i + ".png")));
    }
    for(int i = 1; i<5; i += 1){
        spritesr.add(image = ImageIO.read(new File("C:/Users/Dave/Desktop/Sprites/right" + i + ".png")));
    }
    for(int i = 1; i<5; i += 1){
        spritesu.add(image = ImageIO.read(new File("C:/Users/Dave/Desktop/Sprites/up" + i + ".png")));
    }
}
public static void main(String[] args) throws IOException {
    JFrame frame = new JFrame();
    Maze ate = new Maze();
    frame.addKeyListener(new Input());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(ate);
    frame.setPreferredSize(new Dimension(688, 709));//16, 37
    frame.setVisible(true);
    frame.pack();
}
@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    //call wall drawer
    g.setColor(Color.gray);
    D.draw(g);
    g.setColor(Color.red);
    //set animation
    if(dir == 1){
        g.drawImage(spritesu.get(stage-1),x,y, this);
    }else if(dir == 2){
        g.drawImage(spritesr.get(stage-1),x,y, this);
    }else if(dir == 3){
        g.drawImage(spritesd.get(stage-1),x,y, this);
    }else if(dir == 4){
        g.drawImage(spritesl.get(stage-1),x,y, this);
    }
    System.out.println("set");
}
@Override
public void actionPerformed(ActionEvent e) {
    boolean up =false;
    boolean right =false;
    boolean down =false;
    boolean left =false;

    //next part tests each direction for collisions
    if(Input.right){
        right = true;
        x += 4;
        if(x>672-32){
            x -= 4;
            right = false;
        }else{
            for(int i = 0; i < walls.size(); i += 1){
                if(new Rectangle(x, y, 30, 30).intersects(walls.get(i))){
                    x -= 4;
                    right = false;
                }
            }
        }
    }
    if(Input.left){
        left = true;
        dir=4;
        x-=4;
        if(x<0){
            x += 4;
            left = false;
        }else{
            for(int i = 0; i < walls.size(); i += 1){
                if(new Rectangle(x, y, 32, 32).intersects(walls.get(i))){
                    x += 4;
                    left = false;
                }
            }
        }
    }
    if(Input.down){
        down = true;
        dir=3;
        y+=4;
        if(y>672-32){
            y -= 4;
            down = false;
        }else{
            for(int i = 0; i < walls.size(); i += 1){
                if(new Rectangle(x, y, 32, 32).intersects(walls.get(i))){
                    y -= 4;
                    down = false;
                }
            }
        }
    }
    if(Input.up){
        up = true;
        dir=1;
        y-=4;
        if(y<0){
            y += 4;
            up = false;
        }else{
            for(int i = 0; i < walls.size(); i += 1){
                if(new Rectangle(x, y, 32, 32).intersects(walls.get(i))){
                    y += 4;
                    up = false;
                }
            }
        }
    }
    //sets direction of animation
    if(left||down||right||up){
        if(left){
            dir = 4;
        }
        if(down){
            dir = 3;
        }
        if(right){
            dir = 2;
        }
        if(up){
        dir = 1;
        }
        stage += 1;
        if(stage >= 4 || stage <= 0){
            stage = 1;
        }
        System.out.println(stage);
    }
    repaint();
}
}

我的输入测试器(可能没有必要,但游戏需要运行):

public class Input implements KeyListener {
public static boolean left = false;
public static boolean right = false;
public static boolean up = false;
public static boolean down = false;
public static boolean space = false;
//test for keys
@Override
public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
    if (key == KeyEvent.VK_LEFT)
        left = true;
    if (key == KeyEvent.VK_RIGHT)
        right = true;
    if (key == KeyEvent.VK_UP)
        up = true;
    if (key == KeyEvent.VK_DOWN)
        down = true;
    if (key == KeyEvent.VK_SPACE)
        space = true;
}
@Override
public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
    if (key == KeyEvent.VK_LEFT)
        left = false;
    if (key == KeyEvent.VK_RIGHT)
        right = false;
    if (key == KeyEvent.VK_UP)
        up = false;
    if (key == KeyEvent.VK_DOWN)
        down = false;
    if (key == KeyEvent.VK_SPACE)
        space = false;
}
@Override
public void keyTyped(KeyEvent e) {}
}

和我的Draw课程:

public class Draw {
public void draw(Graphics g){
    //draw everything
    Maze.walls.clear();
    g.fillRect(0, 0, 672, 32);
    g.fillRect(0, 0, 32, 672);
    g.fillRect(0, 640, 320, 32);
    g.fillRect(352, 640, 320, 32);
    g.fillRect(640, 0, 32, 320);
    g.fillRect(640, 352, 32, 320);

    Maze.walls.add(new Rectangle(0, 0, 672, 32));
    Maze.walls.add(new Rectangle(0, 0, 32, 672));
    Maze.walls.add(new Rectangle(0, 640, 320, 32));
    Maze.walls.add(new Rectangle(352, 640, 320, 32));
    Maze.walls.add(new Rectangle(640, 0, 32, 320));
    Maze.walls.add(new Rectangle(640, 352, 32, 320));
}
}

现在,这可以工作并循环三个阶段,但是一旦我将阶段max更改为5,它只会在阶段2和4上绘制,这两个阶段完全相同。谁能告诉我我做错了什么?

1 个答案:

答案 0 :(得分:2)

Swing&#34; Timer默认情况下合并事件。&#34;正如@HOFE所指出的那样,重新读取精灵图像可能会使事情变慢,从而触发效果。相反,在程序启动时将图像读入List<Image>