Hiblah200
Hiblah200

Reputation: 27

Why is my paint method only calling every other time?

I have a set of sprites that I am calling in a Java game, and when I had 3 sprites it worked fine, but when I add a fourth sprite, the repaint method is only called every other time.

Here is my minimal example,

Main class:

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();
}
}

My input tester(probably not necessary, but its needed for the game to run):

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) {}
}

and my Draw class:

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));
}
}

now, this works and cycles three stages, but as soon as I change the stage max to 5, it only paints on stages 2 and 4, which are exactly the same. Can anyone tell me what I am doing wrong?

Upvotes: 1

Views: 72

Answers (1)

trashgod
trashgod

Reputation: 205785

Swing "Timers coalesce events by default." As noted by @HOFE, re-reading your sprite images is likely slowing things down enough to trigger the effect. Instead, read the images into a List<Image> when the program starts.

Upvotes: 2

Related Questions