Archived

This topic is now archived and is closed to further replies.

lupine

[java] help! need delay for 1.1

Recommended Posts

lupine    122
Strangers from distant lands friends of old please consider my problem of some weeks. Using 1.1 I have media tracker and a 2D double buffering "engine" working (slow "engine" but stable) I am trying to show diferent animations ie key in arrow left walk left animation for 3 seconds command button battle battle animaton for 3 seconds For the life of me, I cannot get a "do this for 3 seconds" thing working. I have a sinking feeling that it is right under my nose. please help, Thanks, Robert Corrina

Share this post


Link to post
Share on other sites
Wrathnut    466
Hmm perhaps I can help I have actually finished an animation library for 1.1
What exactly is te problem? Is it that you can''t get the animations to run for x number of seconds? Or that you don''t know when they are done running?

If it is the former, that is fairly easy to do with a well designed object. If it is the latter, it is mostly a matter of perspective.


"And then 2 men appeared... Men in dark suits.. with dark soulless eyes. Men like this could have come from only one place..
The bank."

Share this post


Link to post
Share on other sites
lupine    122
//EDIT POST ________LET ME TRY AND EXPLAIN BETTER

Hey Wrathnut!

I cannot get the animation to run for x number of
seconds and I don't know when the animation is done.

I am showing single images as animation with image tracker
and I am also showing animated gifs.

so like

Y=0; //base animation
animation loop starts here
paint animation (Y)

end animation loop

key in = 4; y = 4;
goto animation loop

//result the animation keeps repeating until
overridden by a new key in.
i am trying to show it only once

"do you like my helmut?"-
yoghurt

[edited by - Lupine on April 30, 2003 11:13:03 AM]

Share this post


Link to post
Share on other sites
lupine    122
*bangs head against wall*

I tried to fix it last night by making the animated
.gif''s finate in their loops and then reloading them
whenever they needed to display.
but the "reload" does not cause the gif loop to
start over.

If I could just get a timer working....


so like

in animation timer START
Y=0; //=base animation

animation loop starts here
if animation timer =3 then y=0
paint animation (Y)

end animation loop

key in = 4; y = 4;
set animationtimer=0
goto animation loop

Share this post


Link to post
Share on other sites
Wrathnut    466
Hmm I see what you are getting at. Yea that was the problem I had at first to. What I finally wound up doing was:

1. Made a graphics library to store individual images.(Depending on your problem a simple array could work for this)

2. Made an animation object that stored a list of objects called animation-frames. Some of the variables it stored were
Start time
Total playing time
Elapsed time
isActived
isLooped
isRunonce
ownerID

3.The anime frames stored a reference to an object in the image library and the total frame time

4. I finally also made an animation manager that kept a master list of animations, and a second list of animations that where currently running. When the animation manager is ''ticked'' it updated the currently running anime''s time and determined if they were finished or should start another loop or so on.

One other thing is that you will probably need to define some kind of base image for you objects.. so that after the animations run the image shown next would be your base image(although this might need to been dynamically assigned according to your object''s state).

It''s a lot of work but the payoff is pretty big in the end. It seems to be a fairly robust system in the end that can be reused for many things.

Here is a listing of the code for my objects if you need something to look at.

gFXManager - contains all image an animation info, just attach it to your game class and it will init all the other classes.

  
import java.awt.Image;
import java.awt.image.PixelGrabber;
import java.awt.MediaTracker;
import java.awt.Component;
import java.util.Vector;

