|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="content-language" content="en">
<title>HylZee</title>
<!--META HTTP-EQUIV="Expires" CONTENT="Fri, Jan 01 1900 00:00:00 GMT"-->
<!-- commented out, seems to affect images META HTTP-EQUIV="Pragma" CONTENT="no-cache"-->
<!--META HTTP-EQUIV="Cache-Control" CONTENT="no-cache"-->
<meta name="author" content="peter.schaefer@gmail.com">
<META HTTP-EQUIV="Reply-to" CONTENT="peter.schaefer@gmail.com">
<meta name="generator" content="Code Monkey 1970.01.18(tm Peter Schaefer)">
<META NAME="description" CONTENT="HylZee - A DHTML puzzle game">
<meta name="keywords" content="HylZee DHTML javascript puzzle game huelsi tal pyr">
<META NAME="Creation_Date" CONTENT="09.10.2004">
<meta name="revisit-after" content="30 days">
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" src="favicon.ico">
<!-- copyright 2004 peter schaefer -->
<!--
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-->
<style type="text/css">
b {font-size:16px;}
.map {color:white;}
.controlembossed {
background: #66CC33;
border-top-style:solid;
border-right-style:solid;
border-bottom-style:solid;
border-left-style:solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-right-color: #99FF66;
border-top-color: #99FF66;
border-left-color: #666666;
border-bottom-color: #666666;
}
a:link { color: #99FF66; }
a:hover { color: #FFFF66; }
a:active { color: #FF9966; }
a:visited { color: #66FF33; }
table,tbody,th,td,img,span {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom 0px;
padding-left: 0px;
padding-top: 0px;
padding-right: 0px;
padding-bottom: 0px;
}
</style>
<script language="JavaScript" type="text/JavaScript">
<!--
// placement of map window
var map_top= 18;
var map_left= 20;
// grid size of map tiles
var cell_height=32;
var cell_width= cell_height;
// size of bullet graphics
var bullet_width= 12;
var bullet_height= 12;
var status_font= 18;
//status bar minimum width
var minStatusbarWidth= 10*32;
var tileset="default"
// number of space units/tile
var step_unit= 100;
// number of ticks/1 tile movement
var ticks_unit= 420;
// ticks/processing of mainLoop
//FIXME: this doesn't work with 40/240;
var theTick= 42;
// frequency of mainloop
var mainDelay= 20;
// which level to load
var lastLevel= "maps/test/devel-001.html";
// show shrinking animations
var shrink= true;
//continue running
var mainProceed= true;
var debug= false;
//
// debugall switches on most annoying debug output
//
var debugall= true;
var hideDebug= true || debug;
//input constants
var key_fire= 70;
var key_right= 39;
var key_down= 40;
var key_up= 38;
var key_left= 37;
//map object
var map= null;
//log repeat functionality
var log_lastMsg="";
var log_count=0;
var log_threshold=2;
var log_limit=3000;
//which codes signal start and home
var code_start='A';
var code_home ='H';
//
// arguments.caller has been deprecated
// So the stacktrace will not work in new browsers
//
function funcname(f) {
var s = f.toString().match(/function (\w*)/)[1];
if ((s == null) || (s.length==0)) return "anonymous";
return s;
}
function stacktrace() {
if(!arguments.caller) {
return "no stacktrace available";
}
var s = "";
for (var a = arguments.caller; a !=null; a = a.caller) {
s += "->"+funcname(a.callee) + "\n";
if (a.caller == a) {s+="*"; break;}
}
return s;
}
function debugMsg(message) {
if(debug) {
//window.status= message;
if(log_lastMsg!=message) {
log_lastMsg=message;
log_count=0;
log_threshold=2;
message="<br>"+message;
}else {
log_count++;
if(log_count>=log_threshold) {
message= "<br>last message repeated "+log_count+" more times.";
log_threshold<<=1;
log_count=0;
}else {
message="";
}
}
if(message) {
var debugDiv= document.getElementById("debugoutput");
if(debugDiv){
var startpos= (debugDiv.innerHTML.length>log_limit)?(debugDiv.innerHTML.length-log_limit):0;
debugDiv.innerHTML= debugDiv.innerHTML.substring(startpos, debugDiv.innerHTML.length)+message;
}else if(debug && debugall) {
alert("debugMsg "+log_lastMsg+" (page isn't loaded yet/no debug window found)");
debugall= false;
}
}
}
}
function debugEval(test) {
debugMsg(test+"="+eval(test));
}
function showLayer(layer) {
var div= document.getElementById(layer);
if(div)
div.style.visibility = 'visible';
}
function hideLayer(layer) {
var div= document.getElementById(layer);
if(div)
div.style.visibility = 'hidden';
}
// the fudge factor is used to work around math rounding errors
var fudge= 0.000001;
function toGridX(x) {
return Math.floor(x/step_unit+fudge);
}
function toGridY(y) {
return Math.floor(y/step_unit+fudge);
}
function toScreenX(x) {
return map_left+Math.floor(x*cell_width+fudge);
}
function toScreenY(y) {
return map_top+Math.floor(y*cell_height+fudge);
}
var protagonist=null;
var gameState=null;
var Coordinate_toString= function() {
return '('+this.x+','+this.y+')';
}
function Coordinate_copy() {
return new Coordinate(this.x,this.y);
}
function Coordinate_clip() {
var clipped= false;
if( this.x<-fudge ) {
this.x=0;
clipped= true;
} else if( this.x-fudge>step_unit*(map.xmax-1) ) {
this.x= step_unit*(map.xmax-1);
clipped= true;
}
if( this.y<-fudge ) {
this.y=0;
clipped= true;
} else if( this.y-fudge>step_unit*(map.ymax-1) ) {
this.y= step_unit*(map.ymax-1);
clipped= true;
}
return clipped;
}
function Coordinate_add(coordinate) {
this.x+= coordinate.x;
this.y+= coordinate.y;
}
function Coordinate_gridLock() {
this.x= step_unit*Math.floor((this.x+step_unit/2+fudge)/step_unit);
this.y= step_unit*Math.floor((this.y+step_unit/2+fudge)/step_unit);
}
function Coordinate(x,y) {
this.x= x;
this.y= y;
//methods
this.clip= Coordinate_clip;
this.toString= Coordinate_toString;
this.add= Coordinate_add;
this.copy= Coordinate_copy;
this.gridLock= Coordinate_gridLock;
}
function toName() {
return 'Avatar of:'+this.name;
}
function Avatar(name,modifier,facing) {
this.name= name;
this.modifier= modifier;
this.facing= facing;
//methods
this.toString= toName;
}
//
// image preloading
//
var myImages= new Array();
function loadImages() {
for (i=0;i<loadImages.arguments.length;i++) {
var pos= myImages.length;
myImages[pos]=new Image();
myImages[pos].src= loadImages.arguments[i];
}
}
function imagePath(imageName) {
return 'images/'+tileset+'/'+imageName;
}
var browsercaps= new Object();
//get internal browser representation/ordering of html
function fixHTML(html) {
if(browsercaps.fixHTML) {
var div= document.getElementById("scratchpad");
div.innerHTML= html;
return div.innerHTML;
}else{
return html;
}
}
//
// Some browser, like gecko, covert innerHTML to canonic representation.
// this causes flickering
//
function debugHTMLrep(text){
var fixed= fixHTML(text);
if( fixed!= text) {
debugMsg("txt:"+escape(text));
debugMsg("fix:"+escape(fixed));
}
}
function Direction_normalize(direction) {
if(direction<0)
direction= (direction- 360*Math.floor(direction/360+fudge))
direction= (direction+360)%360;
return direction;
}
//
// This function almost works for all agents
//
function Protagonist_mapToImage() {
this.image="protagonist";
if(this.mode) {
this.image+= "_"+this.mode;
}
if(this.mode!="victorious") {
if(this.facing>=0 && this.facing<=45)
this.image+= "_right";
else if(this.facing>=45 && this.facing<=135)
this.image+= "_up";
else if(this.facing>=135 && this.facing<=225)
this.image+= "_left";
else if(this.facing>=225 && this.facing<=315)
this.image+= "_down";
else if(this.facing>=315 && this.facing<=360)
this.image+= "_right";
else {
var msg='mapToImage: ('+this.facing+', bad facing)';
debugMsg(msg);
}
}
this.image+="_64.gif";
return this.image;
}
var bullet_right= new Avatar('bullet_small','right',0);
var bullet_up= new Avatar('bullet_small','up',90);
var bullet_left= new Avatar('bullet_small','left',180);
var bullet_down= new Avatar('bullet_small','down',270);
var bird_right= new Avatar('phoenix_moving','right',0);
var bird_up= new Avatar('phoenix_moving','up',90);
var bird_left= new Avatar('phoenix_moving','left',180);
var bird_down= new Avatar('phoenix_moving','down',270);
var siren_right= new Avatar('chess-rook_moving','right',0);
var siren_up= new Avatar('chess-rook_moving','up',90);
var siren_left= new Avatar('chess-rook_moving','left',180);
var siren_down= new Avatar('chess-rook_moving','down',270);
function getSirenForDirection(direction) {
direction= Direction_normalize(direction);
if(direction>=0 && direction<=45)
return siren_right;
else if(direction>=45 && direction<=135)
return siren_up;
else if(direction>=135 && direction<=225)
return siren_left;
else if(direction>=225 && direction<=315)
return siren_down;
else if(direction>=315 && direction<=360)
return siren_right;
else {
var avatar= 'getSiren: fuck up('+direction+', bad argument)';
debugMsg(avatar);
return null;
}
}
function getBirdForDirection(direction) {
direction= Direction_normalize(direction);
if(direction>=0 && direction<=45)
return bird_right;
else if(direction>=45 && direction<=135)
return bird_up;
else if(direction>=135 && direction<=225)
return bird_left;
else if(direction>=225 && direction<=315)
return bird_down;
else if(direction>=315 && direction<=360)
return bird_right;
else {
var avatar= 'getBird: fuck up('+direction+', bad argument)';
debugMsg(avatar);
return null;
}
}
//FIXME: replace all the verbatim stuff with imagePath(imageName)
function mapCodeToImage(code){
var src='';
switch(code) {
case 'H':src='images/'+tileset+'/'+'house_64.gif'; break;
case 'h':src='images/'+tileset+'/'+'house_open_64.gif'; break;
case 'K':src='images/'+tileset+'/'+'ball_red_64.gif'; break;
case 'I':src='images/'+tileset+'/'+'ball_blue_64.gif'; break;
case 'J':src='images/'+tileset+'/'+'ball_green_64.gif'; break;
case 'L':src='images/'+tileset+'/'+'box_blue_64.gif'; break;
case 'C':src='images/'+tileset+'/'+'bricks_red_64.gif'; break;
case 'g':src='images/'+tileset+'/'+'bricks_green_64.gif'; break;
case 'N':src='images/'+tileset+'/'+'bricks_grey_64.gif'; break;
case 'M':src='images/'+tileset+'/'+'centerstone-blue_64.gif'; break;
case 'O':src='images/'+tileset+'/'+'centerstone-grey_64.gif'; break;
case 'R':src='images/'+tileset+'/'+'phoenix_sleeping_left_64.gif'; break;
case 'S':src='images/'+tileset+'/'+'phoenix_sleeping_up_64.gif'; break;
case 'T':src='images/'+tileset+'/'+'phoenix_sleeping_right_64.gif'; break;
case 'U':src='images/'+tileset+'/'+'phoenix_sleeping_down_64.gif'; break;
case 'r':src='images/'+tileset+'/'+'phoenix_awake_left_64.gif'; break;
case 's':src='images/'+tileset+'/'+'phoenix_awake_up_64.gif'; break;
case 't':src='images/'+tileset+'/'+'phoenix_awake_right_64.gif'; break;
case 'u':src='images/'+tileset+'/'+'phoenix_awake_down_64.gif'; break;
case 'P':src='images/'+tileset+'/'+'chess-rook_sleeping_left_64.gif'; break;
case 'p':src='images/'+tileset+'/'+'chess-rook_awake_left_64.gif'; break;
case 'P.right':src='images/'+tileset+'/'+'chess-rook_sleeping_right_64.gif'; break;
case 'p.right':src='images/'+tileset+'/'+'chess-rook_awake_right_64.gif'; break;
case 'p.moving.left':src='images/'+tileset+'/'+'chess-rook_moving_left_64.gif'; break;
case 'p.moving.up':src='images/'+tileset+'/'+'chess-rook_moving_up_64.gif'; break;
case 'p.moving.right':src='images/'+tileset+'/'+'chess-rook_moving_right_64.gif'; break;
case 'p.moving.down':src='images/'+tileset+'/'+'chess-rook_moving_down_64.gif'; break;
//FIXME: this should be handled more elegantly by checking for code.mapToImage and writing adding mapToImage function to avatar
case bullet_right:
case bullet_left:
case bullet_up:
case bullet_down:
case siren_right:
case siren_left:
case siren_up:
case siren_down:
case bird_right:
case bird_left:
case bird_up:
case bird_down:
src='images/'+tileset+'/'+code.name+'_'+code.modifier+'_64.gif';
//debugMsg('setting image:'+src);
break;
case 'Z':src='images/'+tileset+'/'+'cone_up_64.gif'; break;
case '[':src='images/'+tileset+'/'+'cone_down_64.gif'; break;
case 'bullet_big':src='images/'+tileset+'/'+'bullet_big_right_64.gif'; break;
case 'background':src='images/'+tileset+'/'+'background.gif'; break;
default: src='';
}
return src;
}
function mapCodeToHtml(code,width,height) {
var box="";
var imgsrc= mapCodeToImage(code);
if(imgsrc) {
box+='<img src="'+imgsrc+'" alt="'+code+'" title="'+code+'" style="margin: 0px;" border="0" height="'+Math.floor(height)+'" width="'+Math.floor(width)+'">';
if(debug && debugall) {
debugHTMLrep(box);
}
} else {
switch( code ){
case '_':
case ' ':
case 'A':
box= " ";
break;
default:
box= " "+code+" ";
}
}
return box;
}
function Snapshot(what,pos,zoom,time) {
this.what= what;
this.pos= pos;
this.zoom= zoom;
this.time= time;
}
function Code_animate(t) {
var completed= (t-this.a.time)/(this.b.time-this.a.time);
var zoom = this.b.zoom*completed+this.a.zoom*(1.0-completed);
var posx= this.b.pos.x*completed+this.a.pos.x*(1.0-completed);
var posy= this.b.pos.y*completed+this.a.pos.y*(1.0-completed);
var pos= new Coordinate(posx,posy);
//note: clipping suffers badly from bad math which gives >xmax*step_
if( pos.clip() ) {
this.b.time=t;//FIXME:zayin ba debug!
}
if(this.updateObj && this.updateObj.update) {
this.updateObj.update(pos);
}
var animDiv= document.getElementById(this.div);
if(animDiv) {
animDiv.style.left= toScreenX(pos.x/step_unit+(1.0-zoom)*0.5);
animDiv.style.top= toScreenY(pos.y/step_unit+(1.0-zoom)*0.5);
var node= mapCodeToNode(this.a.what,cell_width*zoom,cell_height*zoom,animDiv.id);
if(node!= animDiv.firstChild){
clearChildren(animDiv);
animDiv.appendChild(node);
}
//this redraw often isn't necessary => don't redraw
// var text= mapCodeToHtml(this.a.what,cell_width*zoom,cell_height*zoom);
//
//text= fixHTML(text);
// fixed already !?
// if(text!=animDiv.innerHTML)
// animDiv.innerHTML= text;
} else {
debugMsg("Error: no layer left for animations");
}
}
var animation_divs= new Array();
function Animation_begin() {
this.finished= false;
this.hasChanged= true;
for(var i=0; i<1000; ++i
|