Hi, I jus want to ask why is it that the pacman will move but it will get larger when it is painted..also is that the proper way to draw?.

here is the code

import javax.swing.*;
import java.awt.*;


public class Mypacman extends JFrame implements Runnable{

   int x;
    public Mypacman(){

         setVisible(true);
         setSize(400,400);
         setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
         setTitle("Pacman");
         setBackground(Color.black);

    }

    public void paint(Graphics g)
    {
        g.setColor(Color.RED);
        g.fillArc(x,100,60,60,30,300);
        Thread t=new Thread(this);
        try
        {
            t.sleep(100);       
        }
        catch(Exception e){}
        t.start();


    }

    public void run(){
        if(x<500)
        {
            x++;
        }
       repaint();

    }



    public static void main(String[]args){

        new Mypacman();

    }
}

Hi James, Using Thread is not good?...so the best is Timer?

You can do it with threads and waits etc, but it's too easy to get that wrong. Timer is easy & safe. Here's a little demo program that shows the basic pattern for running an animation in Swing at a predictable speed using a Timer and paintComponent...

import java.awt.Dimension;
import java.awt.Graphics;
import java.util.TimerTask;
import javax.swing.*;

public class Animation0 extends JPanel {
    // absolutely minimal example of how to structure animation in Swing.
    // One method steps the simulation model through time
    // One method updates the screen with the latest data

    public static void main(String[] args) {
        // create and display the animation in a JFrame
        final JFrame frame = new JFrame("Animation 0 (close window to exit)");
        Animation0 animationPanel = new Animation0();
        animationPanel.setPreferredSize(new Dimension(400, 150));
        frame.add(animationPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    // this is the "model" - just a single object moving at constant speed
    int xPos = 0, yPos = 35;    // current position of animated object
    int xSpeed = 1, ySpeed = 0; // current speed ( - for left/up)

    Animation0() {
        // start Timer to update the model every 30 milliseconds...
        // uses a java.util Timer rather than javax.swing Timer
        // to avoid running intensive simulation code on the swing thread
        java.util.Timer timer = new java.util.Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                updateSimulation();
            }
        };
        timer.scheduleAtFixedRate(timerTask, 0, 30);
    }

    public void updateSimulation() {
        // reliably called by Timer every 30 milliseconds
        xPos += xSpeed; // update position of object
        yPos += ySpeed;
        repaint(); // notify that screen refresh is now needed
    }

    // this is the GUI - draws the model on the screen
    @Override
    public void paintComponent(Graphics g) {
        // screen refresh - called by Swing as needed
        // Never update positions etc here because there are no
        // guarantees about when or how many times this will be called.
        super.paintComponent(g); // ensure background etc is painted
        g.fillOval(xPos, yPos, 100, 100); // draw object at current position
    }
}

Hi James,I just want to ask why is it you did not use the SwingUtilities.invokeLater in the main ?

Yes, you should use invokeLater, and I always would in "real" code.

But for this tiny demo it would just create more clutter and hide the real point. I should also mention that I have never (yet!) had a problem building a GUI on the main thread provided that I make it visible as the very last statement (but that's no excuse!).
J

Hi James,...can you please correct me if i am wrong.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Mypacman{


    public Mypacman(){


    }


    public void showUI(){
        JFrame jframe = new JFrame();
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.add(new Mypanel());
        jframe.pack();
        jframe.setVisible(true);
    }


    class Mypanel extends JPanel{

        int xPos = 0, yPos = 35;
        javax.swing.Timer t;

        public Mypanel(){}

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillArc(xPos,yPos,30,30,30,300);
           myTimer();
        }

        public Dimension getPreferredSize() {
            return new Dimension(250,200);
        }

        public void myTimer(){
           t = new javax.swing.Timer(1000, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    updatePosition();
                    repaint();

                }
            });

            t.start();
        }

        public void updatePosition(){
            xPos += 1;
            yPos += 0;

        }

    }


    public static void main(String[]args){

     SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Mypacman pacman = new Mypacman();
                pacman.showUI();

            }
        });

    }
}

27 Btter (but not essental yet) to use a java.util.Timer because the swing timer runs on the swing thread and will interfere with smooth screen updaying as your animation gets more complex (collisions etc)

35: There's no way you should be starting a timer in a paint method - you'll create a new timer every time it's called, and you don't know how often that will be. Start the timer just once, at startup, eg in your MyPanel constructor

Hi James,so the javax.swing.Timer has a donwside?...I change now my code is this what you mean?.Thank you in advance.

import javax.swing.*;
import java.awt.*;
import java.util.TimerTask;



public class Mypacman{


    public Mypacman(){
    }


    public void showUI(){
        JFrame jframe = new JFrame();
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.add(new Mypanel());
        jframe.pack();
        jframe.setVisible(true);
    }


    class Mypanel extends JPanel{

        int xPos = 0, yPos = 35;
        int  arcMouth=300;

        public Mypanel(){
            myTimer();
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillArc(xPos,yPos,30,30,30,arcMouth);


        }

        public Dimension getPreferredSize() {
            return new Dimension(250,200);
        }

        public void myTimer(){
            java.util.Timer timer = new java.util.Timer();
            TimerTask timerTask = new TimerTask() {
                @Override
                public void run() {
                    updatePosition();
                }
            };
            timer.scheduleAtFixedRate(timerTask, 0, 100);
        }

        public void updatePosition(){
            xPos += 1;
            yPos += 0;

            if((xPos%2)==0){
                arcMouth=360;
            }
            else{
                arcMouth=300;
            }
            repaint();
        }

    }


    public static void main(String[]args){

     SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Mypacman pacman = new Mypacman();
                pacman.showUI();

            }
        });

    }
}

That looks OK. Have you tried it?
Problem with swing timer is that it executes on the swing thread, so no GUI updating or painting can happen while the updatePosition is executing. Right now that's not a problem, but if you have lots of things moving, and you're checking for collisions that takes a lot of CPU. By using a util.Timer you have the modelling and the GUI painting on two difffferent threads, which gives far better performance and smoother painting.

Thank you james...Does the timer is the ideal to use when making some games?

Edited 2 Years Ago by toring

This question has already been answered. Start a new discussion instead.