public class gFXManager{
private Vector gFXList;
private MediaTracker gFXTracker;
private animationManager aniManager;
private int lastLoaded;
private Component gComp;

//Image and Anime type enumerations

final static public int PRIMARY = 0;
final static public int SECONDARY = 1;
final static public int FIRE1 = 2;
final static public int FIRE2 = 3;
final static public int MOVE1 = 4;
final static public int MOVE2 = 5;
final static public int MOVE3 = 6;
final static public int MOVE4 = 7;
final static public int MOVE5 = 8;
final static public int MOVE6 = 9;
final static public int EXPLODE1 = 10;
final static public int EXPLODE2 = 11;
final static public int EXPLODE3 = 12;
final static public int EXPLODE4 = 13;
final static public int EXPLODE5 = 14;
final static public int DEATH = 15;
final static public int DAMAGE1 = 16;
final static public int DAMAGE2 = 17;
final static public int DAMAGE3 = 18;
final static public int DAMAGE4 = 19;
final static public int BACKGROUND1 = 20;
final static public int BACKGROUND2 = 21;

gFXManager(Component currentComp){
this.gFXTracker = new MediaTracker(currentComp);
this.gFXList = new Vector();
this.aniManager = new animationManager();
this.lastLoaded = 0;
this.gComp = currentComp;
}

public void addImage(Image image, String name, int type, int w, int h){
this.gFXList.addElement(new gameImage(image, name, type, w, h));
this.gFXTracker.addImage(((gameImage)this.gFXList.lastElement()).getImage(), this.gFXList.size());
}

public void addAnimation(String owner, String name, int type){
this.aniManager.addAnimation(owner, name, type);

}

public void addAnimation(String owner, String name, int type, boolean looped, boolean runOnce){
this.aniManager.addAnimation(owner, name, type, looped, runOnce);

}

public void addAniFrame(String owner, int AnimeType, String imgName, int type, long time){
this.aniManager.addAniFrame(owner, AnimeType, imgName, type, time);
}

public void startAnime(String aniOwner, String aniName, int aniType, long UID){
this.aniManager.startAnime(aniOwner, aniName, aniType, UID);
}

public void stopAnime(long UID){
this.aniManager.stopAnime(UID);
}

public Image getImage(String name, int type){
Image tmpImage = null;
for(int i=0; i < this.gFXList.size(); i++){
if(((gameImage)this.gFXList.elementAt(i)).getName().equalsIgnoreCase(name) && ((gameImage)this.gFXList.elementAt(i)).getType()==type){
tmpImage = ((gameImage)this.gFXList.elementAt(i)).getImage();
}
}

return tmpImage;
}

public Image getCurrentImg(String name, long UID){
Image tmpImage = null;

if(this.aniManager.aniActive(UID)){
tmpImage = this.getImage(this.aniManager.getImgName(UID), this.aniManager.getImgType(UID));
}

//If no active animation was found return the primary image

if(tmpImage == null){
tmpImage = this.getImage(name, PRIMARY);
}
return tmpImage;
}

public gameImage getGameImage(int index){

if(index < this.gFXList.size() && index >= 0){
return ((gameImage)this.gFXList.elementAt(index));
}
else{
return null;
}
}

public gameImage getGameImage(String name, int type){
gameImage tmpImage = null;
for(int i=0; i < this.gFXList.size(); i++){
if(((gameImage)this.gFXList.elementAt(i)).getName().equalsIgnoreCase(name) && ((gameImage)this.gFXList.elementAt(i)).getType()==type){
tmpImage = this.getGameImage(i);
}
}

return tmpImage;
}

public void loadAllImages(){
try{this.gFXTracker.waitForAll();}
catch(InterruptedException e){System.out.println("Interrupted Exception caught while forcing image load. Error: " + e);}
}

public boolean loadNextImage(){
//Try to load the images one at a time

if(lastLoaded < this.gFXList.size()){
try{this.gFXTracker.waitForID(lastLoaded);}
catch(InterruptedException e){System.out.println("Interrupted Exception caught while loading image:" + this.lastLoaded + "; Error: " + e);}

int w = this.getGameImage(this.lastLoaded).getWidth();
int h = this.getGameImage(this.lastLoaded).getHeight();
int pixSrc[] = new int[w*h];

PixelGrabber pg = new PixelGrabber(this.getGameImage(this.lastLoaded).getImage(),0 ,0 ,w ,h, pixSrc, 0 ,w);
try{pg.grabPixels();}
catch(InterruptedException e){System.out.println("Interrupted Exception caught while forcing image load. Error: " + e);}

//Make sure we have data to set the transparency map with

if ( (pg.getStatus() != pg.IMAGEERROR) && (this.gFXTracker.statusID(this.lastLoaded, true) != this.gFXTracker.ABORTED) ) {
//Set the transparency map

this.getGameImage(this.lastLoaded).setTransMap(pixSrc);
}

this.lastLoaded++;
//This might not be the last image return true

return true;
}
else{
//The last image has been loaded report false

return false;
}
}

public void clearRunOnce(String aniName, int aniType, long UID){
this.aniManager.clearRunOnce(aniName, aniType, UID);
}

public boolean animeActive(long UID){
return this.aniManager.aniActive(UID);
}

public void tick(){
this.aniManager.tick();
}

public int totalImages(){
return this.gFXList.size();
}

public int totalImagesLoaded(){
return this.lastLoaded;
}

public boolean collided(String name1, int type1, double x1, double y1, String name2, int type2, double x2, double y2){
return this.getGameImage(name1, type1).collided((int)x1, (int)y1, (int)x2, (int)y2, this.getGameImage(name2, type2).getTransMap());
}

public void flush(String ownerName){

//Flush the gfx list

for(int i= this.gFXList.size()-1; i >= 0; i--){//Loop backward through the vector and remove elements

if(((gameImage)this.gFXList.elementAt(i)).getName().equalsIgnoreCase(ownerName)){
//Flush the game images data

((gameImage)this.gFXList.elementAt(i)).flush();
//Remove it from the manager''s list

this.gFXList.removeElementAt(i);
}
}

//Flush the animation list

this.aniManager.flush(ownerName);

//Need to find a way to flush the media tracker object


}

public void zero(){
this.lastLoaded = this.gFXList.size();
}

public void report(){
//Report about data stored here

System.out.println("========= gFX MANAGER REPORT =========");
System.out.println("Total images stored: " + this.totalImages());
this.aniManager.report();
System.out.println("========= gFX MANAGER REPORT =========");
}
}




