Jump to content

need some help with animations

- - - - -

  • Please log in to reply
18 replies to this topic

#1
twinArmageddons

twinArmageddons

    Newbie

  • Members
  • PipPip
  • 24 posts
im trying to create a simple animation applet with this fella

http://i53.tinypic.com/waowhz_th.gif

im trying to make him run from one side of the screen to the other

this is the code


package miapplet2;


import java.applet.Applet;

import java.awt.Graphics;

import java.awt.Image;

import java.net.*;

import java.awt.Color;

import java.awt.*;

import java.applet.*;


public class animacion extends Applet implements Runnable{



    Image currentDoc;

    Thread runner;


    int xPos=10;

    int ind = 0;


    public void start() {

        if (runner == null) {

            runner = new Thread(this);

            runner.start();

        }

    }


    public void stop() {

        runner = null;

    }


    public void init() {


        try{

            

            URL u = new URL("http://i53.tinypic.com/waowhz_th.gif");

            

            currentDoc = getImage(u);



        } catch (MalformedURLException nameOfTheException)

        {

            System.exit(1);

        }


    


    }



    void pause(int time){

        try {

            Thread.sleep(time);

        } catch (InterruptedException e)

        {

            System.exit(1);

        }

    }


    public void run() {


        repaint();


       

    }



    public void paint (Graphics screen){

        

        if (currentDoc != null) {

            screen.drawImage(currentDoc, xPos, 10, this);

        }


        xPos += 10;

     

    }

   

}

the problem is the character starts running from position 120, that is after all 12 frames have been drawn, i tried to use some double buffering but the problem persists, whats more the extra code adds some graphical bugs


all the examples ive seen so far of double buffering use 2DGraphics instead of imported images like this one so im not even sure if double buffering is the answer, in any case i need help with the double buffer code or any other viable alternative to solve this problem


edit: new code with the same problem


package miapplet2;


import java.applet.Applet;

import java.awt.Graphics;

import java.awt.Image;

import java.net.*;

import java.awt.Color;

import java.awt.*;

import java.applet.*;


public class animacion2 extends Applet implements Runnable{



    Image DocPics[];

    Image offscreenDoc;

    Graphics offscreen;



    Image currentDoc;

    Thread runner;


    int xPos=10;

    int ind = 0;


    public void start() {

        if (runner == null) {

            runner = new Thread(this);

            runner.start();

        }

    }


    public void stop() {

        runner = null;

    }


    public void init() {


        resize(700, 200);


        try{


            URL u[] = new URL[12];


            u[0] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00000.png?t=1306805825");

            u[1] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00001.png?t=1306806273");

            u[2] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00002.png?t=1306805967");

            u[3] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00003.png?t=1306805967");

            u[4] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00004.png?t=1306805968");

            u[5] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00005.png?t=1306806023");

            u[6] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00006.png?t=1306806024");

            u[7] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00007.png?t=1306806025");

            u[8] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00008.png?t=1306806025");

            u[9] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00009.png?t=1306806026");

            u[10] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00010.png?t=1306806361");

            u[11] = new URL("http://i1217.photobucket.com/albums/dd384/UnscrupulousUser/IMG00011.png?t=1306806362");



            DocPics = new Image[u.length];


            for(int i = 0; i<u.length ; i++){

                DocPics[i] = getImage(u[i]);

            }


            currentDoc = DocPics[0];



        } catch (MalformedURLException nameOfTheException)

        {

            System.exit(1);

        }


        offscreenDoc = createImage(size().width, size().height);

        offscreen = offscreenDoc.getGraphics();


    }


