Monday 8 December 2008

The Bridge Applet - Part 3

Now we come to the changeScene function.
  • It makes sure this is a valid scene name;
  • If the player is carrying anything, it relocates the object in the new scene;
  • Displays the hourglass cursor;
  • Fetches the image for the new scene and all the sprite images;
  • Tells bridgedata and displaymanager about it;
  • Flags a song change.

I don't understand the comment which appears to imply that time is saved in subsequent visits to this scene because the data is cached. It looks as though the sprite images are remembered during a scene, but if the same sprite is encountered in a subsequent screen its data is reloaded. Having thought all the way round this, I conclude it's the best strategy. But the way it's implemented is silly, isn't it?

// This function collects the scene and any sprites
// It also reads in the Images for the background and Sprites
// this time only. Once the scene changes, the images are assumed to be
// present.
// Returns the scene name.
public String changeScene(String sceneName)
{
Scene scene = bridgedata.fetchScene(sceneName);
if (scene == null)
{
showStatus("No such scene:" + sceneName);
return currscene;
}
// Deal with any carried items
if (isHolding != null)
{
isHolding.relocate(sceneName);
}
currCursor = Cursor.WAIT_CURSOR;
setCursor(Cursor.getPredefinedCursor(currCursor));
MediaTracker tracker= new java.awt.MediaTracker(this);
URL address = getCurrentUrl("images/"+scene.imagename);
backcloth = getImage(address);
tracker.addImage(backcloth, 0);
Vector slist = bridgedata.getSceneSprites(sceneName);
int serial = 1;
for (int ii = 0; ii< slist.size(); ii++)
{
Sprite sprite = (Sprite)slist.elementAt(ii);
Vector sfnames = sprite.getAllFilenames();
for (int jj = 0; jj < sfnames.size(); jj++)
{
String fn = (String)sfnames.elementAt(jj);
URL addr = getCurrentUrl("images/"+ fn);
Image im = getImage(addr);
tracker.addImage(im, serial++);
}
}
try
{
tracker.waitForAll();
}
catch (InterruptedException e)
{
showStatus("Scene Load Media Tracker Interrupted");
}
// cache images with sprite
for (int ii = 0; ii< slist.size(); ii++)
{
Sprite sprite = (Sprite)slist.elementAt(ii);
Vector sfnames = sprite.getAllFilenames();
for (int jj = 0; jj < sfnames.size(); jj++)
{
String fn = (String)sfnames.elementAt(jj);
URL addr = getCurrentUrl("images/"+ fn);
Image im = getImage(addr);
sprite.addImage(jj, im);
}
}
currCursor = Cursor.DEFAULT_CURSOR;
setCursor(Cursor.getPredefinedCursor(currCursor));

bridgedata.setCurrentScene(sceneName);
displaymanager.setBackground(backcloth);
songName = scene.songname;
songFlag = true;
return sceneName;
}


Straightforward function to create absolute url from relative url.

// Form url from relative string and base
URL getCurrentUrl(String relative)
{
String urlstr = codebasestr.concat(relative);
try
{
URL urlurl = new URL(urlstr);
return urlurl;
}
catch (MalformedURLException e)
{
showStatus("Error" + urlstr);
}
return null;
}


Here is the function that is called by Javascript when the Inventory button is clicked. It sets a flag to request a scene change to the Inventory.

I remarked earlier that a change to Inventory ought not to take place if the current scene is already Inventory. I could duplicate this test here.

// Called from Javascript
public void goInv()
{
showStatus("goInv"); // gil temp
if (!currscene.equals("inventory")) invFlag = true;
}



// Called from Javascript
public String checkSong()
{
String noSong = new String("none");
showStatus("checkSong"); // gil temp
if (songFlag)
{
songFlag = false;
return(songName);
}
return(noSong);
}

No comments: