-1

I'm currently coding a game and I'm trying to have it where if you click on the first button on the front page, it shows a transition screen for 5 seconds, and then shows the game. Here is my code:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ForgottenMain extends JPanel implements KeyListener,MouseListener{
    /**
     * 
     */
    private static final int TIMER_DELAY = 35;
    private static final long serialVersionUID = -4926251405849574401L;
    public static BufferedImage attic,flashlight,player,killer,frontpage,transition;
    public static boolean onFrontPage,up,down,left,right,inAttic,onTransition;
    public static int px,py,kx,ky;
    public static Thread th1,th2;
    public static JFrame frame = new JFrame("Forgotten");
    public static void main(String[] args){
        onFrontPage = true;
        px = 600;
        py = 400;
        ForgottenMain fm = new ForgottenMain();
        frame.add(fm);
        frame.setSize(1200,800);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);
        frame.add(new ForgottenMain());
        fm.repaint();
    }
    public ForgottenMain(){
        init();
    }
    public void init(){
        setSize(1200,800);
        setVisible(true);
        frame.addKeyListener(this);
        frame.addMouseListener(this);
        try{    
            player = ImageIO.read(new File("char.png"));
            flashlight = ImageIO.read(new File("flashlightimage.png"));
            attic = ImageIO.read(new File("attic.png"));
            killer = ImageIO.read(new File("killer.png"));
            frontpage = ImageIO.read(new File("frontpageoutline.png"));
            transition = ImageIO.read(new File("transitionoutline.png"));
        } catch (Exception e){
            e.printStackTrace();
        }


        // Gameloop
          new javax.swing.Timer(TIMER_DELAY, new ActionListener() {
                 public void actionPerformed(ActionEvent e) {
                    gameLoop();
                 }
              }).start();   
    }
    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        int fx = px - 1033;
        int fy = py - 635;
        kx = 500;
        ky = 500;
        // Removes the flickering of the images
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // Resets the screen to make sure that it only shows the character once
        g2.clearRect(0, 0, 1200, 800);
        // Draws the background attic
        if(inAttic == true){
            System.out.println("Drawing attic");
            g2.drawImage(attic,0,0,this);
        }
        if(onFrontPage == true){
            g2.drawImage(frontpage, 0, 0, this);
        } 
        // Draws the player
        if(onFrontPage == false && onTransition == false){
            g2.drawImage(player, px, py, this);
            // Draws the Serial Killer
            g2.drawImage(killer, kx, ky, this);
            // Draws the flashlight
            g2.drawImage(flashlight, fx, fy, this);
        }
        if(onTransition == true){
            g2.drawImage(transition, 0, 0, this);
            System.out.println("Drawing Transition");
            try {
                System.out.println("Sleeping for 5 Seconds");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("Done sleeping.");
            onTransition = false;
            inAttic = true;
        }
        System.out.println(px + " " + py);
    }
    public void gameLoop(){

    }
    @Override
    public void mouseClicked(MouseEvent arg0) {
        System.out.println("MouseLocation: " + arg0.getX() + ", " + arg0.getY());
    }
    @Override
    public void mouseEntered(MouseEvent arg0) {

    }
    @Override
    public void mouseExited(MouseEvent arg0) {

    }
    @Override
    public void mousePressed(MouseEvent e) {
        if(e.getX() > 499 && e.getY() > 343 && e.getX() < 748 && e.getY() < 391){
            onFrontPage = false;
            onTransition = true;
            repaint();
        }
    }
    @Override
    public void mouseReleased(MouseEvent arg0) {

    }

My problem is, in the paint method, in the if statement testing if onTransition is equal to true, it's supposed to draw the image transition, wait 5 seconds, and then draw the game.

However, right now it's waiting 5 seconds, then quickly drawing the transition screen and then the game. For some reason they are out of order.

How can I fix this? I have tried alternate methods of waiting 5 seconds, for example using currentTimeMillis();, but have the same outcome.