    void DocRun(int veces){

     

            if (currentDoc == DocPics[11])

                currentDoc = DocPics[0];

            else

            if (currentDoc == DocPics[0])

                currentDoc = DocPics[1];

            else

            if (currentDoc == DocPics[1])

                currentDoc = DocPics[2];

            else

            if (currentDoc == DocPics[2])

                currentDoc = DocPics[3];

            else

            if (currentDoc == DocPics[3])

                currentDoc = DocPics[4];

            else

            if (currentDoc == DocPics[4])

                currentDoc = DocPics[5];

            else

            if (currentDoc == DocPics[5])

                currentDoc = DocPics[6];

            else

            if (currentDoc == DocPics[6])

                currentDoc = DocPics[7];

            else

            if (currentDoc == DocPics[7])

                currentDoc = DocPics[8];

            else

            if (currentDoc == DocPics[8])

                currentDoc = DocPics[9];

            else

            if (currentDoc == DocPics[9])

                currentDoc = DocPics[10];

            else

            if (currentDoc == DocPics[10])

                currentDoc = DocPics[11];

            else

            if (currentDoc == DocPics[11])

                currentDoc = DocPics[0];

            repaint();

            pause (100);

          

    }




    void pause(int time){

        try {

            Thread.sleep(time);

        } catch (InterruptedException e)

        {

            System.exit(1);

        }

    }


    public void run() {





        Thread thisThread = Thread.currentThread();


        while(runner == thisThread) {

            DocRun(5);

            xPos+=10;

        }

       


    }


    public void update (Graphics screen){

        offscreen.setColor(getBackground());

        offscreen.fillRect(0,0,size().width, size().height);

        offscreen.setColor(getForeground());

        screen.setColor(getBackground());

        screen.fillRect(0,0,size().width, size().height);

        screen.setColor(getForeground());

        paint(screen);

    }


    public void paint (Graphics screen){

       

        if (currentDoc != null) {

            offscreen.drawImage(currentDoc, 0, 10, this);

        }


        screen.drawImage(offscreenDoc, xPos, 0, this);

        


    }


}


sorry for the trouble but i just cant figure out whats wrong with this

Edited by twinArmageddons, 31 May 2011 - 01:25 PM.


#2
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Just let xPos begin at let's say -300.

#3
twinArmageddons

twinArmageddons

    Newbie

  • Members
  • PipPip
  • 24 posts

wim DC said:

Just let xPos begin at let's say -300.

well i made a similar solution, it moves the character back to xPos 0 after it reaches xPos 120, but i was thinking about something a little more... effective

i mean its almost like cheating its not really solving the problem its just hiding it, ive been thinking double buffer might be the answer but i just cant find a code that uses imported images

#4
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts
Oh, I know what's going on. You need to read your Java docs more often! Here's the Applet.getImage method you're calling's documentation:

Java SE 6 Documentation said:

Returns an Image object that can then be painted on the screen. The url that is passed as an argument must specify an absolute URL.

This method always returns immediately, whether or not the image exists. When this applet attempts to draw the image on the screen, the data will be loaded. The graphics primitives that draw the image will incrementally paint on the screen.
What this means is that you don't have the image yet since you're loading it from the internet. Your program will need to wait until it's done, but how? Here's a hint: All Applets are Components, and all Components are ImageObservers! Turns out the Applet will always pass itself as an ImageObserver to Image method calls...
Wow I changed my sig!

#5
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Did some testing at home, and I don't think that's the (whole) problem.

I discovered the paint method gets executed A LOT, and therefor the xPos goes up fast. Even before your pc has decently rendered the applet.
It's the update() method (from Container class) which is called over and over again, which in turn calls this paint method, increasing the xPos with it.
And by the time your pc is ready to show you something it's pretty much halfway and it runs away.

I have no idea why it's updating so frequently. I guess it's normal applet behaviour.