animationManager - Takes care of all of the animations so te gFXManager doesn''t have to

  
import java.util.Vector;

public class animationManager{
private Vector animeList, animeMList;

animationManager(){//Constructor

this.animeList = new Vector();//Active animation list

this.animeMList = new Vector();//Animation master list

}

public void addAnimation(String owner, String name, int type){//Add an animation to the master list

this.animeMList.addElement(new animation(name, owner, type));
}

public void addAnimation(String owner, String name, int type, boolean looped){//Add an animation to the master list

this.animeMList.addElement(new animation(name, owner, type, looped));
}

public void addAnimation(String owner, String name, int type, boolean looped, boolean runOnce){//Add an animation to the master list

this.animeMList.addElement(new animation(name, owner, type, looped, runOnce));
}

public void addAniFrame(String owner, int AnimeType, String imgName, int type, long time){//Add an animation frame

for(int i=0; i < this.animeMList.size(); i++){
if(((animation)(this.animeMList.elementAt(i))).getOwner().equalsIgnoreCase(owner) && ((animation)(this.animeMList.elementAt(i))).getType() == AnimeType){
((animation)(this.animeMList.elementAt(i))).addFrame(imgName, type, time);
}
}
}

public void startAnime(String aniOwner, String aniName, int aniType, long UID){//Try to start an animation sequence rolling


boolean wasFound = false;
int mPlace = -1;

//Search the master list for the animation being requested to start.

MainLoop:for(int i=0; i < this.animeMList.size(); i++){
if(((animation)(this.animeMList.elementAt(i))).getName().equalsIgnoreCase(aniName) && ((animation)(this.animeMList.elementAt(i))).getOwner().equalsIgnoreCase(aniOwner) && ((animation)(this.animeMList.elementAt(i))).getType() == aniType){
mPlace = i;
//Perform a different test for the runOnce''s

if(!((animation)(this.animeMList.elementAt(i))).getRunOnce()){
//Try finding an inactive animation to copy over for the active animation list

for(int j=0; j < this.animeList.size(); j++){
if(!((animation)(this.animeList.elementAt(j))).isActive() && !((animation)(this.animeList.elementAt(j))).getRunOnce()){
//Try to stop all other animations for this object

this.stopAnime(UID);
//Copy the Master data information over the inactive animation

((animation)(this.animeList.elementAt(j))).copy(((animation)(this.animeMList.elementAt(i))));
((animation)(this.animeList.elementAt(j))).setOwnerID(UID);
//Start it going

((animation)this.animeList.elementAt(j)).activate();
wasFound = true;
break MainLoop;
}
}
}
else{//Handle the runOnce animations

//See if the same animation exists within the inactive loop

for(int j=0; j < this.animeList.size(); j++){
//Determine if the request is the owner

if(((animation)this.animeList.elementAt(j)).getOwnerID() == UID){
//Check to see if this is the same anime being called again

if(((animation)this.animeList.elementAt(j)).getName().equalsIgnoreCase(aniName) && ((animation)this.animeList.elementAt(j)).getType() == aniType){
//The same anime is being called again

//Make sure a new one is not added

wasFound = true;
}
}
}
}

}
}

//If no inactive animations were found then create a new animation in the active animations.

if(!wasFound && mPlace >= 0){
//Try to stop all other animations for this object

this.stopAnime(UID);
this.animeList.addElement(new animation());
((animation)(this.animeList.lastElement())).copy(((animation)(this.animeMList.elementAt(mPlace))));
((animation)(this.animeList.lastElement())).setOwnerID(UID);
((animation)(this.animeList.lastElement())).activate();
}

}

public void clearRunOnce(String aniName, int aniType, long UID){
for(int i=0; i < this.animeList.size(); i++){
//See if this is thee same owner and is a runOnce

if(((animation)this.animeList.elementAt(i)).getOwnerID() == UID && ((animation)this.animeList.elementAt(i)).getRunOnce()){
//See if this is the same animation name and type

if(((animation)this.animeList.elementAt(i)).getName().equalsIgnoreCase(aniName) && ((animation)this.animeList.elementAt(i)).getType() == aniType){
//Remove the animation from the active list

this.animeList.removeElementAt(i);
}
}
}
}

public void stopAnime(long UID){//Stop all animations for this ID

for(int i=0; i < this.animeList.size(); i++){
if(((animation)(this.animeList.elementAt(i))).getOwnerID() == UID && ((animation)(this.animeList.elementAt(i))).isActive()){
((animation)(this.animeList.elementAt(i))).kill();
}
}
}

public String getImgName(String owner){//Get the current Imag name

for(int i =0; i < this.animeList.size(); i++){
//Find an active animation for this owner

if(((animation)(this.animeList.elementAt(i))).isActive() && ((animation)(this.animeList.elementAt(i))).getOwner().equalsIgnoreCase(owner)){
return ((animation)(this.animeList.elementAt(i))).getImgName();
}
}
return "";
}

public String getImgName(long UID){//Get the current Imag name

for(int i =0; i < this.animeList.size(); i++){
//Find an active animation for this owner

if(((animation)(this.animeList.elementAt(i))).isActive() && ((animation)(this.animeList.elementAt(i))).getOwnerID() == UID){
return ((animation)(this.animeList.elementAt(i))).getImgName();
}
}
return "
";
}

public int getImgType(String owner){//Get the current Imag type

for(int i =0; i < this.animeList.size(); i++){
//Find an active animation for this owner

if(((animation)(this.animeList.elementAt(i))).isActive() && ((animation)(this.animeList.elementAt(i))).getOwner().equalsIgnoreCase(owner)){
return ((animation)(this.animeList.elementAt(i))).getImgType();
}
}
return -1;
}

public int getImgType(long UID){//Get the current Imag type

for(int i =0; i < this.animeList.size(); i++){
//Find an active animation for this owner

if(((animation)(this.animeList.elementAt(i))).isActive() && ((animation)(this.animeList.elementAt(i))).getOwnerID() == UID){
return ((animation)(this.animeList.elementAt(i))).getImgType();
}
}
return -1;
}

public boolean aniActive(long UID){//Determine if any animation is active for this ID

boolean active = false;

for(int i=0; i < this.animeList.size(); i++){
if(((animation)(this.animeList.elementAt(i))).getOwnerID() == UID && ((animation)(this.animeList.elementAt(i))).isActive()){
active = true;
}
}

return active;
}

public void tick(){//Tick the animation sequences

for(int i=0; i < this.animeList.size(); i++){
if(((animation)(this.animeList.elementAt(i))).isActive()){
((animation)(this.animeList.elementAt(i))).tick();
}
}
}

public void flush(String ownerName){
//Clear the master list

for(int i= this.animeMList.size()-1; i >= 0; i--){//sift through it backwards

if( ((animation)this.animeMList.elementAt(i)).getName().equalsIgnoreCase(ownerName)){
((animation)this.animeMList.elementAt(i)).flush();
this.animeMList.removeElementAt(i);
}
}

//Clear the active list

for(int i= this.animeList.size()-1; i >= 0; i--){//sift through it backwards

if( ((animation)this.animeList.elementAt(i)).getName().equalsIgnoreCase(ownerName)){
((animation)this.animeList.elementAt(i)).flush();
this.animeList.removeElementAt(i);
}
}
}

public void report(){
System.out.println("
---------Begin Animation Manager Report-------");
System.out.println("
Total animations: " + this.animeMList.size());
System.out.println("
Total animations in active list: " + this.animeList.size());
System.out.println("
Active List Info:");
for(int i=0; i < this.animeList.size(); i++){
System.out.println("
Name:" + ((animation)(this.animeList.elementAt(i))).getName() + " ID:" +((animation)(this.animeList.elementAt(i))).getOwnerID());
}
System.out.println("
---------End Animation Manager Report---------");
}
}




animation - stores anime info frames list and such

  
import java.util.Vector;

public class animation{
private Vector aFList;
private String name, owner;
private int type;
private boolean active, loop, runOnce;
private long startTime, ellapsedTime, totalTime, ownerID;

animation(){//Simple animtation constructor

this.aFList = new Vector();
this.name = "";
this.owner = "
";
this.type = 0;
this.ellapsedTime = 0;
this.startTime = 0;
this.totalTime = 0;
this.active = false;
this.loop = false;
this.runOnce = false;
this.ownerID = 0;
}

animation(String aniName, String aniOwner, int aniType){//More complete animation constructor

this.aFList = new Vector();
this.name = aniName;
this.owner = aniOwner;
this.type = aniType;
this.ellapsedTime = 0;
this.startTime = 0;
this.totalTime = 0;
this.active = false;
this.loop = false;
this.runOnce = false;
this.ownerID = 0;
}

animation(String aniName, String aniOwner, int aniType, boolean looped){//More complete animation constructor

this.aFList = new Vector();
this.name = aniName;
this.owner = aniOwner;
this.type = aniType;
this.ellapsedTime = 0;
this.startTime = 0;
this.totalTime = 0;
this.active = false;
this.loop = looped;
this.runOnce = false;
this.ownerID = 0;
}

animation(String aniName, String aniOwner, int aniType, boolean looped, boolean runOnce){//More complete animation constructor

this.aFList = new Vector();
this.name = aniName;
this.owner = aniOwner;
this.type = aniType;
this.ellapsedTime = 0;
this.startTime = 0;
this.totalTime = 0;
this.active = false;
this.loop = looped;
this.runOnce = runOnce;
this.ownerID = 0;
}

animation(String aniName, String aniOwner, long ownerID, int aniType){//More complete animation constructor

this.aFList = new Vector();
this.name = aniName;
this.owner = aniOwner;
this.type = aniType;
this.ellapsedTime = 0;
this.startTime = 0;
this.totalTime = 0;
this.active = false;
this.loop = false;
this.runOnce = false;
this.ownerID = 0;
}

animation(String aniName, String aniOwner, long ownerID, int aniType, boolean looped, boolean runOnce){//More complete animation constructor

this.aFList = new Vector();
this.name = aniName;
this.owner = aniOwner;
this.type = aniType;
this.ellapsedTime = 0;
this.startTime = 0;
this.totalTime = 0;
this.active = false;
this.loop = looped;
this.runOnce = runOnce;
this.ownerID = 0;
}

public void addFrame(String imgName, int imgType, long frameTime){//Add a frame to this animation

this.aFList.addElement(new animationFrame(imgName, imgType, frameTime));
this.totalTime += frameTime;
}

public void activate(){//Activate this animation

this.active = true;
this.startTime = System.currentTimeMillis();
this.ellapsedTime = 0;
}

public void activate(long time){//Activate this animation according to a time sent

this.active = true;
this.startTime = time;
this.ellapsedTime = 0;
}

public void tick(){//Age the frames of animation

this.ellapsedTime = System.currentTimeMillis() - this.startTime;
if(this.ellapsedTime > this.totalTime){
if(this.loop){
this.activate();
}
else{
this.kill();
}
}
}

public void tick(long time){//Age the frames of animtaion according to a time sent

this.ellapsedTime = time - this.startTime;
if(this.ellapsedTime > this.totalTime){
if(this.loop){
this.activate();
}
else{
this.kill();
}
}
}

public void kill(){//Deactivate and reset

this.active = false;
this.ellapsedTime = 0;
this.startTime = 0;
}

public boolean isActive(){//Return if active or not

return this.active;
}

public boolean isLooped(){//Return whether or not this is a looping animation

return this.loop;
}

public String getOwner(){
return this.owner;
}

public long getOwnerID(){
return this.ownerID;
}

public void setOwnerID(long UID){
this.ownerID = UID;
}

public String getName(){
return this.name;
}

public int getType(){
return this.type;
}

public void setRunOnce(boolean b1){
this.runOnce = b1;
}

public boolean getRunOnce(){
return this.runOnce;
}

public String getImgName(){//Returns the most current frame''s image name

//Find the posistion of the current frame and then return the name

long times = 0, oldTime=0;
int tmpNum = -1;

for(int i =0; i < this.aFList.size(); i++){
oldTime = times;
times += ((animationFrame)(this.aFList.elementAt(i))).frameTime;
if(this.ellapsedTime <= times && this.ellapsedTime > oldTime){
tmpNum = i;
}
}
//Cover your butt

if(tmpNum == -1){
return null;
}
else{
return ((animationFrame)(this.aFList.elementAt(tmpNum))).imgName;
}
}

public int getImgType(){//Returns the most current frame''s image type

//Find the posistion of the current frame and then return the type

long times = 0, oldTime=0;
int tmpNum = -1;

for(int i =0; i < this.aFList.size(); i++){
oldTime = times;
times += ((animationFrame)(this.aFList.elementAt(i))).frameTime;
if(this.ellapsedTime <= times && this.ellapsedTime > oldTime){
tmpNum = i;
}
}
if(tmpNum == -1){
return gFXManager.PRIMARY;
}
else{
return ((animationFrame)(this.aFList.elementAt(tmpNum))).imgType;
}
}

public int totalFrames(){//Return the number of frames held by this animation

return this.aFList.size();
}

public void copy(animation otherAnime){//Copy the contents of another animation into this one.

this.aFList = ((Vector)(otherAnime.aFList.clone()));
this.name = otherAnime.name;
this.owner = otherAnime.owner;
this.ownerID = otherAnime.ownerID;
this.type = otherAnime.type;
this.ellapsedTime = otherAnime.ellapsedTime;
this.startTime = otherAnime.startTime;
this.totalTime = otherAnime.totalTime;
this.active = otherAnime.active;
this.loop = otherAnime.loop;
this.runOnce = otherAnime.runOnce;
}

public void flush(){
this.name = "
";
this.owner = "
";
this.aFList.removeAllElements();
}

public void report(){
System.out.println("
-----------Animation Report-----------");
System.out.println("
Owner: " + this.owner + ", Name: " + this.name + ", Type: " + this.type);
for(int i=0; i < this.aFList.size(); i++){
System.out.println("
Frame: " + i + ", ImgName: " + ((animationFrame)(this.aFList.elementAt(i))).imgName + ", ImgType:" + ((animationFrame)(this.aFList.elementAt(i))).imgType + ", FrameTime: " + ((animationFrame)(this.aFList.elementAt(i))).frameTime);
}
System.out.println("
-----------Animation Report-----------");
}

}




animationFrame - a single anime frame''s info

  
public class animationFrame{
public String imgName;
public int imgType;
public long frameTime;

animationFrame(){
this.imgName = "";
this.imgType = 0;
this.frameTime = 0;
}

animationFrame(String name, int type, long time){
this.imgName = name;
this.imgType = type;
this.frameTime = time;
}

}



gameImage - contains pixel maps and image info

  
import java.awt.Image;

public class gameImage{
private Image gfxImage;
private String gfxName;
private int gfxType, width, height;
private boolean loaded;
private TransparencyMap tMap;

gameImage(){
this.gfxName = new String("");
this.gfxType = 0;
this.gfxImage = null;
this.loaded = false;
this.width = 0;
this.height = 0;
}

gameImage(Image image, String name, int type, int w, int h){
this.gfxName = new String(name);
this.gfxType = type;
this.gfxImage = image;
this.loaded = false;
this.width = w;
this.height = h;

}

public String getName(){
return this.gfxName;
}

public int getType(){
return this.gfxType;
}

public int getWidth(){
return this.width;
}

public int getHeight(){
return this.height;
}

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



public void setTransMap(int src[]){
int alpha, counter;
counter = 0;
//Creat the transparency map

this.tMap = new TransparencyMap(this.width, this.height);
//Set the map flags

for(int i = 0; i < this.width; i++){
for(int j=0; j < this.height; j++){
//Get the alpha channel

alpha = (src[j*this.width + i] >> 24) & 0xff;
if(alpha == 255){//This is a fully opaque pixel

this.tMap.setStatus(i, j, true);
counter++;
}
else{//Solid pixel

this.tMap.setStatus(i, j, false);
}
}

}
System.out.println("
Transparent pixels: " + counter);
}

public TransparencyMap getTransMap(){
return this.tMap;
}


public boolean collided(int x, int y, int x2, int y2, TransparencyMap tm2){
this.tMap.setX(x);
this.tMap.setY(y);
tm2.setX(x2);
tm2.setY(y2);
return this.tMap.collide(tm2);
}

public boolean isLoaded(){
return this.loaded;
}

public void copy(gameImage other){
this.gfxImage = other.getImage();
this.gfxType = other.getType();
this.gfxName = other.getName();
this.loaded = other.isLoaded();
this.width = other.getWidth();
this.height = other.getHeight();
this.tMap = other.getTransMap();
}

public void flush(){
this.gfxImage = null;
this.gfxType = 0;
this.gfxName = "
";
this.loaded = false;
}
}



TransparencyMap - Dewi Williams made this class, you can see his tutorial at http://www.develop-games.com

  
/*
* TransparencyMap.java 1.00 25/2/2002
*
* (C) Dewi Williams 2002.
*/


/**
* Terms of use: You may use this class in your own work or publish it provided,
* <br> 1) The source code for this file and any modifications of this file
* is included in all distributions.
* <br> 2) The author (Dewi Williams) is given full credit for
* this class, this should be recognised somewhere within your
* work and the URL www.javage.net should appear somewhere.
* You can claim credit for any modifications made under point 4.
* <br> 3) You may not charge any fee for anything that includes this
* class without first consulting the author.
* <br> 4) You may modify this class on the condition
* it is correcting a bug or making sure that this class performs
* within the contract for each method. If you do this then please
* E-mail me to notify me. This class is not a final class, you can
* add functionality through inheritance if you wish, but
* distribution restrictions still apply to this class, but not to
* any subclasses. The only other modification that can be made is
* placing this class within a package, the only package it can be
* placed in is net.javage.twoD. My E-mail address is
* Dewi@javage.net.
* <br> 5) This class does not come with any warranties, expressed
* or implied, you use it at your own risk, as does anyone
* who uses it as part of your software.
*
* <br><br>
* This class implements a transparency map for a sprite. To use
* this class you should create an instance using the constructor
* and then make successive calls to <tt>setPixel(int x, int y,
* boolean status)</tt> until we have all of the pixel data. By
* default a pixel is not solid. Ideally this should be done before
* the game starts, ie. when the sprites are loaded, doing this will
* give maximum performance from this class. When you want to check
* for collisions you should call <tt>collide(TransparencyMap
* TM)</tt>, this will return <tt>true</tt> if the two sprites do
* collide. During collision detection the first test carried out is
* checking interesection of bounding boxes, only during the second
* phase will this class look at specific pixel information.
* The width, height and co-ordinates for this class are restricted to the range
* of values that the <tt>int</tt> data type can accomodate.
*/

public class TransparencyMap {

/*
* Our transparency information
*/
private int[] data;

/*
* Or if this sprite is over 32 pixels in width, all of the
* subsprites. Either this or data will be null.
*/
private TransparencyMap[] subMaps;

/* The width of the sprite. */
private int width;

/* The height of the sprite. */
private int height;

/*
* The x co-ordinate of the top-left corner of this
* sprite/map.
*/
private int x;

/*
* The y co-ordinate of the rop-left corner of this
* sprite/map.
*/
private int y;

/**
* Creates an instance of this class, all pixels are
* initialised to non-solid.
* @param width The width of the sprite.
* @param height The height of the sprite.
*/
public TransparencyMap(int width, int height) {
if (width<=0 || height<=0)
throw new IllegalArgumentException(
"Both width and height must be >0");
this.width=width;
this.height=height;
if (width>32) {
subMaps=new TransparencyMap[((width-1)/32)+1];
for (int i=0;i<subMaps.length-1;i++) {
subMaps[i]=new TransparencyMap(32, height);
}
int lastWidth=width%32;
subMaps[subMaps.length-1]=
new TransparencyMap(lastWidth==0 ? 32 : lastWidth,
height);
} else {
data=new int[height];
}
setX(0);
setY(0);
}

/**
* Sets the status of one pixel.
* @param x The x co-ordinate of the pixel.
* @param y The y co-ordinate of the pixel.
* @param status If this is true, then the pixel will be
* interpreted as being ''solid''
*/
public void setStatus(int x, int y, boolean status) {
if (x<0 || x>=width || y<0 || y>=height) {
throw new IllegalArgumentException(
"Pixel does not lie within the bounds of the sprite.");
}
if (subMaps!=null) {
subMaps[x/32].setStatus(x%32, y ,status);
} else {
if (status) {
data[y]|=1<<(31-x);
} else {
data[y]&=~(1<<(31-x));
}
}
}

/**
* Retrieves the status of one pixel. Returns <tt>true</tt> if
* the specified pixel is solid.
* @param x The x co-ordinate of the pixel.
* @param y The y co-ordinate of the pixel.
*/
public boolean getStatus(int x, int y) {
if (x<0 || x>=width || y<0 || y>=height) {
throw new IllegalArgumentException(
"Pixel does not lie within the bounds of the sprite.");
}
if (subMaps!=null) {
return subMaps[x/32].getStatus(x%32, y);
} else {
int t=1<<(31-x);
return (data[y]&t)==t;
}
}

/**
* Retrieves the width of this map.
*/
public int getWidth() {
return width;
}

/**
* Retrieves the height of the map.
*/
public int getHeight() {
return height;
}

/**
* Sets the x co-ordinate of the top-left corner of this map.
* This can be negative.
*/
public void setX(int x) {
this.x=x;
if (subMaps!=null) {
for (int i=0;i<subMaps.length;i++) {
subMaps[i].x=x+i*32;
}
}
}

/**
* Retrives the x co-ordinate of the top-leftt corner of this
* map.
*/
public int getX() {
return x;
}

/**
* Sets the y co-ordinate of the top-left corner of this map.
* This can be negative.
*/
public void setY(int y) {
this.y=y;
if (subMaps!=null) {
for (int i=0;i<subMaps.length;i++) {
subMaps[i].y=y;
}
}
}

/**
* Retrives the y co-ordinate of the top-leftt corner of this
* map.
*/
public int getY() {
return y;
}

/**
* The collision detection. Returns <tt>true</tt> iff they have
* collided.
* @param TM The transparency map for the other
* sprite.
*/
public boolean collide(TransparencyMap TM) {
if (subMaps!=null) {
if (!intersects(TM)) return false;
for (int i=0;i<subMaps.length;i++) {
if (TM.collide(subMaps[i])) return true;
}
return false;
} else if (TM.subMaps!=null) {
return TM.collide(this);
} else {
return collide0(TM);
}
}

private boolean collide0(TransparencyMap TM) {
if (TM.x<x) return TM.collide0(this);
if (!intersects(TM)) return false;
int i=TM.y>y ? TM.y-y : 0;
int j=TM.y>y ? 0 : y-TM.y;
int limit=y+height<TM.y+TM.height ? height : TM.y-y+TM.height;
int shift=TM.x-x;
for (;i<limit;i++, j++) {
if ((data[i]&(TM.data[j]>>>shift))!=0) {
return true;
}
}
return false;
}

private boolean intersects(TransparencyMap TM) {
return x+width > TM.x &&
TM.x+TM.width > x &&
y+height > TM.y &&
TM.y+TM.height > y ;
}

/**
* Returns a string representation of this transparency map,
* it consists of a rectangle of binary values, 1 indicating
* that that pixel is solid.
*/

public String toString() {
StringBuffer result=new StringBuffer();
result.append("Width: "+width);
result.append(" Height: "+height);
result.append("\n");
for (int i=0;i<height;i++) {
for (int j=0;j<width;j++) {
result.append(getStatus(j, i) ? 1 : 0);
}
result.append("\n");
}
return result.toString();
}

}




If you want to try out using these classes instead of re-writing one of your own let me know and I will post some example code of how to load up some images and animations and play them back. Anyway I hoped I helped out a bit, if not I can take another whack at it. ^_^



"And then 2 men appeared... Men in dark suits.. with dark soulless eyes. Men like this could have come from only one place..
The bank."

Share this post


Link to post
Share on other sites
lupine    122
It means alot to me, who has no schooling
and who sings the song of not knowing
to get such a gift as your generous answer.

Let me process this (click...click...click)
and I''ll post again ASAP

Thanks

Share this post


Link to post
Share on other sites
lupine    122
bon sua,

IT WORKS MON AMI!

I changed to single images and
put a counter in so I would know
when a sequence is done running.

So know when an animation is complete
there is an automatic return to the
base animation. (with potentials for
more complex switches)

on the down side it now takes almost
160-180 seconds to load all the single
images?? how can I speed that up?
do I need to stuff everything in
a .jar file? (I heard that makes for
faster access & loading)

It''s very smooth once everything gets
loaded but there is like 90% more graphics
files on the way.

any thoughts would be most appreciated

thanks again Wrath. You solved the problem.

Share this post


Link to post
Share on other sites
Wrathnut    466
NP lupine, I am glad you found it useful. I am still in the processs of cleaning my library up so I can release it to the public. So I am kinda of glad it is atleast legible enough for an example.

As for you image problem there are a few things you can do to bring the load time down. Both of these go on the theory that it is faster to load one large object than it is to request and load several smaller objects that total the same size as the large one.

1. Jars. Pack you images into a jar. The down side of this is that all of your graphics are going to be loaded all at once.. That makes it hard to give the use an idea of how long it will take to load your media.. Or a realtime progress report of how the loading is going.

2. Images strips. Put a set of animations into one image. Either horizontally or vertically aligned. Then after the image strip is loaded into memory cut out the indiviual images for use in the graphics library.
The downside of this is that you have the added overhead of manipulating your images several times before they are ready for use. You will also need some standardized widths and heights for all of your images to follow.

Basically it boils down to #1 is easier but less profssional and #2 is harder but more professional.

It might be possible to somehow combine the 2 methods but I haven''t experimented with it yet..

Good luck


"And then 2 men appeared... Men in dark suits.. with dark soulless eyes. Men like this could have come from only one place..
The bank."

Share this post


Link to post
Share on other sites