Precaching images?

Hi!

I’m trying to do my own Arkanoid game. I have solved most problems now, but one stubbornly resist my efforts… I have a spaceship that comes around once in a while, and it drops small bombs. If the bat is hit by a bomb it should explode, and it happily does… But every first time the bat explodes, the animation (consisting of about eighteen gifs in a array of Image) FLICKERS heavily. I suppose the problem is that the images are loaded to memory only when the first explosion occurs, but I have trouble finding a way to preload them.

How do you do that?

Also, when the game works, I intend to post it on the Internet. It would be nice if people tried to play it and maybe comment on the code. What could be made better and stuff like that. Maybe most of us beginners out there could learn something?

Sincerely,

Kaspar

Hello Kaspar,

If you google for MediaTracker it will give you what you are looking for. At least that is my guess.

Hope it will help!

Regards from
ME

:-[

Thanks for the advice…! I thought I had tried the MediaTracker and that it didn’t work, but this time it worked like a charm! Sometimes I wish I had a brain that worked…

Thanks!

/Kaspar

If you succeded in getting MediaTracker to do this I’d like to hear how you did it. Typically what you need to do is predraw all of your gfx before you use them.

Hi Nonnus,

It seems to work for Kaspar. In the past I was faced with the same issue and for me as well problems where solved using the waitforall method.

Maybe the following code ‘proves’ it.
I have a bunch of images that all have a number (1-50)
In the code I will load three sets of them. First no mediatracker, second with mediatracker and the last one
without mediatracker. The first and last run didn’t have an image.


import java.awt.*;
import java.net.*;

public class Media extends Frame{


        public Media(boolean withmediatracker, int imgnr){
                MediaTracker mt;
                Image images[]=new Image[10];
                int i;
            // Make null
            for(i=0; i < 10; i++)
                  images[i]=null;

                for(i=0; i < 10; i++){
                        try{
                           URL url=new URL("http://MyWebServer/homepage/maze/"+(imgnr+i)+".jpg");

                           images[i]=Toolkit.getDefaultToolkit().getImage(url);
                           if(withmediatracker){
                             mt = new MediaTracker(this);
                             mt.addImage( images[i], 0);
                             mt.waitForAll();

                           }

                        }catch(Exception eg){}
                        if(images[i].getWidth(this) < 1){
                                System.out.println("NULL Image found["+i+"]");
                        }

                } // for
        } // Media


        public static void main(String argv[]){
                Media media;
                System.out.println(" Without MediaTracker");
                media=new Media(false,0);
                System.out.println("With MediaTracker");
                media=new Media(true,11);
                System.out.println(" Without MediaTracker");
                media=new Media(false,21);

        }
}


Hopefully this ‘proves’ that mediatracker can be used to cache the images.

Regards from
ME

This is the code that keeps the flickering at bay for me.


public class Mothership implements Runnable {
      
      private GameBoardMultBall gameBoard;
      private Thread t;
      private Image image;
      private int xPosition;
      private int yPosition;
      private int xVel;
      private Random r = new Random();
      private ArrayList bombList;
      private boolean explodeFlag;
      private Image[] explosion;
      private double index;
      private MediaTracker mt;

      public Mothership(GameBoardMultBall gameBoard, ArrayList bombList) {
            this.gameBoard = gameBoard;
            this.bombList = bombList;
            this.image = Toolkit.getDefaultToolkit().getImage("Images/mothership_transparent.gif");
            explosion = new Image[] {
                  Toolkit.getDefaultToolkit().getImage("Images/Mothership explosion/mship_exp_1.gif"),
                  Toolkit.getDefaultToolkit().getImage("Images/Mothership explosion/mship_exp_2.gif"),
                  Toolkit.getDefaultToolkit().getImage("Images/Mothership explosion/mship_exp_3.gif"),
                  Toolkit.getDefaultToolkit().getImage("Images/Mothership explosion/mship_exp_4.gif"),
                  Toolkit.getDefaultToolkit().getImage("Images/Mothership explosion/mship_exp_5.gif"),
                  Toolkit.getDefaultToolkit().getImage("Images/Mothership explosion/mship_exp_6.gif"),
                  Toolkit.getDefaultToolkit().getImage("Images/Mothership explosion/mship_exp_7.gif"),
                  Toolkit.getDefaultToolkit().getImage("Images/Mothership explosion/mship_exp_8.gif"),
                  Toolkit.getDefaultToolkit().getImage("Images/Mothership explosion/mship_exp_9.gif")
            };
            mt = new MediaTracker(gameBoard);
            for(int i = 0; i < explosion.length; i++) 
                  mt.addImage(explosion[i], 0);
            this.xPosition = -60;
            this.yPosition = r.nextInt(41);
            this.xVel = r.nextInt(4) + 1;
            //this.xVel = 2;
      }
      
      public void drawMothership(Graphics g) {
            g.drawImage(image, xPosition, yPosition, null);
      }
      public void enter() {
            t = new Thread(this);
            t.start();
            //return this;
      }
      public int getXPos() {
            return xPosition;
      }
      public void setYPos(int yPos) {
            this.yPosition = yPos;
      }
      public int getYPos() {
            return yPosition;
      }
      public void explode() {
            explodeFlag = true;
      }
      public Thread getThread() {
            return t;
      }
      public void run() {
            System.out.println("Enter Mothership!\nyVel = " + xVel);
            while(xPosition < 550) {
                  xPosition++;
                  int a = r.nextInt(200);
                  if(a == 20) {
                        if(bombList.size() < gameBoard.MAX_BOMBS && explodeFlag != true)
                              bombList.add(new Bomb(xPosition + 15, yPosition + 5));
                  }
                  if(explodeFlag == true || gameBoard.endTurnFlag == true) 
                        break;
                  try{
                        Thread.sleep(xVel * 20);
                  }
                  catch(Exception e) {}
            }
            if(explodeFlag == true) {
                  try{
                        mt.waitForID(0);
                  }
                  catch(InterruptedException ie) {}
                  while(index < explosion.length) {
                        image = explosion[(int) index];
                        index += 0.5;
                        try{
                              Thread.sleep(50);
                        }
                        catch(Exception e) {}
                  }
            }
            System.out.println("Ship eligible for deletion!");
      }

}

Right now my game actually works! The thing left is to optimize it… For instance, I start a thread for about every moving thing in the game (and there are sometimes about 50 things moving…) I have to take those away and make move() methods instead (or does anybody else have good ideas on the subject?). And I do the painting using good old paint(Graphics g)… I didn’t know there was any other way before I checked Kevin’s game tutorial out… Good shit!!!

Time to rewrite…

Thanks for all input! More!

/Kaspar