help with mediatracker & loading images

hi,

I have class to load images and storing them in a hash table. I then need to display the images using another class which extends Canvas.

Heres my images class:

package InvadersGame;

import java.awt.*;
import java.util.*;



public class Images {

/** mediatracker to make sure an image has been loaded */
  private MediaTracker mediaTracker;
  /** hashtable of all loaded images keyed by image file name */
  private Hashtable images;
  /** used for image id in the media tracker */
  private int imageCount=0;

  /**
   * constructing the image object
   * @param frame the parent frame used to load images
   */
  public Images(SpaceInvaders invaders) {
    mediaTracker = new MediaTracker(invaders);
    images = new Hashtable();
  }

  /**
   * load all needed images from files
   */
  public void loadImages()
  {
    //enemy images
    loadImage("images/alien.gif", Color.white);    
  }

  /**
   * load an image from a specific location
   * @param path location of the image file
   * @return an image object, or null if an error happens
   */
  public Image loadImage(String path, Color c)
  {
      
    Image image = Toolkit.getDefaultToolkit().getImage(path);
    addToMediaTracker(image, path);
    if(c!=null)
    {
      //image = GeneralUtil.setTransparentColorOld(image, c);
    }
    waitForImage(image);

    int pos = path.lastIndexOf("/");
    if(pos>=0) images.put(path.substring(pos+1), image);
    return image;
  }

  /**
   * wait for the image to be fully loaded
   * @param image image to be waited for
   */
  private void waitForImage(Image image)
  {
    if(image==null)
    {
      System.out.println("Error Loding Image");
      return;
    }
    while(image.getWidth(null)<0 || image.getHeight(null)<0){}
  }

  private void addToMediaTracker(Image image, String path) {

    if (image == null) {
      System.out.println("Could not load image " + path);
    }
    else {
      mediaTracker.addImage(image, imageCount);
    }
    try {
      mediaTracker.waitForID(imageCount);
      System.out.println("Image loaded " + path +" " +imageCount+" with (w,h)=("+image.getWidth(null)+","+image.getHeight(null)+")");
      imageCount++;
    }
    catch (InterruptedException e) {
      System.out.println("Interrupted while wiating for image " + e);
    }
  }

  /**
   * get an image object from the hashtable given its key
   * @param str image key
   * @return image object if found, otherwise it returns false
   */
  public Image getImage(String str)
  {
    return (Image)images.get(str);
  }
  
   public Image getImageByIndex(int i)
  {
    return (Image)images.get(i);
  }
  
}

and here’s the class that should display the images.

package InvadersGame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics2D;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.Random;
import java.awt.image.BufferStrategy;


public class SpaceInvaders extends Canvas{
    
    Images image;
    
    JPanel panel;
    //AlienEntity al, al2;
    Graphics2D g2;
    boolean gameRunning = true;
    ArrayList<GameEntities> entitiesList;
    AnimationThread thread;
    private BufferStrategy buffer;
    protected Images imgs;
   
    
    class AnimationThread extends Thread
    {
        public void run()
        {
            while(true)
            {
                paintEntities();
                animateEntities();                
                updateGame();
                try
                {
                    sleep(50);
                }
                catch(InterruptedException e){}
            }
        }
    }
    
    public SpaceInvaders() 
    {
        super();
                 
        imgs = new Images(this);
        imgs.loadImage("images/alien.png", null);
        imgs.loadImage("images/a.png", null);
        
        JFrame window = new JFrame("Space Invaders");
        JPanel panel = (JPanel)window.getContentPane();
        setBounds(0, 0, 800, 600);
        
        panel.add(this);
        window.setBounds(0, 0, 800, 600);
        window.setVisible(true);          
        
        window.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
               
        setFocusable(true);
        
        this.createBufferStrategy(2);
        buffer = getBufferStrategy();
        
        thread = new AnimationThread();   
            
        initialise();
    }
    
    
    public void initialise()
    {
        entitiesList = new ArrayList();
        for(int i=0; i<3; i++)
        {
            AlienEntity alien = new AlienEntity(this);
            alien.setX((int)(Math.random()*getWidth()));
            
            entitiesList.add(alien);
        }
    }
    
    public void addGameEntity(GameEntities entity)
    {
        entitiesList.add(entity);
    }
    
   
   public void updateGame()
   {
       //entity out of bounds
       for(int i=0; i<entitiesList.size(); i++)
       {
            if((entitiesList.get(i).getY()>(getHeight()+50))||(entitiesList.get(i).getX()>(getWidth()+50)))
            {
                entitiesList.get(i).setDeletionMarkedTrue(true);
            }
       }     
       
       
       //remove entities with deletion mark true
       for(int i=0; i<entitiesList.size(); i++)
       {
           if(entitiesList.get(i).deletionMark)
           {
               entitiesList.remove(i);
           }
       }
   }
        
    public void paintEntities()
    {
        Graphics2D g = (Graphics2D)buffer.getDrawGraphics();
                
        g.drawImage(imgs.getImageByIndex(0), 0,0,this);
        g.drawImage(imgs.getImageByIndex(1), 20, 20,this);
               
        buffer.show();
    }
    
    public void animateEntities()
    {
         for(int i=0; i<entitiesList.size(); i++)
        {
            entitiesList.get(i).move();
            System.out.println(entitiesList.get(i).getY());
        }
    }
    
    public Image getImage(String name)
    {
        Image image = imgs.getImage(name);
        return image;
    }
    
    
    public void setBufferstrategy(BufferStrategy buffer)
    {
        buffer = buffer;
    }
   

    public static void main(String[] args)
    {        
        SpaceInvaders canvas = new SpaceInvaders();   
        canvas.thread.start();
    }
    
}

Excuse the mess of my code. I’ve been chopping and changing to try and gt the images loaded.

In the SpaceInvaders constructor I load the images:

imgs = new Images(this);
        imgs.loadImage("images/alien.png", null);
        imgs.loadImage("images/a.png", null);

and then in the paint() method I select the image from the hash table by it’s key:

g.drawImage(imgs.getImageByIndex(0), 0,0,this);
        g.drawImage(imgs.getImageByIndex(1), 20, 20,this);
               
        buffer.show();

Both of these steps are successful but the images aren’t displayed in the Frame.

Could someone please help.

cheers

How about… using ImageIO like everyone else?

You appear to be trying to wait be spinning until width or height is greater then -1.

This is wrong a whole bunch of ways. use your media tracker and the MediaTracker.waitforId(…) call.

Thats what a MediaTracker is for.

Thanks for the replies guys. It’s all sorted and working fine now.

I am having another little problem though. I’m writing a simple space invaders game and need to move and shoot at the same time. My current ship movement is controlled by the keyPressed method:

public void keyPressed(KeyEvent e)
    {
        int code = e.getKeyCode();
        
        switch(code)
        {
            case 39:ship.moveRight(); break;
            case 37:ship.moveLeft(); break;
            case 32:  shipFire = new ShipFire(ship.x+0.25*ship.width, ship.y-15, imageHandler.getImages(5));
                      entitiesList.add(shipFire); 
                      System.out.println("FIRE");
                      break;
        }       
       
       
    }

This will only allow me to do one key press at a time, so I can’t press left and space at the same time to move left and fire. Is there a way to re-write it so I can move and fire at the same time?

Cheers :wink:

yes, use if statements instead of switches.

and i’t much nicer to see KeyEvent constants instead of integers for key code. For example, KeyEvent.VK_SPACE.