joey942
  • 159
  • 2
  • 11
  • 4
    use SwingTimer (with programatically repaint() to ForgottenMain) instead of Thread.sleep(5000); – mKorbel Aug 01 '16 at 16:45
  • Could you maybe link me to some kind of example of this? In a previous question I asked for a way to make a gameloop and the timer was suggested, so I used it but I still don't fully understand it. @mKorbel – joey942 Aug 01 '16 at 16:50
  • @joey942 see http://stackoverflow.com/questions/8088002/how-to-use-a-swing-timer-to-start-stop-animation – Austin Aug 01 '16 at 16:51
  • 3
    Don't call `frame.setVisible(true)` until **after** you add your panel to the frame. Also calling fm.repaint() in main() isn't going to have any effect. And NEVER call sleep (or do anything that will take longer than a few milliseconds) in the paintComponent() method. You should follow the advice of @mKorbel and use a SwingTimer, and that timer should be created in your main method, not in the paintComponent method. – FredK Aug 01 '16 at 16:55
  • @Austin Yeah, I have that in init(). How can I use that to check how much time has past? – joey942 Aug 01 '16 at 16:56
  • For an example of how to use a [Swing Timer](https://docs.oracle.com/javase/8/docs/api/javax/swing/Timer.html) follow the [Docs](https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) and check [this example](http://stackoverflow.com/questions/34746795/creating-an-animated-4x4-grid-in-java/34748083#34748083) – Frakcool Aug 01 '16 at 16:58
  • 1
    `I have that in init()`, that's a gameLoop timer (which right now does nothing?) - in the case of 'transition' you may want another `Timer` that is started when you wish the transition to start (eg in the mousePressed method) - set it for 5 seconds, set it to not repeat, and set the flags back to their intended value and repaint in it's `ActionListener` – copeg Aug 01 '16 at 17:00
  • Ah, thank you @copeg. I'll try that out. And currently my gameloop has a bunch of other unrelated things in it, so I removed it to reduce spam. – joey942 Aug 01 '16 at 17:11

1 Answers1

2

You have some serious problems:

  • you add panels twice
  • you have some circuitous use of frame etc

Beyond that the following will work: you have to realize that you don't have control of the painting process. Therefore you should launch a new thread to count the sleep and let the paint do its work uninhibited.

(Also I have removed static - if you really want them you can try to put them back in - if it doesnt work you just throw them out)

class F extends JPanel implements MouseListener{
    /**
     * 
     */
    private static final int TIMER_DELAY = 35;
    private static final long serialVersionUID = -4926251405849574401L;
    public BufferedImage attic,flashlight,player,killer,frontpage,transition;
    public boolean onFrontPage,up,down,left,right,inAttic,onTransition;
    public int px,py,kx,ky;
    public static Thread th1,th2;
    public JFrame frame = new JFrame("Forgotten");
    public F(){
        init();
    }
    public void init(){
        setSize(1200,800);
        setVisible(true);
        onFrontPage = true;
        px = 600;
        py = 400;
        frame.add(this);
        frame.setSize(1200,800);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);

        frame.addMouseListener(this);
        try{    
//            player = ImageIO.read(new File("char.png"));
//            flashlight = ImageIO.read(new File("flashlightimage.png"));
//            attic = ImageIO.read(new File("attic.png"));
//            killer = ImageIO.read(new File("killer.png"));
            attic = ImageIO.read(new File(...));
            frontpage = ImageIO.read(new File(...));
            transition = ImageIO.read(new File(...));
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        int fx = px - 1033;
        int fy = py - 635;
        kx = 500;
        ky = 500;
        // Removes the flickering of the images
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // Resets the screen to make sure that it only shows the character once
        g2.clearRect(0, 0, 1200, 800);
        // Draws the background attic
        if(inAttic == true){
            System.out.println("Drawing attic"+System.currentTimeMillis());
            g2.drawImage(attic,0,0,this);
        }
        if(onFrontPage == true){
            g2.drawImage(frontpage, 0, 0, this);
        } 
        // Draws the player
        if(onFrontPage == false && onTransition == false){
            g2.drawImage(player, px, py, this);
            // Draws the Serial Killer
            g2.drawImage(killer, kx, ky, this);
            // Draws the flashlight
            g2.drawImage(flashlight, fx, fy, this);
        }
        if(onTransition == true){
            Graphics gt=transition.getGraphics();
            gt.setColor(Color.red);
            gt.drawString("xxx"+System.currentTimeMillis(), 10, 100);
            g2.drawImage(transition, 0, 0, this);
            onTransition = false;
            inAttic = true;
        }
        System.out.println(px + " " + py);
    }
    public void gameLoop(){

    }
    @Override
    public void mouseClicked(MouseEvent arg0) {
        System.out.println("MouseLocation: " + arg0.getX() + ", " + arg0.getY());
    }
    @Override
    public void mouseEntered(MouseEvent arg0) {

    }
    @Override
    public void mouseExited(MouseEvent arg0) {

    }
    @Override
    public void mousePressed(MouseEvent e) {
            onFrontPage = false;
            onTransition = true;

    Thread th=new Thread() {
      public void run() {
            repaint();
             System.out.println("Drawing Transition"+System.currentTimeMillis());
            try {
                System.out.println("Sleeping for 5 Seconds"+System.currentTimeMillis());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("Done sleeping."+System.currentTimeMillis());
            repaint();
      }
    };
    th.start();


    }
    @Override
    public void mouseReleased(MouseEvent arg0) {

    }

}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
gpasch
  • 2,672
  • 3
  • 10
  • 12