Saturday, 13 December 2008

The Save / Restore and Mouse actions

Today, we complete Bridge.java with the Save and Restore processes, and the Mouse actions.

Only one save is stored, in a cookie, by the Javascript shell. Whatever state has most recently been saved can be restored as many times as desired.

The static state of the game does not vary much. The state of play is largely determined by the positions of all the sprites. Each sprite is requested to supply its save data.

/* The save process is done in three stages, to prevent
deadly embrace and similar problems with the HTML/Javascript and
the applet.

First, the Javascript sets a saveFlag. Then, when the code is at a good
stage to do the save, the actual save data is built. Finally, every
few seconds, the Javascript checks for a save string in the applet.
Normally this returns an empty string, but in this case it returns
the save data. */

// Called from Javascript
public void doSave()
{
showStatus("doSave"); // gil temp
saveFlag = true;
}
// Called from Javascript
public String getSave()
{
String newsave = new String(saveString);
showStatus("getSave" + newsave); // gil temp
saveString = new String("");
return newsave;
}
// Called from tick()
public String saveGame()
{
String save;
String chunk;
save = new String("game");
save = save.concat("currscene<"+currscene+">");
save = save.concat("popscene<"+popscene+">");
save = save.concat("songname<"+songName+">");
Vector slist = bridgedata.getAllSprites();
for (int ii = 0; ii< slist.size(); ii++)
{
Sprite sprite = (Sprite)slist.elementAt(ii);
chunk = sprite.saveMe();
if (chunk != null)
save = save.concat(chunk);
}
return save;
}

In a similar way to the Save process, game restore takes place as a result of a flag set by Javascript and a subsequent detection of that flag in the tick() method.

// Called from Javascript
public void doRestore(String restoredata)
{
showStatus("doRestore" + restoredata); // gil temp
restoreFlag = true;
restoreData = new String(restoredata);
}
// Called from tick()
public boolean restoreGame(String restore)
{
int start, end;
String save;
String chunk;
String restscene;
showStatus("restoreGame" + restore); // gil temp
start = restore.indexOf("currscene<");
end = restore.indexOf(">", start+10);
if ((start == -1)||(end == -1)) return false;
restscene = restore.substring(start+10, end);
start = restore.indexOf("popscene<", end);
end = restore.indexOf(">", start+9);
if ((start == -1)||(end == -1)) return false;
popscene = restore.substring(start+9, end);
start = restore.indexOf("songname<", end);
end = restore.indexOf(">", start+9);
if ((start == -1)||(end == -1)) return false;
songName = restore.substring(start+9, end);
Vector slist = bridgedata.getAllSprites();
for (int ii = 0; ii< slist.size(); ii++)
{
Sprite sprite = (Sprite)slist.elementAt(ii);
sprite.restoreMe(restore.substring(end));
if (sprite.isGot())
{
isHolding = sprite;
}
}
currscene = changeScene("wait");
thisscene = bridgedata.fetchCurrentScene();
displaymanager.refresh(getGraphics());
currscene = changeScene(restscene);
thisscene = bridgedata.fetchCurrentScene();
return true;
}

Finally, in the Bridge Applet, we get to the Mouse control area.
There are four basic tasks for a click.
  • If the mouse is clicked in a scene change zone, the scene is changed.
  • If a sprite is being held, and it is clicked on another sprite, then a collision may be detected and acted upon.
  • If a double click is made, a sprite may be taken or dropped.
  • If the click is made on a sprite without a held sprite, that counts as a collision and may result in an action.


// Find out where the mouse is.
public void mouseMoved(MouseEvent e)
{
mousex = e.getX();
mousey = e.getY();
}
// What happens on mouse click
public void mouseClicked(MouseEvent e)
{
Vector slist = bridgedata.getSceneSprites(currscene);
int multi = e.getClickCount();
String dest = thisscene.getDest(e.getX(), e.getY());
// Zone click takes priority
if (dest != null)
{
if (dest.equals(""))
{
if (popscene != null)
{
dest = popscene;
}
}
// Wait process
Scene waitscene = bridgedata.fetchScene("wait");
waitscene.songname = songName;
currscene = changeScene("wait");
thisscene = bridgedata.fetchCurrentScene();
displaymanager.refresh(getGraphics());
currscene = changeScene(dest);
thisscene = bridgedata.fetchCurrentScene();
}
// Click one sprite with another
else if (isHolding != null)
{
for (int ii = 0; ii< slist.size(); ii++)
{
Sprite sprite = (Sprite)slist.elementAt(ii);
if (!sprite.getName().equals(isHolding.getName()))
{
if (sprite.isHit(mousex, mousey))
{
bridgedata.collide(sprite.getName(),isHolding.getName());
}
}
}
}

// Pick up sprite
if (multi >= 2)
// Double Click behaviour
{
if (isHolding != null)
{
boolean success = isHolding.dropSprite(currscene);
if (success)
{
isHolding = null;
}
}
else
{
for (int ii = 0; ii< slist.size(); ii++)
{
Sprite sprite = (Sprite)slist.elementAt(ii);
if (sprite.isGettable())
{
if (sprite.isHit(mousex, mousey))
{
sprite.getSprite();
isHolding = sprite;
}
}
}
}
}
// Click a sprite when not holding
else
{
for (int ii = 0; ii< slist.size(); ii++)
{
Sprite sprite = (Sprite)slist.elementAt(ii);
if (sprite.isHit(mousex, mousey))
{
bridgedata.collide(sprite.getName(),null);
}
}
}
}
public void mouseDragged(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
}
//End of Bridge

No comments: