zaterdag 23 oktober 2010

JGame : Dynamically change contents of the background

For my project I wanted to put something on the background which should
not be a sprite and using getBufferGraphics() the image would appear on top
of other sprites. 
In fact I wanted to change a predefined Image from the engine.


The following steps were made to make this happen. Maybe there
is a better method, but this worked for me..



Modify

edit : src-jre\jgame\platform\JREImage.java

public class  JREImage

instead of class JREImage

and make both of the constructor public as well:

public JREImage(....
public JREImage()

===================================

edit src-base\jgame\JGImage.java
On the top :

package ..
import java.awt.*;
(add to the bottom .. before last } <= which is from the class)
public Image getImage();
public void setImage(Image img);


======================================

Edit src-jre\jgame\platform\JREImage.java
(add to the bottom .. before last } <= which is from the class)

public Image getImage(){
return this.img;
}


public void setImage(Image img){
this.img=img;
}


======================================

Edit src-jre\jgame\platform\JGEngine.java

Add this before another defined defineImage function ..


public void defineImage(String imgname,  
JGImage jig){
el.defineImage(imgname,jig);
}




Edit src-base\jgame\impl\EngineLogic.java

Add this before another defineImage function ..

// replace definedImage with new image
public void defineImage(String name, JGImage img){
String imgfile=name;


if (images_loaded.containsKey(name)) {
imgfile=(String)images_loaded.get(name);
undefineImage(name);
}
defineImage(name,"p", 0, img,"-",0,0,0,0);
if(imgfile.length() <1)imgfile=name;
images_loaded.put(name,imgfile);


}





===

Some sample code (modify for example the other JGame code and put the action after a keypress)

public Image readImage(String imagestring){
                String inputLine;
Image retval=null;
                try{


                   URL Url = new URL(getCodeBase().toString()+imagestring);
   retval = ImageIO.read(Url);
                }catch(Exception readfile){
//System.out.println("Read File exception: "+readfile.toString());
}
return retval;


}


// Image load
Image a=readImage(theimage);


// This retrieves JGImage from the background defined image
JGImage bgimg=getImage("background");


// Our own routine to create an Image object from it
java.awt.Image img=bgimg.getImage();


// Make an image to draw stuff on
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
// always use bitmask transparency

BufferedImage buf = gc.createCompatibleImage(img.getWidth(this),img.getHeight(this),Transparency.BITMASK);
Graphics gg=buf.getGraphics();
gg.drawImage(img,0,0,this);






// on top of background draw our own thing
gg.drawImage(a, imagex, imagey, this);


setBGImage("background");


// Make our own JREImage
JREImage je=new JREImage((Image)buf);
// Call our own routine to replace the defined image with the composed image
defineImage("background",(JGImage)je);

// Set the new background
setBGImage("background");



==================================================================



To recompile the jar file:

make-base

Copy the JAR file to your project directory..

1 opmerking:

  1. Right, this is exactly what I wanted to do, however it is very slow. I found a quicker method.

    The problem is the line:
    defineImage("background",(JGImage)je);

    This calls
    undefineImage(name);

    Which is very slow. If you just want to replace an image with one of the same size, you can do this instead - in EngineLogic.java:

    public void reDefineImage(String name, JGImage img) {
    images.put(name, img);
    }

    And add this to JGEngine.java:
    public void reDefineImage(String imgname,
    JGImage jig){
    el.reDefineImage(imgname,jig);
    }


    Now in the above example program, replace:
    defineImage("background",(JGImage)je);
    with
    reDefineImage("background",(JGImage)je);

    MUCH, MUCH faster. :)

    BeantwoordenVerwijderen