Cierius
Cierius

Reputation: 11

Repaint() isn't working and I don't know why

public static void main(String[] args){
    Core game = new Core();
    game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    game.frame.setTitle("Multiply");
    game.frame.setIconImage(testIcon);
    game.frame.add(game);
    game.frame.pack();
    game.frame.setLocationRelativeTo(null);
    game.frame.setResizable(false);
    game.frame.setVisible(true);

    t1.start();

    new Core().run();
}

public Core(){
    KeyListener listener = new MyKeyListener();
    addKeyListener(listener);
    setFocusable(true);

    Dimension size = new Dimension(width, height);  //variable that sets the size of the window to 1280x720p
    setPreferredSize(size);                         //Sets the size of the window to "size" 

    frame = new JFrame();                           //makes frame into the JFrame window
}


public void run(){
    running = true;
    loop();
}

public void render(){
        repaint();
        System.out.println("runnin");
}

private synchronized void loop(){   //Running loop, while the game is open this will always be running
    long lastLoopTime = System.nanoTime();
    final int TARGET_FPS = 60;
    final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
    int fps = 0;
    long lastFpsTime = 0;

    while(running == true){
        long now = System.nanoTime();
        long updateLength = now - lastLoopTime;
        lastLoopTime = now;
        double delta = updateLength / ((double)OPTIMAL_TIME);

        lastFpsTime += updateLength;
        fps++;

        if (lastFpsTime >= 1000000000)
          {
             System.out.println("(FPS: "+fps+")");
             lastFpsTime = 0;
             fps = 0;
          }

        enemyAI();
        render();

        try {
            Thread.sleep( (lastLoopTime-System.nanoTime() + OPTIMAL_TIME)/1000000 );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void enemyAI(){
    if(menu != true){
        enemyX++;
    }
}

@Override
public synchronized void paint(Graphics g) {        // Draws top first to bottom last 
    super.paint(g);
    String imagesString = "C:/Users/BigBertha/Desktop/Multiply_Game_Engine/";
    Image background = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/Green_Background.png");
    Image character = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/Character.png");
    Image enemy = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/Enemy.png");
    Image inDevText = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/InDevText.png");

    Image menuScreen = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/MainMenu.png");
    Image menuArrow = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/MainMenuArrow.png");
    //Image loadingScreen = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/LoadingScreen.png");

    if(menu){
        g.drawImage(menuScreen, 0, 0, 1290, 730, this);

        if(menuAPos1){ //play
            g.drawImage(menuArrow, menuArrowX1, menuArrowY1, 125, 100, this);
            loading = true;
        }
        else if(menuAPos2){
            g.drawImage(menuArrow, menuArrowX2, menuArrowY2, 125, 100, this);
        }
        else if(menuAPos3){
            g.drawImage(menuArrow, menuArrowX3, menuArrowY3, 125, 100, this);
        }
            g.drawImage(inDevText, width - 95, height - 20, 100, 40, this); //removed eventually
    }
else if(running){
        g.drawImage(background, 0, 0, 1290, 730, this); //draws the black background
        g.drawImage(inDevText, width - 95, height - 20, 100, 40, this); //removed eventually
        g.drawImage(character, charX, charY, charSizeX, charSizeY, this); //draws the character
        g.drawImage(enemy, enemyX, enemyY, enemySizeX, enemySizeY, this);
}
}

I need the loop() method to be able to run repaint() but it does nothing when it's called. I've tried many different variations to try and get it to work but nothing has worked. I've been thinking about using JOGL but i need to complete at least a decent amount of a game prototype for school.

Upvotes: 1

Views: 72

Answers (1)

Radiodef
Radiodef

Reputation: 37845

  1. Your use of synchronized is possibly causing the freeze. Since the run method never releases the monitor, paint can't be entered. Instead of Thread.sleep(long) (which does not release a monitor) you could try wait(long) (which does release a monitor).

    try {
        wait( (lastLoopTime-System.nanoTime() + OPTIMAL_TIME)
                    / 1000000 );
    } ...
    

    But you should really consider whether synchronizing the whole run method is necessary. It could cause frame rate problems if the game loop is not waiting often enough.

  2. It's unclear where you are starting the thread for game if you are starting one at all... (This might also cause the problem 'does nothing' which you are seeing.)

    Core game = new Core();
    ...
    
    t1.start();
    
    new Core().run();
    

    new Core().run() creates a second, unrelated instance and calls its run method directly on the main thread. You should instead be doing something like new Thread(core).run(). (Is that what t1 is?)

  3. You shouldn't be loading images inside paint (the calls to Toolkit.getImage). Doing this means you are loading each file every frame. You should load your resources once in to a class or instance field.

  4. We generally don't override public void paint(Graphics) in Swing programs, we override protected void paintComponent(Graphics).

Also see

Upvotes: 4

Related Questions