What you can do is override this update method and force it to not update so frequently.
But since I think it's normal behaviour to be running so frequently, it may be better to NOT do that.
What I would do is: don't raise xPos in the paint() method, but increase it in your thread's run() method. (so even tho paint is called multiple times, your character won't move unless YOU tell it to do so.)

On a side note, your run() method is wrong. Your thread will stop right after having executed that 1 line. You need a loop in the run method to keep it going.
I suggest you look up some Thread examples.

#6
twinArmageddons

twinArmageddons

    Newbie

  • Members
  • PipPip
  • 24 posts

wim DC said:

Did some testing at home, and I don't think that's the (whole) problem.

I discovered the paint method gets executed A LOT, and therefor the xPos goes up fast. Even before your pc has decently rendered the applet.
It's the update() method (from Container class) which is called over and over again, which in turn calls this paint method, increasing the xPos with it.
And by the time your pc is ready to show you something it's pretty much halfway and it runs away.

I have no idea why it's updating so frequently. I guess it's normal applet behaviour.

What you can do is override this update method and force it to not update so frequently.
But since I think it's normal behaviour to be running so frequently, it may be better to NOT do that.
What I would do is: don't raise xPos in the paint() method, but increase it in your thread's run() method. (so even tho paint is called multiple times, your character won't move unless YOU tell it to do so.)

On a side note, your run() method is wrong. Your thread will stop right after having executed that 1 line. You need a loop in the run method to keep it going.
I suggest you look up some Thread examples.

you are right about the run() method and your solution makes sense, ill try it as soon as i get home


the run() there is actually a placeholder, im planning on adding some more behaviour to this applet based on an example on a java book im reading ("teach yourself java in 21 days" also known as "the bible of java amateurs") but i was trying to figure out how to solve this problem first and since i had already extended the applet and i had to overwrite the run() method, well...

#7
twinArmageddons

twinArmageddons

    Newbie

  • Members
  • PipPip
  • 24 posts
ok this is the new run() method, i deleted the xPos+= 10 from paint


    public void run() {


        Thread thisThread = Thread.currentThread();

        

        while(runner == thisThread) {

            repaint();

            xPos += 10;

        }

        

       

    }


aaannnndddd it doesnt work, at all, it shows nothing on the screen


edit: nevermind i added a sleep() method, it now works almost perfectly

#8
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Actually because this update() method is constantly calling the paint() method, you don't have to do repaint() in the thread I think. Just upping the xPos should be enough.

#9
twinArmageddons

twinArmageddons

    Newbie

  • Members
  • PipPip
  • 24 posts
double post, ****

for a programmer's forum, this place is really buggy :/

#10
twinArmageddons

twinArmageddons

    Newbie

  • Members
  • PipPip
  • 24 posts

wim DC said:

Actually because this update() method is constantly calling the paint() method, you don't have to do repaint() in the thread I think. Just upping the xPos should be enough.

you are right

i have a question, where is the update method being called here? is it the drawImage method? is it overloaded to constantly call the update method when a gif image is used as a parameter?

#11
lethalwire

lethalwire

    while(false){ ... }

  • Members
  • PipPipPipPipPipPipPip
  • 748 posts
  • Programming Language:Java, PHP
  • Learning:Java, PHP

twinArmageddons said:

you are right

i have a question, where is the update method being called here? is it the drawImage method? is it overloaded to constantly call the update method when a gif image is used as a parameter?


From Painting in AWT and Swing :

Quote

The AWT causes the event dispatching thread to invoke update() on the component.

but only because:

Quote

The program determines that either part or all of a component needs to be repainted in response to some internal state change.


But be sure to note:

Quote

If the component did not override update(), the default implementation of update() clears the component's background (if it's not a lightweight component) and simply calls paint().
Which is also your case, because you didn't override the update() method.

You have access to the update() method because you have extended JApplet. By extending JApplet you have acquired update() from the Component class.

#12
twinArmageddons

twinArmageddons

    Newbie

  • Members
  • PipPip
  • 24 posts

lethalwire said:

From Painting in AWT and Swing :


but only because:




But be sure to note:

Which is also your case, because you didn't override the update() method.

You have access to the update() method because you have extended JApplet. By extending JApplet you have acquired update() from the Component class.

yeah the reason i did not override the update() method is becuz my previous code used images with transparent background and as you can imagine if i overode the code to not clear the background, the results would've been quite... messy


in fact im going to try that code again since i believe i solved the double buffering problem




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users