summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbeach.pngbin0 -> 7057 bytes
-rwxr-xr-xbreaststroke3.gifbin0 -> 26789 bytes
-rwxr-xr-xbreaststroke3.pngbin0 -> 25902 bytes
-rwxr-xr-xcannonball.gifbin0 -> 7811 bytes
-rwxr-xr-xetc/manjumping.pngbin0 -> 51799 bytes
-rwxr-xr-xetc/manrunning.pngbin0 -> 35352 bytes
-rwxr-xr-xetc/manrunningsprite.pngbin0 -> 43462 bytes
-rwxr-xr-xetc/manrunningsprite_left.pngbin0 -> 44258 bytes
-rwxr-xr-xetc/manstandingsprite.pngbin0 -> 276454 bytes
-rwxr-xr-xetc/manstandingsprite_left.pngbin0 -> 296104 bytes
-rwxr-xr-xfloat3.gifbin0 -> 35506 bytes
-rwxr-xr-xfloat3.pngbin0 -> 29261 bytes
-rwxr-xr-xfonts/Commodore-64-v6.3.TTFbin0 -> 51008 bytes
-rwxr-xr-xfonts/Commodore-Angled-v1.2.ttfbin0 -> 19660 bytes
-rwxr-xr-xfonts/Commodore-Rounded-v1.2.ttfbin0 -> 20084 bytes
-rwxr-xr-xgeometry.html502
-rwxr-xr-xgeometry2.html671
-rwxr-xr-xgeometry3.html957
-rwxr-xr-xgeometry4.html1158
-rwxr-xr-xgeometry5.html1392
-rwxr-xr-xgeometry6.html1393
-rwxr-xr-xguru.gifbin0 -> 736302 bytes
-rwxr-xr-xguru2.gifbin0 -> 269271 bytes
-rwxr-xr-xindex.html1393
-rwxr-xr-xjquery.gamequery-0.5.1.js1164
-rwxr-xr-xlandscape/abovewaterislandbg.pngbin0 -> 3103 bytes
-rwxr-xr-xlandscape/abovewaterislandcorner.pngbin0 -> 833 bytes
-rwxr-xr-xlandscape/bush.pngbin0 -> 1038 bytes
-rwxr-xr-xlandscape/island1bg.pngbin0 -> 11927 bytes
-rwxr-xr-xlandscape/island1fg.pngbin0 -> 8827 bytes
-rwxr-xr-xlandscape/island_bush.pngbin0 -> 3687 bytes
-rwxr-xr-xlandscape/palmtree.pngbin0 -> 2484 bytes
-rwxr-xr-xlandscape/scotch.gifbin0 -> 1073 bytes
-rwxr-xr-xlandscape/underwaterislandbg.pngbin0 -> 3154 bytes
-rwxr-xr-xlandscape/underwaterislandcorner.pngbin0 -> 1020 bytes
-rwxr-xr-xlandscape/watercorner.pngbin0 -> 1323 bytes
-rwxr-xr-xmanrunning.gifbin0 -> 38238 bytes
-rwxr-xr-xmanrunning2.gifbin0 -> 39286 bytes
-rwxr-xr-xmanstanding.gifbin0 -> 96794 bytes
-rwxr-xr-xmanstanding2.gifbin0 -> 96467 bytes
-rwxr-xr-xparticle.html109
-rwxr-xr-xpossible/.htaccess1
-rwxr-xr-xpossible/1298527286040-dumpfm-pepper-1298436051425-dumpfm-pepper-chevre_1.pngbin0 -> 198177 bytes
-rwxr-xr-xpossible/1298590356231-dumpfm-pepper-fingercheese.pngbin0 -> 62725 bytes
-rwxr-xr-xpossible/1300591584954-dumpfm-pepper-nantucket_paradigm.pngbin0 -> 473270 bytes
-rwxr-xr-xpossible/1301351326112-dumpfm-pepper-glitter_wom2.gifbin0 -> 26055 bytes
-rwxr-xr-xpossible/1302286721060-dumpfm-pepper-cell_phone_glitter.gifbin0 -> 192883 bytes
-rwxr-xr-xpossible/plasmus5.gifbin0 -> 4770 bytes
-rwxr-xr-xpossible/plasmusuk.gifbin0 -> 9221 bytes
-rwxr-xr-xsand.pngbin0 -> 16415 bytes
-rwxr-xr-xsea.pngbin0 -> 16413 bytes
-rwxr-xr-xsky.pngbin0 -> 16415 bytes
-rwxr-xr-xsplash.gifbin0 -> 8623 bytes
-rwxr-xr-xsprites/.htaccess1
-rwxr-xr-xsprites/breaststroke.gifbin0 -> 22092 bytes
-rwxr-xr-xsprites/breaststroke1.pngbin0 -> 17789 bytes
-rwxr-xr-xsprites/breaststroke2.pngbin0 -> 22166 bytes
-rwxr-xr-xsprites/breaststroke3.pngbin0 -> 24502 bytes
-rwxr-xr-xsprites/cannonball.pngbin0 -> 7935 bytes
-rwxr-xr-xsprites/cannonball2.pngbin0 -> 15809 bytes
-rwxr-xr-xsprites/diving1.pngbin0 -> 24887 bytes
-rwxr-xr-xsprites/diving2.gifbin0 -> 22901 bytes
-rwxr-xr-xsprites/diving2.pngbin0 -> 20356 bytes
-rwxr-xr-xsprites/float.gifbin0 -> 31839 bytes
-rwxr-xr-xsprites/float1.pngbin0 -> 28688 bytes
-rwxr-xr-xsprites/float2.pngbin0 -> 27392 bytes
-rwxr-xr-xsprites/float3.pngbin0 -> 25589 bytes
-rwxr-xr-xsprites/jumping.pngbin0 -> 51799 bytes
-rwxr-xr-xsprites/jumping2.pngbin0 -> 25301 bytes
-rwxr-xr-xsprites/mandiving1.gifbin0 -> 22901 bytes
-rwxr-xr-xsprites/manrunningsprite.pngbin0 -> 57391 bytes
-rwxr-xr-xsprites/manrunningsprite_left.pngbin0 -> 58053 bytes
-rwxr-xr-xsprites/manstandingsprite.pngbin0 -> 80808 bytes
-rwxr-xr-xsprites/manstandingsprite_brown.pngbin0 -> 48270 bytes
-rwxr-xr-xsprites/manstandingsprite_left.pngbin0 -> 80890 bytes
-rwxr-xr-xsprites/orig/manrunning.pngbin0 -> 35352 bytes
-rwxr-xr-xsprites/orig/manrunningsprite.pngbin0 -> 43462 bytes
-rwxr-xr-xsprites/orig/manrunningsprite_left.pngbin0 -> 44258 bytes
-rwxr-xr-xsprites/orig/manstandingsprite.pngbin0 -> 276454 bytes
-rwxr-xr-xsprites/orig/manstandingsprite_left.pngbin0 -> 296104 bytes
-rwxr-xr-xsprites/orig/sand.pngbin0 -> 16415 bytes
-rwxr-xr-xsprites/orig/sky.pngbin0 -> 16415 bytes
-rwxr-xr-xsprites/running2.gifbin0 -> 39286 bytes
-rwxr-xr-xsprites/splash.pngbin0 -> 9418 bytes
-rwxr-xr-xsprites/splash2.pngbin0 -> 20453 bytes
-rwxr-xr-xsprites/standing2.gifbin0 -> 96467 bytes
-rwxr-xr-xsprites/swimming1.gifbin0 -> 22195 bytes
-rwxr-xr-xsprites/swimming1.pngbin0 -> 16883 bytes
-rwxr-xr-xsprites/swimming2.pngbin0 -> 20921 bytes
-rwxr-xr-xsprites/swimtrans.pngbin0 -> 9156 bytes
-rwxr-xr-xswimtrans.gifbin0 -> 9399 bytes
-rwxr-xr-xswimtrans.pngbin0 -> 8335 bytes
-rwxr-xr-xv1.html230
-rwxr-xr-xv2.html420
-rwxr-xr-xv3.html501
-rwxr-xr-xv4.html629
-rwxr-xr-xv5.html632
-rwxr-xr-xv6.html736
98 files changed, 11889 insertions, 0 deletions
diff --git a/beach.png b/beach.png
new file mode 100755
index 0000000..5654de7
--- /dev/null
+++ b/beach.png
Binary files differ
diff --git a/breaststroke3.gif b/breaststroke3.gif
new file mode 100755
index 0000000..08512d0
--- /dev/null
+++ b/breaststroke3.gif
Binary files differ
diff --git a/breaststroke3.png b/breaststroke3.png
new file mode 100755
index 0000000..2323195
--- /dev/null
+++ b/breaststroke3.png
Binary files differ
diff --git a/cannonball.gif b/cannonball.gif
new file mode 100755
index 0000000..b8bf1f0
--- /dev/null
+++ b/cannonball.gif
Binary files differ
diff --git a/etc/manjumping.png b/etc/manjumping.png
new file mode 100755
index 0000000..834df7f
--- /dev/null
+++ b/etc/manjumping.png
Binary files differ
diff --git a/etc/manrunning.png b/etc/manrunning.png
new file mode 100755
index 0000000..7827444
--- /dev/null
+++ b/etc/manrunning.png
Binary files differ
diff --git a/etc/manrunningsprite.png b/etc/manrunningsprite.png
new file mode 100755
index 0000000..82b9ba1
--- /dev/null
+++ b/etc/manrunningsprite.png
Binary files differ
diff --git a/etc/manrunningsprite_left.png b/etc/manrunningsprite_left.png
new file mode 100755
index 0000000..dd29c7b
--- /dev/null
+++ b/etc/manrunningsprite_left.png
Binary files differ
diff --git a/etc/manstandingsprite.png b/etc/manstandingsprite.png
new file mode 100755
index 0000000..ff41388
--- /dev/null
+++ b/etc/manstandingsprite.png
Binary files differ
diff --git a/etc/manstandingsprite_left.png b/etc/manstandingsprite_left.png
new file mode 100755
index 0000000..083cf70
--- /dev/null
+++ b/etc/manstandingsprite_left.png
Binary files differ
diff --git a/float3.gif b/float3.gif
new file mode 100755
index 0000000..e428263
--- /dev/null
+++ b/float3.gif
Binary files differ
diff --git a/float3.png b/float3.png
new file mode 100755
index 0000000..77cc5ff
--- /dev/null
+++ b/float3.png
Binary files differ
diff --git a/fonts/Commodore-64-v6.3.TTF b/fonts/Commodore-64-v6.3.TTF
new file mode 100755
index 0000000..5ce242d
--- /dev/null
+++ b/fonts/Commodore-64-v6.3.TTF
Binary files differ
diff --git a/fonts/Commodore-Angled-v1.2.ttf b/fonts/Commodore-Angled-v1.2.ttf
new file mode 100755
index 0000000..a9f5d41
--- /dev/null
+++ b/fonts/Commodore-Angled-v1.2.ttf
Binary files differ
diff --git a/fonts/Commodore-Rounded-v1.2.ttf b/fonts/Commodore-Rounded-v1.2.ttf
new file mode 100755
index 0000000..eee50a3
--- /dev/null
+++ b/fonts/Commodore-Rounded-v1.2.ttf
Binary files differ
diff --git a/geometry.html b/geometry.html
new file mode 100755
index 0000000..e496483
--- /dev/null
+++ b/geometry.html
@@ -0,0 +1,502 @@
+<!doctype html>
+<html>
+<head><title>GEOMETRY</title></head>
+<style type="text/css">
+body
+ {
+ background-color: #000;
+ overflow: hidden;
+ }
+#frustrum
+ {
+ z-index: 666;
+ border: 1px solid red;
+ }
+#player
+ {
+ z-index: 999;
+ background-color: #0f0;
+ }
+#hud
+ {
+ font-size: 14px;
+ font-family: monospace;
+ background-color: #333;
+ z-index: 1000;
+ color: #fff;
+ opacity: 0.7;
+ white-space: pre;
+ }
+#tests
+ {
+ position: fixed;
+ right: 400px;
+ z-index: 1001;
+ }
+</style>
+
+<body>
+<!--
+<div id="tests">
+<button id="random_x">RANDOM X</button>
+</div>
+-->
+</body>
+
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript">
+var FRAME_RATE = 30
+
+var ABOVE_SURFACE = 3
+var ON_SURFACE = 2
+var LANDING_ON_SURFACE = 1
+var BELOW_SURFACE = 0
+var BEYOND_SURFACE = -1
+var OFF_MAP = -2
+
+var ORIENTATION_RIGHT = 1
+var ORIENTATION_LEFT = -1
+
+var KEY_LEFT = 37
+var KEY_UP = 38
+var KEY_RIGHT = 39
+var KEY_DOWN = 40
+var KEYTRACK = {}
+KEYTRACK[KEY_LEFT] = false
+KEYTRACK[KEY_UP] = false
+KEYTRACK[KEY_RIGHT] = false
+KEYTRACK[KEY_DOWN] = false
+
+function clamp (x, min, max)
+ {
+ return Math.max(min, Math.min(x, max))
+ }
+var HUD =
+ {
+ div: document.createElement("div"),
+ surface: false,
+ update: function ()
+ {
+ var activity = Player.running ? "RUNNING" : ""
+ activity += Player.jumping ? " JUMPING" : ""
+ activity += Player.cannonball ? " CANNONBALL" : ""
+ activity += Player.underwater ? " UNDERWATER" : ""
+ var orientation = Player.orientation === ORIENTATION_RIGHT ? "RIGHT" : "LEFT"
+ HUD.div.innerHTML =
+ [
+ "",
+ "PLAYER", Player.x, Player.y, activity, orientation, "\n",
+ "SPEED ", Player.dx, Player.dy, HUD.surface, "\n",
+ "CANVAS", Canvas.x, Canvas.y, "\n",
+ "KEY_UP", KEYTRACK[KEY_UP], "\n",
+ "KEY_DOWN", KEYTRACK[KEY_DOWN], "\n",
+ "KEY_LEFT", KEYTRACK[KEY_LEFT], "\n",
+ "KEY_RIGHT", KEYTRACK[KEY_RIGHT], "\n",
+ ].join(" ")
+ },
+ init: function ()
+ {
+ HUD.div.style.position = "fixed"
+ HUD.div.style.top = 0
+ HUD.div.style.right = 0
+ HUD.div.style.width = 300 + "px"
+ HUD.div.style.height = 300 + "px"
+ HUD.div.setAttribute("id", "hud")
+ document.body.appendChild(HUD.div)
+ },
+ }
+var Canvas =
+ {
+ div: document.createElement("canvas"),
+ x: 0,
+ y: 0,
+ width: 500,
+ height: 320,
+ surfaces:
+ [
+ [0,50, 90,95],
+ [90,95, 110,110],
+ [110,110, 200,300],
+ [200,300, 220,300],
+ [220,300, 300,200],
+ [300,200, 400,95],
+ [400,95, 500,80],
+ ],
+ furniture:
+ [
+ [30,50],
+ [75,120],
+ [200,200],
+ [350,110],
+ [450,87],
+ ],
+ init: function ()
+ {
+ ctx = Canvas.div.getContext("2d"),
+ Canvas.div.style.position = "fixed"
+ Canvas.div.style.top = 0
+ Canvas.div.style.left = 0
+ Canvas.div.setAttribute("width", 4000+"px")
+ Canvas.div.setAttribute("height", 800+"px")
+ document.body.appendChild(Canvas.div)
+ ctx.beginPath()
+ for (var x = 0.5; x < Canvas.width; x += 10)
+ {
+ ctx.moveTo(x, 0)
+ ctx.lineTo(x, Canvas.height)
+ }
+ for (var y = 0.5; y < Canvas.height; y += 10)
+ {
+ ctx.moveTo(0, y)
+ ctx.lineTo(Canvas.width, y)
+ }
+ ctx.strokeStyle = "#333"
+ ctx.stroke()
+ ctx.fillStyle = "rgba(0,20,255,0.5)"
+ ctx.fillRect(0, Physics.water_level+0.5, Canvas.width, Canvas.height - Physics.water_level)
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var surface = Canvas.surfaces[i]
+ ctx.beginPath()
+ ctx.moveTo(surface[0] + 0.5, surface[1] + 0.5)
+ ctx.lineTo(surface[2] + 0.5, surface[3] + 0.5)
+ ctx.strokeStyle = "#0bf"
+ ctx.stroke()
+ }
+ for (var i = 0; i < Canvas.furniture.length; i++)
+ {
+ console.log(Canvas.furniture[i])
+ var div = document.createElement("div")
+ div.style.position = "fixed"
+ div.style.top = Canvas.furniture[i][1] + "px"
+ div.style.left = Canvas.furniture[i][0] + "px"
+ div.style.background = "yellow"
+ div.style.width = 2 + "px"
+ div.style.height = 2 + "px"
+ div.style.zIndex = 333
+ document.body.appendChild(div)
+ Frustrum.furniture.push (new furniture (div, Canvas.furniture[i][0],Canvas.furniture[i][1]))
+ }
+ },
+ }
+function furniture (div, x, y)
+ {
+ // this.id = div
+ this.elem = div
+ this.x = x
+ this.y = y
+ this.update = function ()
+ {
+ this.elem.style.top = this.y - Frustrum.y + "px"
+ this.elem.style.left = this.x - Frustrum.x + "px"
+ }
+ }
+var Frustrum =
+ {
+ div: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: 200,
+ height: 150,
+ halfwidth: 0,
+ halfheight: 0,
+ furniture: [],
+ redraw: function ()
+ {
+ Canvas.div.style.top = Canvas.y - Frustrum.y + "px"
+ Canvas.div.style.left = Canvas.x - Frustrum.x + "px"
+
+ Player.div.style.top = Player.y - Frustrum.y + "px"
+ Player.div.style.left = Player.x - Frustrum.x + "px"
+
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].update()
+ },
+ update: function ()
+ {
+ if (Player.underwater)
+ {
+ Frustrum.dest_y = Player.y - Frustrum.halfheight + Player.height
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth + Player.width
+ if (Player.y > Canvas.height - Frustrum.halfheight)
+ Frustrum.dest_y = Canvas.height - Frustrum.height
+ }
+ else
+ {
+ Frustrum.dest_x = 0
+ Frustrum.dest_y = 0
+ }
+ if (Player.x > Canvas.width - Frustrum.halfwidth)
+ Frustrum.dest_x = Canvas.width - Frustrum.width
+ else if (Player.x > Frustrum.halfwidth)
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth
+ Frustrum.y = Math.floor( (Frustrum.dest_y + Frustrum.y * 9) / 10 )
+ Frustrum.x = Math.floor( (Frustrum.dest_x + Frustrum.x * 9) / 10 )
+ // Frustrum.div.style.top = Frustrum.y + "px"
+ // Frustrum.div.style.left = Frustrum.x + "px"
+ },
+ init: function ()
+ {
+ Frustrum.div.style.position = "fixed"
+ Frustrum.div.style.top = 0
+ Frustrum.div.style.left = 0
+ Frustrum.div.style.width = Frustrum.width + "px"
+ Frustrum.div.style.height = Frustrum.height + "px"
+ Frustrum.div.setAttribute("id", "frustrum")
+ document.body.appendChild(Frustrum.div)
+ Frustrum.halfwidth = Frustrum.width/2
+ Frustrum.halfheight = Frustrum.height/2
+ },
+ }
+var Physics =
+ {
+ gravity: 1,
+ dx_walk: 2,
+ dx_swim: 2,
+ dy_swim_up: -2,
+ dy_swim_down: 2,
+ dy_resistance: 5,
+ dx_resistance: 5,
+ air_resistance: 5,
+ water_resistance: 2,
+ water_level: 100,
+ jump_power: -5,
+ }
+var Player =
+ {
+ div: document.createElement("div"),
+ running: false,
+ jumping: false,
+ start_jump: false,
+ swimming: false,
+ cannonball: false,
+ orientation: ORIENTATION_RIGHT,
+ dx: 0,
+ dy: 0,
+ x: 50,
+ y: 5,
+ width: 2,
+ height: 4,
+ yIntercept: 0,
+ surface: Canvas.surfaces[0],
+ findNearestSurface: function (feet)
+ {
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var s = Canvas.surfaces[i]
+ if (Player.onSurface(feet, s) > BELOW_SURFACE)
+ {
+ return s
+ }
+ }
+ return OFF_MAP
+ },
+ onSurface: function (feet, s)
+ {
+ if (s === OFF_MAP)
+ return OFF_MAP
+
+ // within bounds
+ if (Player.x < s[0] || Player.x > s[2])
+ return BEYOND_SURFACE
+
+ // above the line
+ if (s[1] === s[3])
+ {
+ if (feet < s[1])
+ return ABOVE_SURFACE
+ if (feet <= s[1] + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ }
+ var slope = (s[3] - s[1]) / (s[2] - s[0])
+ Player.yIntercept = (Player.x - s[0]) * slope + s[1]
+ // console.log(Player.yIntercept, Player.y)
+ if (feet < Player.yIntercept)
+ return ABOVE_SURFACE
+ if (feet <= Player.yIntercept + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ if (Player.surfaceState === ON_SURFACE)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ },
+ underwater: false,
+ update: function ()
+ {
+ var feet = Player.y + Player.height
+ Player.feet = feet
+ Player.surfaceState = Player.onSurface(feet, Player.surface)
+ switch (Player.surfaceState)
+ {
+ case ABOVE_SURFACE:
+ HUD.surface = "ABOVE SURFACE"
+ Player.yIntercept = Player.surface[1]
+ Player.dy = Math.min(Player.dy + Physics.gravity, Physics.dy_resistance)
+ break
+ case ON_SURFACE:
+ HUD.surface = "ON SURFACE"
+ Player.dy = 0
+ Player.y = Player.yIntercept - Player.height
+ Player.jumping = false
+ // Tests.random_x()
+ break
+ case BELOW_SURFACE:
+ HUD.surface = "BELOW SURFACE"
+ break
+ case BEYOND_SURFACE:
+ HUD.surface = "BEYOND SURFACE"
+ // Player.surface = false
+ Player.surface = Player.findNearestSurface(feet)
+ Player.update()
+ break
+ case OFF_MAP:
+ HUD.surface = "OFF MAP"
+ break
+ }
+ // Player.div.style.left = Player.x + "px"
+ // Player.div.style.top = Player.y + "px"
+ if (Player.underwater)
+ {
+ if (Player.y > Physics.water_level - 2 && Player.y < Physics.water_level + 2)
+ Player.dy = 0
+ else if (Player.y < Physics.water_level)
+ {
+ Player.underwater = false
+ Player.cannonball = false
+ Physics.dx_resistance = Physics.air_resistance
+ Physics.dy_resistance = Physics.air_resistance
+ }
+ if (KEYTRACK[KEY_UP])
+ Player.dy = Physics.dy_swim_up
+ if (KEYTRACK[KEY_DOWN])
+ Player.dy = Physics.dy_swim_down
+ if (KEYTRACK[KEY_LEFT] || KEYTRACK[KEY_RIGHT])
+ Player.dx = Physics.dx_swim * Player.orientation
+ else
+ Player.dx = 0
+ }
+ else
+ {
+ if (Player.y > Physics.water_level)
+ {
+ Player.jumping = false
+ Player.cannonball = false
+ Player.underwater = true
+ Player.yJump = Physics.water_level
+ Physics.dx_resistance = Physics.water_resistance
+ Physics.dy_resistance = Physics.water_resistance
+ }
+ else if (Player.yJump < Physics.water_level && Player.yIntercept > Physics.water_level)
+ Player.cannonball = true
+ else
+ Player.cannonball = false
+ if ((Player.start_jump || KEYTRACK[KEY_UP]) && Player.surfaceState === ON_SURFACE)
+ {
+ Player.start_jump = false
+ Player.jumping = true
+ Player.yJump = Player.y
+ Player.dy = Physics.jump_power
+ Player.y += Player.dy
+ Player.surfaceState = ABOVE_SURFACE
+ }
+ if (KEYTRACK[KEY_LEFT] || KEYTRACK[KEY_RIGHT])
+ Player.dx = Physics.dx_walk * Player.orientation
+ else
+ Player.dx = 0
+ }
+ Player.y += Player.dy
+ Player.x = clamp (Player.x + Player.dx, 0, Canvas.width)
+ },
+ init: function ()
+ {
+ Player.div.style.position = "fixed"
+ Player.div.style.top = Player.y + "px"
+ Player.div.style.left = Player.x + "px"
+ Player.div.style.width = Player.width + "px"
+ Player.div.style.height = Player.height + "px"
+ Player.div.setAttribute("id", "player")
+ document.body.appendChild(Player.div)
+ },
+ }
+var Events =
+ {
+ keydown: function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_UP:
+ if (Player.underwater || Player.jumping)
+ break
+ Player.start_jump = true
+ break
+ case KEY_LEFT:
+ Player.orientation = ORIENTATION_LEFT
+ break
+ case KEY_RIGHT:
+ Player.orientation = ORIENTATION_RIGHT
+ break
+ }
+ },
+ keyup: function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ },
+ loop: function ()
+ {
+ Player.update()
+ Frustrum.update()
+ Frustrum.redraw()
+ HUD.update()
+ },
+ init: function ()
+ {
+ $(document).bind("keydown", Events.keydown)
+ $(document).bind("keyup", Events.keyup)
+ setInterval(Events.loop, FRAME_RATE)
+ },
+ }
+var Tests =
+ {
+ random_x: function ()
+ {
+ Player.x = Player.x+1 // Math.floor(Math.random () * 500)
+ if (Player.x > Canvas.width)
+ {
+ Player.x = 0
+ Player.y = 0
+ }
+ // Player.y = 50 // Math.floor(Math.random () * 50)
+ Player.surface = Canvas.surfaces[0]
+ //if (Math.random() > 0.3)
+ // {
+ // Player.dy = -5
+ // }
+ },
+ init: function ()
+ {
+ $("#random_x").click(Tests.random_x)
+ },
+ }
+var Main =
+ {
+ init: function ()
+ {
+ Tests.init()
+ Canvas.init()
+ Player.init()
+ Frustrum.init()
+ HUD.init()
+ Events.init()
+ },
+ }
+Main.init ()
+</script>
+</html>
+
diff --git a/geometry2.html b/geometry2.html
new file mode 100755
index 0000000..15927c0
--- /dev/null
+++ b/geometry2.html
@@ -0,0 +1,671 @@
+<!doctype html>
+<html>
+<head><title>GEOMETRY</title></head>
+<style type="text/css">
+*
+ {
+ // border: 1px solid red;
+ }
+body
+ {
+ background-color: #87CEEB;
+ overflow: hidden;
+ }
+#frustrum
+ {
+ z-index: 666;
+ }
+#player
+ {
+ z-index: 980;
+ background-color: #0f0;
+ }
+#grid
+ {
+ display: none;
+ z-index: 950;
+ }
+#water
+ {
+ z-index: 800;
+ background-color: #6666cc;
+ }
+#seafloor
+ {
+ z-index: 810;
+ background-color: #8380ab;
+ }
+#background
+ {
+ position: fixed;
+ overflow: visible;
+ z-index: 900;
+ }
+#foreground
+ {
+ overflow: visible;
+ z-index: 999;
+ }
+#hud
+ {
+ font-size: 14px;
+ font-family: monospace;
+ background-color: #333;
+ z-index: 1000;
+ color: #fff;
+ opacity: 0.7;
+ white-space: pre;
+ }
+#tests
+ {
+ position: fixed;
+ right: 400px;
+ z-index: 1001;
+ }
+.flip
+ {
+ -moz-transform: scaleX(-1);
+ -o-transform: scaleX(-1);
+ -webkit-transform: scaleX(-1);
+ transform: scaleX(-1);
+ filter: FlipH;
+ -ms-filter: "FlipH";
+ }
+</style>
+
+<body>
+</body>
+
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript" src="jquery.gamequery-0.5.1.js"></script>
+<script type="text/javascript">
+var SCREEN_WIDTH = $(window).width()
+var SCREEN_HEIGHT = $(window).height()
+var REFRESH_RATE = 30
+var ISLAND_HEIGHT = 576
+var WATER_OFFSET = 458
+var SKY_OFFSET = SCREEN_HEIGHT - ISLAND_HEIGHT
+var FLOOR_OFFSET = SKY_OFFSET + WATER_OFFSET
+var SEAFLOOR_DEPTH = 600
+
+var FALL_THRESHOLD = 10
+
+var ABOVE_SURFACE = 3
+var ON_SURFACE = 2
+var LANDING_ON_SURFACE = 1
+var BELOW_SURFACE = 0
+var BEYOND_SURFACE = -1
+var OFF_MAP = -2
+
+var ORIENTATION_RIGHT = 1
+var ORIENTATION_LEFT = -1
+
+var KEY_LEFT = 37
+var KEY_UP = 38
+var KEY_RIGHT = 39
+var KEY_DOWN = 40
+var KEYTRACK = {}
+KEYTRACK[KEY_LEFT] = false
+KEYTRACK[KEY_UP] = false
+KEYTRACK[KEY_RIGHT] = false
+KEYTRACK[KEY_DOWN] = false
+
+function clamp (x, min, max)
+ {
+ return Math.max(min, Math.min(x, max))
+ }
+var HUD =
+ {
+ div: document.createElement("div"),
+ surface: false,
+ msg: "",
+ update: function ()
+ {
+ var activity = Player.running ? "RUNNING" : ""
+ activity += Player.jumping ? " JUMPING" : ""
+ activity += Player.cannonball ? " CANNONBALL" : ""
+ activity += Player.underwater ? " UNDERWATER" : ""
+ var orientation = Player.orientation === ORIENTATION_RIGHT ? "RIGHT" : "LEFT"
+ HUD.div.innerHTML =
+ [
+ "",
+ "PLAYER", Player.x, Player.y, activity, orientation, "\n",
+ "SPEED ", Player.dx, Player.dy, HUD.surface, "\n",
+ "CANVAS", Canvas.x, Canvas.y, "\n",
+ "KEY_UP", KEYTRACK[KEY_UP], "\n",
+ "KEY_DOWN", KEYTRACK[KEY_DOWN], "\n",
+ "KEY_LEFT", KEYTRACK[KEY_LEFT], "\n",
+ "KEY_RIGHT", KEYTRACK[KEY_RIGHT], "\n",
+ "SCREEN", SCREEN_WIDTH, SCREEN_HEIGHT, SKY_OFFSET, "\n",
+ HUD.msg,
+ ].join(" ")
+ },
+ init: function ()
+ {
+ HUD.div.style.position = "fixed"
+ HUD.div.style.top = 0
+ HUD.div.style.right = 0
+ HUD.div.style.width = 300 + "px"
+ HUD.div.style.height = 300 + "px"
+ HUD.div.setAttribute("id", "hud")
+ document.body.appendChild(HUD.div)
+ },
+ }
+var Canvas =
+ {
+ div: document.createElement("canvas"),
+ background: document.createElement("div"),
+ foreground: document.createElement("div"),
+ water: document.createElement("div"),
+ seafloor: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: 2024+1224,
+ height: 3000,
+ surfaces: [],
+ ground: [
+ [0,-90],
+ [700,-90],
+ [1000,-70],
+ [1200,0],
+ [1210,SEAFLOOR_DEPTH],
+ [1980,SEAFLOOR_DEPTH],
+ [2080,0],
+ [2090,-90],
+ [2800,-90],
+ [2024+1224,-90],
+ ],
+ recalculate_surfaces: function ()
+ {
+ var calc = []
+ for (var i = 1; i < Canvas.ground.length; i++)
+ {
+ var two = Canvas.ground[i]
+ var one = Canvas.ground[i-1]
+ // console.log(one,two)
+ calc.push([one[0], one[1]+FLOOR_OFFSET, two[0], two[1]+FLOOR_OFFSET])
+ }
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var s = Canvas.surfaces[i]
+ calc.push([s[0], s[1]+FLOOR_OFFSET, s[2], s[3]+FLOOR_OFFSET])
+ }
+ Canvas.surfaces = calc
+ },
+ background_elements:
+ [
+ // x, y, width, height, image
+ [0, 0, 1224, 576, "landscape/island1bg.png"],
+ [0, 576, 1224, 1000, "#8380ab"],
+ [2024, 576, 1224, 1000, "#8380ab"],
+ [1224, WATER_OFFSET + SEAFLOOR_DEPTH - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [1824, WATER_OFFSET + SEAFLOOR_DEPTH - 152, 200, 152, "landscape/underwaterislandcorner.png", "flip"],
+ [2024, 0, 1224, 576, "landscape/island1bg.png", "flip"],
+ ],
+ foreground_elements:
+ [
+ // x, y, width, height, image
+ [0, -34, 1224, 576, "landscape/island1fg.png"],
+ ],
+ init: function ()
+ {
+ Canvas.background.style.position = "fixed"
+ Canvas.background.style.top = 0 + "px"
+ Canvas.background.style.left = 0 + "px"
+ Canvas.background.style.width = Canvas.width + "px"
+ Canvas.background.style.height = Canvas.height + "px"
+ Canvas.background.setAttribute("id", "background")
+ document.body.appendChild(Canvas.background)
+
+ Canvas.foreground.style.position = "fixed"
+ Canvas.foreground.style.top = 0 + "px"
+ Canvas.foreground.style.left = 0 + "px"
+ Canvas.foreground.style.width = Canvas.width + "px"
+ Canvas.foreground.style.height = Canvas.height + "px"
+ Canvas.foreground.setAttribute("id", "foreground")
+ document.body.appendChild(Canvas.foreground)
+
+ Canvas.water.style.position = "fixed"
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + "px"
+ Canvas.water.style.left = 0 + "px"
+ Canvas.water.style.width = Canvas.width + "px"
+ Canvas.water.style.height = Canvas.height + "px"
+ Canvas.water.setAttribute("id", "water")
+ document.body.appendChild(Canvas.water)
+
+ Canvas.seafloor.style.position = "fixed"
+ Canvas.seafloor.style.top = SKY_OFFSET + SEAFLOOR_DEPTH + "px"
+ Canvas.seafloor.style.left = 0 + "px"
+ Canvas.seafloor.style.width = Canvas.width + "px"
+ Canvas.seafloor.style.height = Canvas.height + "px"
+ Canvas.seafloor.setAttribute("id", "seafloor")
+ document.body.appendChild(Canvas.seafloor)
+
+ ctx = Canvas.div.getContext("2d"),
+ Canvas.div.style.position = "fixed"
+ Canvas.div.style.top = 0
+ Canvas.div.style.left = 0
+ Canvas.div.setAttribute("width", Canvas.width+"px")
+ Canvas.div.setAttribute("height", Canvas.height+"px")
+ Canvas.div.setAttribute("id", "grid")
+ document.body.appendChild(Canvas.div)
+
+ ctx.beginPath()
+ for (var x = 0.5; x < Canvas.width; x += 10)
+ {
+ ctx.moveTo(x, 0)
+ ctx.lineTo(x, Canvas.height)
+ }
+ for (var y = 0.5; y < Canvas.height; y += 10)
+ {
+ ctx.moveTo(0, y)
+ ctx.lineTo(Canvas.width, y)
+ }
+ ctx.strokeStyle = "rgba(255,255,255,0.2)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, SKY_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, SKY_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, FLOOR_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, FLOOR_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ /*
+ ctx.fillStyle = "rgba(0,20,255,0.5)"
+ ctx.fillRect(0, Physics.water_level+0.5, Canvas.width, Canvas.height - Physics.water_level)
+ */
+
+ Canvas.recalculate_surfaces ()
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var surface = Canvas.surfaces[i]
+ ctx.beginPath()
+ ctx.moveTo(surface[0] + 0.5, surface[1] + 0.5)
+ ctx.lineTo(surface[2] + 0.5, surface[3] + 0.5)
+ ctx.strokeStyle = "#0bf"
+ ctx.stroke()
+ }
+ for (var i = 0; i < Canvas.background_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.background, Canvas.background_elements[i]))
+ }
+ for (var i = 0; i < Canvas.foreground_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.foreground, Canvas.foreground_elements[i]))
+ }
+ },
+ }
+function Furniture (container, row)
+ {
+ var div = document.createElement("div")
+ div.style.position = "fixed"
+ div.style.left = row[0] + "px"
+ div.style.top = SKY_OFFSET + row[1] + "px"
+ div.style.width = row[2] + "px"
+ div.style.height = row[3] + "px"
+ if (row[4].substr(0,1) === "#")
+ div.style.background = row[4]
+ else
+ div.style.background = "url('" + row[4] + "')"
+ if (row.length === 6)
+ div.className = row[5]
+ container.appendChild(div)
+
+ // this.container = container
+ this.elem = div
+ this.x = row[0]
+ this.y = row[1]
+ this.width = row[2]
+ this.height = row[3]
+ this.background = row[4]
+ this.update = function ()
+ {
+ this.elem.style.top = SKY_OFFSET + this.y - Frustrum.y + "px"
+ this.elem.style.left = this.x - Frustrum.x + "px"
+ }
+ }
+var Frustrum =
+ {
+ div: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ furniture: [],
+ redraw: function ()
+ {
+ Canvas.div.style.top = Canvas.y - Frustrum.y + "px"
+ Canvas.div.style.left = Canvas.x - Frustrum.x + "px"
+
+ Player.div.style.top = Player.y - Frustrum.y + "px"
+ Player.div.style.left = Player.x - Frustrum.x + "px"
+
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + Canvas.y - Frustrum.y + "px"
+ Canvas.seafloor.style.top = SKY_OFFSET + WATER_OFFSET + SEAFLOOR_DEPTH + Canvas.y - Frustrum.y + "px"
+
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].update()
+ },
+ update: function ()
+ {
+ if (Player.underwater)
+ {
+ Frustrum.dest_y = Player.y - Frustrum.halfheight + Player.height
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth + Player.width
+ if (Player.y > Canvas.height - Frustrum.halfheight)
+ Frustrum.dest_y = Canvas.height - Frustrum.height
+ }
+ else
+ {
+ Frustrum.dest_x = 0
+ Frustrum.dest_y = 0
+ }
+ if (Player.x > Canvas.width - Frustrum.halfwidth)
+ Frustrum.dest_x = Canvas.width - Frustrum.width
+ else if (Player.x > Frustrum.halfwidth)
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth
+ Frustrum.y = Math.floor( (Frustrum.dest_y + Frustrum.y * 9) / 10 )
+ Frustrum.x = Math.floor( (Frustrum.dest_x + Frustrum.x * 9) / 10 )
+ // Frustrum.div.style.top = Frustrum.y + "px"
+ // Frustrum.div.style.left = Frustrum.x + "px"
+ },
+ init: function ()
+ {
+ Frustrum.div.style.position = "fixed"
+ Frustrum.div.style.top = 0
+ Frustrum.div.style.left = 0
+ Frustrum.div.style.width = Frustrum.width + "px"
+ Frustrum.div.style.height = Frustrum.height + "px"
+ Frustrum.div.setAttribute("id", "frustrum")
+ document.body.appendChild(Frustrum.div)
+ Frustrum.halfwidth = Frustrum.width/2
+ Frustrum.halfheight = Frustrum.height/2
+ },
+ }
+var Physics =
+ {
+ gravity: 5,
+ dx_walk: 50,
+ dx_swim: 50,
+ dy_swim_up: -20,
+ dy_swim_down: 20,
+ dy_resistance: 15,
+ dx_resistance: 15,
+ air_resistance: 15,
+ water_resistance: 8,
+ water_level: SKY_OFFSET + WATER_OFFSET,
+ jump_power: -45,
+ }
+var Player =
+ {
+ div: document.createElement("div"),
+ running: false,
+ jumping: false,
+ start_jump: false,
+ swimming: false,
+ cannonball: false,
+ orientation: ORIENTATION_RIGHT,
+ dx: 0,
+ dy: 0,
+ x: 0,
+ y: 0,
+ width: 100,
+ height: 167,
+ yIntercept: 0,
+ surface: [0,0,0,0],
+ surface_left: [0,0,0,0],
+ surface_right: [0,0,0,0],
+ findNearestSurface: function (feet)
+ {
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var s = Canvas.surfaces[i]
+ if (Player.onSurface(feet, s) > BELOW_SURFACE)
+ {
+ return s
+ }
+ }
+ return OFF_MAP
+ },
+ onSurface: function (feet, s)
+ {
+ if (s === OFF_MAP)
+ return OFF_MAP
+
+ // within bounds
+ if (Player.x < s[0] || Player.x > s[2])
+ return BEYOND_SURFACE
+
+ // above the line
+ if (s[1] === s[3])
+ {
+ Player.slope = 0
+ Player.yIntercept = s[1]
+ if (feet < s[1])
+ return ABOVE_SURFACE
+ if (feet <= s[1] + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ }
+ var slope = (s[3] - s[1]) / (s[2] - s[0])
+ Player.slope = slope
+ Player.yIntercept = (Player.x - s[0]) * slope + s[1]
+
+ if (feet < Player.yIntercept - 1)
+ return ABOVE_SURFACE
+ if (feet <= Player.yIntercept + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ if (Player.surfaceState === ON_SURFACE)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ },
+ underwater: false,
+ update: function ()
+ {
+ var feet = Player.y + Player.height
+ Player.feet = feet
+ Player.surfaceState = Player.onSurface(feet, Player.surface)
+ switch (Player.surfaceState)
+ {
+ case ABOVE_SURFACE:
+ HUD.surface = "ABOVE SURFACE"
+ if (Player.underwater)
+ Player.dy = Math.min(Player.dy + Physics.gravity, Physics.dy_resistance)
+ else
+ Player.dy = Player.dy + Physics.gravity
+ if (Player.y + Player.dy + Player.height > Player.yIntercept)
+ {
+ Player.y = Player.yIntercept - Player.height
+ Player.dy = 0
+ Player.surfaceState = ON_SURFACE
+ }
+ break
+ case ON_SURFACE:
+ HUD.surface = "ON SURFACE"
+ Player.dy = 0
+ Player.y = Player.yIntercept - Player.height
+ Player.jumping = false
+ HUD.msg = [Player.y, Player.yIntercept, Player.height, "...", Player.surface]
+ // clearInterval(Events.interval)
+ // Tests.random_x()
+ break
+ case BELOW_SURFACE:
+ HUD.surface = "BELOW SURFACE"
+ Player.dy = 0
+ Player.y = Player.yIntercept - Player.height
+ Player.surfaceState = ON_SURFACE
+ break
+ case BEYOND_SURFACE:
+ HUD.surface = "BEYOND SURFACE"
+ Player.surface = Player.findNearestSurface(feet)
+ Player.update()
+ break
+ case OFF_MAP:
+ HUD.surface = "OFF MAP"
+ break
+ }
+ // Player.div.style.left = Player.x + "px"
+ // Player.div.style.top = Player.y + "px"
+ if (Player.underwater)
+ {
+ if (Player.y > Physics.water_level - 2 && Player.y < Physics.water_level + 2)
+ Player.dy = 0
+ else if (Player.y < Physics.water_level)
+ {
+ Player.underwater = false
+ Player.cannonball = false
+ Physics.dx_resistance = Physics.air_resistance
+ Physics.dy_resistance = Physics.air_resistance
+ }
+ if (KEYTRACK[KEY_UP])
+ Player.dy = Physics.dy_swim_up
+ if (KEYTRACK[KEY_DOWN])
+ Player.dy = Physics.dy_swim_down
+ if (KEYTRACK[KEY_LEFT] || KEYTRACK[KEY_RIGHT])
+ Player.dx = Physics.dx_swim * Player.orientation
+ else
+ Player.dx = 0
+ }
+ else
+ {
+ if (Player.y > Physics.water_level)
+ {
+ Player.jumping = false
+ Player.cannonball = false
+ Player.underwater = true
+ Player.yJump = Physics.water_level
+ Physics.dx_resistance = Physics.water_resistance
+ Physics.dy_resistance = Physics.water_resistance
+ }
+ else if (Player.yJump < Physics.water_level && Player.yIntercept > Physics.water_level)
+ Player.cannonball = true
+ else
+ Player.cannonball = false
+ if ((Player.start_jump || KEYTRACK[KEY_UP]) && Player.surfaceState === ON_SURFACE)
+ {
+ Player.start_jump = false
+ Player.jumping = true
+ Player.yJump = Player.y
+ Player.dy = Physics.jump_power
+ Player.y += Player.dy
+ Player.surfaceState = ABOVE_SURFACE
+ }
+ if (KEYTRACK[KEY_LEFT])
+ {
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else
+ Player.dx = 0
+ }
+ Player.y += Player.dy
+ Player.x = clamp (Player.x + Player.dx, 10, Canvas.width-Player.width - 20)
+ },
+ init: function ()
+ {
+ Player.x = 200
+ Player.y = SKY_OFFSET + FLOOR_OFFSET - 350 - Player.height
+ Player.div.style.position = "fixed"
+ Player.div.style.top = Player.y + "px"
+ Player.div.style.left = Player.x + "px"
+ Player.div.style.width = Player.width + "px"
+ Player.div.style.height = Player.height + "px"
+ Player.div.setAttribute("id", "player")
+ document.body.appendChild(Player.div)
+ },
+ }
+var Events =
+ {
+ interval: false,
+ keydown: function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_UP:
+ if (Player.underwater || Player.jumping)
+ break
+ Player.start_jump = true
+ break
+ case KEY_LEFT:
+ Player.orientation = ORIENTATION_LEFT
+ break
+ case KEY_RIGHT:
+ Player.orientation = ORIENTATION_RIGHT
+ break
+ case 71: // "G"
+ $("#grid").toggle()
+ break
+ }
+ },
+ keyup: function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ },
+ loop: function ()
+ {
+ Player.update()
+ Frustrum.update()
+ Frustrum.redraw()
+ HUD.update()
+ },
+ init: function ()
+ {
+ $(document).bind("keydown", Events.keydown)
+ $(document).bind("keyup", Events.keyup)
+ Events.interval = setInterval(Events.loop, REFRESH_RATE)
+ },
+ }
+var Tests =
+ {
+ random_x: function ()
+ {
+ Player.x = Player.x+1 // Math.floor(Math.random () * 500)
+ if (Player.x > Canvas.width)
+ {
+ Player.x = 0
+ Player.y = 0
+ }
+ // Player.y = 50 // Math.floor(Math.random () * 50)
+ Player.surface = Canvas.surfaces[0]
+ //if (Math.random() > 0.3)
+ // {
+ // Player.dy = -5
+ // }
+ },
+ init: function ()
+ {
+ // $("#random_x").click(Tests.random_x)
+ },
+ }
+var Main =
+ {
+ init: function ()
+ {
+ // Tests.init()
+ Canvas.init()
+ Player.init()
+ Frustrum.init()
+ HUD.init()
+ Events.init()
+ },
+ }
+Main.init ()
+</script>
+</html>
+
diff --git a/geometry3.html b/geometry3.html
new file mode 100755
index 0000000..ec262f9
--- /dev/null
+++ b/geometry3.html
@@ -0,0 +1,957 @@
+<!doctype html>
+<html>
+<head><title>GEOMETRY</title></head>
+<style type="text/css">
+*
+ {
+ // border: 1px solid red;
+ }
+body
+ {
+ background-color: #87CEEB;
+ overflow: hidden;
+ }
+#frustrum
+ {
+ z-index: 666;
+ }
+#player
+ {
+ z-index: 980;
+ }
+#grid
+ {
+ display: none;
+ z-index: 950;
+ }
+#water
+ {
+ z-index: 800;
+ background-color: #6666cc;
+ }
+#seafloor
+ {
+ z-index: 810;
+ background-color: #8380ab;
+ }
+#background
+ {
+ position: fixed;
+ overflow: visible;
+ z-index: 900;
+ }
+#foreground
+ {
+ overflow: visible;
+ z-index: 999;
+ }
+#hud
+ {
+ font-size: 14px;
+ font-family: monospace;
+ background-color: #333;
+ z-index: 1000;
+ color: #fff;
+ opacity: 0.7;
+ white-space: pre;
+ }
+#tests
+ {
+ position: fixed;
+ right: 400px;
+ z-index: 1001;
+ }
+.flip
+ {
+ -moz-transform: scaleX(-1);
+ -o-transform: scaleX(-1);
+ -webkit-transform: scaleX(-1);
+ transform: scaleX(-1);
+ filter: FlipH;
+ -ms-filter: "FlipH";
+ }
+</style>
+
+<body>
+</body>
+
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript" src="jquery.gamequery-0.5.1.js"></script>
+<script type="text/javascript">
+var SCREEN_WIDTH = $(window).width()
+var SCREEN_HEIGHT = $(window).height()
+var REFRESH_RATE = 40
+var ISLAND_HEIGHT = 576
+var WATER_OFFSET = 458
+var SKY_OFFSET = SCREEN_HEIGHT - ISLAND_HEIGHT
+var FLOOR_OFFSET = SKY_OFFSET + WATER_OFFSET
+var SEAFLOOR_DEPTH = 600
+
+var SURFACE_THRESHOLD = 10
+
+var ABOVE_SURFACE = 3
+var ON_SURFACE = 2
+var LANDING_ON_SURFACE = 1
+var BELOW_SURFACE = 0
+var BEYOND_SURFACE = -1
+var OFF_MAP = -2
+
+var ORIENTATION_RIGHT = 1
+var ORIENTATION_LEFT = -1
+
+var KEY_LEFT = 37
+var KEY_UP = 38
+var KEY_RIGHT = 39
+var KEY_DOWN = 40
+var KEYTRACK = {}
+KEYTRACK[KEY_LEFT] = false
+KEYTRACK[KEY_UP] = false
+KEYTRACK[KEY_RIGHT] = false
+KEYTRACK[KEY_DOWN] = false
+
+function clamp (x, min, max)
+ {
+ return Math.max(min, Math.min(x, max))
+ }
+function slope (a, b)
+ {
+ if (b[0] === a[0])
+ return 0
+ return (b[1] - a[1]) / (b[0] - a[0])
+ }
+var HUD =
+ {
+ div: document.createElement("div"),
+ surface: false,
+ msg: "",
+ update: function ()
+ {
+ var activity = Player.running ? "RUNNING" : ""
+ activity += Player.jumping ? " JUMPING" : ""
+ activity += Player.cannonball ? " CANNONBALL" : ""
+ activity += Player.underwater ? " UNDERWATER" : ""
+ var orientation = Player.orientation === ORIENTATION_RIGHT ? "RIGHT" : "LEFT"
+ HUD.div.innerHTML =
+ [
+ "",
+ "PLAYER", Math.floor(Player.x), Math.floor(Player.y), activity, orientation, "\n",
+ "SPEED ", Math.floor(Player.dx), Math.floor(Player.dy), HUD.surface, "\n",
+ "CANVAS", Canvas.x, Canvas.y, "\n",
+ "KEY_UP", KEYTRACK[KEY_UP], "\n",
+ "KEY_DOWN", KEYTRACK[KEY_DOWN], "\n",
+ "KEY_LEFT", KEYTRACK[KEY_LEFT], "\n",
+ "KEY_RIGHT", KEYTRACK[KEY_RIGHT], "\n",
+ "SCREEN", SCREEN_WIDTH, SCREEN_HEIGHT, SKY_OFFSET, "\n",
+ "LEFT", Player.surface_left, "\n",
+ "SURFACE", Player.surface, "\n",
+ "RIGHT", Player.surface_right, "\n",
+ HUD.msg,
+ ].join(" ")
+ },
+ init: function ()
+ {
+ HUD.div.style.position = "fixed"
+ HUD.div.style.top = 0
+ HUD.div.style.right = 0
+ HUD.div.style.width = 300 + "px"
+ HUD.div.style.height = 300 + "px"
+ HUD.div.setAttribute("id", "hud")
+ document.body.appendChild(HUD.div)
+ },
+ }
+var Terrain =
+ {
+ }
+var Canvas =
+ {
+ div: document.createElement("canvas"),
+ background: document.createElement("div"),
+ foreground: document.createElement("div"),
+ water: document.createElement("div"),
+ seafloor: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: 2024+1224,
+ height: 3000,
+ surfaces: [],
+ ground: [
+ [0,-90],
+ [700,-90],
+ [1000,-70],
+ [1200,10],
+ [1210,SEAFLOOR_DEPTH],
+ [2010,SEAFLOOR_DEPTH],
+ [2060,10],
+ [2390,-90],
+ [2800,-90],
+ [2024+1224,-90],
+ ],
+ recalculate_surfaces: function ()
+ {
+ var calc = []
+ for (var i = 1; i < Canvas.ground.length; i++)
+ {
+ var two = Canvas.ground[i]
+ var one = Canvas.ground[i-1]
+ calc.push([one[0], one[1]+FLOOR_OFFSET, two[0], two[1]+FLOOR_OFFSET, slope(one, two)])
+ }
+ Canvas.surfaces = calc
+ },
+ background_elements:
+ [
+ // x, y, width, height, image
+ [0, 0, 1224, 576, "landscape/island1bg.png"],
+ [0, 576, 1224, 1000, "#8380ab"],
+ [2024, 576, 1224, 1000, "#8380ab"],
+ [1224, WATER_OFFSET + SEAFLOOR_DEPTH - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [1824, WATER_OFFSET + SEAFLOOR_DEPTH - 152, 200, 152, "landscape/underwaterislandcorner.png", "flip"],
+ [2024, 0, 1224, 576, "landscape/island1bg.png", "flip"],
+ ],
+ foreground_elements:
+ [
+ // x, y, width, height, image
+ [0, -34, 1224, 576, "landscape/island1fg.png"],
+ ],
+ init: function ()
+ {
+ Canvas.background.style.position = "fixed"
+ Canvas.background.style.top = 0 + "px"
+ Canvas.background.style.left = 0 + "px"
+ Canvas.background.style.width = Canvas.width + "px"
+ Canvas.background.style.height = Canvas.height + "px"
+ Canvas.background.setAttribute("id", "background")
+ document.body.appendChild(Canvas.background)
+
+ Canvas.foreground.style.position = "fixed"
+ Canvas.foreground.style.top = 0 + "px"
+ Canvas.foreground.style.left = 0 + "px"
+ Canvas.foreground.style.width = Canvas.width + "px"
+ Canvas.foreground.style.height = Canvas.height + "px"
+ Canvas.foreground.setAttribute("id", "foreground")
+ document.body.appendChild(Canvas.foreground)
+
+ Canvas.water.style.position = "fixed"
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + "px"
+ Canvas.water.style.left = 0 + "px"
+ Canvas.water.style.width = Canvas.width + "px"
+ Canvas.water.style.height = Canvas.height + "px"
+ Canvas.water.setAttribute("id", "water")
+ document.body.appendChild(Canvas.water)
+
+ Canvas.seafloor.style.position = "fixed"
+ Canvas.seafloor.style.top = SKY_OFFSET + SEAFLOOR_DEPTH + "px"
+ Canvas.seafloor.style.left = 0 + "px"
+ Canvas.seafloor.style.width = Canvas.width + "px"
+ Canvas.seafloor.style.height = Canvas.height + "px"
+ Canvas.seafloor.setAttribute("id", "seafloor")
+ document.body.appendChild(Canvas.seafloor)
+
+ ctx = Canvas.div.getContext("2d"),
+ Canvas.div.style.position = "fixed"
+ Canvas.div.style.top = 0
+ Canvas.div.style.left = 0
+ Canvas.div.setAttribute("width", Canvas.width+"px")
+ Canvas.div.setAttribute("height", Canvas.height+"px")
+ Canvas.div.setAttribute("id", "grid")
+ document.body.appendChild(Canvas.div)
+
+ ctx.beginPath()
+ for (var x = 0.5; x < Canvas.width; x += 10)
+ {
+ ctx.moveTo(x, 0)
+ ctx.lineTo(x, Canvas.height)
+ }
+ for (var y = 0.5; y < Canvas.height; y += 10)
+ {
+ ctx.moveTo(0, y)
+ ctx.lineTo(Canvas.width, y)
+ }
+ ctx.strokeStyle = "rgba(255,255,255,0.2)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, SKY_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, SKY_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, FLOOR_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, FLOOR_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ /*
+ ctx.fillStyle = "rgba(0,20,255,0.5)"
+ ctx.fillRect(0, Physics.water_level+0.5, Canvas.width, Canvas.height - Physics.water_level)
+ */
+
+ Canvas.recalculate_surfaces ()
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var surface = Canvas.surfaces[i]
+ ctx.beginPath()
+ ctx.moveTo(surface[0] + 0.5, surface[1] + 0.5)
+ ctx.lineTo(surface[2] + 0.5, surface[3] + 0.5)
+ ctx.strokeStyle = "#0bf"
+ ctx.stroke()
+ }
+ for (var i = 0; i < Canvas.background_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.background, Canvas.background_elements[i]))
+ }
+ for (var i = 0; i < Canvas.foreground_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.foreground, Canvas.foreground_elements[i]))
+ }
+ },
+ }
+function Animation (parent, data)
+ {
+ this.data = data
+ var frame = 0
+ var frameDelay = 0
+ var orientation = ORIENTATION_RIGHT
+ var done = false
+ this.div = document.createElement("div")
+ this.div.style.backgroundImage = "url(" + data.src + ")"
+ $(this.div).hide()
+ this.div.style.width = data.width + "px"
+ this.div.style.height = data.height + "px"
+ parent.div.appendChild(this.div)
+ this.activate = function ()
+ {
+ done = false
+ frame = 0
+ $(parent.div).children().each(function(){ $(this).hide() })
+ $(this.div).show()
+ parent.div.style.backgroundPosition = "0px 0px"
+ parent.div.style.width = data.width + "px"
+ parent.div.style.height = data.height + "px"
+ parent.width = data.width
+ parent.height = data.height
+ parent.x_offset = data.x_offset
+ parent.y_offset = data.y_offset
+ parent.feet_offset = data.feet_offset
+ this.orient (parent.orientation)
+ }
+ this.orient = function (direction)
+ {
+ orientation = direction
+ if (direction === ORIENTATION_RIGHT)
+ parent.div.className = ""
+ else
+ parent.div.className = "flip"
+ }
+ this.animate = function ()
+ {
+ if (done)
+ return
+ if (data.rate > 1)
+ {
+ frameDelay -= 1
+ if (frameDelay > 0)
+ return
+ else
+ frameDelay = data.rate
+ }
+ this.div.style.backgroundPosition = "0px " + (-1 * data.delta * frame) + "px"
+ frame += 1
+ if (frame > data.frames)
+ {
+ if (! data.loop)
+ done = true
+ else
+ frame = 0
+ if (data.dispose)
+ $(this.div).hide()
+ }
+ }
+ }
+function Furniture (container, row)
+ {
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ var div = document.createElement("div")
+ div.style.position = "fixed"
+ div.style.left = row[0] + "px"
+ div.style.top = SKY_OFFSET + row[1] + "px"
+ div.style.width = row[2] + "px"
+ div.style.height = row[3] + "px"
+ if (! row[4])
+ div.style.background = "transparent"
+ else if (row[4].substr(0,1) === "#")
+ div.style.background = row[4]
+ else
+ div.style.background = "url('" + row[4] + "')"
+ if (row.length === 6)
+ div.className = row[5]
+ container.appendChild(div)
+
+ // this.container = container
+ this.div = div
+ this.x = row[0]
+ this.y = row[1]
+ this.width = row[2]
+ this.height = row[3]
+ this.background = row[4]
+ this.update = function ()
+ {
+ this.div.style.top = SKY_OFFSET + this.y - Frustrum.y + "px"
+ this.div.style.left = this.x - Frustrum.x + "px"
+ }
+ }
+var Frustrum =
+ {
+ div: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ furniture: [],
+ sprites: [],
+ animating: true,
+ redraw: function ()
+ {
+ Canvas.div.style.top = Canvas.y - Frustrum.y + "px"
+ Canvas.div.style.left = Canvas.x - Frustrum.x + "px"
+
+ Player.div.style.top = Player.y + Player.y_offset - Frustrum.y + "px"
+ Player.div.style.left = Player.x + Player.x_offset - Frustrum.x + "px"
+
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + Canvas.y - Frustrum.y + "px"
+ Canvas.seafloor.style.top = SKY_OFFSET + WATER_OFFSET + SEAFLOOR_DEPTH + Canvas.y - Frustrum.y + "px"
+
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].update ()
+
+ // Frustrum.animating = ! Frustrum.animating
+ if (Frustrum.animating)
+ for (var i = 0; i < Frustrum.sprites.length; i++)
+ Frustrum.sprites[i].animation.animate ()
+ },
+ update: function ()
+ {
+ if (Player.underwater || Player.near_surface)
+ {
+ Frustrum.dest_y = Player.y - Frustrum.halfheight + Player.height
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth + Player.width
+ if (Player.y > Canvas.height - Frustrum.halfheight)
+ Frustrum.dest_y = Canvas.height - Frustrum.height
+ }
+ else
+ {
+ Frustrum.dest_x = 0
+ Frustrum.dest_y = 0
+ }
+ if (Player.x > Canvas.width - Frustrum.halfwidth)
+ Frustrum.dest_x = Canvas.width - Frustrum.width
+ else if (Player.x > Frustrum.halfwidth)
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth
+ Frustrum.y = Math.floor( (Frustrum.dest_y + Frustrum.y * 9) / 10 )
+ Frustrum.x = Math.floor( (Frustrum.dest_x + Frustrum.x * 9) / 10 )
+ // Frustrum.div.style.top = Frustrum.y + "px"
+ // Frustrum.div.style.left = Frustrum.x + "px"
+ },
+ init: function ()
+ {
+ Frustrum.div.style.position = "fixed"
+ Frustrum.div.style.top = 0
+ Frustrum.div.style.left = 0
+ Frustrum.div.style.width = Frustrum.width + "px"
+ Frustrum.div.style.height = Frustrum.height + "px"
+ Frustrum.div.setAttribute("id", "frustrum")
+ document.body.appendChild(Frustrum.div)
+ Frustrum.halfwidth = Frustrum.width/2
+ Frustrum.halfheight = Frustrum.height/2
+ },
+ }
+var Physics =
+ {
+ gravity: 5,
+ gravity_land: 5,
+ gravity_water: -3,
+ dx_walk: 25,
+ dx_swim: 20,
+ dx_swim_max: 40,
+ dy_swim_up: -25,
+ dy_swim_down: 25,
+ dy_resistance: 15,
+ dx_resistance: 15,
+ air_resistance: 15,
+ water_resistance: 8,
+ water_level: SKY_OFFSET + WATER_OFFSET,
+ jump_power: -35,
+ }
+var Player =
+ {
+ div: document.createElement("div"),
+ running: false,
+ jumping: false,
+ start_jump: false,
+ swimming_vertical: false,
+ swimming_horizontal: false,
+ cannonball: false,
+ orientation: ORIENTATION_RIGHT,
+ dx: 0,
+ dy: 0,
+ x: 0,
+ y: 0,
+ width: 100,
+ height: 167,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+ yIntercept: 0,
+ surface: [0,0,0,0],
+ surface_left: [0,0,0,0],
+ surface_right: [0,0,0,0],
+ findNearestSurface: function (x, feet)
+ {
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var s = Canvas.surfaces[i]
+ if (Player.onSurface(x, feet, s) > BELOW_SURFACE)
+ {
+ Player.surface = s
+ Player.surface_right = Canvas.surfaces[i+1]
+ Player.surface_left = Canvas.surfaces[i-1]
+ }
+ }
+ return OFF_MAP
+ },
+ onSurface: function (x, feet, s)
+ {
+ if (s === OFF_MAP)
+ return OFF_MAP
+
+ // within bounds
+ if (x < s[0] || x > s[2])
+ return BEYOND_SURFACE
+
+ // above the line
+ if (s[1] === s[3])
+ {
+ Player.slope = 0
+ Player.yIntercept = s[1]
+ Player.yInterceptRight = s[1]
+ if (feet < s[1])
+ return ABOVE_SURFACE
+ if (feet <= s[1] + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ }
+ Player.slope = s[4]
+ Player.yIntercept = (x + Player.x_offset - s[0]) * Player.slope + s[1]
+ Player.yInterceptRight = (x + Player.width + Player.x_offset - s[0]) * Player.slope + s[1]
+
+ if (feet < Player.yIntercept - 1)
+ return ABOVE_SURFACE
+ if (feet <= Player.yIntercept + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ if (Player.surfaceState === ON_SURFACE)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ },
+ underwater: false,
+ update: function ()
+ {
+ var feet = Player.y + Player.height + Player.feet_offset
+ Player.feet = feet
+ Player.surfaceState = Player.onSurface(Player.x, feet, Player.surface)
+ switch (Player.surfaceState)
+ {
+ case ABOVE_SURFACE:
+ HUD.surface = "ABOVE SURFACE"
+ if (Player.underwater)
+ Player.dy = Math.min(Player.dy + Physics.gravity, Physics.dy_resistance)
+ else
+ Player.dy = Player.dy + Physics.gravity
+ if (Player.y + Player.dy + Player.height > Player.yIntercept)
+ {
+ Player.y = Player.yIntercept - Player.height
+ Player.dy = 0
+ Player.surfaceState = ON_SURFACE
+ }
+ break
+ case ON_SURFACE:
+ HUD.surface = "ON SURFACE"
+ if (Player.underwater)
+ {
+ Player.dy = Math.min(0, Player.dy)
+ if (Player.surface.slope === 0)
+ Player.y = Player.yIntercept - Player.height
+ }
+ else
+ {
+ Player.cannonball = false
+ Player.dy = 0
+ // partially underwater
+ if (Player.y + Player.height > FLOOR_OFFSET)
+ {
+ Player.y = Player.surface[1] - Player.height
+ }
+ else
+ Player.y = Player.yIntercept - Player.height
+ }
+ Player.jumping = false
+ break
+ case BELOW_SURFACE:
+ HUD.surface = "BELOW SURFACE"
+ Player.dy = 0
+ Player.y = Player.yIntercept - Player.height
+ Player.surfaceState = ON_SURFACE
+ break
+ case BEYOND_SURFACE:
+ HUD.surface = "BEYOND SURFACE"
+ Player.findNearestSurface(Player.x, feet)
+ Player.update()
+ break
+ case OFF_MAP:
+ HUD.surface = "OFF MAP"
+ break
+ }
+
+ if (Player.cannonball)
+ {
+ if (Player.y > Physics.water_level)
+ {
+ Player.cannonball = false
+ Splash.place(Player.x)
+ }
+ if (Player.yIntercept <= Physics.water_level)
+ {
+ Player.idle ()
+ }
+ }
+ else if (! Player.underwater && Player.y > Physics.water_level)
+ {
+ Player.running = false
+ Player.jumping = false
+ Player.underwater = true
+ Physics.gravity = Physics.gravity_water
+ Splash.place(Player.x)
+ Player.cannonball = false
+ Player.yJump = Physics.water_level
+ Physics.dx_resistance = Physics.water_resistance
+ Physics.dy_resistance = Physics.water_resistance
+ }
+ else if (Player.underwater)
+ {
+ if (Player.y > Physics.water_level - SURFACE_THRESHOLD && Player.y < Physics.water_level + SURFACE_THRESHOLD && ! Player.swimming_vertical)
+ {
+ if (Player.dy > 0)
+ Player.dy += 1
+ else
+ Player.dy -= 1
+ Player.dy *= 1/10
+ Player.y = clamp(Player.y, Physics.water_level - SURFACE_THRESHOLD, Physics.water_level + SURFACE_THRESHOLD)
+ if (Player.y + Player.dy < Physics.water_level - SURFACE_THRESHOLD)
+ Player.dy *= -1
+ if (Player.y + Player.dy > Physics.water_level + SURFACE_THRESHOLD)
+ Player.dy *= -1
+ Player.near_surface = true
+ }
+ else if (Player.y < Physics.water_level)
+ {
+ Player.near_surface = false
+ Player.underwater = false
+ Player.cannonball = false
+ Physics.gravity = Physics.gravity_land
+ Physics.dx_resistance = Physics.air_resistance
+ Physics.dy_resistance = Physics.air_resistance
+ }
+ else
+ {
+ Player.near_surface = false
+ }
+ if (KEYTRACK[KEY_UP])
+ {
+ Player.dy = Physics.dy_swim_up
+ Player.swimming_vertical = true
+ }
+ else if (KEYTRACK[KEY_DOWN] && Player.surfaceState !== ON_SURFACE)
+ {
+ Player.dy = Physics.dy_swim_down
+ Player.swimming_vertical = true
+ }
+ else
+ {
+ Player.dy *= 9/10
+ Player.swimming_vertical = false
+ }
+ if (KEYTRACK[KEY_LEFT] || KEYTRACK[KEY_RIGHT])
+ {
+ Player.dx = Physics.dx_swim * Player.orientation
+ Player.swimming_horizontal = true
+ }
+ else
+ {
+ Player.swimming_horizontal = false
+ Player.dx *= 9/10
+ }
+ if (Player.orientation === ORIENTATION_LEFT && Player.surface_left[4] > 2 && Player.x + Player.dx <= Player.surface_left[2])
+ {
+ Player.swimming_horizontal = false
+ Player.x = Player.surface_left[2]
+ Player.dx = 0
+ KEYTRACK[KEY_LEFT] = false
+ }
+ else if (Player.orientation === ORIENTATION_RIGHT && Player.surface_right[4] < -2 && Player.x + Player.width >= Player.surface_right[0])
+ {
+ Player.swimming_horizontal = false
+ Player.dx = 0
+ }
+ }
+ else if (Player.jumping && Player.yJump < Physics.water_level &&
+ ((Player.orientation === ORIENTATION_RIGHT && Player.yIntercept > Physics.water_level) ||
+ (Player.orientation === ORIENTATION_LEFT && Player.yInterceptRight > Physics.water_level)))
+ {
+ Player.animation = Player.animations.cannonball
+ Player.animation.activate ()
+ Player.running = false
+ Player.jumping = false
+ Player.cannonball = true
+ }
+ else
+ {
+ if ((Player.start_jump || KEYTRACK[KEY_UP]) && Player.surfaceState === ON_SURFACE)
+ {
+ Player.start_jump = false
+ Player.jumping = true
+ Player.yJump = Player.y
+ Player.dy = Physics.jump_power
+ Player.y += Player.dy
+ Player.surfaceState = ABOVE_SURFACE
+ }
+ if (KEYTRACK[KEY_LEFT])
+ {
+ if (! Player.running)
+ {
+ Player.animation = Player.animations.run
+ Player.animation.activate ()
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ if (! Player.running)
+ {
+ Player.animation = Player.animations.run
+ Player.animation.activate ()
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else
+ {
+ if (Player.running)
+ Player.idle ()
+ Player.dx = 0
+ }
+ }
+ Player.y += Player.dy
+ Player.x += Player.dx
+ if (Player.x < 10)
+ {
+ if (Player.running)
+ Player.idle ()
+ Player.dx = 0
+ Player.x = 10
+ }
+ else if (Player.x > Canvas.width-Player.width - 20)
+ {
+ if (Player.running)
+ Player.idle ()
+ Player.dx = 0
+ Player.x = Canvas.width-Player.width - 20
+ }
+ },
+ idle: function ()
+ {
+ Player.animation = Player.animations.idle
+ Player.animation.activate()
+ Player.running = false
+ },
+ init: function ()
+ {
+ Player.x = 200
+ Player.y = SKY_OFFSET + FLOOR_OFFSET - 350 - Player.height
+ Player.div.style.position = "fixed"
+ Player.div.style.top = Player.y + "px"
+ Player.div.style.left = Player.x + "px"
+ Player.div.style.width = Player.width + "px"
+ Player.div.style.height = Player.height + "px"
+ Player.div.setAttribute("id", "player")
+ Player.animation = Player.animations.idle
+ Player.animation.activate ()
+ document.body.appendChild(Player.div)
+ Frustrum.sprites.push (Player)
+ },
+ }
+var Events =
+ {
+ interval: false,
+ keydown: function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_UP:
+ if (Player.underwater || Player.jumping)
+ break
+ Player.start_jump = true
+ break
+ case KEY_LEFT:
+ Player.orientation = ORIENTATION_LEFT
+ Player.animation.orient (Player.orientation)
+ break
+ case KEY_RIGHT:
+ Player.orientation = ORIENTATION_RIGHT
+ Player.animation.orient (Player.orientation)
+ break
+ case 71: // "G"
+ $("#grid").toggle()
+ Player.div.style.border = "1px solid red"
+ break
+ }
+ },
+ keyup: function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ },
+ blur: function ()
+ {
+ KEYTRACK[KEY_UP] = false
+ KEYTRACK[KEY_DOWN] = false
+ KEYTRACK[KEY_LEFT] = false
+ KEYTRACK[KEY_RIGHT] = false
+ Player.running = false
+ },
+ loop: function ()
+ {
+ Player.update()
+ Frustrum.update()
+ Frustrum.redraw()
+ HUD.update()
+ },
+ init: function ()
+ {
+ $(document).bind("keydown", Events.keydown)
+ $(document).bind("keyup", Events.keyup)
+ $(document).bind("blur", Events.blur)
+ Events.interval = setInterval(Events.loop, REFRESH_RATE)
+ },
+ }
+var Splash =
+ {
+ src: "sprites/splash2.png",
+ width: 200,
+ height: 134,
+ delta: 134,
+ frames: 7,
+ rate: 3,
+ loop: false,
+ dispose: true,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+
+ x: 0,
+ y: -134,
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ furniture: new Furniture (Canvas.foreground, [0, WATER_OFFSET - 127, 200, 134, false]),
+ animation: false,
+ div: false,
+ orientation: true,
+ place: function (x)
+ {
+ Splash.x = x - 30
+ Splash.furniture.x = x
+ Splash.orientation = ! Splash.orientation
+ if (Splash.orientation)
+ Splash.animation.orient(ORIENTATION_LEFT)
+ else
+ Splash.animation.orient(ORIENTATION_RIGHT)
+ Splash.animation.activate()
+ },
+ init: function ()
+ {
+ Splash.div = Splash.furniture.div
+ Splash.animation = new Animation (Splash, Splash)
+ Frustrum.furniture.push (Splash.furniture)
+ Frustrum.sprites.push (Splash)
+ },
+ }
+Player.animations =
+ {
+ "idle": new Animation (Player,
+ {
+ src: "sprites/manstandingsprite.png",
+ width: 140,
+ height: 231,
+ frames: 7,
+ rate: 1,
+ loop: true,
+ delta: 229,
+ x_offset: -10,
+ y_offset: 20,
+ feet_offset: 0,
+ }),
+ "run": new Animation (Player,
+ {
+ src: "sprites/manrunningsprite.png",
+ width: 140,
+ height: 214,
+ frames: 15,
+ loop: true,
+ rate: 1,
+ delta: 226,
+ x_offset: -5,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "cannonball": new Animation (Player,
+ {
+ src: "sprites/cannonball2.png",
+ width: 140,
+ height: 225,
+ frames: 4,
+ rate: 2,
+ loop: false,
+ delta: 225,
+ x_offset: -8,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ }
+var Tests =
+ {
+ init: function ()
+ {
+ // $("#random_x").click(Tests.random_x)
+ },
+ }
+var Main =
+ {
+ init: function ()
+ {
+ // Tests.init()
+ Canvas.init()
+ Player.init()
+ Splash.init()
+ Frustrum.init()
+ HUD.init()
+ Events.init()
+ },
+ }
+Main.init ()
+</script>
+</html>
+
diff --git a/geometry4.html b/geometry4.html
new file mode 100755
index 0000000..5af7fc7
--- /dev/null
+++ b/geometry4.html
@@ -0,0 +1,1158 @@
+<!doctype html>
+<html>
+<head><title>GEOMETRY</title></head>
+<style type="text/css">
+*
+ {
+ // border: 1px solid red;
+ }
+body
+ {
+ background-color: #87CEEB;
+ overflow: hidden;
+ }
+#frustrum
+ {
+ z-index: 666;
+ }
+#player
+ {
+ z-index: 980;
+ }
+#grid
+ {
+ display: none;
+ z-index: 950;
+ }
+#water
+ {
+ z-index: 800;
+ background-color: #6666cc;
+ }
+#seafloor
+ {
+ z-index: 810;
+ background-color: #8380ab;
+ }
+#background
+ {
+ position: fixed;
+ overflow: visible;
+ z-index: 900;
+ }
+#foreground
+ {
+ overflow: visible;
+ z-index: 999;
+ }
+#hud
+ {
+ font-size: 14px;
+ font-family: monospace;
+ background-color: #333;
+ z-index: 1000;
+ color: #fff;
+ opacity: 0.7;
+ white-space: pre;
+ }
+#tests
+ {
+ position: fixed;
+ right: 400px;
+ z-index: 1001;
+ }
+.flip
+ {
+ -moz-transform: scaleX(-1);
+ -o-transform: scaleX(-1);
+ -webkit-transform: scaleX(-1);
+ transform: scaleX(-1);
+ filter: FlipH;
+ -ms-filter: "FlipH";
+ }
+.flop
+ {
+ -moz-transform: scaleY(-1);
+ -o-transform: scaleY(-1);
+ -webkit-transform: scaleY(-1);
+ transform: scaleY(-1);
+ filter: FlipV;
+ -ms-filter: "FlipV";
+ }
+.flip_flop
+ {
+ -moz-transform: scaleX(-1) scaleY(-1);
+ -o-transform: scaleX(-1) scaleY(-1);
+ -webkit-transform: scaleX(-1) scaleY(-1);
+ transform: scaleX(-1) scaleY(-1);
+ filter: FlipV FlipH;
+ -ms-filter: "FlipV FlipH";
+ }
+</style>
+
+<body>
+</body>
+
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript">
+var SCREEN_WIDTH = $(window).width()
+var SCREEN_HEIGHT = $(window).height()
+var REFRESH_RATE = 40
+var ISLAND_HEIGHT = 576
+var WATER_OFFSET = 458
+var SKY_OFFSET = SCREEN_HEIGHT - ISLAND_HEIGHT
+var FLOOR_OFFSET = SKY_OFFSET + WATER_OFFSET
+var SEAFLOOR_DEPTH = 1800
+
+var SURFACE_THRESHOLD = 10
+
+var ABOVE_SURFACE = 3
+var ON_SURFACE = 2
+var LANDING_ON_SURFACE = 1
+var BELOW_SURFACE = 0
+var BEYOND_SURFACE = -1
+var OFF_MAP = -2
+
+var ORIENTATION_RIGHT = 1
+var ORIENTATION_LEFT = -1
+
+var KEY_LEFT = 37
+var KEY_UP = 38
+var KEY_RIGHT = 39
+var KEY_DOWN = 40
+var KEYTRACK = {}
+KEYTRACK[KEY_LEFT] = false
+KEYTRACK[KEY_UP] = false
+KEYTRACK[KEY_RIGHT] = false
+KEYTRACK[KEY_DOWN] = false
+
+function clamp (x, min, max)
+ {
+ return Math.max(min, Math.min(x, max))
+ }
+function slope (a, b)
+ {
+ if (b[0] === a[0])
+ return 0
+ return (b[1] - a[1]) / (b[0] - a[0])
+ }
+var HUD =
+ {
+ div: document.createElement("div"),
+ surface: false,
+ msg: "",
+ update: function ()
+ {
+ var activity = Player.running ? "RUNNING" : ""
+ activity += Player.jumping ? " JUMPING" : ""
+ activity += Player.cannonball ? " CANNONBALL" : ""
+ activity += Player.underwater ? " UNDERWATER" : ""
+ var orientation = Player.orientation === ORIENTATION_RIGHT ? "RIGHT" : "LEFT"
+ HUD.div.innerHTML =
+ [
+ "",
+ "PLAYER", Math.floor(Player.x), Math.floor(Player.y), activity, orientation, "\n",
+ "SPEED ", Math.floor(Player.dx), Math.floor(Player.dy), HUD.surface, "\n",
+ "CANVAS", Canvas.x, Canvas.y, "\n",
+ "KEY_UP", KEYTRACK[KEY_UP], "\n",
+ "KEY_DOWN", KEYTRACK[KEY_DOWN], "\n",
+ "KEY_LEFT", KEYTRACK[KEY_LEFT], "\n",
+ "KEY_RIGHT", KEYTRACK[KEY_RIGHT], "\n",
+ "SCREEN", SCREEN_WIDTH, SCREEN_HEIGHT, SKY_OFFSET, "\n",
+ "LEFT", Player.surface_left, "\n",
+ "SURFACE", Player.surface, "\n",
+ "RIGHT", Player.surface_right, "\n",
+ HUD.msg,
+ ].join(" ")
+ },
+ init: function ()
+ {
+ HUD.div.style.position = "fixed"
+ HUD.div.style.top = 0
+ HUD.div.style.right = 0
+ HUD.div.style.width = 300 + "px"
+ HUD.div.style.height = 300 + "px"
+ HUD.div.setAttribute("id", "hud")
+ document.body.appendChild(HUD.div)
+ },
+ }
+var COLOR_SEABED = "#8380ab"
+var COLOR_SAND = "#cc995e"
+var COLOR_WATER = "#6666cc"
+var COLOR_MOUNTAIN = "#5a7035"
+var ISLAND_WIDTH = 1224
+var Terrain =
+ {
+ "left_island": function (x)
+ {
+ Canvas.background_elements.push
+ (
+ // x y width height src
+ [x, 0, 1224, 576, "landscape/island1bg.png", "flip"],
+ [x, 576, 1224, 1600, COLOR_SEABED]
+ )
+ Canvas.ground.push
+ (
+ [x+10, 10],
+ [x+150,-70],
+ [x+330,-90],
+ [x+1000,-90]
+ )
+ return 1224
+ },
+ "right_island": function (x)
+ {
+ Canvas.background_elements.push
+ (
+ [x, 0, 1224, 576, "landscape/island1bg.png"],
+ [x, 576, 1224, 1600, COLOR_SEABED]
+ )
+ Canvas.ground.push
+ (
+ [x,-90],
+ [x+700,-90],
+ [x+1000,-70],
+ [x+1200, 10]
+ )
+ return 1224
+ },
+ "ocean": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, width, 1000, COLOR_SEABED],
+ [x+width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+width, depth]
+ )
+ return width
+ },
+ "ocean_pit": function (x, width, depth)
+ {
+ floor_width = 800
+ pit_width = 700
+ depth = 800
+ pit_depth = 1800
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, floor_width, 1000, COLOR_SEABED],
+ [x+floor_width, WATER_OFFSET + pit_depth, pit_width, 1000, COLOR_SEABED],
+ [x+floor_width, WATER_OFFSET + pit_depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x+floor_width-200, WATER_OFFSET + depth, 200, 152, "landscape/watercorner.png", "flip_flop"],
+ [x+floor_width+pit_width-200, WATER_OFFSET + pit_depth - 152, 200, 152, "landscape/underwaterislandcorner.png", "flip"],
+ [x+floor_width+pit_width, WATER_OFFSET + depth, floor_width, 1000, COLOR_SEABED],
+ [x+floor_width+pit_width, WATER_OFFSET + depth, 200, 152, "landscape/watercorner.png", "flop"],
+ [x+floor_width+pit_width+floor_width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+floor_width-10, depth],
+ [x+floor_width, pit_depth],
+ [x+floor_width+pit_width, pit_depth],
+ [x+floor_width+pit_width+10, depth],
+ [x+floor_width+pit_width+floor_width, depth]
+ )
+ return floor_width + pit_width + floor_width
+ },
+ "land": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ )
+ Canvas.ground.push
+ (
+ )
+ },
+ "sequence":
+ [
+ ["right_island"],
+ ["ocean_pit", 1200, 600],
+ ["left_island"],
+ // ["land", 800, 0],
+ ["right_island"],
+ ["ocean", 1800, 800],
+ ["left_island"],
+ ],
+ parse_sequence: function ()
+ {
+ var x = 0
+ for (var i = 0; i < Terrain.sequence.length; i++)
+ {
+ var seq = Terrain.sequence[i]
+ if (seq.length === 3)
+ x += Terrain[seq[0]] (x, seq[1], seq[2])
+ else
+ x += Terrain[seq[0]] (x)
+ }
+ Canvas.width = x
+ },
+ }
+var Canvas =
+ {
+ div: document.createElement("canvas"),
+ background: document.createElement("div"),
+ foreground: document.createElement("div"),
+ water: document.createElement("div"),
+ seafloor: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: 2024+1224,
+ height: 3000,
+ surfaces: [],
+ ground: [],
+ calculate_surfaces: function ()
+ {
+ Terrain.parse_sequence ()
+ var calc = []
+ var one, two
+ for (var i = 1; i < Canvas.ground.length; i++)
+ {
+ two = Canvas.ground[i]
+ one = Canvas.ground[i-1]
+ calc.push([one[0], one[1]+FLOOR_OFFSET, two[0], two[1]+FLOOR_OFFSET, slope(one, two)])
+ }
+ calc.push([two[0], two[1]+FLOOR_OFFSET, Canvas.width, two[1]+FLOOR_OFFSET, slope(two, [Canvas.width, two[1]])])
+ Canvas.surfaces = calc
+ },
+ background_elements:
+ [
+ [1224 + 1050, 1900, 230, 322, "guru2.gif"],
+ ],
+ foreground_elements:
+ [
+ // x, y, width, height, image
+ [0, -34, 1224, 576, "landscape/island1fg.png"],
+ [1100 + 1224*2 + 930, -34, 1224, 576, "landscape/island1fg.png", "flip"],
+ [1100 + 1224*2 + 750, -14, 722, 576, "landscape/island_bush.png", "flip"],
+ ],
+ init: function ()
+ {
+ Canvas.calculate_surfaces ()
+
+ Canvas.background.style.position = "fixed"
+ Canvas.background.style.top = 0 + "px"
+ Canvas.background.style.left = 0 + "px"
+ Canvas.background.style.width = Canvas.width + "px"
+ Canvas.background.style.height = Canvas.height + "px"
+ Canvas.background.setAttribute("id", "background")
+ document.body.appendChild(Canvas.background)
+
+ Canvas.foreground.style.position = "fixed"
+ Canvas.foreground.style.top = 0 + "px"
+ Canvas.foreground.style.left = 0 + "px"
+ Canvas.foreground.style.width = Canvas.width + "px"
+ Canvas.foreground.style.height = Canvas.height + "px"
+ Canvas.foreground.setAttribute("id", "foreground")
+ document.body.appendChild(Canvas.foreground)
+
+ Canvas.water.style.position = "fixed"
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + "px"
+ Canvas.water.style.left = 0 + "px"
+ Canvas.water.style.width = Canvas.width + "px"
+ Canvas.water.style.height = Canvas.height + "px"
+ Canvas.water.setAttribute("id", "water")
+ document.body.appendChild(Canvas.water)
+
+ Canvas.seafloor.style.position = "fixed"
+ Canvas.seafloor.style.top = SKY_OFFSET + SEAFLOOR_DEPTH + "px"
+ Canvas.seafloor.style.left = 0 + "px"
+ Canvas.seafloor.style.width = Canvas.width + "px"
+ Canvas.seafloor.style.height = Canvas.height + "px"
+ Canvas.seafloor.setAttribute("id", "seafloor")
+ document.body.appendChild(Canvas.seafloor)
+
+ ctx = Canvas.div.getContext("2d"),
+ Canvas.div.style.position = "fixed"
+ Canvas.div.style.top = 0
+ Canvas.div.style.left = 0
+ Canvas.div.setAttribute("width", Canvas.width+"px")
+ Canvas.div.setAttribute("height", Canvas.height+"px")
+ Canvas.div.setAttribute("id", "grid")
+ document.body.appendChild(Canvas.div)
+
+ ctx.beginPath()
+ for (var x = 0.5; x < Canvas.width; x += 10)
+ {
+ ctx.moveTo(x, 0)
+ ctx.lineTo(x, Canvas.height)
+ }
+ for (var y = 0.5; y < Canvas.height; y += 10)
+ {
+ ctx.moveTo(0, y)
+ ctx.lineTo(Canvas.width, y)
+ }
+ ctx.strokeStyle = "rgba(255,255,255,0.2)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, SKY_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, SKY_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, FLOOR_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, FLOOR_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ /*
+ ctx.fillStyle = "rgba(0,20,255,0.5)"
+ ctx.fillRect(0, Physics.water_level+0.5, Canvas.width, Canvas.height - Physics.water_level)
+ */
+
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var surface = Canvas.surfaces[i]
+ ctx.beginPath()
+ ctx.moveTo(surface[0] + 0.5, surface[1] + 0.5)
+ ctx.lineTo(surface[2] + 0.5, surface[3] + 0.5)
+ ctx.strokeStyle = "#0bf"
+ ctx.stroke()
+ }
+ for (var i = 0; i < Canvas.background_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.background, Canvas.background_elements[i]))
+ }
+ for (var i = 0; i < Canvas.foreground_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.foreground, Canvas.foreground_elements[i]))
+ }
+ },
+ }
+function Animation (parent, data)
+ {
+ this.data = data
+ var frame = 0
+ var frameDelay = 0
+ var orientation = ORIENTATION_RIGHT
+ var done = false
+ this.div = document.createElement("div")
+ this.div.style.backgroundImage = "url(" + data.src + ")"
+ $(this.div).hide()
+ this.div.style.width = data.width + "px"
+ this.div.style.height = data.height + "px"
+ this.rate = data.rate
+ parent.div.appendChild(this.div)
+ this.activate = function ()
+ {
+ done = false
+ frame = 0
+ $(parent.div).children().each(function(){ $(this).hide() })
+ $(this.div).show()
+ parent.div.style.backgroundPosition = "0px 0px"
+ parent.div.style.width = data.width + "px"
+ parent.div.style.height = data.height + "px"
+ parent.width = data.width
+ parent.height = data.height
+ parent.x_offset = data.x_offset
+ parent.y_offset = data.y_offset
+ parent.feet_offset = data.feet_offset
+ this.orient (parent.orientation)
+ }
+ this.orient = function (direction)
+ {
+ orientation = direction
+ if (direction === ORIENTATION_RIGHT)
+ parent.div.className = ""
+ else
+ parent.div.className = "flip"
+ }
+ this.animate = function ()
+ {
+ if (done)
+ return
+ if (this.rate > 1)
+ {
+ frameDelay -= 1
+ if (frameDelay > 0)
+ return
+ else
+ frameDelay = this.rate
+ }
+ this.div.style.backgroundPosition = "0px " + (-1 * data.delta * frame) + "px"
+ frame += 1
+ if (frame > data.frames)
+ {
+ if (! data.loop)
+ done = true
+ else
+ frame = 0
+ if (data.dispose)
+ $(this.div).hide()
+ }
+ }
+ }
+function Furniture (container, row)
+ {
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ var div = document.createElement("div")
+ div.style.position = "fixed"
+ div.style.left = row[0] + "px"
+ div.style.top = SKY_OFFSET + row[1] + "px"
+ div.style.width = row[2] + "px"
+ div.style.height = row[3] + "px"
+ if (! row[4])
+ div.style.background = "transparent"
+ else if (row[4].substr(0,1) === "#")
+ div.style.background = row[4]
+ else
+ div.style.background = "url('" + row[4] + "')"
+ if (row.length === 6)
+ div.className = row[5]
+ container.appendChild(div)
+
+ // this.container = container
+ this.div = div
+ this.x = row[0]
+ this.y = row[1]
+ this.width = row[2]
+ this.height = row[3]
+ this.background = row[4]
+ this.update = function ()
+ {
+ this.div.style.top = SKY_OFFSET + this.y - Frustrum.y + "px"
+ this.div.style.left = this.x - Frustrum.x + "px"
+ }
+ }
+var Frustrum =
+ {
+ div: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ furniture: [],
+ sprites: [],
+ animating: true,
+ redraw: function ()
+ {
+ Canvas.div.style.top = Canvas.y - Frustrum.y + "px"
+ Canvas.div.style.left = Canvas.x - Frustrum.x + "px"
+
+ Player.div.style.top = Player.y + Player.y_offset - Frustrum.y + "px"
+ Player.div.style.left = Player.x + Player.x_offset - Frustrum.x + "px"
+
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + Canvas.y - Frustrum.y + "px"
+ Canvas.seafloor.style.top = SKY_OFFSET + WATER_OFFSET + SEAFLOOR_DEPTH + Canvas.y - Frustrum.y + "px"
+
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].update ()
+
+ // Frustrum.animating = ! Frustrum.animating
+ if (Frustrum.animating)
+ for (var i = 0; i < Frustrum.sprites.length; i++)
+ Frustrum.sprites[i].animation.animate ()
+ },
+ update: function ()
+ {
+ if (Player.underwater || Player.near_surface)
+ {
+ Frustrum.dest_y = Player.y - Frustrum.halfheight + Player.height
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth + Player.width
+ if (Player.y > Canvas.height - Frustrum.halfheight)
+ Frustrum.dest_y = Canvas.height - Frustrum.height
+ }
+ else
+ {
+ Frustrum.dest_x = 0
+ Frustrum.dest_y = 0
+ }
+ if (Player.x > Canvas.width - Frustrum.halfwidth)
+ Frustrum.dest_x = Canvas.width - Frustrum.width
+ else if (Player.x > Frustrum.halfwidth)
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth
+ Frustrum.y = Math.floor( (Frustrum.dest_y + Frustrum.y * 9) / 10 )
+ Frustrum.x = Math.floor( (Frustrum.dest_x + Frustrum.x * 9) / 10 )
+ // Frustrum.div.style.top = Frustrum.y + "px"
+ // Frustrum.div.style.left = Frustrum.x + "px"
+ },
+ init: function ()
+ {
+ Frustrum.div.style.position = "fixed"
+ Frustrum.div.style.top = 0
+ Frustrum.div.style.left = 0
+ Frustrum.div.style.width = Frustrum.width + "px"
+ Frustrum.div.style.height = Frustrum.height + "px"
+ Frustrum.div.setAttribute("id", "frustrum")
+ document.body.appendChild(Frustrum.div)
+ Frustrum.halfwidth = Frustrum.width/2
+ Frustrum.halfheight = Frustrum.height/2
+ },
+ }
+var Physics =
+ {
+ gravity: 5,
+ gravity_land: 5,
+ gravity_water: -3,
+ dx_walk: 25,
+ dx_swim: 20,
+ dx_swim_max: 40,
+ dy_swim_up: -25,
+ dy_swim_down: 25,
+ dy_resistance: 15,
+ dx_resistance: 15,
+ air_resistance: 15,
+ water_resistance: 8,
+ water_level: SKY_OFFSET + WATER_OFFSET,
+ jump_power: -35,
+ }
+var Player =
+ {
+ div: document.createElement("div"),
+ running: false,
+ jumping: false,
+ start_jump: false,
+ swimming_vertical: false,
+ swimming_horizontal: false,
+ cannonball: false,
+ diving: false,
+ orientation: ORIENTATION_RIGHT,
+ dx: 0,
+ dy: 0,
+ x: 0,
+ y: 0,
+ exiting_water: 0,
+ width: 100,
+ height: 167,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+ yIntercept: 0,
+ surface: [0,0,0,0],
+ surface_left: [0,0,0,0],
+ surface_right: [0,0,0,0],
+ findNearestSurface: function (x, feet)
+ {
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var s = Canvas.surfaces[i]
+ if (Player.onSurface(x, feet, s) > BELOW_SURFACE)
+ {
+ Player.surface = s
+ Player.surface_right = Canvas.surfaces[i+1]
+ Player.surface_left = Canvas.surfaces[i-1]
+ }
+ }
+ return OFF_MAP
+ },
+ onSurface: function (x, feet, s)
+ {
+ if (s === OFF_MAP)
+ return OFF_MAP
+
+ // within bounds
+ if (x < s[0] || x > s[2])
+ return BEYOND_SURFACE
+
+ // above the line
+ if (s[1] === s[3])
+ {
+ Player.slope = 0
+ Player.yIntercept = s[1]
+ Player.yInterceptRight = s[1]
+ if (feet < s[1])
+ return ABOVE_SURFACE
+ if (feet <= s[1] + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ }
+ Player.slope = s[4]
+ Player.yIntercept = (x + Player.x_offset - s[0]) * Player.slope + s[1]
+ Player.yInterceptRight = (x + Player.width + Player.x_offset - s[0]) * Player.slope + s[1]
+
+ if (feet < Player.yIntercept - 1)
+ return ABOVE_SURFACE
+ if (feet <= Player.yIntercept + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ if (Player.surfaceState === ON_SURFACE)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ },
+ underwater: false,
+ update: function ()
+ {
+ var feet = Player.y + Player.height + Player.feet_offset
+ Player.feet = feet
+ Player.surfaceState = Player.onSurface(Player.x, feet, Player.surface)
+ switch (Player.surfaceState)
+ {
+ case ABOVE_SURFACE:
+ HUD.surface = "ABOVE SURFACE"
+ if (Player.underwater)
+ Player.dy = Math.min(Player.dy + Physics.gravity, Physics.dy_resistance)
+ else
+ Player.dy = Player.dy + Physics.gravity
+ if (Player.y + Player.dy + Player.height > Player.yIntercept)
+ {
+ Player.y = Player.yIntercept - Player.height
+ Player.dy = 0
+ Player.surfaceState = ON_SURFACE
+ }
+ break
+ case ON_SURFACE:
+ HUD.surface = "ON SURFACE"
+ if (Player.underwater)
+ {
+ Player.dy = Math.min(0, Player.dy)
+ if (Player.surface.slope === 0)
+ Player.y = Player.yIntercept - Player.height
+ }
+ else
+ {
+ Player.cannonball = false
+ Player.dy = 0
+ // partially underwater
+ if (Player.y + Player.height > FLOOR_OFFSET)
+ {
+ Player.y = Player.surface[1] - Player.height
+ }
+ else
+ Player.y = Player.yIntercept - Player.height
+ }
+ Player.jumping = false
+ break
+ case BELOW_SURFACE:
+ HUD.surface = "BELOW SURFACE"
+ Player.dy = 0
+ Player.y = Player.yIntercept - Player.height
+ Player.surfaceState = ON_SURFACE
+ break
+ case BEYOND_SURFACE:
+ HUD.surface = "BEYOND SURFACE"
+ Player.findNearestSurface(Player.x, feet)
+ Player.update()
+ break
+ case OFF_MAP:
+ HUD.surface = "OFF MAP"
+ break
+ }
+
+ if (Player.cannonball)
+ {
+ Player.diving = false
+ if (Player.y > Physics.water_level)
+ {
+ Player.cannonball = false
+ Splash.place(Player.x)
+ }
+ if (Player.yIntercept <= Physics.water_level)
+ {
+ Player.idle ()
+ }
+ }
+ else if (! Player.underwater && Player.y > Physics.water_level)
+ {
+ Player.animation = Player.animations.swim
+ Player.animation.activate ()
+ Player.running = false
+ Player.jumping = false
+ Player.diving = false
+ Player.underwater = true
+ Physics.gravity = Physics.gravity_water
+ Splash.place(Player.x)
+ Player.cannonball = false
+ Player.yJump = Physics.water_level
+ Physics.dx_resistance = Physics.water_resistance
+ Physics.dy_resistance = Physics.water_resistance
+ }
+ else if (Player.underwater)
+ {
+ if (Player.y > Physics.water_level - SURFACE_THRESHOLD && Player.y < Physics.water_level + SURFACE_THRESHOLD && ! Player.swimming_vertical)
+ {
+ if (Player.dy > 0)
+ Player.dy += 1
+ else
+ Player.dy -= 1
+ Player.dy *= 1/10
+ Player.y = clamp(Player.y, Physics.water_level - SURFACE_THRESHOLD, Physics.water_level + SURFACE_THRESHOLD)
+ if (Player.y + Player.dy < Physics.water_level - SURFACE_THRESHOLD)
+ Player.dy *= -1
+ if (Player.y + Player.dy > Physics.water_level + SURFACE_THRESHOLD)
+ Player.dy *= -1
+ Player.near_surface = true
+ }
+ else if (Player.y < Physics.water_level)
+ {
+ Player.exiting_water = 60
+ Player.near_surface = false
+ Player.underwater = false
+ Player.cannonball = false
+ Player.diving = false
+ Physics.gravity = Physics.gravity_land
+ Physics.dx_resistance = Physics.air_resistance
+ Physics.dy_resistance = Physics.air_resistance
+ }
+ else
+ {
+ Player.near_surface = false
+ }
+ if (KEYTRACK[KEY_UP])
+ {
+ Player.dy = Physics.dy_swim_up
+ Player.swimming_vertical = true
+ }
+ else if (KEYTRACK[KEY_DOWN] && Player.surfaceState !== ON_SURFACE)
+ {
+ Player.dy = Physics.dy_swim_down
+ Player.swimming_vertical = true
+ }
+ else
+ {
+ Player.dy *= 9/10
+ Player.swimming_vertical = false
+ }
+ if (KEYTRACK[KEY_LEFT] || KEYTRACK[KEY_RIGHT])
+ {
+ Player.dx = Physics.dx_swim * Player.orientation
+ Player.swimming_horizontal = true
+ Player.animation.rate = 1
+ }
+ else
+ {
+ Player.swimming_horizontal = false
+ Player.dx *= 9/10
+ Player.animation.rate = Math.min (Player.animation.rate + 0.01, 6)
+ HUD.msg = Player.animation.rate
+ }
+ if (Player.orientation === ORIENTATION_LEFT && Player.surface_left[4] > 2 && Player.x + Player.dx <= Player.surface_left[2])
+ {
+ if (Player.y + Player.height >= Player.surface_left[1])
+ {
+ Player.swimming_horizontal = false
+ Player.x = Player.surface_left[2]
+ Player.dx = 0
+ KEYTRACK[KEY_LEFT] = false
+ }
+ }
+ else if (Player.orientation === ORIENTATION_RIGHT && Player.surface_right[4] < -2 && Player.x + Player.width >= Player.surface_right[0])
+ {
+ if (Player.y + Player.height >= Player.surface_right[3])
+ {
+ Player.swimming_horizontal = false
+ Player.dx = 0
+ }
+ }
+ }
+ else if (Player.jumping && Player.yJump < Physics.water_level &&
+ ((Player.orientation === ORIENTATION_RIGHT && Player.yIntercept > Physics.water_level) ||
+ (Player.orientation === ORIENTATION_LEFT && Player.yInterceptRight > Physics.water_level)))
+ {
+ Player.animation = Player.animations.cannonball
+ Player.animation.activate ()
+ Player.running = false
+ Player.jumping = false
+ Player.cannonball = true
+ Player.diving = false
+ }
+ else
+ {
+ if ((Player.start_jump || KEYTRACK[KEY_UP]) && Player.surfaceState === ON_SURFACE)
+ {
+ Player.start_jump = false
+ Player.jumping = true
+ Player.diving = false
+ Player.yJump = Player.y
+ Player.dy = Physics.jump_power
+ Player.y += Player.dy
+ Player.surfaceState = ABOVE_SURFACE
+ }
+ if (KEYTRACK[KEY_LEFT])
+ {
+ if (Player.exiting_water < 0 && Player.yIntercept > Physics.water_level || Player.diving)
+ {
+ if (! Player.diving && ! Player.cannonball && ! Player.jumping)
+ {
+ Player.animation = Player.animations.dive
+ Player.animation.activate ()
+ Player.diving = true
+ }
+ }
+ else if (! Player.running)
+ {
+ Player.animation = Player.animations.run
+ Player.animation.activate ()
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ if (Player.exiting_water < 0 && Player.yInterceptRight > Physics.water_level || Player.diving)
+ {
+ if (! Player.diving && ! Player.cannonball && ! Player.jumping)
+ {
+ Player.animation = Player.animations.dive
+ Player.animation.activate ()
+ Player.diving = true
+ }
+ }
+ else if (! Player.running)
+ {
+ Player.animation = Player.animations.run
+ Player.animation.activate ()
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else
+ {
+ if (Player.running)
+ Player.idle ()
+ Player.dx = 0
+ }
+ }
+ Player.exiting_water -= 1
+ Player.y += Player.dy
+ Player.x += Player.dx
+ if (Player.x < 10)
+ {
+ if (Player.running)
+ Player.idle ()
+ Player.dx = 0
+ Player.x = 10
+ }
+ else if (Player.x > Canvas.width-Player.width - 20)
+ {
+ if (Player.running)
+ Player.idle ()
+ Player.dx = 0
+ Player.x = Canvas.width-Player.width - 20
+ }
+ },
+ idle: function ()
+ {
+ Player.animation = Player.animations.idle
+ Player.animation.activate()
+ Player.running = false
+ },
+ init: function ()
+ {
+ Player.x = 200
+ Player.y = SKY_OFFSET + FLOOR_OFFSET - 350 - Player.height
+ Player.div.style.position = "fixed"
+ Player.div.style.top = Player.y + "px"
+ Player.div.style.left = Player.x + "px"
+ Player.div.style.width = Player.width + "px"
+ Player.div.style.height = Player.height + "px"
+ Player.div.setAttribute("id", "player")
+ Player.animation = Player.animations.idle
+ Player.animation.activate ()
+ document.body.appendChild(Player.div)
+ Frustrum.sprites.push (Player)
+ },
+ }
+var Events =
+ {
+ interval: false,
+ keydown: function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_UP:
+ if (Player.underwater || Player.jumping)
+ break
+ Player.start_jump = true
+ break
+ case KEY_LEFT:
+ Player.orientation = ORIENTATION_LEFT
+ Player.animation.orient (Player.orientation)
+ break
+ case KEY_RIGHT:
+ Player.orientation = ORIENTATION_RIGHT
+ Player.animation.orient (Player.orientation)
+ break
+ case 71: // "G"
+ $("#grid").toggle()
+ Player.div.style.border = "1px solid red"
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].div.style.border = "1px solid #0f0"
+ break
+ }
+ },
+ keyup: function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ },
+ blur: function ()
+ {
+ KEYTRACK[KEY_UP] = false
+ KEYTRACK[KEY_DOWN] = false
+ KEYTRACK[KEY_LEFT] = false
+ KEYTRACK[KEY_RIGHT] = false
+ Player.running = false
+ Player.dx = 0
+ },
+ loop: function ()
+ {
+ Player.update()
+ Frustrum.update()
+ Frustrum.redraw()
+ HUD.update()
+ },
+ init: function ()
+ {
+ $(document).bind("keydown", Events.keydown)
+ $(document).bind("keyup", Events.keyup)
+ $(document).bind("blur", Events.blur)
+ Events.interval = setInterval(Events.loop, REFRESH_RATE)
+ },
+ }
+var Splash =
+ {
+ src: "sprites/splash2.png",
+ width: 200,
+ height: 134,
+ delta: 134,
+ frames: 7,
+ rate: 3,
+ loop: false,
+ dispose: true,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+
+ x: 0,
+ y: -134,
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ furniture: new Furniture (Canvas.foreground, [0, WATER_OFFSET - 127, 200, 134, false]),
+ animation: false,
+ div: false,
+ orientation: true,
+ place: function (x)
+ {
+ Splash.x = x - 30
+ Splash.furniture.x = x
+ Splash.orientation = ! Splash.orientation
+ if (Splash.orientation)
+ Splash.animation.orient(ORIENTATION_LEFT)
+ else
+ Splash.animation.orient(ORIENTATION_RIGHT)
+ Splash.animation.activate()
+ },
+ init: function ()
+ {
+ Splash.div = Splash.furniture.div
+ Splash.animation = new Animation (Splash, Splash)
+ Frustrum.furniture.push (Splash.furniture)
+ Frustrum.sprites.push (Splash)
+ },
+ }
+Player.animations =
+ {
+ "idle": new Animation (Player,
+ {
+ src: "sprites/manstandingsprite.png",
+ width: 140,
+ height: 231,
+ frames: 7,
+ rate: 1,
+ loop: true,
+ delta: 229,
+ x_offset: -10,
+ y_offset: 20,
+ feet_offset: 0,
+ }),
+ "run": new Animation (Player,
+ {
+ src: "sprites/manrunningsprite.png",
+ width: 140,
+ height: 214,
+ frames: 15,
+ loop: true,
+ rate: 1,
+ delta: 226,
+ x_offset: -5,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "jump": new Animation (Player,
+ {
+ src: "sprites/jumping2.png",
+ width: 140,
+ height: 214,
+ frames: 2,
+ loop: true,
+ rate: 2,
+ delta: 226,
+ x_offset: -5,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "cannonball": new Animation (Player,
+ {
+ src: "sprites/cannonball2.png",
+ width: 140,
+ height: 225,
+ frames: 4,
+ rate: 2,
+ loop: false,
+ delta: 225,
+ x_offset: -8,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "dive": new Animation (Player,
+ {
+ src: "sprites/diving2.png",
+ width: 280,
+ height: 208,
+ frames: 4,
+ rate: 2,
+ loop: false,
+ delta: 208,
+ x_offset: -8,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "swim": new Animation (Player,
+ {
+ src: "sprites/swimming2.png",
+ width: 280,
+ height: 116,
+ frames: 10,
+ rate: 1,
+ loop: true,
+ delta: 116,
+ x_offset: 0,
+ y_offset: -10,
+ feet_offset: 0,
+ }),
+ }
+var Tests =
+ {
+ init: function ()
+ {
+ // $("#random_x").click(Tests.random_x)
+ },
+ }
+var Main =
+ {
+ init: function ()
+ {
+ // Tests.init()
+ Canvas.init()
+ Player.init()
+ Splash.init()
+ Frustrum.init()
+ HUD.init()
+ Events.init()
+ },
+ }
+Main.init ()
+</script>
+</html>
+
diff --git a/geometry5.html b/geometry5.html
new file mode 100755
index 0000000..95e9c68
--- /dev/null
+++ b/geometry5.html
@@ -0,0 +1,1392 @@
+<!doctype html>
+<html>
+<head><title>GEOMETRY</title></head>
+<style type="text/css">
+*
+ {
+ // border: 1px solid red;
+ }
+body
+ {
+ background-color: #87CEEB;
+ overflow: hidden;
+ }
+#frustrum
+ {
+ z-index: 666;
+ }
+#player
+ {
+ z-index: 980;
+ }
+#grid
+ {
+ display: none;
+ z-index: 950;
+ }
+#water
+ {
+ z-index: 800;
+ background-color: #6666cc;
+ }
+#seafloor
+ {
+ z-index: 810;
+ background-color: #8380ab;
+ }
+#background
+ {
+ position: fixed;
+ overflow: visible;
+ z-index: 900;
+ }
+#foreground
+ {
+ overflow: visible;
+ z-index: 999;
+ }
+#hud
+ {
+ font-size: 14px;
+ font-family: monospace;
+ background-color: #333;
+ z-index: 1000;
+ color: #fff;
+ opacity: 0.7;
+ white-space: pre;
+ }
+#tests
+ {
+ position: fixed;
+ right: 400px;
+ z-index: 1001;
+ }
+.dialog
+ {
+ display: none
+ padding: 10px;
+ font-family: Courier New, monospace;
+ font-size: 28px;
+ font-weight: bold;
+ border: 2px solid black;
+ background-color: white;
+ }
+.flip
+ {
+ -moz-transform: scaleX(-1);
+ -o-transform: scaleX(-1);
+ -webkit-transform: scaleX(-1);
+ transform: scaleX(-1);
+ filter: FlipH;
+ -ms-filter: "FlipH";
+ }
+.flop
+ {
+ -moz-transform: scaleY(-1);
+ -o-transform: scaleY(-1);
+ -webkit-transform: scaleY(-1);
+ transform: scaleY(-1);
+ filter: FlipV;
+ -ms-filter: "FlipV";
+ }
+.flip_flop
+ {
+ -moz-transform: scaleX(-1) scaleY(-1);
+ -o-transform: scaleX(-1) scaleY(-1);
+ -webkit-transform: scaleX(-1) scaleY(-1);
+ transform: scaleX(-1) scaleY(-1);
+ filter: FlipV FlipH;
+ -ms-filter: "FlipV FlipH";
+ }
+</style>
+
+<body>
+</body>
+
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript">
+var SCREEN_WIDTH = $(window).width()
+var SCREEN_HEIGHT = $(window).height()
+var REFRESH_RATE = 40
+var ISLAND_HEIGHT = 576
+var WATER_OFFSET = 458
+var SKY_OFFSET = SCREEN_HEIGHT - ISLAND_HEIGHT
+var FLOOR_OFFSET = SKY_OFFSET + WATER_OFFSET
+var SEAFLOOR_DEPTH = 1800
+
+var PLAYER_START_X = 200
+
+var SURFACE_THRESHOLD = 10
+
+var ABOVE_SURFACE = 3
+var ON_SURFACE = 2
+var LANDING_ON_SURFACE = 1
+var BELOW_SURFACE = 0
+var BEYOND_SURFACE = -1
+var OFF_MAP = -2
+
+var ORIENTATION_RIGHT = 1
+var ORIENTATION_LEFT = -1
+
+var KEY_LEFT = 37
+var KEY_UP = 38
+var KEY_RIGHT = 39
+var KEY_DOWN = 40
+var KEYTRACK = {}
+KEYTRACK[KEY_LEFT] = false
+KEYTRACK[KEY_UP] = false
+KEYTRACK[KEY_RIGHT] = false
+KEYTRACK[KEY_DOWN] = false
+
+function clamp (x, min, max)
+ {
+ return Math.max(min, Math.min(x, max))
+ }
+function slope (a, b)
+ {
+ if (b[0] === a[0])
+ return 0
+ return (b[1] - a[1]) / (b[0] - a[0])
+ }
+var HUD =
+ {
+ div: document.createElement("div"),
+ surface: false,
+ msg: "",
+ update: function ()
+ {
+ var activity = Player.running ? "RUNNING" : ""
+ activity += Player.jumping ? " JUMPING" : ""
+ activity += Player.cannonball ? " CANNONBALL" : ""
+ activity += Player.underwater ? " UNDERWATER" : ""
+ var orientation = Player.orientation === ORIENTATION_RIGHT ? "RIGHT" : "LEFT"
+ HUD.div.innerHTML =
+ [
+ "",
+ "PLAYER", Math.floor(Player.x), Math.floor(Player.y), activity, orientation, "\n",
+ "SPEED ", Math.floor(Player.dx), Math.floor(Player.dy), HUD.surface, "\n",
+ "CANVAS", Canvas.x, Canvas.y, "\n",
+ "KEY_UP", KEYTRACK[KEY_UP], "\n",
+ "KEY_DOWN", KEYTRACK[KEY_DOWN], "\n",
+ "KEY_LEFT", KEYTRACK[KEY_LEFT], "\n",
+ "KEY_RIGHT", KEYTRACK[KEY_RIGHT], "\n",
+ "SCREEN", SCREEN_WIDTH, SCREEN_HEIGHT, SKY_OFFSET, "\n",
+ "LEFT", Player.surface_left, "\n",
+ "SURFACE", Player.surface, "\n",
+ "RIGHT", Player.surface_right, "\n",
+ HUD.msg,
+ ].join(" ")
+ },
+ init: function ()
+ {
+ HUD.div.style.position = "fixed"
+ HUD.div.style.top = 0
+ HUD.div.style.right = 0
+ HUD.div.style.width = 300 + "px"
+ HUD.div.style.height = 300 + "px"
+ HUD.div.setAttribute("id", "hud")
+ document.body.appendChild(HUD.div)
+ },
+ }
+var COLOR_SEABED = "#8380ab"
+var COLOR_SAND = "#cc995e"
+var COLOR_WATER = "#6666cc"
+var COLOR_MOUNTAIN = "#5a7035"
+var ISLAND_WIDTH = 1224
+var Terrain =
+ {
+ "left_island": function (x)
+ {
+ Canvas.background_elements.push
+ (
+ // x y width height src
+ [x, 0, 1224, 576, "landscape/island1bg.png", "flip"],
+ [x, 576, 1224, 1600, COLOR_SEABED]
+ )
+ Canvas.ground.push
+ (
+ [x+10, 10],
+ [x+150,-70],
+ [x+330,-90],
+ [x+1000,-90]
+ )
+ return 1224
+ },
+ "right_island": function (x)
+ {
+ Canvas.background_elements.push
+ (
+ [x, 0, 1224, 576, "landscape/island1bg.png"],
+ [x, 576, 1224, 1600, COLOR_SEABED]
+ )
+ Canvas.ground.push
+ (
+ [x,-90],
+ [x+700,-90],
+ [x+1000,-70],
+ [x+1200, 10]
+ )
+ return 1224
+ },
+ "ocean": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, width, 1000, COLOR_SEABED],
+ [x+width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+width, depth]
+ )
+ return width
+ },
+ "ocean_plaid": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, width, 1000, "landscape/scotch.gif",],
+ [x+width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+width, depth]
+ )
+ return width
+ },
+ "ocean_pit": function (x, width, depth)
+ {
+ floor_width = 800
+ pit_width = 700
+ depth = 800
+ pit_depth = 1800
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, floor_width, 1000, COLOR_SEABED],
+ [x+floor_width, WATER_OFFSET + pit_depth, pit_width, 1000, COLOR_SEABED],
+ [x+floor_width, WATER_OFFSET + pit_depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x+floor_width-200, WATER_OFFSET + depth, 200, 152, "landscape/watercorner.png", "flip_flop"],
+ [x+floor_width+pit_width-200, WATER_OFFSET + pit_depth - 152, 200, 152, "landscape/underwaterislandcorner.png", "flip"],
+ [x+floor_width+pit_width, WATER_OFFSET + depth, floor_width, 1000, COLOR_SEABED],
+ [x+floor_width+pit_width, WATER_OFFSET + depth, 200, 152, "landscape/watercorner.png", "flop"],
+ [x+floor_width+pit_width+floor_width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"],
+ [x + floor_width + 250, 1900, 230, 322, "guru2.gif"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+floor_width-10, depth],
+ [x+floor_width, pit_depth],
+ [x+floor_width+pit_width, pit_depth],
+ [x+floor_width+pit_width+10, depth],
+ [x+floor_width+pit_width+floor_width, depth]
+ )
+
+ return floor_width + pit_width + floor_width
+ },
+ "land": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ )
+ Canvas.ground.push
+ (
+ )
+ },
+ "first_island_foliage": function (x)
+ {
+ Canvas.foreground_elements.push(
+ [x, -34, 1224, 576, "landscape/island1fg.png"]
+ )
+ return 0
+ },
+ "second_island_foliage": function (x)
+ {
+ Canvas.foreground_elements.push(
+ [x+930, -34, 1224, 576, "landscape/island1fg.png", "flip"],
+ [x+750, -14, 722, 576, "landscape/island_bush.png", "flip"]
+ )
+ return 0
+ },
+ "tree_island_foliage": function (x)
+ {
+ Canvas.foreground_elements.push(
+ [x+280, -20, 199, 576, "landscape/palmtree.png", ],
+ [x+1750, 39, 722, 576, "landscape/island_bush.png", "flip"],
+ [x+2220, -40, 199, 576, "landscape/palmtree.png", "flip"],
+ [x+950, 39, 722, 576, "landscape/island_bush.png"],
+ [x+450, 64, 722, 576, "landscape/island_bush.png", "flip"],
+ [x+1720, -20, 199, 576, "landscape/palmtree.png", "flip"],
+ [x+1920, -34, 199, 576, "landscape/palmtree.png", "flip"]
+ )
+ return 0
+ },
+ "sequence":
+ [
+ ["first_island_foliage"],
+ ["right_island"],
+ ["ocean_pit", 1200, 600],
+ ["second_island_foliage"],
+ ["left_island"],
+ ["right_island"],
+ ["ocean_plaid", 2000, 1000],
+ ["tree_island_foliage"],
+ ["left_island"],
+ ["right_island"],
+ ["ocean", 2500, 950],
+ ["left_island"],
+ ],
+ parse_sequence: function ()
+ {
+ var x = 0
+ for (var i = 0; i < Terrain.sequence.length; i++)
+ {
+ var seq = Terrain.sequence[i]
+ if (seq.length === 3)
+ x += Terrain[seq[0]] (x, seq[1], seq[2])
+ else
+ x += Terrain[seq[0]] (x)
+ }
+ Canvas.width = x
+ },
+ }
+var Canvas =
+ {
+ div: document.createElement("canvas"),
+ background: document.createElement("div"),
+ foreground: document.createElement("div"),
+ water: document.createElement("div"),
+ seafloor: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: 2024+1224,
+ height: 3000,
+ surfaces: [],
+ ground: [],
+ calculate_surfaces: function ()
+ {
+ Terrain.parse_sequence ()
+ var calc = []
+ var one, two
+ for (var i = 1; i < Canvas.ground.length; i++)
+ {
+ two = Canvas.ground[i]
+ one = Canvas.ground[i-1]
+ calc.push([one[0], one[1]+FLOOR_OFFSET, two[0], two[1]+FLOOR_OFFSET, slope(one, two)])
+ }
+ calc.push([two[0], two[1]+FLOOR_OFFSET, Canvas.width, two[1]+FLOOR_OFFSET, slope(two, [Canvas.width, two[1]])])
+ Canvas.surfaces = calc
+ },
+ background_elements:
+ [
+ ],
+ foreground_elements:
+ [
+ // x, y, width, height, image
+ ],
+ init: function ()
+ {
+ Canvas.calculate_surfaces ()
+
+ Canvas.background.style.position = "fixed"
+ Canvas.background.style.top = 0 + "px"
+ Canvas.background.style.left = 0 + "px"
+ Canvas.background.style.width = Canvas.width + "px"
+ Canvas.background.style.height = Canvas.height + "px"
+ Canvas.background.setAttribute("id", "background")
+ document.body.appendChild(Canvas.background)
+
+ Canvas.foreground.style.position = "fixed"
+ Canvas.foreground.style.top = 0 + "px"
+ Canvas.foreground.style.left = 0 + "px"
+ Canvas.foreground.style.width = Canvas.width + "px"
+ Canvas.foreground.style.height = Canvas.height + "px"
+ Canvas.foreground.setAttribute("id", "foreground")
+ document.body.appendChild(Canvas.foreground)
+
+ Canvas.water.style.position = "fixed"
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + "px"
+ Canvas.water.style.left = 0 + "px"
+ Canvas.water.style.width = Canvas.width + "px"
+ Canvas.water.style.height = Canvas.height + "px"
+ Canvas.water.setAttribute("id", "water")
+ document.body.appendChild(Canvas.water)
+
+ Canvas.seafloor.style.position = "fixed"
+ Canvas.seafloor.style.top = SKY_OFFSET + SEAFLOOR_DEPTH + "px"
+ Canvas.seafloor.style.left = 0 + "px"
+ Canvas.seafloor.style.width = Canvas.width + "px"
+ Canvas.seafloor.style.height = Canvas.height + "px"
+ Canvas.seafloor.setAttribute("id", "seafloor")
+ document.body.appendChild(Canvas.seafloor)
+
+ ctx = Canvas.div.getContext("2d"),
+ Canvas.div.style.position = "fixed"
+ Canvas.div.style.top = 0
+ Canvas.div.style.left = 0
+ Canvas.div.setAttribute("width", Canvas.width+"px")
+ Canvas.div.setAttribute("height", Canvas.height+"px")
+ Canvas.div.setAttribute("id", "grid")
+ document.body.appendChild(Canvas.div)
+
+ ctx.beginPath()
+ for (var x = 0.5; x < Canvas.width; x += 10)
+ {
+ ctx.moveTo(x, 0)
+ ctx.lineTo(x, Canvas.height)
+ }
+ for (var y = 0.5; y < Canvas.height; y += 10)
+ {
+ ctx.moveTo(0, y)
+ ctx.lineTo(Canvas.width, y)
+ }
+ ctx.strokeStyle = "rgba(255,255,255,0.2)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, SKY_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, SKY_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, FLOOR_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, FLOOR_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ /*
+ ctx.fillStyle = "rgba(0,20,255,0.5)"
+ ctx.fillRect(0, Physics.water_level+0.5, Canvas.width, Canvas.height - Physics.water_level)
+ */
+
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var surface = Canvas.surfaces[i]
+ ctx.beginPath()
+ ctx.moveTo(surface[0] + 0.5, surface[1] + 0.5)
+ ctx.lineTo(surface[2] + 0.5, surface[3] + 0.5)
+ ctx.strokeStyle = "#0bf"
+ ctx.stroke()
+ }
+ for (var i = 0; i < Canvas.background_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.background, Canvas.background_elements[i]))
+ }
+ for (var i = 0; i < Canvas.foreground_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.foreground, Canvas.foreground_elements[i]))
+ }
+ },
+ }
+function Animation (parent, data)
+ {
+ this.data = data
+ this.active = false
+ var frame = 0
+ var frameDelay = 0
+ var orientation = ORIENTATION_RIGHT
+ var done = false
+ this.div = document.createElement("div")
+ this.div.style.backgroundImage = "url(" + data.src + ")"
+ $(this.div).hide()
+ this.div.style.width = data.width + "px"
+ this.div.style.height = data.height + "px"
+ this.rate = data.rate
+ parent.div.appendChild(this.div)
+ this.activate = function ()
+ {
+ done = false
+ frame = 0
+ $(parent.div).children().each(function(){ $(this).hide() })
+ $(this.div).show()
+ parent.div.style.backgroundPosition = "0px 0px"
+ parent.div.style.width = data.width + "px"
+ parent.div.style.height = data.height + "px"
+ parent.width = data.width
+ parent.height = data.height
+ parent.x_offset = data.x_offset
+ parent.y_offset = data.y_offset
+ parent.feet_offset = data.feet_offset
+ this.orient (parent.orientation)
+ }
+ this.orient = function (direction)
+ {
+ orientation = direction
+ if (direction === ORIENTATION_RIGHT)
+ parent.div.className = ""
+ else
+ parent.div.className = "flip"
+ }
+ this.animate = function ()
+ {
+ if (done)
+ return
+ if (this.rate > 1)
+ {
+ frameDelay -= 1
+ if (frameDelay > 0)
+ return
+ else
+ frameDelay = this.rate
+ }
+ this.div.style.backgroundPosition = "0px " + (-1 * data.delta * frame) + "px"
+ frame += 1
+ if (frame > data.frames)
+ {
+ if (! data.loop)
+ done = true
+ else
+ frame = 0
+ if (data.dispose)
+ $(this.div).hide()
+ }
+ if (this.data.callback)
+ this.data.callback ()
+ }
+ }
+function Furniture (container, row)
+ {
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ var div = document.createElement("div")
+ div.style.position = "fixed"
+ div.style.left = row[0] + "px"
+ div.style.top = SKY_OFFSET + row[1] + "px"
+ div.style.width = row[2] + "px"
+ div.style.height = row[3] + "px"
+ if (! row[4])
+ div.style.background = "transparent"
+ else if (row[4].substr(0,1) === "#")
+ div.style.background = row[4]
+ else
+ div.style.background = "url('" + row[4] + "')"
+ if (row.length === 6)
+ div.className = row[5]
+ container.appendChild(div)
+
+ // this.container = container
+ this.div = div
+ this.x = row[0]
+ this.y = row[1]
+ this.width = row[2]
+ this.height = row[3]
+ this.background = row[4]
+ this.update = function ()
+ {
+ this.div.style.top = SKY_OFFSET + this.y - Frustrum.y + "px"
+ this.div.style.left = this.x - Frustrum.x + "px"
+ }
+ }
+var Frustrum =
+ {
+ div: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ furniture: [],
+ sprites: [],
+ animating: true,
+ redraw: function ()
+ {
+ Canvas.div.style.top = Canvas.y - Frustrum.y + "px"
+ Canvas.div.style.left = Canvas.x - Frustrum.x + "px"
+
+ Player.div.style.top = Player.y + Player.y_offset - Frustrum.y + "px"
+ Player.div.style.left = Player.x + Player.x_offset - Frustrum.x + "px"
+
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + Canvas.y - Frustrum.y + "px"
+ Canvas.seafloor.style.top = SKY_OFFSET + WATER_OFFSET + SEAFLOOR_DEPTH + Canvas.y - Frustrum.y + "px"
+
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].update ()
+
+ // Frustrum.animating = ! Frustrum.animating
+ if (Frustrum.animating)
+ for (var i = 0; i < Frustrum.sprites.length; i++)
+ Frustrum.sprites[i].animation.animate ()
+ },
+ update: function ()
+ {
+ if (Player.underwater || Player.near_surface)
+ {
+ Frustrum.dest_y = Player.y - Frustrum.halfheight + Player.height
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth + Player.width
+ if (Player.y > Canvas.height - Frustrum.halfheight)
+ Frustrum.dest_y = Canvas.height - Frustrum.height
+ }
+ else
+ {
+ Frustrum.dest_x = 0
+ Frustrum.dest_y = 0
+ }
+ if (Player.x > Canvas.width - Frustrum.halfwidth)
+ Frustrum.dest_x = Canvas.width - Frustrum.width
+ else if (Player.x > Frustrum.halfwidth)
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth
+ Frustrum.y = Math.floor( (Frustrum.dest_y + Frustrum.y * 9) / 10 )
+ Frustrum.x = Math.floor( (Frustrum.dest_x + Frustrum.x * 9) / 10 )
+ // Frustrum.div.style.top = Frustrum.y + "px"
+ // Frustrum.div.style.left = Frustrum.x + "px"
+ },
+ init: function ()
+ {
+ Frustrum.div.style.position = "fixed"
+ Frustrum.div.style.top = 0
+ Frustrum.div.style.left = 0
+ Frustrum.div.style.width = Frustrum.width + "px"
+ Frustrum.div.style.height = Frustrum.height + "px"
+ Frustrum.div.setAttribute("id", "frustrum")
+ document.body.appendChild(Frustrum.div)
+ Frustrum.halfwidth = Frustrum.width/2
+ Frustrum.halfheight = Frustrum.height/2
+ },
+ }
+var Physics =
+ {
+ gravity: 5,
+ gravity_land: 5,
+ gravity_water: -3,
+ dx_walk: 25,
+ dx_swim: 20,
+ dx_swim_max: 40,
+ dy_swim_up: -25,
+ dy_swim_down: 25,
+ dy_resistance: 15,
+ dx_resistance: 15,
+ air_resistance: 15,
+ water_resistance: 8,
+ water_level: SKY_OFFSET + WATER_OFFSET,
+ jump_power: -35,
+ }
+var Player =
+ {
+ div: document.createElement("div"),
+ running: false,
+ jumping: false,
+ start_jump: false,
+ swimming_vertical: false,
+ swimming_horizontal: false,
+ cannonball: false,
+ diving: false,
+ orientation: ORIENTATION_RIGHT,
+ current_mode: 'idle',
+ modes: {},
+ dx: 0,
+ dy: 0,
+ x: 0,
+ y: 0,
+ exiting_water: 0,
+ width: 100,
+ height: 167,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+ yIntercept: 0,
+ surface: [0,0,0,0],
+ surface_left: [0,0,0,0],
+ surface_right: [0,0,0,0],
+ findNearestSurface: function (x, feet)
+ {
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var s = Canvas.surfaces[i]
+ if (Player.onSurface(x, feet, s) > BELOW_SURFACE)
+ {
+ Player.surface = s
+ Player.surface_right = Canvas.surfaces[i+1]
+ Player.surface_left = Canvas.surfaces[i-1]
+ }
+ }
+ return OFF_MAP
+ },
+ onSurface: function (x, feet, s)
+ {
+ if (s === OFF_MAP)
+ return OFF_MAP
+
+ // within bounds
+ if (x < s[0] || x > s[2])
+ return BEYOND_SURFACE
+
+ // above the line
+ if (s[1] === s[3])
+ {
+ Player.slope = 0
+ Player.yIntercept = s[1]
+ Player.yInterceptRight = s[1]
+ if (feet < s[1])
+ return ABOVE_SURFACE
+ if (feet <= s[1] + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ }
+ Player.slope = s[4]
+ Player.yIntercept = (x + Player.x_offset - s[0]) * Player.slope + s[1]
+ Player.yInterceptRight = (x + Player.width + Player.x_offset - s[0]) * Player.slope + s[1]
+
+ if (feet < Player.yIntercept - 1)
+ return ABOVE_SURFACE
+ if (feet <= Player.yIntercept + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ if (Player.surfaceState === ON_SURFACE)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ },
+ underwater: false,
+ update: function ()
+ {
+ var feet = Player.y + Player.height + Player.feet_offset
+ Player.feet = feet
+ Player.surfaceState = Player.onSurface(Player.x, feet, Player.surface)
+ switch (Player.surfaceState)
+ {
+ case ABOVE_SURFACE:
+ HUD.surface = "ABOVE SURFACE"
+ if (Player.underwater)
+ Player.dy = Math.min(Player.dy + Physics.gravity, Physics.dy_resistance)
+ else
+ Player.dy = Player.dy + Physics.gravity
+ if (Player.y + Player.dy + Player.height > Player.yIntercept)
+ {
+ Player.y = Player.yIntercept - Player.height
+ Player.dy = 0
+ Player.surfaceState = ON_SURFACE
+ }
+ break
+ case ON_SURFACE:
+ HUD.surface = "ON SURFACE"
+ if (Player.underwater)
+ {
+ Player.dy = Math.min(0, Player.dy)
+ if (Player.surface.slope === 0)
+ Player.y = Player.yIntercept - Player.height
+ }
+ else
+ {
+ Player.cannonball = false
+ Player.dy = 0
+ // partially underwater
+ if (Player.y + Player.height > FLOOR_OFFSET)
+ {
+ Player.y = Player.surface[1] - Player.height
+ }
+ else
+ Player.y = Player.yIntercept - Player.height
+ }
+ Player.jumping = false
+ break
+ case BELOW_SURFACE:
+ HUD.surface = "BELOW SURFACE"
+ Player.dy = 0
+ Player.y = Player.yIntercept - Player.height
+ Player.surfaceState = ON_SURFACE
+ break
+ case BEYOND_SURFACE:
+ HUD.surface = "BEYOND SURFACE"
+ Player.findNearestSurface(Player.x, feet)
+ Player.update()
+ break
+ case OFF_MAP:
+ HUD.surface = "OFF MAP"
+ break
+ }
+
+ if (Player.cannonball)
+ {
+ Player.diving = false
+ if (Player.y > Physics.water_level)
+ {
+ Player.cannonball = false
+ Splash.place(Player.x)
+ }
+ if (Player.yIntercept <= Physics.water_level)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ }
+ else if (! Player.underwater && Player.y > Physics.water_level)
+ {
+ Player.setAnimationSwim()
+ // Player.setAnimation ("swim")
+ Player.running = false
+ Player.jumping = false
+ Player.diving = false
+ Player.underwater = true
+ Physics.gravity = Physics.gravity_water
+ Splash.place(Player.x)
+ Player.cannonball = false
+ Player.yJump = Physics.water_level
+ Physics.dx_resistance = Physics.water_resistance
+ Physics.dy_resistance = Physics.water_resistance
+ }
+ else if (Player.underwater)
+ {
+ if (Player.y > Physics.water_level - SURFACE_THRESHOLD && Player.y < Physics.water_level + SURFACE_THRESHOLD && ! Player.swimming_vertical)
+ {
+ if (Player.dy > 0)
+ Player.dy += 1
+ else
+ Player.dy -= 1
+ Player.dy *= 1/10
+ Player.y = clamp(Player.y, Physics.water_level - SURFACE_THRESHOLD, Physics.water_level + SURFACE_THRESHOLD)
+ if (Player.y + Player.dy < Physics.water_level - SURFACE_THRESHOLD)
+ Player.dy *= -1
+ if (Player.y + Player.dy > Physics.water_level + SURFACE_THRESHOLD)
+ Player.dy *= -1
+ Player.near_surface = true
+ }
+ else if (Player.y < Physics.water_level)
+ {
+ Player.exiting_water = 60
+ Player.near_surface = false
+ Player.underwater = false
+ Player.cannonball = false
+ Player.diving = false
+ Physics.gravity = Physics.gravity_land
+ Physics.dx_resistance = Physics.air_resistance
+ Physics.dy_resistance = Physics.air_resistance
+ }
+ else
+ {
+ Player.near_surface = false
+ }
+ if (KEYTRACK[KEY_UP])
+ {
+ Player.dy = Physics.dy_swim_up
+ Player.swimming_vertical = true
+ }
+ else if (KEYTRACK[KEY_DOWN] && Player.surfaceState !== ON_SURFACE)
+ {
+ Player.dy = Physics.dy_swim_down
+ Player.swimming_vertical = true
+ }
+ else
+ {
+ Player.dy *= 9/10
+ Player.swimming_vertical = false
+ }
+ if (KEYTRACK[KEY_LEFT] || KEYTRACK[KEY_RIGHT])
+ {
+ Player.dx = Physics.dx_swim * Player.orientation
+ Player.swimming_horizontal = true
+ Player.setAnimationSwim()
+ Player.animation.rate = 2
+ }
+ else
+ {
+ Player.swimming_horizontal = false
+ Player.dx *= 9/10
+ Player.animation.rate = Math.min (Player.animation.rate + 0.01, 6)
+ Player.setAnimation("float")
+ }
+ if (Player.orientation === ORIENTATION_LEFT && Player.surface_left[4] > 2 && Player.x + Player.dx <= Player.surface_left[2])
+ {
+ if (Player.y + Player.height >= Player.surface_left[1])
+ {
+ Player.swimming_horizontal = false
+ Player.x = Player.surface_left[2]
+ Player.dx = 0
+ KEYTRACK[KEY_LEFT] = false
+ }
+ }
+ else if (Player.orientation === ORIENTATION_RIGHT && Player.surface_right[4] < -2 && Player.x + Player.width >= Player.surface_right[0])
+ {
+ if (Player.y + Player.height >= Player.surface_right[3])
+ {
+ Player.swimming_horizontal = false
+ Player.dx = 0
+ }
+ }
+ }
+ else if (Player.jumping && Player.yJump < Physics.water_level &&
+ ((Player.orientation === ORIENTATION_RIGHT && Player.yIntercept > Physics.water_level) ||
+ (Player.orientation === ORIENTATION_LEFT && Player.yInterceptRight > Physics.water_level)))
+ {
+ if (! Player.animations['dive'].active)
+ Player.setAnimation("cannonball")
+ Player.running = false
+ Player.jumping = false
+ Player.cannonball = true
+ Player.diving = false
+ }
+ else
+ {
+ if ((Player.start_jump || KEYTRACK[KEY_UP]) && Player.surfaceState === ON_SURFACE)
+ {
+ Player.start_jump = false
+ Player.jumping = true
+ Player.diving = false
+ Player.yJump = Player.y
+ Player.dy = Physics.jump_power
+ Player.y += Player.dy
+ Player.surfaceState = ABOVE_SURFACE
+ }
+ if (KEYTRACK[KEY_LEFT])
+ {
+ if (Player.exiting_water < 0 && Player.yIntercept > Physics.water_level || Player.diving)
+ {
+ if (! Player.diving && ! Player.cannonball && ! Player.jumping)
+ {
+ Player.setAnimation("dive")
+ Player.diving = true
+ }
+ }
+ else if (! Player.running)
+ {
+ Player.setAnimation("run")
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ if (Player.exiting_water < 0 && Player.yInterceptRight > Physics.water_level || Player.diving)
+ {
+ if (! Player.diving && ! Player.cannonball && ! Player.jumping)
+ {
+ Player.setAnimation("dive")
+ Player.diving = true
+ }
+ }
+ else if (! Player.running)
+ {
+ Player.setAnimation("run")
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else
+ {
+ if (Player.running)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ Player.dx = 0
+ }
+ }
+ Player.exiting_water -= 1
+ Player.y += Player.dy
+ Player.x += Player.dx
+ if (Player.x < 10)
+ {
+ if (Player.running)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ Player.dx = 0
+ Player.x = 10
+ }
+ else if (Player.x > Canvas.width-Player.width - 20)
+ {
+ if (Player.running)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ Player.dx = 0
+ Player.x = Canvas.width-Player.width - 20
+ }
+ },
+ lastSwitch: 0,
+ setAnimationSwim: function ()
+ {
+ if (Player.lastSwitch > 0)
+ {
+ Player.lastSwitch -= 1
+ return
+ }
+ Player.lastSwitch = 1
+ Player.setAnimation ("swim")
+ },
+ setAnimation: function (mode)
+ {
+ if (! Player.animations[mode].active)
+ {
+ Player.animations[Player.current_mode].active = false
+ Player.animations[mode].active = true
+ Player.current_mode = mode
+ Player.animation = Player.animations[mode]
+ Player.animation.activate ()
+ }
+ },
+ init: function ()
+ {
+ Player.x = PLAYER_START_X
+ Player.y = SKY_OFFSET + FLOOR_OFFSET - 350 - Player.height
+ Player.div.style.position = "fixed"
+ Player.div.style.top = Player.y + "px"
+ Player.div.style.left = Player.x + "px"
+ Player.div.style.width = Player.width + "px"
+ Player.div.style.height = Player.height + "px"
+ Player.div.setAttribute("id", "player")
+ Player.setAnimation(STARTING_MODE)
+ Player.running = false
+ document.body.appendChild(Player.div)
+ Frustrum.sprites.push (Player)
+ },
+ }
+var Events =
+ {
+ interval: false,
+ keydown: function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_UP:
+ if (Player.underwater || Player.jumping)
+ break
+ Player.start_jump = true
+ break
+ case KEY_LEFT:
+ Player.orientation = ORIENTATION_LEFT
+ Player.animation.orient (Player.orientation)
+ break
+ case KEY_RIGHT:
+ Player.orientation = ORIENTATION_RIGHT
+ Player.animation.orient (Player.orientation)
+ break
+ case 71: // "G"
+ $("#grid").toggle()
+ Player.div.style.border = "1px solid red"
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].div.style.border = "1px solid #0f0"
+ break
+ }
+ },
+ keyup: function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ },
+ blur: function ()
+ {
+ KEYTRACK[KEY_UP] = false
+ KEYTRACK[KEY_DOWN] = false
+ KEYTRACK[KEY_LEFT] = false
+ KEYTRACK[KEY_RIGHT] = false
+ Player.running = false
+ Player.dx = 0
+ },
+ loop: function ()
+ {
+ Player.update()
+ Frustrum.update()
+ Frustrum.redraw()
+ // HUD.update()
+ },
+ init: function ()
+ {
+ $(document).bind("keydown", Events.keydown)
+ $(document).bind("keyup", Events.keyup)
+ $(document).bind("blur", Events.blur)
+ Events.interval = setInterval(Events.loop, REFRESH_RATE)
+ },
+ }
+var Splash =
+ {
+ src: "sprites/splash2.png",
+ width: 200,
+ height: 134,
+ delta: 134,
+ frames: 7,
+ rate: 3,
+ loop: false,
+ dispose: true,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+
+ x: 0,
+ y: -134,
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ furniture: new Furniture (Canvas.foreground, [0, WATER_OFFSET - 127, 200, 134, false]),
+ animation: false,
+ div: false,
+ orientation: true,
+ place: function (x)
+ {
+ Splash.x = x - 30
+ Splash.furniture.x = x
+ Splash.orientation = ! Splash.orientation
+ if (Splash.orientation)
+ Splash.animation.orient(ORIENTATION_LEFT)
+ else
+ Splash.animation.orient(ORIENTATION_RIGHT)
+ Splash.animation.activate()
+ },
+ init: function ()
+ {
+ Splash.div = Splash.furniture.div
+ Splash.animation = new Animation (Splash, Splash)
+ Frustrum.furniture.push (Splash.furniture)
+ Frustrum.sprites.push (Splash)
+ },
+ }
+var Dialog =
+ {
+ box: false,
+ is_open: false,
+ width: 420,
+ open: function (x, y)
+ {
+ if (Dialog.is_open)
+ return
+ Dialog.x = x - 100
+ Dialog.furniture.x = x - 100
+ Dialog.y = y - 100
+ Dialog.furniture.x = y - 100
+ Dialog.box.innerHTML = Dudes.next_message()
+ $(Dialog.furniture.div).show(200)
+ Dialog.is_open = true
+ },
+ close: function ()
+ {
+ $(Dialog.furniture.div).hide(200)
+ Dialog.is_open = false
+ },
+ init: function ()
+ {
+ Dialog.furniture = new Furniture (Canvas.foreground, [Dialog.width, 0, 400, "auto", false])
+ var dialogbox = document.createElement("div")
+ dialogbox.style.display = "block"
+ dialogbox.style.width = Dialog.width + "px"
+ dialogbox.style.padding = "10px"
+ dialogbox.style.background = "#fff"
+ dialogbox.className = "dialog"
+ Dialog.box = dialogbox
+ Dialog.furniture.div.appendChild(dialogbox)
+ Dialog.close ()
+ },
+ }
+function Dude (x)
+ {
+ var dialog_open = false
+ this.width = 140
+ this.height = 231
+ this.x = x
+ this.y = 170
+ this.furniture = new Furniture (Canvas.background, [this.x, this.y, this.width, this.height, false])
+ this.div = this.furniture.div
+ this.dialog = function ()
+ {
+ if (Player.x > x - 200 && Player.x < x + 140 + 200)
+ {
+ dialog_open = true
+ Dialog.open (x, FLOOR_OFFSET - 280 - 231)
+ }
+ else if (dialog_open)
+ {
+ dialog_open = false
+ Dialog.close ()
+ }
+ }
+ this.animation = new Animation (this,
+ {
+ src: "sprites/manstandingsprite.png",
+ width: this.width,
+ height: this.height,
+ frames: 7,
+ rate: 1,
+ loop: true,
+ delta: 229,
+ x_offset: -10,
+ y_offset: 20,
+ feet_offset: 0,
+ callback: this.dialog,
+ })
+ Frustrum.furniture.push (this.furniture)
+ Frustrum.sprites.push (this)
+ this.animation.activate()
+ }
+var Dudes =
+ {
+ dudes: [],
+ last_message: 0,
+ next_message: function ()
+ {
+ var msg = Dudes.messages[Dudes.last_message]
+ while (true)
+ {
+ new_message = Math.floor( Math.random() * Dudes.messages.length )
+ if (new_message !== Dudes.last_message)
+ {
+ Dudes.last_message = new_message
+ break
+ }
+ }
+ return msg
+ },
+ messages:
+ [
+ "this place looks very elegant, but hard to penetrate",
+ "GEE WIZ!! THANKS!!",
+ // "a baby frog is not a frog, not a frog It's a tadpole Tadpole, tadpole Baby frog is called a ta-d-pole!",
+ "If all else fails use fire.",
+ "I NEVER DIE!!",
+ "you have <i>snazz</i>",
+ "It's taken me a long time to get in to the \"boss\" position.",
+ "I know mark wahlberg.",
+ "And it's almost like...<i>whimsically abstract</i>...yet at the same time <i>conscious of its form</i>.",
+ "I'm supposed to be guarding the lake, but I prefer to just wander around",
+ "I think, therefore I am.",
+ "You have responded to me!!",
+ "These pools are where real heroes test their mettal.",
+ "She can slice me like a blowfish.",
+ // "Realizing failure, the robot has changed his name to Marvin and is feeling very depressed.",
+ "Again, you can find my picture in the dictionary, under the word \"ultimate.\"",
+ "It's just sooo over for you.",
+ "WOW! THE CAPTAIN OF THE DRAGONSHIP DESTINY! COME DROP ANCHOR IN MY HARBOR!",
+ "JUST A MINUTE, TOOTS!",
+ "WINNER HA. I've dropped logz that wuz bigger'n you.",
+ "Darkness...let it hold you in peace, like your mom's arms",
+ "I just happened to watch these hippies fly into a rage. The hateful hippies...",
+ "TRY AGAIN TOMATO FACE!",
+ "YOUR FLEAS CAN'T BEAT ME. I KNOW YOUR THOUGHTS.",
+ "MY IMAGINATION KNOWS NO LIMIT...AH, MY NOSE IS ALMOST BLEEDING I FEEL SO HORNY!",
+ "I HOPE I RUN ACROSS MY PARENTS OUT HERE. SURE WOULD FEEL GOOD TO RUN THOSE <I>FUN^#%RS</I> OVER.",
+ ],
+ init: function ()
+ {
+ var idxes = [850, 4200, 4800, 5400, 6200]
+ for (i in idxes)
+ {
+ Dudes.dudes.push( new Dude (idxes[i]) )
+ }
+ },
+ }
+STARTING_MODE = "idle"
+Player.animations =
+ {
+ "idle": new Animation (Player,
+ {
+ src: "sprites/manstandingsprite.png",
+ width: 140,
+ height: 231,
+ frames: 7,
+ rate: 1,
+ loop: true,
+ delta: 229,
+ x_offset: -10,
+ y_offset: 20,
+ feet_offset: 0,
+ }),
+ "run": new Animation (Player,
+ {
+ src: "sprites/manrunningsprite.png",
+ width: 140,
+ height: 214,
+ frames: 15,
+ loop: true,
+ rate: 1,
+ delta: 226,
+ x_offset: -5,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "jump": new Animation (Player,
+ {
+ src: "sprites/jumping2.png",
+ width: 140,
+ height: 214,
+ frames: 2,
+ loop: true,
+ rate: 2,
+ delta: 226,
+ x_offset: -5,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "cannonball": new Animation (Player,
+ {
+ src: "sprites/cannonball2.png",
+ width: 140,
+ height: 220,
+ frames: 4,
+ rate: 2,
+ loop: false,
+ delta: 230,
+ x_offset: -8,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "dive": new Animation (Player,
+ {
+ src: "sprites/diving2.png",
+ width: 280,
+ height: 207,
+ frames: 4,
+ rate: 2,
+ loop: false,
+ delta: 210,
+ x_offset: -8,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "swim": new Animation (Player,
+ {
+ src: "sprites/breaststroke3.png",
+ width: 320,
+ height: 177,
+ frames: 9,
+ rate: 2,
+ loop: true,
+ delta: 203,
+ x_offset: 0,
+ y_offset: -10,
+ feet_offset: 0,
+ }),
+ "float": new Animation (Player,
+ {
+ src: "sprites/float3.png",
+ width: 130,
+ height: 266,
+ frames: 8,
+ rate: 2,
+ loop: true,
+ delta: 266,
+ x_offset: 0,
+ y_offset: -37,
+ feet_offset: 0,
+ }),
+ }
+var Tests =
+ {
+ init: function ()
+ {
+ // $("#random_x").click(Tests.random_x)
+ },
+ }
+var Main =
+ {
+ init: function ()
+ {
+ // Tests.init()
+ Canvas.init()
+ Player.init()
+ Splash.init()
+ Frustrum.init()
+ // HUD.init()
+ Events.init()
+ Dudes.init ()
+ Dialog.init ()
+ },
+ }
+Main.init ()
+</script>
+</html>
+
diff --git a/geometry6.html b/geometry6.html
new file mode 100755
index 0000000..52a3fe8
--- /dev/null
+++ b/geometry6.html
@@ -0,0 +1,1393 @@
+<!doctype html>
+<html>
+<head><title>GEOMETRY</title></head>
+<style type="text/css">
+*
+ {
+ // border: 1px solid red;
+ }
+body
+ {
+ background-color: #87CEEB;
+ overflow: hidden;
+ }
+#frustrum
+ {
+ z-index: 666;
+ }
+#player
+ {
+ z-index: 980;
+ }
+#grid
+ {
+ display: none;
+ z-index: 950;
+ }
+#water
+ {
+ z-index: 800;
+ background-color: #6666cc;
+ }
+#seafloor
+ {
+ z-index: 810;
+ background-color: #8380ab;
+ }
+#background
+ {
+ position: fixed;
+ overflow: visible;
+ z-index: 900;
+ }
+#foreground
+ {
+ overflow: visible;
+ z-index: 999;
+ }
+#hud
+ {
+ font-size: 14px;
+ font-family: monospace;
+ background-color: #333;
+ z-index: 1000;
+ color: #fff;
+ opacity: 0.7;
+ white-space: pre;
+ }
+#tests
+ {
+ position: fixed;
+ right: 400px;
+ z-index: 1001;
+ }
+.dialog
+ {
+ display: none
+ padding: 10px;
+ font-family: Courier New, monospace;
+ font-size: 28px;
+ font-weight: bold;
+ border: 2px solid black;
+ background-color: white;
+ }
+.flip
+ {
+ -moz-transform: scaleX(-1);
+ -o-transform: scaleX(-1);
+ -webkit-transform: scaleX(-1);
+ transform: scaleX(-1);
+ filter: FlipH;
+ -ms-filter: "FlipH";
+ }
+.flop
+ {
+ -moz-transform: scaleY(-1);
+ -o-transform: scaleY(-1);
+ -webkit-transform: scaleY(-1);
+ transform: scaleY(-1);
+ filter: FlipV;
+ -ms-filter: "FlipV";
+ }
+.flip_flop
+ {
+ -moz-transform: scaleX(-1) scaleY(-1);
+ -o-transform: scaleX(-1) scaleY(-1);
+ -webkit-transform: scaleX(-1) scaleY(-1);
+ transform: scaleX(-1) scaleY(-1);
+ filter: FlipV FlipH;
+ -ms-filter: "FlipV FlipH";
+ }
+</style>
+
+<body>
+</body>
+
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript">
+var SCREEN_WIDTH = $(window).width()
+var SCREEN_HEIGHT = $(window).height()
+var REFRESH_RATE = 40
+var ISLAND_HEIGHT = 576
+var WATER_OFFSET = 458
+var SKY_OFFSET = SCREEN_HEIGHT - ISLAND_HEIGHT
+var FLOOR_OFFSET = SKY_OFFSET + WATER_OFFSET
+var SEAFLOOR_DEPTH = 1800
+
+var PLAYER_START_X = 200
+
+var SURFACE_THRESHOLD = 10
+
+var ABOVE_SURFACE = 3
+var ON_SURFACE = 2
+var LANDING_ON_SURFACE = 1
+var BELOW_SURFACE = 0
+var BEYOND_SURFACE = -1
+var OFF_MAP = -2
+
+var ORIENTATION_RIGHT = 1
+var ORIENTATION_LEFT = -1
+
+var KEY_LEFT = 37
+var KEY_UP = 38
+var KEY_RIGHT = 39
+var KEY_DOWN = 40
+var KEYTRACK = {}
+KEYTRACK[KEY_LEFT] = false
+KEYTRACK[KEY_UP] = false
+KEYTRACK[KEY_RIGHT] = false
+KEYTRACK[KEY_DOWN] = false
+
+function clamp (x, min, max)
+ {
+ return Math.max(min, Math.min(x, max))
+ }
+function slope (a, b)
+ {
+ if (b[0] === a[0])
+ return 0
+ return (b[1] - a[1]) / (b[0] - a[0])
+ }
+var HUD =
+ {
+ div: document.createElement("div"),
+ surface: false,
+ msg: "",
+ update: function ()
+ {
+ var activity = Player.running ? "RUNNING" : ""
+ activity += Player.jumping ? " JUMPING" : ""
+ activity += Player.cannonball ? " CANNONBALL" : ""
+ activity += Player.underwater ? " UNDERWATER" : ""
+ var orientation = Player.orientation === ORIENTATION_RIGHT ? "RIGHT" : "LEFT"
+ HUD.div.innerHTML =
+ [
+ "",
+ "PLAYER", Math.floor(Player.x), Math.floor(Player.y), activity, orientation, "\n",
+ "SPEED ", Math.floor(Player.dx), Math.floor(Player.dy), HUD.surface, "\n",
+ "CANVAS", Canvas.x, Canvas.y, "\n",
+ "KEY_UP", KEYTRACK[KEY_UP], "\n",
+ "KEY_DOWN", KEYTRACK[KEY_DOWN], "\n",
+ "KEY_LEFT", KEYTRACK[KEY_LEFT], "\n",
+ "KEY_RIGHT", KEYTRACK[KEY_RIGHT], "\n",
+ "SCREEN", SCREEN_WIDTH, SCREEN_HEIGHT, SKY_OFFSET, "\n",
+ "LEFT", Player.surface_left, "\n",
+ "SURFACE", Player.surface, "\n",
+ "RIGHT", Player.surface_right, "\n",
+ HUD.msg,
+ ].join(" ")
+ },
+ init: function ()
+ {
+ HUD.div.style.position = "fixed"
+ HUD.div.style.top = 0
+ HUD.div.style.right = 0
+ HUD.div.style.width = 300 + "px"
+ HUD.div.style.height = 300 + "px"
+ HUD.div.setAttribute("id", "hud")
+ document.body.appendChild(HUD.div)
+ },
+ }
+var COLOR_SEABED = "#8380ab"
+var COLOR_SAND = "#cc995e"
+var COLOR_WATER = "#6666cc"
+var COLOR_MOUNTAIN = "#5a7035"
+var ISLAND_WIDTH = 1224
+var Terrain =
+ {
+ "left_island": function (x)
+ {
+ Canvas.background_elements.push
+ (
+ // x y width height src
+ [x, 0, 1224, 576, "landscape/island1bg.png", "flip"],
+ [x, 576, 1224, 1600, COLOR_SEABED]
+ )
+ Canvas.ground.push
+ (
+ [x+10, 10],
+ [x+150,-70],
+ [x+330,-90],
+ [x+1000,-90]
+ )
+ return 1224
+ },
+ "right_island": function (x)
+ {
+ Canvas.background_elements.push
+ (
+ [x, 0, 1224, 576, "landscape/island1bg.png"],
+ [x, 576, 1224, 1600, COLOR_SEABED]
+ )
+ Canvas.ground.push
+ (
+ [x,-90],
+ [x+700,-90],
+ [x+1000,-70],
+ [x+1200, 10]
+ )
+ return 1224
+ },
+ "ocean": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, width, 1000, COLOR_SEABED],
+ [x+width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+width, depth]
+ )
+ return width
+ },
+ "ocean_plaid": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, width, 1000, "landscape/scotch.gif",],
+ [x+width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+width, depth]
+ )
+ return width
+ },
+ "ocean_pit": function (x, width, depth)
+ {
+ floor_width = 800
+ pit_width = 700
+ depth = 800
+ pit_depth = 1800
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, floor_width, 1000, COLOR_SEABED],
+ [x+floor_width, WATER_OFFSET + pit_depth, pit_width, 1000, COLOR_SEABED],
+ [x+floor_width, WATER_OFFSET + pit_depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x+floor_width-200, WATER_OFFSET + depth, 200, 152, "landscape/watercorner.png", "flip_flop"],
+ [x+floor_width+pit_width-200, WATER_OFFSET + pit_depth - 152, 200, 152, "landscape/underwaterislandcorner.png", "flip"],
+ [x+floor_width+pit_width, WATER_OFFSET + depth, floor_width, 1000, COLOR_SEABED],
+ [x+floor_width+pit_width, WATER_OFFSET + depth, 200, 152, "landscape/watercorner.png", "flop"],
+ [x+floor_width+pit_width+floor_width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"],
+ [x + floor_width + 250, 1900, 230, 322, "guru2.gif"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+floor_width-10, depth],
+ [x+floor_width, pit_depth],
+ [x+floor_width+pit_width, pit_depth],
+ [x+floor_width+pit_width+10, depth],
+ [x+floor_width+pit_width+floor_width, depth]
+ )
+
+ return floor_width + pit_width + floor_width
+ },
+ "land": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ )
+ Canvas.ground.push
+ (
+ )
+ },
+ "first_island_foliage": function (x)
+ {
+ Canvas.foreground_elements.push(
+ [x, -34, 1224, 576, "landscape/island1fg.png"]
+ )
+ return 0
+ },
+ "second_island_foliage": function (x)
+ {
+ Canvas.foreground_elements.push(
+ [x+930, -34, 1224, 576, "landscape/island1fg.png", "flip"],
+ [x+750, -14, 722, 576, "landscape/island_bush.png", "flip"]
+ )
+ return 0
+ },
+ "tree_island_foliage": function (x)
+ {
+ Canvas.foreground_elements.push(
+ [x+280, -20, 199, 576, "landscape/palmtree.png", ],
+ [x+1750, 39, 722, 576, "landscape/island_bush.png", "flip"],
+ [x+2220, -40, 199, 576, "landscape/palmtree.png", "flip"],
+ [x+950, 39, 722, 576, "landscape/island_bush.png"],
+ [x+450, 64, 722, 576, "landscape/island_bush.png", "flip"],
+ [x+1720, -20, 199, 576, "landscape/palmtree.png", "flip"],
+ [x+1920, -34, 199, 576, "landscape/palmtree.png", "flip"]
+ )
+ return 0
+ },
+ "sequence":
+ [
+ ["first_island_foliage"],
+ ["right_island"],
+ ["ocean_pit", 1200, 600],
+ ["second_island_foliage"],
+ ["left_island"],
+ ["right_island"],
+ // ["ocean_plaid", 2000, 1000],
+ ["ocean", 2000, 1000],
+ ["tree_island_foliage"],
+ ["left_island"],
+ ["right_island"],
+ ["ocean", 2500, 950],
+ ["left_island"],
+ ],
+ parse_sequence: function ()
+ {
+ var x = 0
+ for (var i = 0; i < Terrain.sequence.length; i++)
+ {
+ var seq = Terrain.sequence[i]
+ if (seq.length === 3)
+ x += Terrain[seq[0]] (x, seq[1], seq[2])
+ else
+ x += Terrain[seq[0]] (x)
+ }
+ Canvas.width = x
+ },
+ }
+var Canvas =
+ {
+ div: document.createElement("canvas"),
+ background: document.createElement("div"),
+ foreground: document.createElement("div"),
+ water: document.createElement("div"),
+ seafloor: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: 2024+1224,
+ height: 3000,
+ surfaces: [],
+ ground: [],
+ calculate_surfaces: function ()
+ {
+ Terrain.parse_sequence ()
+ var calc = []
+ var one, two
+ for (var i = 1; i < Canvas.ground.length; i++)
+ {
+ two = Canvas.ground[i]
+ one = Canvas.ground[i-1]
+ calc.push([one[0], one[1]+FLOOR_OFFSET, two[0], two[1]+FLOOR_OFFSET, slope(one, two)])
+ }
+ calc.push([two[0], two[1]+FLOOR_OFFSET, Canvas.width, two[1]+FLOOR_OFFSET, slope(two, [Canvas.width, two[1]])])
+ Canvas.surfaces = calc
+ },
+ background_elements:
+ [
+ ],
+ foreground_elements:
+ [
+ // x, y, width, height, image
+ ],
+ init: function ()
+ {
+ Canvas.calculate_surfaces ()
+
+ Canvas.background.style.position = "fixed"
+ Canvas.background.style.top = 0 + "px"
+ Canvas.background.style.left = 0 + "px"
+ Canvas.background.style.width = Canvas.width + "px"
+ Canvas.background.style.height = Canvas.height + "px"
+ Canvas.background.setAttribute("id", "background")
+ document.body.appendChild(Canvas.background)
+
+ Canvas.foreground.style.position = "fixed"
+ Canvas.foreground.style.top = 0 + "px"
+ Canvas.foreground.style.left = 0 + "px"
+ Canvas.foreground.style.width = Canvas.width + "px"
+ Canvas.foreground.style.height = Canvas.height + "px"
+ Canvas.foreground.setAttribute("id", "foreground")
+ document.body.appendChild(Canvas.foreground)
+
+ Canvas.water.style.position = "fixed"
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + "px"
+ Canvas.water.style.left = 0 + "px"
+ Canvas.water.style.width = Canvas.width + "px"
+ Canvas.water.style.height = Canvas.height + "px"
+ Canvas.water.setAttribute("id", "water")
+ document.body.appendChild(Canvas.water)
+
+ Canvas.seafloor.style.position = "fixed"
+ Canvas.seafloor.style.top = SKY_OFFSET + SEAFLOOR_DEPTH + "px"
+ Canvas.seafloor.style.left = 0 + "px"
+ Canvas.seafloor.style.width = Canvas.width + "px"
+ Canvas.seafloor.style.height = Canvas.height + "px"
+ Canvas.seafloor.setAttribute("id", "seafloor")
+ document.body.appendChild(Canvas.seafloor)
+
+ ctx = Canvas.div.getContext("2d"),
+ Canvas.div.style.position = "fixed"
+ Canvas.div.style.top = 0
+ Canvas.div.style.left = 0
+ Canvas.div.setAttribute("width", Canvas.width+"px")
+ Canvas.div.setAttribute("height", Canvas.height+"px")
+ Canvas.div.setAttribute("id", "grid")
+ document.body.appendChild(Canvas.div)
+
+ ctx.beginPath()
+ for (var x = 0.5; x < Canvas.width; x += 10)
+ {
+ ctx.moveTo(x, 0)
+ ctx.lineTo(x, Canvas.height)
+ }
+ for (var y = 0.5; y < Canvas.height; y += 10)
+ {
+ ctx.moveTo(0, y)
+ ctx.lineTo(Canvas.width, y)
+ }
+ ctx.strokeStyle = "rgba(255,255,255,0.2)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, SKY_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, SKY_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, FLOOR_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, FLOOR_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ /*
+ ctx.fillStyle = "rgba(0,20,255,0.5)"
+ ctx.fillRect(0, Physics.water_level+0.5, Canvas.width, Canvas.height - Physics.water_level)
+ */
+
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var surface = Canvas.surfaces[i]
+ ctx.beginPath()
+ ctx.moveTo(surface[0] + 0.5, surface[1] + 0.5)
+ ctx.lineTo(surface[2] + 0.5, surface[3] + 0.5)
+ ctx.strokeStyle = "#0bf"
+ ctx.stroke()
+ }
+ for (var i = 0; i < Canvas.background_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.background, Canvas.background_elements[i]))
+ }
+ for (var i = 0; i < Canvas.foreground_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.foreground, Canvas.foreground_elements[i]))
+ }
+ },
+ }
+function Animation (parent, data)
+ {
+ this.data = data
+ this.active = false
+ var frame = 0
+ var frameDelay = 0
+ var orientation = ORIENTATION_RIGHT
+ var done = false
+ this.div = document.createElement("div")
+ this.div.style.backgroundImage = "url(" + data.src + ")"
+ $(this.div).hide()
+ this.div.style.width = data.width + "px"
+ this.div.style.height = data.height + "px"
+ this.rate = data.rate
+ parent.div.appendChild(this.div)
+ this.activate = function ()
+ {
+ done = false
+ frame = 0
+ $(parent.div).children().each(function(){ $(this).hide() })
+ $(this.div).show()
+ parent.div.style.backgroundPosition = "0px 0px"
+ parent.div.style.width = data.width + "px"
+ parent.div.style.height = data.height + "px"
+ parent.width = data.width
+ parent.height = data.height
+ parent.x_offset = data.x_offset
+ parent.y_offset = data.y_offset
+ parent.feet_offset = data.feet_offset
+ this.orient (parent.orientation)
+ }
+ this.orient = function (direction)
+ {
+ orientation = direction
+ if (direction === ORIENTATION_RIGHT)
+ parent.div.className = ""
+ else
+ parent.div.className = "flip"
+ }
+ this.animate = function ()
+ {
+ if (done)
+ return
+ if (this.rate > 1)
+ {
+ frameDelay -= 1
+ if (frameDelay > 0)
+ return
+ else
+ frameDelay = this.rate
+ }
+ this.div.style.backgroundPosition = "0px " + (-1 * data.delta * frame) + "px"
+ frame += 1
+ if (frame > data.frames)
+ {
+ if (! data.loop)
+ done = true
+ else
+ frame = 0
+ if (data.dispose)
+ $(this.div).hide()
+ }
+ if (this.data.callback)
+ this.data.callback ()
+ }
+ }
+function Furniture (container, row)
+ {
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ var div = document.createElement("div")
+ div.style.position = "fixed"
+ div.style.left = row[0] + "px"
+ div.style.top = SKY_OFFSET + row[1] + "px"
+ div.style.width = row[2] + "px"
+ div.style.height = row[3] + "px"
+ if (! row[4])
+ div.style.background = "transparent"
+ else if (row[4].substr(0,1) === "#")
+ div.style.background = row[4]
+ else
+ div.style.background = "url('" + row[4] + "')"
+ if (row.length === 6)
+ div.className = row[5]
+ container.appendChild(div)
+
+ // this.container = container
+ this.div = div
+ this.x = row[0]
+ this.y = row[1]
+ this.width = row[2]
+ this.height = row[3]
+ this.background = row[4]
+ this.update = function ()
+ {
+ this.div.style.top = SKY_OFFSET + this.y - Frustrum.y + "px"
+ this.div.style.left = this.x - Frustrum.x + "px"
+ }
+ }
+var Frustrum =
+ {
+ div: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ furniture: [],
+ sprites: [],
+ animating: true,
+ redraw: function ()
+ {
+ Canvas.div.style.top = Canvas.y - Frustrum.y + "px"
+ Canvas.div.style.left = Canvas.x - Frustrum.x + "px"
+
+ Player.div.style.top = Player.y + Player.y_offset - Frustrum.y + "px"
+ Player.div.style.left = Player.x + Player.x_offset - Frustrum.x + "px"
+
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + Canvas.y - Frustrum.y + "px"
+ Canvas.seafloor.style.top = SKY_OFFSET + WATER_OFFSET + SEAFLOOR_DEPTH + Canvas.y - Frustrum.y + "px"
+
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].update ()
+
+ // Frustrum.animating = ! Frustrum.animating
+ if (Frustrum.animating)
+ for (var i = 0; i < Frustrum.sprites.length; i++)
+ Frustrum.sprites[i].animation.animate ()
+ },
+ update: function ()
+ {
+ if (Player.underwater || Player.near_surface)
+ {
+ Frustrum.dest_y = Player.y - Frustrum.halfheight + Player.height
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth + Player.width
+ if (Player.y > Canvas.height - Frustrum.halfheight)
+ Frustrum.dest_y = Canvas.height - Frustrum.height
+ }
+ else
+ {
+ Frustrum.dest_x = 0
+ Frustrum.dest_y = 0
+ }
+ if (Player.x > Canvas.width - Frustrum.halfwidth)
+ Frustrum.dest_x = Canvas.width - Frustrum.width
+ else if (Player.x > Frustrum.halfwidth)
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth
+ Frustrum.y = Math.floor( (Frustrum.dest_y + Frustrum.y * 9) / 10 )
+ Frustrum.x = Math.floor( (Frustrum.dest_x + Frustrum.x * 9) / 10 )
+ // Frustrum.div.style.top = Frustrum.y + "px"
+ // Frustrum.div.style.left = Frustrum.x + "px"
+ },
+ init: function ()
+ {
+ Frustrum.div.style.position = "fixed"
+ Frustrum.div.style.top = 0
+ Frustrum.div.style.left = 0
+ Frustrum.div.style.width = Frustrum.width + "px"
+ Frustrum.div.style.height = Frustrum.height + "px"
+ Frustrum.div.setAttribute("id", "frustrum")
+ document.body.appendChild(Frustrum.div)
+ Frustrum.halfwidth = Frustrum.width/2
+ Frustrum.halfheight = Frustrum.height/2
+ },
+ }
+var Physics =
+ {
+ gravity: 5,
+ gravity_land: 5,
+ gravity_water: -3,
+ dx_walk: 25,
+ dx_swim: 20,
+ dx_swim_max: 40,
+ dy_swim_up: -25,
+ dy_swim_down: 25,
+ dy_resistance: 15,
+ dx_resistance: 15,
+ air_resistance: 15,
+ water_resistance: 8,
+ water_level: SKY_OFFSET + WATER_OFFSET,
+ jump_power: -35,
+ }
+var Player =
+ {
+ div: document.createElement("div"),
+ running: false,
+ jumping: false,
+ start_jump: false,
+ swimming_vertical: false,
+ swimming_horizontal: false,
+ cannonball: false,
+ diving: false,
+ orientation: ORIENTATION_RIGHT,
+ current_mode: 'idle',
+ modes: {},
+ dx: 0,
+ dy: 0,
+ x: 0,
+ y: 0,
+ exiting_water: 0,
+ width: 100,
+ height: 167,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+ yIntercept: 0,
+ surface: [0,0,0,0],
+ surface_left: [0,0,0,0],
+ surface_right: [0,0,0,0],
+ findNearestSurface: function (x, feet)
+ {
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var s = Canvas.surfaces[i]
+ if (Player.onSurface(x, feet, s) > BELOW_SURFACE)
+ {
+ Player.surface = s
+ Player.surface_right = Canvas.surfaces[i+1]
+ Player.surface_left = Canvas.surfaces[i-1]
+ }
+ }
+ return OFF_MAP
+ },
+ onSurface: function (x, feet, s)
+ {
+ if (s === OFF_MAP)
+ return OFF_MAP
+
+ // within bounds
+ if (x < s[0] || x > s[2])
+ return BEYOND_SURFACE
+
+ // above the line
+ if (s[1] === s[3])
+ {
+ Player.slope = 0
+ Player.yIntercept = s[1]
+ Player.yInterceptRight = s[1]
+ if (feet < s[1])
+ return ABOVE_SURFACE
+ if (feet <= s[1] + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ }
+ Player.slope = s[4]
+ Player.yIntercept = (x + Player.x_offset - s[0]) * Player.slope + s[1]
+ Player.yInterceptRight = (x + Player.width + Player.x_offset - s[0]) * Player.slope + s[1]
+
+ if (feet < Player.yIntercept - 1)
+ return ABOVE_SURFACE
+ if (feet <= Player.yIntercept + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ if (Player.surfaceState === ON_SURFACE)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ },
+ underwater: false,
+ update: function ()
+ {
+ var feet = Player.y + Player.height + Player.feet_offset
+ Player.feet = feet
+ Player.surfaceState = Player.onSurface(Player.x, feet, Player.surface)
+ switch (Player.surfaceState)
+ {
+ case ABOVE_SURFACE:
+ HUD.surface = "ABOVE SURFACE"
+ if (Player.underwater)
+ Player.dy = Math.min(Player.dy + Physics.gravity, Physics.dy_resistance)
+ else
+ Player.dy = Player.dy + Physics.gravity
+ if (Player.y + Player.dy + Player.height > Player.yIntercept)
+ {
+ Player.y = Player.yIntercept - Player.height
+ Player.dy = 0
+ Player.surfaceState = ON_SURFACE
+ }
+ break
+ case ON_SURFACE:
+ HUD.surface = "ON SURFACE"
+ if (Player.underwater)
+ {
+ Player.dy = Math.min(0, Player.dy)
+ if (Player.surface.slope === 0)
+ Player.y = Player.yIntercept - Player.height
+ }
+ else
+ {
+ Player.cannonball = false
+ Player.dy = 0
+ // partially underwater
+ if (Player.y + Player.height > FLOOR_OFFSET)
+ {
+ Player.y = Player.surface[1] - Player.height
+ }
+ else
+ Player.y = Player.yIntercept - Player.height
+ }
+ Player.jumping = false
+ break
+ case BELOW_SURFACE:
+ HUD.surface = "BELOW SURFACE"
+ Player.dy = 0
+ Player.y = Player.yIntercept - Player.height
+ Player.surfaceState = ON_SURFACE
+ break
+ case BEYOND_SURFACE:
+ HUD.surface = "BEYOND SURFACE"
+ Player.findNearestSurface(Player.x, feet)
+ Player.update()
+ break
+ case OFF_MAP:
+ HUD.surface = "OFF MAP"
+ break
+ }
+
+ if (Player.cannonball)
+ {
+ Player.diving = false
+ if (Player.y > Physics.water_level)
+ {
+ Player.cannonball = false
+ Splash.place(Player.x)
+ }
+ if (Player.yIntercept <= Physics.water_level)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ }
+ else if (! Player.underwater && Player.y > Physics.water_level)
+ {
+ Player.setAnimationSwim()
+ // Player.setAnimation ("swim")
+ Player.running = false
+ Player.jumping = false
+ Player.diving = false
+ Player.underwater = true
+ Physics.gravity = Physics.gravity_water
+ Splash.place(Player.x)
+ Player.cannonball = false
+ Player.yJump = Physics.water_level
+ Physics.dx_resistance = Physics.water_resistance
+ Physics.dy_resistance = Physics.water_resistance
+ }
+ else if (Player.underwater)
+ {
+ if (Player.y > Physics.water_level - SURFACE_THRESHOLD && Player.y < Physics.water_level + SURFACE_THRESHOLD && ! Player.swimming_vertical)
+ {
+ if (Player.dy > 0)
+ Player.dy += 1
+ else
+ Player.dy -= 1
+ Player.dy *= 1/10
+ Player.y = clamp(Player.y, Physics.water_level - SURFACE_THRESHOLD, Physics.water_level + SURFACE_THRESHOLD)
+ if (Player.y + Player.dy < Physics.water_level - SURFACE_THRESHOLD)
+ Player.dy *= -1
+ if (Player.y + Player.dy > Physics.water_level + SURFACE_THRESHOLD)
+ Player.dy *= -1
+ Player.near_surface = true
+ }
+ else if (Player.y < Physics.water_level)
+ {
+ Player.exiting_water = 60
+ Player.near_surface = false
+ Player.underwater = false
+ Player.cannonball = false
+ Player.diving = false
+ Physics.gravity = Physics.gravity_land
+ Physics.dx_resistance = Physics.air_resistance
+ Physics.dy_resistance = Physics.air_resistance
+ }
+ else
+ {
+ Player.near_surface = false
+ }
+ if (KEYTRACK[KEY_UP])
+ {
+ Player.dy = Physics.dy_swim_up
+ Player.swimming_vertical = true
+ }
+ else if (KEYTRACK[KEY_DOWN] && Player.surfaceState !== ON_SURFACE)
+ {
+ Player.dy = Physics.dy_swim_down
+ Player.swimming_vertical = true
+ }
+ else
+ {
+ Player.dy *= 9/10
+ Player.swimming_vertical = false
+ }
+ if (KEYTRACK[KEY_LEFT] || KEYTRACK[KEY_RIGHT])
+ {
+ Player.dx = Physics.dx_swim * Player.orientation
+ Player.swimming_horizontal = true
+ Player.setAnimationSwim()
+ Player.animation.rate = 2
+ }
+ else
+ {
+ Player.swimming_horizontal = false
+ Player.dx *= 9/10
+ Player.animation.rate = Math.min (Player.animation.rate + 0.01, 6)
+ Player.setAnimation("float")
+ }
+ if (Player.orientation === ORIENTATION_LEFT && Player.surface_left[4] > 2 && Player.x + Player.dx <= Player.surface_left[2])
+ {
+ if (Player.y + Player.height >= Player.surface_left[1])
+ {
+ Player.swimming_horizontal = false
+ Player.x = Player.surface_left[2]
+ Player.dx = 0
+ KEYTRACK[KEY_LEFT] = false
+ }
+ }
+ else if (Player.orientation === ORIENTATION_RIGHT && Player.surface_right[4] < -2 && Player.x + Player.width >= Player.surface_right[0])
+ {
+ if (Player.y + Player.height >= Player.surface_right[3])
+ {
+ Player.swimming_horizontal = false
+ Player.dx = 0
+ }
+ }
+ }
+ else if (Player.jumping && Player.yJump < Physics.water_level &&
+ ((Player.orientation === ORIENTATION_RIGHT && Player.yIntercept > Physics.water_level) ||
+ (Player.orientation === ORIENTATION_LEFT && Player.yInterceptRight > Physics.water_level)))
+ {
+ if (! Player.animations['dive'].active)
+ Player.setAnimation("cannonball")
+ Player.running = false
+ Player.jumping = false
+ Player.cannonball = true
+ Player.diving = false
+ }
+ else
+ {
+ if ((Player.start_jump || KEYTRACK[KEY_UP]) && Player.surfaceState === ON_SURFACE)
+ {
+ Player.start_jump = false
+ Player.jumping = true
+ Player.diving = false
+ Player.yJump = Player.y
+ Player.dy = Physics.jump_power
+ Player.y += Player.dy
+ Player.surfaceState = ABOVE_SURFACE
+ }
+ if (KEYTRACK[KEY_LEFT])
+ {
+ if (Player.exiting_water < 0 && Player.yIntercept > Physics.water_level || Player.diving)
+ {
+ if (! Player.diving && ! Player.cannonball && ! Player.jumping)
+ {
+ Player.setAnimation("dive")
+ Player.diving = true
+ }
+ }
+ else if (! Player.running)
+ {
+ Player.setAnimation("run")
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ if (Player.exiting_water < 0 && Player.yInterceptRight > Physics.water_level || Player.diving)
+ {
+ if (! Player.diving && ! Player.cannonball && ! Player.jumping)
+ {
+ Player.setAnimation("dive")
+ Player.diving = true
+ }
+ }
+ else if (! Player.running)
+ {
+ Player.setAnimation("run")
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else
+ {
+ if (Player.running)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ Player.dx = 0
+ }
+ }
+ Player.exiting_water -= 1
+ Player.y += Player.dy
+ Player.x += Player.dx
+ if (Player.x < 10)
+ {
+ if (Player.running)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ Player.dx = 0
+ Player.x = 10
+ }
+ else if (Player.x > Canvas.width-Player.width - 20)
+ {
+ if (Player.running)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ Player.dx = 0
+ Player.x = Canvas.width-Player.width - 20
+ }
+ },
+ lastSwitch: 0,
+ setAnimationSwim: function ()
+ {
+ if (Player.lastSwitch > 0)
+ {
+ Player.lastSwitch -= 1
+ return
+ }
+ Player.lastSwitch = 1
+ Player.setAnimation ("swim")
+ },
+ setAnimation: function (mode)
+ {
+ if (! Player.animations[mode].active)
+ {
+ Player.animations[Player.current_mode].active = false
+ Player.animations[mode].active = true
+ Player.current_mode = mode
+ Player.animation = Player.animations[mode]
+ Player.animation.activate ()
+ }
+ },
+ init: function ()
+ {
+ Player.x = PLAYER_START_X
+ Player.y = SKY_OFFSET + FLOOR_OFFSET - 350 - Player.height
+ Player.div.style.position = "fixed"
+ Player.div.style.top = Player.y + "px"
+ Player.div.style.left = Player.x + "px"
+ Player.div.style.width = Player.width + "px"
+ Player.div.style.height = Player.height + "px"
+ Player.div.setAttribute("id", "player")
+ Player.setAnimation(STARTING_MODE)
+ Player.running = false
+ document.body.appendChild(Player.div)
+ Frustrum.sprites.push (Player)
+ },
+ }
+var Events =
+ {
+ interval: false,
+ keydown: function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_UP:
+ if (Player.underwater || Player.jumping)
+ break
+ Player.start_jump = true
+ break
+ case KEY_LEFT:
+ Player.orientation = ORIENTATION_LEFT
+ Player.animation.orient (Player.orientation)
+ break
+ case KEY_RIGHT:
+ Player.orientation = ORIENTATION_RIGHT
+ Player.animation.orient (Player.orientation)
+ break
+ case 71: // "G"
+ $("#grid").toggle()
+ Player.div.style.border = "1px solid red"
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].div.style.border = "1px solid #0f0"
+ break
+ }
+ },
+ keyup: function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ },
+ blur: function ()
+ {
+ KEYTRACK[KEY_UP] = false
+ KEYTRACK[KEY_DOWN] = false
+ KEYTRACK[KEY_LEFT] = false
+ KEYTRACK[KEY_RIGHT] = false
+ Player.running = false
+ Player.dx = 0
+ },
+ loop: function ()
+ {
+ Player.update()
+ Frustrum.update()
+ Frustrum.redraw()
+ // HUD.update()
+ },
+ init: function ()
+ {
+ $(document).bind("keydown", Events.keydown)
+ $(document).bind("keyup", Events.keyup)
+ $(document).bind("blur", Events.blur)
+ Events.interval = setInterval(Events.loop, REFRESH_RATE)
+ },
+ }
+var Splash =
+ {
+ src: "sprites/splash2.png",
+ width: 200,
+ height: 134,
+ delta: 134,
+ frames: 7,
+ rate: 3,
+ loop: false,
+ dispose: true,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+
+ x: 0,
+ y: -134,
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ furniture: new Furniture (Canvas.foreground, [0, WATER_OFFSET - 127, 200, 134, false]),
+ animation: false,
+ div: false,
+ orientation: true,
+ place: function (x)
+ {
+ Splash.x = x - 30
+ Splash.furniture.x = x
+ Splash.orientation = ! Splash.orientation
+ if (Splash.orientation)
+ Splash.animation.orient(ORIENTATION_LEFT)
+ else
+ Splash.animation.orient(ORIENTATION_RIGHT)
+ Splash.animation.activate()
+ },
+ init: function ()
+ {
+ Splash.div = Splash.furniture.div
+ Splash.animation = new Animation (Splash, Splash)
+ Frustrum.furniture.push (Splash.furniture)
+ Frustrum.sprites.push (Splash)
+ },
+ }
+var Dialog =
+ {
+ box: false,
+ is_open: false,
+ width: 420,
+ open: function (x, y)
+ {
+ if (Dialog.is_open)
+ return
+ Dialog.x = x - 100
+ Dialog.furniture.x = x - 100
+ Dialog.y = y - 300
+ Dialog.furniture.x = y - 300
+ Dialog.box.innerHTML = Dudes.next_message()
+ $(Dialog.furniture.div).show(100)
+ Dialog.is_open = true
+ },
+ close: function ()
+ {
+ $(Dialog.furniture.div).hide(200)
+ Dialog.is_open = false
+ },
+ init: function ()
+ {
+ Dialog.furniture = new Furniture (Canvas.foreground, [Dialog.width, 0, 400, "auto", false])
+ var dialogbox = document.createElement("div")
+ dialogbox.style.display = "block"
+ dialogbox.style.width = Dialog.width + "px"
+ dialogbox.style.padding = "10px"
+ dialogbox.style.background = "#fff"
+ dialogbox.className = "dialog"
+ Dialog.box = dialogbox
+ Dialog.furniture.div.appendChild(dialogbox)
+ Dialog.close ()
+ },
+ }
+function Dude (x)
+ {
+ var dialog_open = false
+ this.width = 140
+ this.height = 231
+ this.x = x
+ this.y = 170
+ this.furniture = new Furniture (Canvas.background, [this.x, this.y, this.width, this.height, false])
+ this.div = this.furniture.div
+ this.dialog = function ()
+ {
+ if (Player.x > x - 200 && Player.x < x + 140 + 200)
+ {
+ dialog_open = true
+ Dialog.open (x, FLOOR_OFFSET - 280 - 231)
+ }
+ else if (dialog_open)
+ {
+ dialog_open = false
+ Dialog.close ()
+ }
+ }
+ this.animation = new Animation (this,
+ {
+ src: "sprites/manstandingsprite.png",
+ width: this.width,
+ height: this.height,
+ frames: 7,
+ rate: 1,
+ loop: true,
+ delta: 229,
+ x_offset: -10,
+ y_offset: 20,
+ feet_offset: 0,
+ callback: this.dialog,
+ })
+ Frustrum.furniture.push (this.furniture)
+ Frustrum.sprites.push (this)
+ this.animation.activate()
+ }
+var Dudes =
+ {
+ dudes: [],
+ last_message: 0,
+ next_message: function ()
+ {
+ var msg = Dudes.messages[Dudes.last_message]
+ while (true)
+ {
+ new_message = Math.floor( Math.random() * Dudes.messages.length )
+ if (new_message !== Dudes.last_message)
+ {
+ Dudes.last_message = new_message
+ break
+ }
+ }
+ return msg
+ },
+ messages:
+ [
+ "this place looks very elegant, but hard to penetrate",
+ "GEE WIZ!! THANKS!!",
+ // "a baby frog is not a frog, not a frog It's a tadpole Tadpole, tadpole Baby frog is called a ta-d-pole!",
+ "If all else fails use fire.",
+ "I NEVER DIE!!",
+ "you have <i>snazz</i>",
+ "It's taken me a long time to get in to the \"boss\" position.",
+ // "I know mark wahlberg.",
+ "And it's almost like...<i>whimsically abstract</i>...yet at the same time <i>conscious of its form</i>.",
+ "I'm supposed to be guarding the lake, but I prefer to just wander around",
+ "I think, therefore I am.",
+ "You have responded to me!!",
+ "These pools are where real heroes test their mettal.",
+ "She can slice me like a blowfish.",
+ // "Realizing failure, the robot has changed his name to Marvin and is feeling very depressed.",
+ "Again, you can find my picture in the dictionary, under the word \"ultimate.\"",
+ "It's just sooo over for you.",
+ "WOW! THE CAPTAIN OF THE DRAGONSHIP DESTINY! COME DROP ANCHOR IN MY HARBOR!",
+ "JUST A MINUTE, TOOTS!",
+ "WINNER HA. I've dropped logz that wuz bigger'n you.",
+ "Darkness...let it hold you in peace, like your mom's arms",
+ // "I just happened to watch these hippies fly into a rage. The hateful hippies...",
+ "TRY AGAIN TOMATO FACE!",
+ // "YOUR FLEAS CAN'T BEAT ME. I KNOW YOUR THOUGHTS.",
+ // "MY IMAGINATION KNOWS NO LIMIT...AH, MY NOSE IS ALMOST BLEEDING I FEEL SO HORNY!",
+ // "I HOPE I RUN ACROSS MY PARENTS OUT HERE. SURE WOULD FEEL GOOD TO RUN THOSE <I>FUN^#%RS</I> OVER.",
+ ],
+ init: function ()
+ {
+ var idxes = [850, 4200, 5400, 9400]
+ for (i in idxes)
+ {
+ Dudes.dudes.push( new Dude (idxes[i]) )
+ }
+ },
+ }
+STARTING_MODE = "idle"
+Player.animations =
+ {
+ "idle": new Animation (Player,
+ {
+ src: "sprites/manstandingsprite.png",
+ width: 140,
+ height: 231,
+ frames: 7,
+ rate: 1,
+ loop: true,
+ delta: 229,
+ x_offset: -10,
+ y_offset: 20,
+ feet_offset: 0,
+ }),
+ "run": new Animation (Player,
+ {
+ src: "sprites/manrunningsprite.png",
+ width: 140,
+ height: 214,
+ frames: 15,
+ loop: true,
+ rate: 1,
+ delta: 226,
+ x_offset: -5,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "jump": new Animation (Player,
+ {
+ src: "sprites/jumping2.png",
+ width: 140,
+ height: 214,
+ frames: 2,
+ loop: true,
+ rate: 2,
+ delta: 226,
+ x_offset: -5,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "cannonball": new Animation (Player,
+ {
+ src: "sprites/cannonball2.png",
+ width: 140,
+ height: 220,
+ frames: 4,
+ rate: 2,
+ loop: false,
+ delta: 230,
+ x_offset: -8,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "dive": new Animation (Player,
+ {
+ src: "sprites/diving2.png",
+ width: 280,
+ height: 207,
+ frames: 4,
+ rate: 2,
+ loop: false,
+ delta: 210,
+ x_offset: -8,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "swim": new Animation (Player,
+ {
+ src: "sprites/breaststroke3.png",
+ width: 320,
+ height: 177,
+ frames: 9,
+ rate: 2,
+ loop: true,
+ delta: 203,
+ x_offset: 0,
+ y_offset: -10,
+ feet_offset: 0,
+ }),
+ "float": new Animation (Player,
+ {
+ src: "sprites/float3.png",
+ width: 130,
+ height: 266,
+ frames: 8,
+ rate: 2,
+ loop: true,
+ delta: 266,
+ x_offset: 0,
+ y_offset: -37,
+ feet_offset: 0,
+ }),
+ }
+var Tests =
+ {
+ init: function ()
+ {
+ // $("#random_x").click(Tests.random_x)
+ },
+ }
+var Main =
+ {
+ init: function ()
+ {
+ // Tests.init()
+ Canvas.init()
+ Player.init()
+ Splash.init()
+ Frustrum.init()
+ // HUD.init()
+ Events.init()
+ Dudes.init ()
+ Dialog.init ()
+ },
+ }
+Main.init ()
+</script>
+</html>
+
diff --git a/guru.gif b/guru.gif
new file mode 100755
index 0000000..1800002
--- /dev/null
+++ b/guru.gif
Binary files differ
diff --git a/guru2.gif b/guru2.gif
new file mode 100755
index 0000000..b1caf81
--- /dev/null
+++ b/guru2.gif
Binary files differ
diff --git a/index.html b/index.html
new file mode 100755
index 0000000..739ee18
--- /dev/null
+++ b/index.html
@@ -0,0 +1,1393 @@
+<!doctype html>
+<html>
+<head><title>MEATHEADZ</title></head>
+<style type="text/css">
+*
+ {
+ // border: 1px solid red;
+ }
+body
+ {
+ background-color: #87CEEB;
+ overflow: hidden;
+ }
+#frustrum
+ {
+ z-index: 666;
+ }
+#player
+ {
+ z-index: 980;
+ }
+#grid
+ {
+ display: none;
+ z-index: 950;
+ }
+#water
+ {
+ z-index: 800;
+ background-color: #6666cc;
+ }
+#seafloor
+ {
+ z-index: 810;
+ background-color: #8380ab;
+ }
+#background
+ {
+ position: fixed;
+ overflow: visible;
+ z-index: 900;
+ }
+#foreground
+ {
+ overflow: visible;
+ z-index: 999;
+ }
+#hud
+ {
+ font-size: 14px;
+ font-family: monospace;
+ background-color: #333;
+ z-index: 1000;
+ color: #fff;
+ opacity: 0.7;
+ white-space: pre;
+ }
+#tests
+ {
+ position: fixed;
+ right: 400px;
+ z-index: 1001;
+ }
+.dialog
+ {
+ display: none
+ padding: 10px;
+ font-family: Courier New, monospace;
+ font-size: 28px;
+ font-weight: bold;
+ border: 2px solid black;
+ background-color: white;
+ }
+.flip
+ {
+ -moz-transform: scaleX(-1);
+ -o-transform: scaleX(-1);
+ -webkit-transform: scaleX(-1);
+ transform: scaleX(-1);
+ filter: FlipH;
+ -ms-filter: "FlipH";
+ }
+.flop
+ {
+ -moz-transform: scaleY(-1);
+ -o-transform: scaleY(-1);
+ -webkit-transform: scaleY(-1);
+ transform: scaleY(-1);
+ filter: FlipV;
+ -ms-filter: "FlipV";
+ }
+.flip_flop
+ {
+ -moz-transform: scaleX(-1) scaleY(-1);
+ -o-transform: scaleX(-1) scaleY(-1);
+ -webkit-transform: scaleX(-1) scaleY(-1);
+ transform: scaleX(-1) scaleY(-1);
+ filter: FlipV FlipH;
+ -ms-filter: "FlipV FlipH";
+ }
+</style>
+
+<body>
+</body>
+
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript">
+var SCREEN_WIDTH = $(window).width()
+var SCREEN_HEIGHT = $(window).height()
+var REFRESH_RATE = 40
+var ISLAND_HEIGHT = 576
+var WATER_OFFSET = 458
+var SKY_OFFSET = SCREEN_HEIGHT - ISLAND_HEIGHT
+var FLOOR_OFFSET = SKY_OFFSET + WATER_OFFSET
+var SEAFLOOR_DEPTH = 1800
+
+var PLAYER_START_X = 200
+
+var SURFACE_THRESHOLD = 10
+
+var ABOVE_SURFACE = 3
+var ON_SURFACE = 2
+var LANDING_ON_SURFACE = 1
+var BELOW_SURFACE = 0
+var BEYOND_SURFACE = -1
+var OFF_MAP = -2
+
+var ORIENTATION_RIGHT = 1
+var ORIENTATION_LEFT = -1
+
+var KEY_LEFT = 37
+var KEY_UP = 38
+var KEY_RIGHT = 39
+var KEY_DOWN = 40
+var KEYTRACK = {}
+KEYTRACK[KEY_LEFT] = false
+KEYTRACK[KEY_UP] = false
+KEYTRACK[KEY_RIGHT] = false
+KEYTRACK[KEY_DOWN] = false
+
+function clamp (x, min, max)
+ {
+ return Math.max(min, Math.min(x, max))
+ }
+function slope (a, b)
+ {
+ if (b[0] === a[0])
+ return 0
+ return (b[1] - a[1]) / (b[0] - a[0])
+ }
+var HUD =
+ {
+ div: document.createElement("div"),
+ surface: false,
+ msg: "",
+ update: function ()
+ {
+ var activity = Player.running ? "RUNNING" : ""
+ activity += Player.jumping ? " JUMPING" : ""
+ activity += Player.cannonball ? " CANNONBALL" : ""
+ activity += Player.underwater ? " UNDERWATER" : ""
+ var orientation = Player.orientation === ORIENTATION_RIGHT ? "RIGHT" : "LEFT"
+ HUD.div.innerHTML =
+ [
+ "",
+ "PLAYER", Math.floor(Player.x), Math.floor(Player.y), activity, orientation, "\n",
+ "SPEED ", Math.floor(Player.dx), Math.floor(Player.dy), HUD.surface, "\n",
+ "CANVAS", Canvas.x, Canvas.y, "\n",
+ "KEY_UP", KEYTRACK[KEY_UP], "\n",
+ "KEY_DOWN", KEYTRACK[KEY_DOWN], "\n",
+ "KEY_LEFT", KEYTRACK[KEY_LEFT], "\n",
+ "KEY_RIGHT", KEYTRACK[KEY_RIGHT], "\n",
+ "SCREEN", SCREEN_WIDTH, SCREEN_HEIGHT, SKY_OFFSET, "\n",
+ "LEFT", Player.surface_left, "\n",
+ "SURFACE", Player.surface, "\n",
+ "RIGHT", Player.surface_right, "\n",
+ HUD.msg,
+ ].join(" ")
+ },
+ init: function ()
+ {
+ HUD.div.style.position = "fixed"
+ HUD.div.style.top = 0
+ HUD.div.style.right = 0
+ HUD.div.style.width = 300 + "px"
+ HUD.div.style.height = 300 + "px"
+ HUD.div.setAttribute("id", "hud")
+ document.body.appendChild(HUD.div)
+ },
+ }
+var COLOR_SEABED = "#8380ab"
+var COLOR_SAND = "#cc995e"
+var COLOR_WATER = "#6666cc"
+var COLOR_MOUNTAIN = "#5a7035"
+var ISLAND_WIDTH = 1224
+var Terrain =
+ {
+ "left_island": function (x)
+ {
+ Canvas.background_elements.push
+ (
+ // x y width height src
+ [x, 0, 1224, 576, "landscape/island1bg.png", "flip"],
+ [x, 576, 1224, 1600, COLOR_SEABED]
+ )
+ Canvas.ground.push
+ (
+ [x+10, 10],
+ [x+150,-70],
+ [x+330,-90],
+ [x+1000,-90]
+ )
+ return 1224
+ },
+ "right_island": function (x)
+ {
+ Canvas.background_elements.push
+ (
+ [x, 0, 1224, 576, "landscape/island1bg.png"],
+ [x, 576, 1224, 1600, COLOR_SEABED]
+ )
+ Canvas.ground.push
+ (
+ [x,-90],
+ [x+700,-90],
+ [x+1000,-70],
+ [x+1200, 10]
+ )
+ return 1224
+ },
+ "ocean": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, width, 1000, COLOR_SEABED],
+ [x+width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+width, depth]
+ )
+ return width
+ },
+ "ocean_plaid": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, width, 1000, "landscape/scotch.gif",],
+ [x+width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+width, depth]
+ )
+ return width
+ },
+ "ocean_pit": function (x, width, depth)
+ {
+ floor_width = 800
+ pit_width = 700
+ depth = 800
+ pit_depth = 1800
+ Canvas.background_elements.push
+ (
+ [x, WATER_OFFSET + depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x, WATER_OFFSET + depth, floor_width, 1000, COLOR_SEABED],
+ [x+floor_width, WATER_OFFSET + pit_depth, pit_width, 1000, COLOR_SEABED],
+ [x+floor_width, WATER_OFFSET + pit_depth - 152, 200, 152, "landscape/underwaterislandcorner.png",],
+ [x+floor_width-200, WATER_OFFSET + depth, 200, 152, "landscape/watercorner.png", "flip_flop"],
+ [x+floor_width+pit_width-200, WATER_OFFSET + pit_depth - 152, 200, 152, "landscape/underwaterislandcorner.png", "flip"],
+ [x+floor_width+pit_width, WATER_OFFSET + depth, floor_width, 1000, COLOR_SEABED],
+ [x+floor_width+pit_width, WATER_OFFSET + depth, 200, 152, "landscape/watercorner.png", "flop"],
+ [x+floor_width+pit_width+floor_width-200, WATER_OFFSET+depth-152, 200, 152, "landscape/underwaterislandcorner.png", "flip"],
+ [x + floor_width + 250, 1900, 230, 322, "guru2.gif"]
+ )
+ Canvas.ground.push
+ (
+ [x, depth],
+ [x+floor_width-10, depth],
+ [x+floor_width, pit_depth],
+ [x+floor_width+pit_width, pit_depth],
+ [x+floor_width+pit_width+10, depth],
+ [x+floor_width+pit_width+floor_width, depth]
+ )
+
+ return floor_width + pit_width + floor_width
+ },
+ "land": function (x, width, depth)
+ {
+ Canvas.background_elements.push
+ (
+ )
+ Canvas.ground.push
+ (
+ )
+ },
+ "first_island_foliage": function (x)
+ {
+ Canvas.foreground_elements.push(
+ [x, -34, 1224, 576, "landscape/island1fg.png"]
+ )
+ return 0
+ },
+ "second_island_foliage": function (x)
+ {
+ Canvas.foreground_elements.push(
+ [x+930, -34, 1224, 576, "landscape/island1fg.png", "flip"],
+ [x+750, -14, 722, 576, "landscape/island_bush.png", "flip"]
+ )
+ return 0
+ },
+ "tree_island_foliage": function (x)
+ {
+ Canvas.foreground_elements.push(
+ [x+280, -20, 199, 576, "landscape/palmtree.png", ],
+ [x+1750, 39, 722, 576, "landscape/island_bush.png", "flip"],
+ [x+2220, -40, 199, 576, "landscape/palmtree.png", "flip"],
+ [x+950, 39, 722, 576, "landscape/island_bush.png"],
+ [x+450, 64, 722, 576, "landscape/island_bush.png", "flip"],
+ [x+1720, -20, 199, 576, "landscape/palmtree.png", "flip"],
+ [x+1920, -34, 199, 576, "landscape/palmtree.png", "flip"]
+ )
+ return 0
+ },
+ "sequence":
+ [
+ ["first_island_foliage"],
+ ["right_island"],
+ ["ocean", 2000, 1000],
+ ["second_island_foliage"],
+ ["left_island"],
+ ["right_island"],
+ // ["ocean_plaid", 2000, 1000],
+ ["ocean_pit", 1200, 600],
+ ["tree_island_foliage"],
+ ["left_island"],
+ ["right_island"],
+ ["ocean", 2500, 950],
+ ["left_island"],
+ ],
+ parse_sequence: function ()
+ {
+ var x = 0
+ for (var i = 0; i < Terrain.sequence.length; i++)
+ {
+ var seq = Terrain.sequence[i]
+ if (seq.length === 3)
+ x += Terrain[seq[0]] (x, seq[1], seq[2])
+ else
+ x += Terrain[seq[0]] (x)
+ }
+ Canvas.width = x
+ },
+ }
+var Canvas =
+ {
+ div: document.createElement("canvas"),
+ background: document.createElement("div"),
+ foreground: document.createElement("div"),
+ water: document.createElement("div"),
+ seafloor: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: 2024+1224,
+ height: 3000,
+ surfaces: [],
+ ground: [],
+ calculate_surfaces: function ()
+ {
+ Terrain.parse_sequence ()
+ var calc = []
+ var one, two
+ for (var i = 1; i < Canvas.ground.length; i++)
+ {
+ two = Canvas.ground[i]
+ one = Canvas.ground[i-1]
+ calc.push([one[0], one[1]+FLOOR_OFFSET, two[0], two[1]+FLOOR_OFFSET, slope(one, two)])
+ }
+ calc.push([two[0], two[1]+FLOOR_OFFSET, Canvas.width, two[1]+FLOOR_OFFSET, slope(two, [Canvas.width, two[1]])])
+ Canvas.surfaces = calc
+ },
+ background_elements:
+ [
+ ],
+ foreground_elements:
+ [
+ // x, y, width, height, image
+ ],
+ init: function ()
+ {
+ Canvas.calculate_surfaces ()
+
+ Canvas.background.style.position = "fixed"
+ Canvas.background.style.top = 0 + "px"
+ Canvas.background.style.left = 0 + "px"
+ Canvas.background.style.width = Canvas.width + "px"
+ Canvas.background.style.height = Canvas.height + "px"
+ Canvas.background.setAttribute("id", "background")
+ document.body.appendChild(Canvas.background)
+
+ Canvas.foreground.style.position = "fixed"
+ Canvas.foreground.style.top = 0 + "px"
+ Canvas.foreground.style.left = 0 + "px"
+ Canvas.foreground.style.width = Canvas.width + "px"
+ Canvas.foreground.style.height = Canvas.height + "px"
+ Canvas.foreground.setAttribute("id", "foreground")
+ document.body.appendChild(Canvas.foreground)
+
+ Canvas.water.style.position = "fixed"
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + "px"
+ Canvas.water.style.left = 0 + "px"
+ Canvas.water.style.width = Canvas.width + "px"
+ Canvas.water.style.height = Canvas.height + "px"
+ Canvas.water.setAttribute("id", "water")
+ document.body.appendChild(Canvas.water)
+
+ Canvas.seafloor.style.position = "fixed"
+ Canvas.seafloor.style.top = SKY_OFFSET + SEAFLOOR_DEPTH + "px"
+ Canvas.seafloor.style.left = 0 + "px"
+ Canvas.seafloor.style.width = Canvas.width + "px"
+ Canvas.seafloor.style.height = Canvas.height + "px"
+ Canvas.seafloor.setAttribute("id", "seafloor")
+ document.body.appendChild(Canvas.seafloor)
+
+ ctx = Canvas.div.getContext("2d"),
+ Canvas.div.style.position = "fixed"
+ Canvas.div.style.top = 0
+ Canvas.div.style.left = 0
+ Canvas.div.setAttribute("width", Canvas.width+"px")
+ Canvas.div.setAttribute("height", Canvas.height+"px")
+ Canvas.div.setAttribute("id", "grid")
+ document.body.appendChild(Canvas.div)
+
+ ctx.beginPath()
+ for (var x = 0.5; x < Canvas.width; x += 10)
+ {
+ ctx.moveTo(x, 0)
+ ctx.lineTo(x, Canvas.height)
+ }
+ for (var y = 0.5; y < Canvas.height; y += 10)
+ {
+ ctx.moveTo(0, y)
+ ctx.lineTo(Canvas.width, y)
+ }
+ ctx.strokeStyle = "rgba(255,255,255,0.2)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, SKY_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, SKY_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ ctx.beginPath()
+ ctx.moveTo(0, FLOOR_OFFSET+0.5)
+ ctx.lineTo(Canvas.width+0.5, FLOOR_OFFSET+0.5)
+ ctx.strokeStyle = "rgba(255,255,0,1)"
+ ctx.stroke()
+
+ /*
+ ctx.fillStyle = "rgba(0,20,255,0.5)"
+ ctx.fillRect(0, Physics.water_level+0.5, Canvas.width, Canvas.height - Physics.water_level)
+ */
+
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var surface = Canvas.surfaces[i]
+ ctx.beginPath()
+ ctx.moveTo(surface[0] + 0.5, surface[1] + 0.5)
+ ctx.lineTo(surface[2] + 0.5, surface[3] + 0.5)
+ ctx.strokeStyle = "#0bf"
+ ctx.stroke()
+ }
+ for (var i = 0; i < Canvas.background_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.background, Canvas.background_elements[i]))
+ }
+ for (var i = 0; i < Canvas.foreground_elements.length; i++)
+ {
+ Frustrum.furniture.push (new Furniture (Canvas.foreground, Canvas.foreground_elements[i]))
+ }
+ },
+ }
+function Animation (parent, data)
+ {
+ this.data = data
+ this.active = false
+ var frame = 0
+ var frameDelay = 0
+ var orientation = ORIENTATION_RIGHT
+ var done = false
+ this.div = document.createElement("div")
+ this.div.style.backgroundImage = "url(" + data.src + ")"
+ $(this.div).hide()
+ this.div.style.width = data.width + "px"
+ this.div.style.height = data.height + "px"
+ this.rate = data.rate
+ parent.div.appendChild(this.div)
+ this.activate = function ()
+ {
+ done = false
+ frame = 0
+ $(parent.div).children().each(function(){ $(this).hide() })
+ $(this.div).show()
+ parent.div.style.backgroundPosition = "0px 0px"
+ parent.div.style.width = data.width + "px"
+ parent.div.style.height = data.height + "px"
+ parent.width = data.width
+ parent.height = data.height
+ parent.x_offset = data.x_offset
+ parent.y_offset = data.y_offset
+ parent.feet_offset = data.feet_offset
+ this.orient (parent.orientation)
+ }
+ this.orient = function (direction)
+ {
+ orientation = direction
+ if (direction === ORIENTATION_RIGHT)
+ parent.div.className = ""
+ else
+ parent.div.className = "flip"
+ }
+ this.animate = function ()
+ {
+ if (done)
+ return
+ if (this.rate > 1)
+ {
+ frameDelay -= 1
+ if (frameDelay > 0)
+ return
+ else
+ frameDelay = this.rate
+ }
+ this.div.style.backgroundPosition = "0px " + (-1 * data.delta * frame) + "px"
+ frame += 1
+ if (frame > data.frames)
+ {
+ if (! data.loop)
+ done = true
+ else
+ frame = 0
+ if (data.dispose)
+ $(this.div).hide()
+ }
+ if (this.data.callback)
+ this.data.callback ()
+ }
+ }
+function Furniture (container, row)
+ {
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ var div = document.createElement("div")
+ div.style.position = "fixed"
+ div.style.left = row[0] + "px"
+ div.style.top = SKY_OFFSET + row[1] + "px"
+ div.style.width = row[2] + "px"
+ div.style.height = row[3] + "px"
+ if (! row[4])
+ div.style.background = "transparent"
+ else if (row[4].substr(0,1) === "#")
+ div.style.background = row[4]
+ else
+ div.style.background = "url('" + row[4] + "')"
+ if (row.length === 6)
+ div.className = row[5]
+ container.appendChild(div)
+
+ // this.container = container
+ this.div = div
+ this.x = row[0]
+ this.y = row[1]
+ this.width = row[2]
+ this.height = row[3]
+ this.background = row[4]
+ this.update = function ()
+ {
+ this.div.style.top = SKY_OFFSET + this.y - Frustrum.y + "px"
+ this.div.style.left = this.x - Frustrum.x + "px"
+ }
+ }
+var Frustrum =
+ {
+ div: document.createElement("div"),
+ x: 0,
+ y: 0,
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ furniture: [],
+ sprites: [],
+ animating: true,
+ redraw: function ()
+ {
+ Canvas.div.style.top = Canvas.y - Frustrum.y + "px"
+ Canvas.div.style.left = Canvas.x - Frustrum.x + "px"
+
+ Player.div.style.top = Player.y + Player.y_offset - Frustrum.y + "px"
+ Player.div.style.left = Player.x + Player.x_offset - Frustrum.x + "px"
+
+ Canvas.water.style.top = SKY_OFFSET + WATER_OFFSET + Canvas.y - Frustrum.y + "px"
+ Canvas.seafloor.style.top = SKY_OFFSET + WATER_OFFSET + SEAFLOOR_DEPTH + Canvas.y - Frustrum.y + "px"
+
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].update ()
+
+ // Frustrum.animating = ! Frustrum.animating
+ if (Frustrum.animating)
+ for (var i = 0; i < Frustrum.sprites.length; i++)
+ Frustrum.sprites[i].animation.animate ()
+ },
+ update: function ()
+ {
+ if (Player.underwater || Player.near_surface)
+ {
+ Frustrum.dest_y = Player.y - Frustrum.halfheight + Player.height
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth + Player.width
+ if (Player.y > Canvas.height - Frustrum.halfheight)
+ Frustrum.dest_y = Canvas.height - Frustrum.height
+ }
+ else
+ {
+ Frustrum.dest_x = 0
+ Frustrum.dest_y = 0
+ }
+ if (Player.x > Canvas.width - Frustrum.halfwidth)
+ Frustrum.dest_x = Canvas.width - Frustrum.width
+ else if (Player.x > Frustrum.halfwidth)
+ Frustrum.dest_x = Player.x - Frustrum.halfwidth
+ Frustrum.y = Math.floor( (Frustrum.dest_y + Frustrum.y * 9) / 10 )
+ Frustrum.x = Math.floor( (Frustrum.dest_x + Frustrum.x * 9) / 10 )
+ // Frustrum.div.style.top = Frustrum.y + "px"
+ // Frustrum.div.style.left = Frustrum.x + "px"
+ },
+ init: function ()
+ {
+ Frustrum.div.style.position = "fixed"
+ Frustrum.div.style.top = 0
+ Frustrum.div.style.left = 0
+ Frustrum.div.style.width = Frustrum.width + "px"
+ Frustrum.div.style.height = Frustrum.height + "px"
+ Frustrum.div.setAttribute("id", "frustrum")
+ document.body.appendChild(Frustrum.div)
+ Frustrum.halfwidth = Frustrum.width/2
+ Frustrum.halfheight = Frustrum.height/2
+ },
+ }
+var Physics =
+ {
+ gravity: 5,
+ gravity_land: 5,
+ gravity_water: -3,
+ dx_walk: 25,
+ dx_swim: 20,
+ dx_swim_max: 40,
+ dy_swim_up: -25,
+ dy_swim_down: 25,
+ dy_resistance: 15,
+ dx_resistance: 15,
+ air_resistance: 15,
+ water_resistance: 8,
+ water_level: SKY_OFFSET + WATER_OFFSET,
+ jump_power: -35,
+ }
+var Player =
+ {
+ div: document.createElement("div"),
+ running: false,
+ jumping: false,
+ start_jump: false,
+ swimming_vertical: false,
+ swimming_horizontal: false,
+ cannonball: false,
+ diving: false,
+ orientation: ORIENTATION_RIGHT,
+ current_mode: 'idle',
+ modes: {},
+ dx: 0,
+ dy: 0,
+ x: 0,
+ y: 0,
+ exiting_water: 0,
+ width: 100,
+ height: 167,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+ yIntercept: 0,
+ surface: [0,0,0,0],
+ surface_left: [0,0,0,0],
+ surface_right: [0,0,0,0],
+ findNearestSurface: function (x, feet)
+ {
+ for (var i = 0; i < Canvas.surfaces.length; i++)
+ {
+ var s = Canvas.surfaces[i]
+ if (Player.onSurface(x, feet, s) > BELOW_SURFACE)
+ {
+ Player.surface = s
+ Player.surface_right = Canvas.surfaces[i+1]
+ Player.surface_left = Canvas.surfaces[i-1]
+ }
+ }
+ return OFF_MAP
+ },
+ onSurface: function (x, feet, s)
+ {
+ if (s === OFF_MAP)
+ return OFF_MAP
+
+ // within bounds
+ if (x < s[0] || x > s[2])
+ return BEYOND_SURFACE
+
+ // above the line
+ if (s[1] === s[3])
+ {
+ Player.slope = 0
+ Player.yIntercept = s[1]
+ Player.yInterceptRight = s[1]
+ if (feet < s[1])
+ return ABOVE_SURFACE
+ if (feet <= s[1] + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ }
+ Player.slope = s[4]
+ Player.yIntercept = (x + Player.x_offset - s[0]) * Player.slope + s[1]
+ Player.yInterceptRight = (x + Player.width + Player.x_offset - s[0]) * Player.slope + s[1]
+
+ if (feet < Player.yIntercept - 1)
+ return ABOVE_SURFACE
+ if (feet <= Player.yIntercept + Player.dy + Physics.gravity + Player.height)
+ return ON_SURFACE
+ if (Player.surfaceState === ON_SURFACE)
+ return ON_SURFACE
+ // if (! Player.surface)
+ // return ON_SURFACE
+ return ON_SURFACE
+ // return BELOW_SURFACE
+ },
+ underwater: false,
+ update: function ()
+ {
+ var feet = Player.y + Player.height + Player.feet_offset
+ Player.feet = feet
+ Player.surfaceState = Player.onSurface(Player.x, feet, Player.surface)
+ switch (Player.surfaceState)
+ {
+ case ABOVE_SURFACE:
+ HUD.surface = "ABOVE SURFACE"
+ if (Player.underwater)
+ Player.dy = Math.min(Player.dy + Physics.gravity, Physics.dy_resistance)
+ else
+ Player.dy = Player.dy + Physics.gravity
+ if (Player.y + Player.dy + Player.height > Player.yIntercept)
+ {
+ Player.y = Player.yIntercept - Player.height
+ Player.dy = 0
+ Player.surfaceState = ON_SURFACE
+ }
+ break
+ case ON_SURFACE:
+ HUD.surface = "ON SURFACE"
+ if (Player.underwater)
+ {
+ Player.dy = Math.min(0, Player.dy)
+ if (Player.surface.slope === 0)
+ Player.y = Player.yIntercept - Player.height
+ }
+ else
+ {
+ Player.cannonball = false
+ Player.dy = 0
+ // partially underwater
+ if (Player.y + Player.height > FLOOR_OFFSET)
+ {
+ Player.y = Player.surface[1] - Player.height
+ }
+ else
+ Player.y = Player.yIntercept - Player.height
+ }
+ Player.jumping = false
+ break
+ case BELOW_SURFACE:
+ HUD.surface = "BELOW SURFACE"
+ Player.dy = 0
+ Player.y = Player.yIntercept - Player.height
+ Player.surfaceState = ON_SURFACE
+ break
+ case BEYOND_SURFACE:
+ HUD.surface = "BEYOND SURFACE"
+ Player.findNearestSurface(Player.x, feet)
+ Player.update()
+ break
+ case OFF_MAP:
+ HUD.surface = "OFF MAP"
+ break
+ }
+
+ if (Player.cannonball)
+ {
+ Player.diving = false
+ if (Player.y > Physics.water_level)
+ {
+ Player.cannonball = false
+ Splash.place(Player.x)
+ }
+ if (Player.yIntercept <= Physics.water_level)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ }
+ else if (! Player.underwater && Player.y > Physics.water_level)
+ {
+ Player.setAnimationSwim()
+ // Player.setAnimation ("swim")
+ Player.running = false
+ Player.jumping = false
+ Player.diving = false
+ Player.underwater = true
+ Physics.gravity = Physics.gravity_water
+ Splash.place(Player.x)
+ Player.cannonball = false
+ Player.yJump = Physics.water_level
+ Physics.dx_resistance = Physics.water_resistance
+ Physics.dy_resistance = Physics.water_resistance
+ }
+ else if (Player.underwater)
+ {
+ if (Player.y > Physics.water_level - SURFACE_THRESHOLD && Player.y < Physics.water_level + SURFACE_THRESHOLD && ! Player.swimming_vertical)
+ {
+ if (Player.dy > 0)
+ Player.dy += 1
+ else
+ Player.dy -= 1
+ Player.dy *= 1/10
+ Player.y = clamp(Player.y, Physics.water_level - SURFACE_THRESHOLD, Physics.water_level + SURFACE_THRESHOLD)
+ if (Player.y + Player.dy < Physics.water_level - SURFACE_THRESHOLD)
+ Player.dy *= -1
+ if (Player.y + Player.dy > Physics.water_level + SURFACE_THRESHOLD)
+ Player.dy *= -1
+ Player.near_surface = true
+ }
+ else if (Player.y < Physics.water_level)
+ {
+ Player.exiting_water = 60
+ Player.near_surface = false
+ Player.underwater = false
+ Player.cannonball = false
+ Player.diving = false
+ Physics.gravity = Physics.gravity_land
+ Physics.dx_resistance = Physics.air_resistance
+ Physics.dy_resistance = Physics.air_resistance
+ }
+ else
+ {
+ Player.near_surface = false
+ }
+ if (KEYTRACK[KEY_UP])
+ {
+ Player.dy = Physics.dy_swim_up
+ Player.swimming_vertical = true
+ }
+ else if (KEYTRACK[KEY_DOWN] && Player.surfaceState !== ON_SURFACE)
+ {
+ Player.dy = Physics.dy_swim_down
+ Player.swimming_vertical = true
+ }
+ else
+ {
+ Player.dy *= 9/10
+ Player.swimming_vertical = false
+ }
+ if (KEYTRACK[KEY_LEFT] || KEYTRACK[KEY_RIGHT])
+ {
+ Player.dx = Physics.dx_swim * Player.orientation
+ Player.swimming_horizontal = true
+ Player.setAnimationSwim()
+ Player.animation.rate = 2
+ }
+ else
+ {
+ Player.swimming_horizontal = false
+ Player.dx *= 9/10
+ Player.animation.rate = Math.min (Player.animation.rate + 0.01, 6)
+ Player.setAnimation("float")
+ }
+ if (Player.orientation === ORIENTATION_LEFT && Player.surface_left[4] > 2 && Player.x + Player.dx <= Player.surface_left[2])
+ {
+ if (Player.y + Player.height >= Player.surface_left[1])
+ {
+ Player.swimming_horizontal = false
+ Player.x = Player.surface_left[2]
+ Player.dx = 0
+ KEYTRACK[KEY_LEFT] = false
+ }
+ }
+ else if (Player.orientation === ORIENTATION_RIGHT && Player.surface_right[4] < -2 && Player.x + Player.width >= Player.surface_right[0])
+ {
+ if (Player.y + Player.height >= Player.surface_right[3])
+ {
+ Player.swimming_horizontal = false
+ Player.dx = 0
+ }
+ }
+ }
+ else if (Player.jumping && Player.yJump < Physics.water_level &&
+ ((Player.orientation === ORIENTATION_RIGHT && Player.yIntercept > Physics.water_level) ||
+ (Player.orientation === ORIENTATION_LEFT && Player.yInterceptRight > Physics.water_level)))
+ {
+ if (! Player.animations['dive'].active)
+ Player.setAnimation("cannonball")
+ Player.running = false
+ Player.jumping = false
+ Player.cannonball = true
+ Player.diving = false
+ }
+ else
+ {
+ if ((Player.start_jump || KEYTRACK[KEY_UP]) && Player.surfaceState === ON_SURFACE)
+ {
+ Player.start_jump = false
+ Player.jumping = true
+ Player.diving = false
+ Player.yJump = Player.y
+ Player.dy = Physics.jump_power
+ Player.y += Player.dy
+ Player.surfaceState = ABOVE_SURFACE
+ }
+ if (KEYTRACK[KEY_LEFT])
+ {
+ if (Player.exiting_water < 0 && Player.yIntercept > Physics.water_level || Player.diving)
+ {
+ if (! Player.diving && ! Player.cannonball && ! Player.jumping)
+ {
+ Player.setAnimation("dive")
+ Player.diving = true
+ }
+ }
+ else if (! Player.running)
+ {
+ Player.setAnimation("run")
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ if (Player.exiting_water < 0 && Player.yInterceptRight > Physics.water_level || Player.diving)
+ {
+ if (! Player.diving && ! Player.cannonball && ! Player.jumping)
+ {
+ Player.setAnimation("dive")
+ Player.diving = true
+ }
+ }
+ else if (! Player.running)
+ {
+ Player.setAnimation("run")
+ Player.running = true
+ }
+ Player.dx = Physics.dx_walk * Player.orientation
+ }
+ else
+ {
+ if (Player.running)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ Player.dx = 0
+ }
+ }
+ Player.exiting_water -= 1
+ Player.y += Player.dy
+ Player.x += Player.dx
+ if (Player.x < 10)
+ {
+ if (Player.running)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ Player.dx = 0
+ Player.x = 10
+ }
+ else if (Player.x > Canvas.width-Player.width - 20)
+ {
+ if (Player.running)
+ {
+ Player.setAnimation("idle")
+ Player.running = false
+ }
+ Player.dx = 0
+ Player.x = Canvas.width-Player.width - 20
+ }
+ },
+ lastSwitch: 0,
+ setAnimationSwim: function ()
+ {
+ if (Player.lastSwitch > 0)
+ {
+ Player.lastSwitch -= 1
+ return
+ }
+ Player.lastSwitch = 1
+ Player.setAnimation ("swim")
+ },
+ setAnimation: function (mode)
+ {
+ if (! Player.animations[mode].active)
+ {
+ Player.animations[Player.current_mode].active = false
+ Player.animations[mode].active = true
+ Player.current_mode = mode
+ Player.animation = Player.animations[mode]
+ Player.animation.activate ()
+ }
+ },
+ init: function ()
+ {
+ Player.x = PLAYER_START_X
+ Player.y = SKY_OFFSET + FLOOR_OFFSET - 350 - Player.height
+ Player.div.style.position = "fixed"
+ Player.div.style.top = Player.y + "px"
+ Player.div.style.left = Player.x + "px"
+ Player.div.style.width = Player.width + "px"
+ Player.div.style.height = Player.height + "px"
+ Player.div.setAttribute("id", "player")
+ Player.setAnimation(STARTING_MODE)
+ Player.running = false
+ document.body.appendChild(Player.div)
+ Frustrum.sprites.push (Player)
+ },
+ }
+var Events =
+ {
+ interval: false,
+ keydown: function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_UP:
+ if (Player.underwater || Player.jumping)
+ break
+ Player.start_jump = true
+ break
+ case KEY_LEFT:
+ Player.orientation = ORIENTATION_LEFT
+ Player.animation.orient (Player.orientation)
+ break
+ case KEY_RIGHT:
+ Player.orientation = ORIENTATION_RIGHT
+ Player.animation.orient (Player.orientation)
+ break
+ case 71: // "G"
+ $("#grid").toggle()
+ Player.div.style.border = "1px solid red"
+ for (var i = 0; i < Frustrum.furniture.length; i++)
+ Frustrum.furniture[i].div.style.border = "1px solid #0f0"
+ break
+ }
+ },
+ keyup: function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ },
+ blur: function ()
+ {
+ KEYTRACK[KEY_UP] = false
+ KEYTRACK[KEY_DOWN] = false
+ KEYTRACK[KEY_LEFT] = false
+ KEYTRACK[KEY_RIGHT] = false
+ Player.running = false
+ Player.dx = 0
+ },
+ loop: function ()
+ {
+ Player.update()
+ Frustrum.update()
+ Frustrum.redraw()
+ // HUD.update()
+ },
+ init: function ()
+ {
+ $(document).bind("keydown", Events.keydown)
+ $(document).bind("keyup", Events.keyup)
+ $(document).bind("blur", Events.blur)
+ Events.interval = setInterval(Events.loop, REFRESH_RATE)
+ },
+ }
+var Splash =
+ {
+ src: "sprites/splash2.png",
+ width: 200,
+ height: 134,
+ delta: 134,
+ frames: 7,
+ rate: 3,
+ loop: false,
+ dispose: true,
+ x_offset: 0,
+ y_offset: 0,
+ feet_offset: 0,
+
+ x: 0,
+ y: -134,
+ // 0 left 1 top 2 width 3 height 4 src 5 class
+ furniture: new Furniture (Canvas.foreground, [0, WATER_OFFSET - 127, 200, 134, false]),
+ animation: false,
+ div: false,
+ orientation: true,
+ place: function (x)
+ {
+ Splash.x = x - 30
+ Splash.furniture.x = x
+ Splash.orientation = ! Splash.orientation
+ if (Splash.orientation)
+ Splash.animation.orient(ORIENTATION_LEFT)
+ else
+ Splash.animation.orient(ORIENTATION_RIGHT)
+ Splash.animation.activate()
+ },
+ init: function ()
+ {
+ Splash.div = Splash.furniture.div
+ Splash.animation = new Animation (Splash, Splash)
+ Frustrum.furniture.push (Splash.furniture)
+ Frustrum.sprites.push (Splash)
+ },
+ }
+var Dialog =
+ {
+ box: false,
+ is_open: false,
+ width: 420,
+ open: function (x, y)
+ {
+ if (Dialog.is_open)
+ return
+ Dialog.x = x - 100
+ Dialog.furniture.x = x - 100
+ Dialog.y = y - 300
+ Dialog.furniture.x = y - 300
+ Dialog.box.innerHTML = Dudes.next_message()
+ $(Dialog.furniture.div).show(100)
+ Dialog.is_open = true
+ },
+ close: function ()
+ {
+ $(Dialog.furniture.div).hide(200)
+ Dialog.is_open = false
+ },
+ init: function ()
+ {
+ Dialog.furniture = new Furniture (Canvas.foreground, [Dialog.width, 0, 400, "auto", false])
+ var dialogbox = document.createElement("div")
+ dialogbox.style.display = "block"
+ dialogbox.style.width = Dialog.width + "px"
+ dialogbox.style.padding = "10px"
+ dialogbox.style.background = "#fff"
+ dialogbox.className = "dialog"
+ Dialog.box = dialogbox
+ Dialog.furniture.div.appendChild(dialogbox)
+ Dialog.close ()
+ },
+ }
+function Dude (x)
+ {
+ var dialog_open = false
+ this.width = 140
+ this.height = 231
+ this.x = x
+ this.y = 170
+ this.furniture = new Furniture (Canvas.background, [this.x, this.y, this.width, this.height, false])
+ this.div = this.furniture.div
+ this.dialog = function ()
+ {
+ if (Player.x > x - 200 && Player.x < x + 140 + 200)
+ {
+ dialog_open = true
+ Dialog.open (x, FLOOR_OFFSET - 280 - 231)
+ }
+ else if (dialog_open)
+ {
+ dialog_open = false
+ Dialog.close ()
+ }
+ }
+ this.animation = new Animation (this,
+ {
+ src: "sprites/manstandingsprite.png",
+ width: this.width,
+ height: this.height,
+ frames: 7,
+ rate: 1,
+ loop: true,
+ delta: 229,
+ x_offset: -10,
+ y_offset: 20,
+ feet_offset: 0,
+ callback: this.dialog,
+ })
+ Frustrum.furniture.push (this.furniture)
+ Frustrum.sprites.push (this)
+ this.animation.activate()
+ }
+var Dudes =
+ {
+ dudes: [],
+ last_message: 0,
+ next_message: function ()
+ {
+ var msg = Dudes.messages[Dudes.last_message]
+ while (true)
+ {
+ new_message = Math.floor( Math.random() * Dudes.messages.length )
+ if (new_message !== Dudes.last_message)
+ {
+ Dudes.last_message = new_message
+ break
+ }
+ }
+ return msg
+ },
+ messages:
+ [
+ "this place looks very elegant, but hard to penetrate",
+ "GEE WIZ!! THANKS!!",
+ // "a baby frog is not a frog, not a frog It's a tadpole Tadpole, tadpole Baby frog is called a ta-d-pole!",
+ "If all else fails use fire.",
+ "I NEVER DIE!!",
+ "you have <i>snazz</i>",
+ "It's taken me a long time to get in to the \"boss\" position.",
+ // "I know mark wahlberg.",
+ "And it's almost like...<i>whimsically abstract</i>...yet at the same time <i>conscious of its form</i>.",
+ "I'm supposed to be guarding the lake, but I prefer to just wander around",
+ "I think, therefore I am.",
+ "You have responded to me!!",
+ "These pools are where real heroes test their mettal.",
+ "She can slice me like a blowfish.",
+ // "Realizing failure, the robot has changed his name to Marvin and is feeling very depressed.",
+ "Again, you can find my picture in the dictionary, under the word \"ultimate.\"",
+ "It's just sooo over for you.",
+ "WOW! THE CAPTAIN OF THE DRAGONSHIP DESTINY! COME DROP ANCHOR IN MY HARBOR!",
+ "JUST A MINUTE, TOOTS!",
+ "WINNER HA. I've dropped logz that wuz bigger'n you.",
+ "Darkness...let it hold you in peace, like your mom's arms",
+ // "I just happened to watch these hippies fly into a rage. The hateful hippies...",
+ "TRY AGAIN TOMATO FACE!",
+ // "YOUR FLEAS CAN'T BEAT ME. I KNOW YOUR THOUGHTS.",
+ // "MY IMAGINATION KNOWS NO LIMIT...AH, MY NOSE IS ALMOST BLEEDING I FEEL SO HORNY!",
+ // "I HOPE I RUN ACROSS MY PARENTS OUT HERE. SURE WOULD FEEL GOOD TO RUN THOSE <I>FUN^#%RS</I> OVER.",
+ ],
+ init: function ()
+ {
+ var idxes = [850, 4200, 5400, 9400]
+ for (i in idxes)
+ {
+ Dudes.dudes.push( new Dude (idxes[i]) )
+ }
+ },
+ }
+STARTING_MODE = "idle"
+Player.animations =
+ {
+ "idle": new Animation (Player,
+ {
+ src: "sprites/manstandingsprite.png",
+ width: 140,
+ height: 231,
+ frames: 7,
+ rate: 1,
+ loop: true,
+ delta: 229,
+ x_offset: -10,
+ y_offset: 20,
+ feet_offset: 0,
+ }),
+ "run": new Animation (Player,
+ {
+ src: "sprites/manrunningsprite.png",
+ width: 140,
+ height: 214,
+ frames: 15,
+ loop: true,
+ rate: 1,
+ delta: 226,
+ x_offset: -5,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "jump": new Animation (Player,
+ {
+ src: "sprites/jumping2.png",
+ width: 140,
+ height: 214,
+ frames: 2,
+ loop: true,
+ rate: 2,
+ delta: 226,
+ x_offset: -5,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "cannonball": new Animation (Player,
+ {
+ src: "sprites/cannonball2.png",
+ width: 140,
+ height: 220,
+ frames: 4,
+ rate: 2,
+ loop: false,
+ delta: 230,
+ x_offset: -8,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "dive": new Animation (Player,
+ {
+ src: "sprites/diving2.png",
+ width: 280,
+ height: 207,
+ frames: 4,
+ rate: 2,
+ loop: false,
+ delta: 210,
+ x_offset: -8,
+ y_offset: 0,
+ feet_offset: 0,
+ }),
+ "swim": new Animation (Player,
+ {
+ src: "sprites/breaststroke3.png",
+ width: 320,
+ height: 177,
+ frames: 9,
+ rate: 2,
+ loop: true,
+ delta: 203,
+ x_offset: 0,
+ y_offset: -10,
+ feet_offset: 0,
+ }),
+ "float": new Animation (Player,
+ {
+ src: "sprites/float3.png",
+ width: 130,
+ height: 266,
+ frames: 8,
+ rate: 2,
+ loop: true,
+ delta: 266,
+ x_offset: 0,
+ y_offset: -37,
+ feet_offset: 0,
+ }),
+ }
+var Tests =
+ {
+ init: function ()
+ {
+ // $("#random_x").click(Tests.random_x)
+ },
+ }
+var Main =
+ {
+ init: function ()
+ {
+ // Tests.init()
+ Canvas.init()
+ Player.init()
+ Splash.init()
+ Frustrum.init()
+ // HUD.init()
+ Dudes.init ()
+ Dialog.init ()
+ Events.init()
+ },
+ }
+Main.init ()
+</script>
+</html>
+
diff --git a/jquery.gamequery-0.5.1.js b/jquery.gamequery-0.5.1.js
new file mode 100755
index 0000000..07b81ee
--- /dev/null
+++ b/jquery.gamequery-0.5.1.js
@@ -0,0 +1,1164 @@
+/*
+ * gameQuery rev. 0.5.1
+ *
+ * Copyright (c) 2008 Selim Arsever (gamequery.onaluf.org)
+ * licensed under the MIT (MIT-LICENSE.txt)
+ */
+// this allow to used the convenient $ notation in a plugins
+(function($) {
+
+ $.extend({ gameQuery: {
+ /**
+ * This is the Animation Object
+ */
+ Animation: function (options) {
+ // private default values
+ var defaults = {
+ imageURL: "",
+ numberOfFrame: 1,
+ delta: 0,
+ rate: 30,
+ type: 0,
+ distance: 0,
+ offsetx: 0,
+ offsety: 0
+ };
+
+ // options extends defaults
+ options = $.extend(defaults, options);
+
+ //"public" attributes:
+ this.imageURL = options.imageURL; // The url of the image to be used as an animation or sprite
+ this.numberOfFrame = options.numberOfFrame;// The number of frame to be displayed when playing the animation
+ this.delta = options.delta; // The the distance in pixels between two frame
+ this.rate = options.rate; // The rate at which the frame must be played in miliseconds
+ this.type = options.type; // The type of the animation.This is bitwise OR of the properties.
+ this.distance = options.distance; // The the distance in pixels between two animation
+ this.offsetx = options.offsetx; // The x coordinate where the first sprite begin
+ this.offsety = options.offsety; // The y coordinate where the first sprite begin
+
+ //Whenever a new animation is created we add it to the ResourceManager animation list
+ $.gameQuery.resourceManager.addAnimation(this);
+
+ return true;
+ },
+
+ // "constants" for the different type of an animation
+ ANIMATION_VERTICAL: 1, // genertated by a verical offset of the background
+ ANIMATION_HORIZONTAL: 2, // genertated by a horizontal offset of the background
+ ANIMATION_ONCE: 4, // played only once (else looping indefinitly)
+ ANIMATION_CALLBACK: 8, // A callack is exectued at the end of a cycle
+ ANIMATION_MULTI: 16, // The image file contains many animations
+
+ // "constants" for the different type of geometry for a sprite
+ GEOMETRY_RECTANGLE: 1,
+ GEOMETRY_DISC: 2,
+
+ // basic values
+ refreshRate: 30,
+
+ /**
+ * An object to manages the resources loading
+ **/
+ resourceManager: {
+ animations: [], // List of animation / images used in the game
+ sounds: [], // List of sounds used in the game
+ callbacks: [], // List of the functions called at each refresh
+ running: false, // State of the game,
+
+ /**
+ * This function the covers things to load befor to start the game.
+ **/
+ preload: function() {
+ //Start loading the images
+ for (var i = this.animations.length-1 ; i >= 0; i --){
+ this.animations[i].domO = new Image();
+ this.animations[i].domO.src = this.animations[i].imageURL;
+ }
+
+ //Start loading the sounds
+ for (var i = this.sounds.length-1 ; i >= 0; i --){
+ this.sounds[i].load();
+ }
+
+ $.gameQuery.resourceManager.waitForResources();
+ },
+
+ /**
+ * This function the waits for all the resources called for in preload() to finish loading.
+ **/
+ waitForResources: function() {
+ var loadbarEnabled = ($.gameQuery.loadbar != undefined);
+ if(loadbarEnabled){
+ $($.gameQuery.loadbar.id).width(0);
+ var loadBarIncremant = $.gameQuery.loadbar.width / (this.animations.length + this.sounds.length);
+ }
+ //check the images
+ var imageCount = 0;
+ for(var i=0; i < this.animations.length; i++){
+ if(this.animations[i].domO.complete){
+ imageCount++;
+ }
+ }
+ //check the sounds
+ var soundCount = 0;
+ for(var i=0; i < this.sounds.length; i++){
+ var temp = this.sounds[i].ready();
+ if(temp){
+ soundCount++;
+ }
+ }
+ //update the loading bar
+ if(loadbarEnabled){
+ $("#"+$.gameQuery.loadbar.id).width((imageCount+soundCount)*loadBarIncremant);
+ if($.gameQuery.loadbar.callback){
+ $.gameQuery.loadbar.callback((imageCount+soundCount)/(this.animations.length + this.sounds.length)*100);
+ }
+ }
+ if($.gameQuery.resourceManager.loadCallback){
+ var percent = (imageCount+soundCount)/(this.animations.length + this.sounds.length)*100;
+ $.gameQuery.resourceManager.loadCallback(percent);
+ }
+ if(imageCount + soundCount < (this.animations.length + this.sounds.length)){
+ imgWait=setTimeout(function () {
+ $.gameQuery.resourceManager.waitForResources();
+ }, 100);
+ } else {
+ // all the resources are loaded!
+ // We can associate the animation's images to their coresponding sprites
+ $.gameQuery.sceengraph.children().each(function(){
+ // recursive call on the children:
+ $(this).children().each(arguments.callee);
+ // add the image as a background
+ if(this.gameQuery && this.gameQuery.animation){
+ $(this).css("background-image", "url("+this.gameQuery.animation.imageURL+")");
+ // we set the correct kind of repeat
+ if(this.gameQuery.animation.type & $.gameQuery.ANIMATION_VERTICAL) {
+ $(this).css("background-repeat", "repeat-x");
+ } else if(this.gameQuery.animation.type & $.gameQuery.ANIMATION_HORIZONTAL) {
+ $(this).css("background-repeat", "repeat-y");
+ } else {
+ $(this).css("background-repeat", "no-repeat");
+ }
+ }
+ });
+
+ // And launch the refresh loop
+ $.gameQuery.resourceManager.running = true;
+ setInterval(function () {
+ $.gameQuery.resourceManager.refresh();
+ },($.gameQuery.refreshRate));
+ if($.gameQuery.startCallback){
+ $.gameQuery.startCallback();
+ }
+ //make the sceengraph visible
+ $.gameQuery.sceengraph.css("visibility","visible");
+ }
+ },
+
+ /**
+ * This function refresh a unique sprite here 'this' represent a dom object
+ **/
+ refreshSprite: function() {
+ //Call this function on all the children:
+ // is 'this' a sprite ?
+ if(this.gameQuery != undefined){
+ var gameQuery = this.gameQuery;
+ // does 'this' has an animation ?
+ if(gameQuery.animation){
+ //Do we have anything to do?
+ if(gameQuery.idleCounter == gameQuery.animation.rate-1){
+ // does 'this' loops?
+ if(gameQuery.animation.type & $.gameQuery.ANIMATION_ONCE){
+ if(gameQuery.currentFrame < gameQuery.animation.numberOfFrame-2){
+ gameQuery.currentFrame++;
+ } else if(gameQuery.currentFrame == gameQuery.animation.numberOfFrame-2) {
+ gameQuery.currentFrame++;
+ // does 'this' has a callback ?
+ if(gameQuery.animation.type & $.gameQuery.ANIMATION_CALLBACK){
+ if($.isFunction(gameQuery.callback)){
+ gameQuery.callback(this);
+ }
+ }
+ }
+ } else {
+ gameQuery.currentFrame = (gameQuery.currentFrame+1)%gameQuery.animation.numberOfFrame;
+ if(gameQuery.currentFrame == 0){
+ // does 'this' has a callback ?
+ if(gameQuery.animation.type & $.gameQuery.ANIMATION_CALLBACK){
+ if($.isFunction(gameQuery.callback)){
+ gameQuery.callback(this);
+ }
+ }
+ }
+ }
+ // update the background:
+ if(gameQuery.animation.type & $.gameQuery.ANIMATION_VERTICAL){
+ if(gameQuery.multi){
+ $(this).css("background-position",""+(-gameQuery.animation.offsetx-gameQuery.multi)+"px "+(-gameQuery.animation.offsety-gameQuery.animation.delta*gameQuery.currentFrame)+"px");
+ } else {
+ $(this).css("background-position",""+(-gameQuery.animation.offsetx)+"px "+(-gameQuery.animation.offsety-gameQuery.animation.delta*gameQuery.currentFrame)+"px");
+ }
+ } else if(gameQuery.animation.type & $.gameQuery.ANIMATION_HORIZONTAL) {
+ if(gameQuery.multi){
+ $(this).css("background-position",""+(-gameQuery.animation.offsetx-gameQuery.animation.delta*gameQuery.currentFrame)+"px "+(-gameQuery.animation.offsety-gameQuery.multi)+"px");
+ } else {
+ $(this).css("background-position",""+(-gameQuery.animation.offsetx-gameQuery.animation.delta*gameQuery.currentFrame)+"px "+(-gameQuery.animation.offsety)+"px");
+ }
+ }
+ }
+ gameQuery.idleCounter = (gameQuery.idleCounter+1)%gameQuery.animation.rate;
+ }
+ }
+ return true;
+ },
+
+ /**
+ * This function refresh a unique tile-map here 'this' represent a dom object
+ **/
+ refreshTilemap: function() {
+ //Call this function on all the children:
+ // is 'this' a sprite ?
+ if(this.gameQuery != undefined){
+ var gameQuery = this.gameQuery;
+ if($.isArray(gameQuery.frameTracker)){
+ for(var i=0; i<gameQuery.frameTracker.length; i++){
+ //Do we have anything to do?
+ if(gameQuery.idleCounter[i] == gameQuery.animations[i].rate-1){
+ // does 'this' loops?
+ if(gameQuery.animations[i].type & $.gameQuery.ANIMATION_ONCE){
+ if(gameQuery.frameTracker[i] < gameQuery.animations[i].numberOfFrame-1){
+ gameQuery.frameTracker[i]++;
+ }
+ } else {
+ gameQuery.frameTracker[i] = (gameQuery.frameTracker[i]+1)%gameQuery.animations[i].numberOfFrame;
+ }
+ }
+ gameQuery.idleCounter[i] = (gameQuery.idleCounter[i]+1)%gameQuery.animations[i].rate;
+ }
+ } else {
+ //Do we have anything to do?
+ if(gameQuery.idleCounter == gameQuery.animations.rate-1){
+ // does 'this' loops?
+ if(gameQuery.animations.type & $.gameQuery.ANIMATION_ONCE){
+ if(gameQuery.frameTracker < gameQuery.animations.numberOfFrame-1){
+ gameQuery.frameTracker++;
+ }
+ } else {
+ gameQuery.frameTracker = (gameQuery.frameTracker+1)%gameQuery.animations.numberOfFrame;
+ }
+ }
+ gameQuery.idleCounter = (gameQuery.idleCounter+1)%gameQuery.animations.rate;
+ }
+
+
+ // update the background of all active tiles:
+ $(this).find(".active").each(function(){
+ if($.isArray(gameQuery.frameTracker)){
+ var animationNumber = this.gameQuery.animationNumber
+ if(gameQuery.animations[animationNumber].type & $.gameQuery.ANIMATION_VERTICAL){
+ $(this).css("background-position",""+(-gameQuery.animations[animationNumber].offsetx)+"px "+(-gameQuery.animations[animationNumber].offsety-gameQuery.animations[animationNumber].delta*gameQuery.frameTracker[animationNumber])+"px");
+ } else if(gameQuery.animations[animationNumber].type & $.gameQuery.ANIMATION_HORIZONTAL) {
+ $(this).css("background-position",""+(-gameQuery.animations[animationNumber].offsetx-gameQuery.animations[animationNumber].delta*gameQuery.frameTracker[animationNumber])+"px "+(-gameQuery.animations[animationNumber].offsety)+"px");
+ }
+ } else {
+ if(gameQuery.animations.type & $.gameQuery.ANIMATION_VERTICAL){
+ $(this).css("background-position",""+(-gameQuery.animations.offsetx-this.gameQuery.multi)+"px "+(-gameQuery.animations.offsety-gameQuery.animations.delta*gameQuery.frameTracker)+"px");
+ } else if(gameQuery.animations.type & $.gameQuery.ANIMATION_HORIZONTAL) {
+ $(this).css("background-position",""+(-gameQuery.animations.offsetx-gameQuery.animations.delta*gameQuery.frameTracker)+"px "+(-gameQuery.animations.offsety-this.gameQuery.multi)+"px");
+ }
+ }
+ });
+ }
+ return true;
+ },
+
+ /**
+ * This function is called periodically to refresh the state of the game.
+ **/
+ refresh: function() {
+ $.gameQuery.playground.find(".sprite").each(this.refreshSprite);
+ $.gameQuery.playground.find(".tileSet").each(this.refreshTilemap);
+ var deadCallback= new Array();
+ for (var i = this.callbacks.length-1; i >= 0; i--){
+ if(this.callbacks[i].idleCounter == this.callbacks[i].rate-1){
+ var returnedValue = this.callbacks[i].fn();
+ if(typeof returnedValue == 'boolean'){
+ // if we have a boolean: 'true' means 'no more execution', 'false' means 'execute once more'
+ if(returnedValue){
+ deadCallback.push(i);
+ }
+ } else if(typeof returnedValue == 'number') {
+ // if we have a number it re-defines the time to the nex call
+ this.callbacks[i].rate = Math.round(returnedValue/$.gameQuery.refreshRate);
+ this.callbacks[i].idleCounter = 0;
+ }
+ }
+ this.callbacks[i].idleCounter = (this.callbacks[i].idleCounter+1)%this.callbacks[i].rate;
+ }
+ for(var i = deadCallback.length-1; i >= 0; i--){
+ this.callbacks.splice(deadCallback[i],1);
+ }
+ },
+
+ addAnimation: function(animation) {
+ if($.inArray(animation,this.animations)<0){
+ //normalize the animationRate:
+ animation.rate = Math.round(animation.rate/$.gameQuery.refreshRate);
+ if(animation.rate==0){
+ animation.rate = 1;
+ }
+ this.animations.push(animation);
+ }
+ },
+
+ addSound: function(sound){
+ if($.inArray(sound,this.sounds)<0){
+ this.sounds.push(sound);
+ }
+ },
+
+
+ registerCallback: function(fn, rate){
+ rate = Math.round(rate/$.gameQuery.refreshRate);
+ if(rate==0){
+ rate = 1;
+ }
+ this.callbacks.push({fn: fn, rate: rate, idleCounter: 0});
+ }
+ },
+
+ // This is a single place to update the underlying data of sprites/groups/tiles
+ update: function(descriptor, transformation) {
+ // Did we really recieve a descriptor or a jQuery object instead?
+ if(!$.isPlainObject(descriptor)){
+ // Then we must get real descriptor
+ if(descriptor.length > 0){
+ var gameQuery = descriptor[0].gameQuery;
+ } else {
+ var gameQuery = descriptor.gameQuery;
+ }
+ } else {
+ var gameQuery = descriptor;
+ }
+ // If we couldn't find one we return
+ if(!gameQuery) return;
+ if(gameQuery.tileSet === true){
+ //then we have a tilemap!
+ descriptor = $(descriptor);
+ // find the tilemap offset relatif to the playground:
+ var playgroundOffset = $.gameQuery.playground.offset();
+ var tileSetOffset = descriptor.offset();
+ tileSetOffset = {top: tileSetOffset.top - playgroundOffset.top, left: tileSetOffset.left - playgroundOffset.left};
+ // test what kind of transformation we have and react accordingly:
+ // Update the descriptor
+ for(property in transformation){
+ switch(property){
+ case "left":
+ //Do we need to activate/desactive the first/last column
+ var left = parseFloat(transformation.left);
+ //Get the tileSet offset (relatif to the playground)
+ var playgroundOffset = $.gameQuery.playground.offset();
+ var tileSetOffset = descriptor.parent().offset();
+ tileSetOffset = {top: tileSetOffset.top - playgroundOffset.top, left: tileSetOffset.left + left - playgroundOffset.left};
+
+ //actvates the visible tiles
+ var firstColumn = Math.max(Math.min(Math.floor(-tileSetOffset.left/gameQuery.width), gameQuery.sizex),0);
+ var lastColumn = Math.max(Math.min(Math.ceil(($.gameQuery.playground[0].width-tileSetOffset.left)/gameQuery.width), gameQuery.sizex),0);
+
+ for(var i = gameQuery.firstRow; i < gameQuery.lastRow; i++){
+ // if old first col < new first col
+ // deactivate the newly invisible tiles
+ for(var j = gameQuery.firstColumn; j < firstColumn ; j++) {
+ $("#tile_"+descriptor.attr("id")+"_"+i+"_"+j).removeClass("active");
+ }
+ //and activate the newly visible tiles
+ for(var j = gameQuery.lastColumn; j < lastColumn ; j++) {
+ $("#tile_"+descriptor.attr("id")+"_"+i+"_"+j).addClass("active");
+ }
+
+ // if old first col > new first col
+ // deactivate the newly invisible tiles
+ for(var j = lastColumn; j < gameQuery.lastColumn ; j++) {
+ $("#tile_"+descriptor.attr("id")+"_"+i+"_"+j).removeClass("active");
+ }
+ //activate the newly visible tiles
+ for(var j = firstColumn; j < gameQuery.firstColumn ; j++) {
+ $("#tile_"+descriptor.attr("id")+"_"+i+"_"+j).addClass("active");
+ }
+ }
+
+ gameQuery.firstColumn = firstColumn;
+ gameQuery.lastColumn = lastColumn;
+ break;
+ case "top":
+ //Do we need to activate/desactive the first/last row
+ var top = parseFloat(transformation.top);
+ //Get the tileSet offset (relatif to the playground)
+ var playgroundOffset = $.gameQuery.playground.offset();
+ var tileSetOffset = descriptor.parent().offset();
+ tileSetOffset = {top: tileSetOffset.top + top - playgroundOffset.top, left: tileSetOffset.left - playgroundOffset.left};
+
+ //actvates the visible tiles
+ var firstRow = Math.max(Math.min(Math.floor(-tileSetOffset.top/gameQuery.height), gameQuery.sizey), 0);
+ var lastRow = Math.max(Math.min(Math.ceil(($.gameQuery.playground[0].height-tileSetOffset.top)/gameQuery.height), gameQuery.sizey), 0);
+
+
+ for(var j = gameQuery.firstColumn; j < gameQuery.lastColumn ; j++) {
+ // if old first row < new first row
+ // deactivate the newly invisible tiles
+ for(var i = gameQuery.firstRow; i < firstRow; i++){
+ $("#tile_"+descriptor.attr("id")+"_"+i+"_"+j).removeClass("active");
+ }
+ //and activate the newly visible tiles
+ for(var i = gameQuery.lastRow; i < lastRow; i++){
+ $("#tile_"+descriptor.attr("id")+"_"+i+"_"+j).addClass("active");
+ }
+
+ // if old first row < new first row
+ // deactivate the newly invisible tiles
+ for(var i = lastRow; i < gameQuery.lastRow; i++){
+ $("#tile_"+descriptor.attr("id")+"_"+i+"_"+j).removeClass("active");
+ }
+ //and activate the newly visible tiles
+ for(var i = firstRow; i < gameQuery.firstRow; i++){
+ $("#tile_"+descriptor.attr("id")+"_"+i+"_"+j).addClass("active");
+ }
+ }
+
+ gameQuery.firstRow = firstRow;
+ gameQuery.lastRow = lastRow;
+
+ break;
+ case "angle": //(in degree)
+ //TODO
+ break;
+ case "factor":
+ //TODO
+ break;
+ }
+ }
+
+ } else {
+ var refreshBoundingCircle = $.gameQuery.playground && !$.gameQuery.playground.disableCollision;
+
+ // Update the descriptor
+ for(property in transformation){
+ switch(property){
+ case "left":
+ gameQuery.posx = parseFloat(transformation.left);
+ if(refreshBoundingCircle){
+ gameQuery.boundingCircle.x = gameQuery.posx+gameQuery.width/2;
+ }
+ break;
+ case "top":
+ gameQuery.posy = parseFloat(transformation.top);
+ if(refreshBoundingCircle){
+ gameQuery.boundingCircle.y = gameQuery.posy+gameQuery.height/2;
+ }
+ break;
+ case "width":
+ gameQuery.width = parseFloat(transformation.width);
+ break;
+ case "height":
+ gameQuery.height = parseFloat(transformation.height);
+ break;
+ case "angle": //(in degree)
+ gameQuery.angle = parseFloat(transformation.angle);
+ break;
+ case "factor":
+ gameQuery.factor = parseFloat(transformation.factor);
+ if(refreshBoundingCircle){
+ gameQuery.boundingCircle.radius = gameQuery.factor*gameQuery.boundingCircle.originalRadius;
+ }
+ break;
+ }
+ }
+ }
+ },
+
+ // This is a utility function that returns the radius for a geometry
+ proj: function (elem, angle) {
+ switch (elem.geometry){
+ case $.gameQuery.GEOMETRY_RECTANGLE :
+ var b = angle*Math.PI*2/360;
+ var Rx = Math.abs(Math.cos(b)*elem.width/2*elem.factor)+Math.abs(Math.sin(b)*elem.height/2*elem.factor);
+ var Ry = Math.abs(Math.cos(b)*elem.height/2*elem.factor)+Math.abs(Math.sin(b)*elem.width/2*elem.factor);
+
+ return {x: Rx, y: Ry};
+ }
+ },
+
+ // This is a utility function for collision of two object
+ collide: function(elem1, offset1, elem2, offset2) {
+ // test real collision (only for two rectangle...)
+ if((elem1.geometry == $.gameQuery.GEOMETRY_RECTANGLE && elem2.geometry == $.gameQuery.GEOMETRY_RECTANGLE)){
+
+ var dx = offset2.x + elem2.boundingCircle.x - elem1.boundingCircle.x - offset1.x;
+ var dy = offset2.y + elem2.boundingCircle.y - elem1.boundingCircle.y - offset1.y;
+ var a = Math.atan(dy/dx);
+
+ var Dx = Math.abs(Math.cos(a-elem1.angle*Math.PI*2/360)/Math.cos(a)*dx);
+ var Dy = Math.abs(Math.sin(a-elem1.angle*Math.PI*2/360)/Math.sin(a)*dy);
+
+ var R = $.gameQuery.proj(elem2, elem2.angle-elem1.angle);
+
+ if((elem1.width/2*elem1.factor+R.x <= Dx) || (elem1.height/2*elem1.factor+R.y <= Dy)) {
+ return false;
+ } else {
+ var Dx = Math.abs(Math.cos(a-elem2.angle*Math.PI*2/360)/Math.cos(a)*-dx);
+ var Dy = Math.abs(Math.sin(a-elem2.angle*Math.PI*2/360)/Math.sin(a)*-dy);
+
+ var R = $.gameQuery.proj(elem1, elem1.angle-elem2.angle);
+
+ if((elem2.width/2*elem2.factor+R.x <= Dx) || (elem2.height/2*elem2.factor+R.y <= Dy)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+ // This function mute (or unmute) all the sounds.
+ }, muteSound: function(muted){
+ for (var i = $.gameQuery.resourceManager.sounds.length-1 ; i >= 0; i --) {
+ $.gameQuery.resourceManager.sounds[i].muted(muted);
+ }
+ }, playground: function() {
+ return $.gameQuery.playground
+ // This function define a callback that will be called upon during the
+ // loading of the game's resources. The function will recieve as unique
+ // parameter a number representing the progess percentage.
+ }, loadCallback: function(callback){
+ $.gameQuery.resourceManager.loadCallback = callback;
+ }});
+
+ $.fn.extend({
+ /**
+ * Define the div to use for the display the game and initailize it.
+ * This could be called on any node it doesn't matter.
+ * The returned node is the playground node.
+ * This IS a desrtuctive call
+ **/
+ playground: function(options) {
+ if(this.length == 1){
+ if(this[0] == document){ // Old usage check
+ throw "Old playground usage, use $.playground() to retreive the playground and $('mydiv').playground(options) to set the div!";
+ }
+ options = $.extend({
+ height: 320,
+ width: 480,
+ refreshRate: 30,
+ position: "absolute",
+ keyTracker: false,
+ disableCollision: false
+ }, options);
+ //We save the playground node and set some variable for this node:
+ $.gameQuery.playground = this;
+ $.gameQuery.refreshRate = options.refreshRate;
+ $.gameQuery.playground[0].height = options.height;
+ $.gameQuery.playground[0].width = options.width;
+
+ // We initialize the apearance of the div
+ $.gameQuery.playground.css({
+ position: options.position,
+ display: "block",
+ overflow: "hidden",
+ height: options.height+"px",
+ width: options.width+"px"
+ })
+ .append("<div id='sceengraph' style='visibility: hidden'/>");
+
+ $.gameQuery.sceengraph = $("#sceengraph");
+
+ //Add the keyTracker to the gameQuery object:
+ $.gameQuery.keyTracker = {};
+ // we only enable the real tracking if the users wants it
+ if(options.keyTracker){
+ $(document).keydown(function(event){
+ $.gameQuery.keyTracker[event.keyCode] = true;
+ });
+ $(document).keyup(function(event){
+ $.gameQuery.keyTracker[event.keyCode] = false;
+ });
+ }
+ }
+ return this;
+ },
+
+ /**
+ * Starts the game. The resources from the resource manager are preloaded if necesary
+ * Works only for the playgroung node.
+ * This is a non-desrtuctive call
+ **/
+ startGame: function(callback) {
+ //if the element is the playground we start the game:
+ $.gameQuery.startCallback = callback;
+ $.gameQuery.resourceManager.preload();
+ return this;
+ },
+
+ /**
+ * Add a group to the sceen graph
+ * works only on the sceengraph root or on another group
+ * This IS a desrtuctive call and should be terminated with end() to go back one level up in the chaining
+ **/
+ addGroup: function(group, options) {
+ options = $.extend({
+ width: 32,
+ height: 32,
+ posx: 0,
+ posy: 0,
+ overflow: "visible",
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ angle: 0,
+ factor: 1
+ }, options);
+
+ var newGroupElement = "<div id='"+group+"' class='group' style='position: absolute; display: block; overflow: "+options.overflow+"; top: "+options.posy+"px; left: "+options.posx+"px; height: "+options.height+"px; width: "+options.width+"px;' />";
+ if(this == $.gameQuery.playground){
+ $.gameQuery.sceengraph.append(newGroupElement);
+ } else if ((this == $.gameQuery.sceengraph)||(this.hasClass("group"))){
+ this.append(newGroupElement);
+ }
+ var newGroup = $("#"+group);
+ newGroup[0].gameQuery = options;
+ newGroup[0].gameQuery.boundingCircle = {x: options.posx + options.width/2,
+ y: options.posy + options.height/0,
+ originalRadius: Math.sqrt(Math.pow(options.width,2) + Math.pow(options.height,2))/2};
+ newGroup[0].gameQuery.boundingCircle.radius = newGroup[0].gameQuery.boundingCircle.originalRadius;
+ newGroup[0].gameQuery.group = true;
+ return this.pushStack(newGroup);
+ },
+
+ /**
+ * Add a sprite to the current node.
+ * Works only on the playground, the sceengraph root or a sceengraph group
+ * This is a non-desrtuctive call
+ **/
+ addSprite: function(sprite, options) {
+ options = $.extend({
+ width: 32,
+ height: 32,
+ posx: 0,
+ posy: 0,
+ idleCounter: 0,
+ currentFrame: 0,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ angle: 0,
+ factor: 1
+ }, options);
+
+ var newSpriteElem = "<div id='"+sprite+"' class='sprite' style='position: absolute; display: block; overflow: hidden; height: "+options.height+"px; width: "+options.width+"px; left: "+options.posx+"px; top: "+options.posy+"px; background-position: "+((options.animation)? -options.animation.offsetx : 0)+"px "+((options.animation)? -options.animation.offsety : 0)+"px;' />";
+ if(this == $.gameQuery.playground){
+ $.gameQuery.sceengraph.append(newSpriteElem);
+ } else {
+ this.append(newSpriteElem);
+ }
+
+ //if the game has already started we want to add the animation's image as a background now:
+ if(options.animation){
+ if($.gameQuery.resourceManager.running){
+ $("#"+sprite).css("background-image", "url("+options.animation.imageURL+")");
+ }
+ if(options.animation.type & $.gameQuery.ANIMATION_VERTICAL) {
+ $("#"+sprite).css("background-repeat", "repeat-x");
+ } else if(options.animation.type & $.gameQuery.ANIMATION_HORIZONTAL) {
+ $("#"+sprite).css("background-repeat", "repeat-y");
+ } else {
+ $("#"+sprite).css("background-repeat", "no-repeat");
+ }
+ }
+
+
+ var spriteDOMObject = $("#"+sprite)[0];
+ if(spriteDOMObject != undefined){
+ spriteDOMObject.gameQuery = options;
+ //Compute bounding Cirlce:
+ spriteDOMObject.gameQuery.boundingCircle = {x: options.posx + options.width/2,
+ y: options.posy + options.height/2,
+ originalRadius: Math.sqrt(Math.pow(options.width,2) + Math.pow(options.height,2))/2};
+ spriteDOMObject.gameQuery.boundingCircle.radius = spriteDOMObject.gameQuery.boundingCircle.originalRadius;
+ }
+ return this;
+ },
+
+ /**
+ * Remove the sprite on which it is called. This is here for backward compatibility but it doesn't
+ * do anything more than simply calling .remove()
+ * This is a non-desrtuctive call.
+ **/
+ removeSprite: function() {
+ this.remove();
+ return this;
+ },
+
+ /**
+ * Add a Tile Map to the selected element.
+ * This is a non-destructive call.
+ **/
+ addTilemap: function(name, tileDescription, animationList, options){
+ options = $.extend({
+ width: 32,
+ height: 32,
+ sizex: 32,
+ sizey: 32,
+ posx: 0,
+ posy: 0
+ }, options);
+
+ //var newSpriteElem = "<div id='"+sprite+"' style='position: absolute; display: block; overflow: hidden; height: "+options.height+"px; width: "+options.width+"px; left: "+options.posx+"px; top: "+options.posy+"px; background-position: 0px 0px;' />";
+
+ var tileSet = $("<div class='tileSet' style='position: absolute; display: block; overflow: hidden;' />");
+ tileSet.css({top: options.posy, left: options.posx, height: options.height*options.sizey, width: options.width*options.sizex}).attr("id",name);
+ if(this == $.gameQuery.playground){
+ $.gameQuery.sceengraph.append(tileSet);
+ } else {
+ this.append(tileSet);
+ }
+
+ if($.isArray(animationList)){
+ var frameTracker = [];
+ var idleCounter = [];
+ for(var i=0; i<animationList.length; i++){
+ frameTracker[i] = 0;
+ idleCounter[i] = 0;
+ }
+ tileSet[0].gameQuery = options
+ tileSet[0].gameQuery.frameTracker = frameTracker;
+ tileSet[0].gameQuery.animations = animationList;
+ tileSet[0].gameQuery.idleCounter = idleCounter;
+ tileSet[0].gameQuery.tileSet = true;
+ } else {
+ tileSet[0].gameQuery = options
+ tileSet[0].gameQuery.frameTracker = 0;
+ tileSet[0].gameQuery.animations = animationList;
+ tileSet[0].gameQuery.idleCounter = 0;
+ tileSet[0].gameQuery.tileSet = true;
+ }
+
+ if(typeof tileDescription == "function"){
+ for(var i=0; i<options.sizey; i++){
+ for(var j=0; j<options.sizex; j++){
+ if(tileDescription(i,j) != 0){
+ if($.isArray(animationList)){
+ // for many simple animation:
+ tileSet.addSprite("tile_"+name+"_"+i+"_"+j,
+ {width: options.width,
+ height: options.height,
+ posx: j*options.width,
+ posy: i*options.height,
+ animation: animationList[tileDescription(i,j)-1]});
+ var newTile = $("#tile_"+name+"_"+i+"_"+j);
+ newTile.removeClass("sprite");
+ newTile.addClass("tileType_"+(tileDescription(i,j)-1));
+ newTile[0].gameQuery.animationNumber = tileDescription(i,j)-1;
+ } else {
+ // for multi-animation:
+ tileSet.addSprite("tile_"+name+"_"+i+"_"+j,
+ {width: options.width,
+ height: options.height,
+ posx: j*options.width,
+ posy: i*options.height,
+ animation: animationList});
+ var newTile = $("#tile_"+name+"_"+i+"_"+j);
+ newTile.setAnimation(tileDescription(i,j)-1);
+ newTile.removeClass("sprite");
+ newTile.addClass("tileType_"+(tileDescription(i,j)-1));
+ }
+ }
+ }
+ }
+ } else if(typeof tileDescription == "object") {
+ for(var i=0; i<tileDescription.length; i++){
+ for(var j=0; j<tileDescription[0].length; j++){
+ if(tileDescription[i][j] != 0){
+ if($.isArray(animationList)){
+ // for many simple animation:
+ tileSet.addSprite("tile_"+name+"_"+i+"_"+j,
+ {width: options.width,
+ height: options.height,
+ posx: j*options.width,
+ posy: i*options.height,
+ animation: animationList[tileDescription[i][j]-1]});
+ var newTile = $("#tile_"+name+"_"+i+"_"+j);
+ newTile.removeClass("sprite");
+ newTile.addClass("tileType_"+(tileDescription[i][j]-1));
+ newTile[0].gameQuery.animationNumber = tileDescription[i][j]-1;
+ } else {
+ // for multi-animation:
+ tileSet.addSprite("tile_"+name+"_"+i+"_"+j,
+ {width: options.width,
+ height: options.height,
+ posx: j*options.width,
+ posy: i*options.height,
+ animation: animationList});
+ var newTile = $("#tile_"+name+"_"+i+"_"+j);
+ newTile.setAnimation(tileDescription[i][j]-1);
+ newTile.removeClass("active");
+ newTile.addClass("tileType_"+(tileDescription[i][j]-1));
+ }
+ }
+ }
+ }
+ }
+ //Get the tileSet offset (relatif to the playground)
+ var playgroundOffset = $.gameQuery.playground.offset();
+ var tileSetOffset = tileSet.offset();
+ tileSetOffset = {top: tileSetOffset.top - playgroundOffset.top, left: tileSetOffset.left - playgroundOffset.left};
+
+ //actvates the visible tiles
+ var firstRow = Math.max(Math.min(Math.floor(-tileSetOffset.top/options.height), options.sizey), 0);
+ var lastRow = Math.max(Math.min(Math.ceil(($.gameQuery.playground[0].height-tileSetOffset.top)/options.height), options.sizey), 0);
+ var firstColumn = Math.max(Math.min(Math.floor(-tileSetOffset.left/options.width), options.sizex), 0);
+ var lastColumn = Math.max(Math.min(Math.ceil(($.gameQuery.playground[0].width-tileSetOffset.left)/options.width), options.sizex), 0);
+
+ tileSet[0].gameQuery.firstRow = firstRow;
+ tileSet[0].gameQuery.lastRow = lastRow;
+ tileSet[0].gameQuery.firstColumn = firstColumn;
+ tileSet[0].gameQuery.lastColumn = lastColumn;
+
+ for(var i = firstRow; i < lastRow; i++){
+ for(var j = firstColumn; j < lastColumn ; j++) {
+ $("#tile_"+name+"_"+i+"_"+j).toggleClass("active");
+ }
+ }
+ return this.pushStack(tileSet);
+ },
+
+ /**
+ * Changes the animation associated with a sprite.
+ * WARNING: no check are made to ensure that the object is really a sprite
+ * This is a non-desrtuctive call
+ **/
+ setAnimation: function(animation, callback) {
+ var gameQuery = this[0].gameQuery;
+ if(typeof animation == "number"){
+ if(gameQuery.animation.type & $.gameQuery.ANIMATION_MULTI){
+ var distance = gameQuery.animation.distance * animation;
+ gameQuery.multi = distance;
+ if(gameQuery.animation.type & $.gameQuery.ANIMATION_VERTICAL) {
+ gameQuery.currentFrame = 0;
+ this.css("background-position",""+(-distance-gameQuery.animation.offsetx)+"px "+(-gameQuery.animation.offsety)+"px");
+ } else if(gameQuery.animation.type & $.gameQuery.ANIMATION_HORIZONTAL) {
+ gameQuery.currentFrame = 0;
+ this.css("background-position",""+(-gameQuery.animation.offsetx)+"px "+(-distance-gameQuery.animation.offsety)+"px");
+ }
+ }
+ } else {
+ if(animation){
+ gameQuery.animation = animation;
+ gameQuery.currentFrame = 0;
+ this.css({"background-image": "url("+animation.imageURL+")", "background-position": ""+(-animation.offsetx)+"px "+(-animation.offsety)+"px"});
+
+ if(gameQuery.animation.type & $.gameQuery.ANIMATION_VERTICAL) {
+ this.css("background-repeat", "repeat-x");
+ } else if(gameQuery.animation.type & $.gameQuery.ANIMATION_HORIZONTAL) {
+ this.css("background-repeat", "repeat-y");
+ } else {
+ this.css("background-repeat", "no-repeat");
+ }
+ } else {
+ this.css("background-image", "");
+ }
+ }
+
+ if(callback != undefined){
+ this[0].gameQuery.callback = callback;
+ }
+
+ return this;
+ },
+
+ /**
+ * This function add the sound to the resourceManger for later use and associate it to the selected dom element(s).
+ * This is a non-desrtuctive call
+ **/
+ addSound: function(sound, add) {
+ // Does a SoundWrapper exists
+ if($.gameQuery.SoundWrapper) {
+ var gameQuery = this[0].gameQuery;
+ // should we add to existing sounds ?
+ if(add) {
+ // we do, have we some sound associated with 'this'?
+ var sounds = gameQuery.sounds;
+ if(sounds) {
+ // yes, we add it
+ sounds.push(sound);
+ } else {
+ // no, we create a new sound array
+ gameQuery.sounds = [sound];
+ }
+ } else {
+ // no, we replace all sounds with this one
+ gameQuery.sounds = [sound];
+ }
+ }
+ return this;
+ },
+
+ /**
+ * This function plays the sound(s) associated with the selected dom element(s)
+ * This is a non-desrtuctive call
+ **/
+ playSound: function() {
+ $(this).each(function(){
+ var gameQuery = this.gameQuery;
+ if(gameQuery.sounds) {
+ for(var i = gameQuery.sounds.length-1 ; i >= 0; i --) {
+ gameQuery.sounds[i].play();
+ }
+ }
+ });
+
+ return this;
+ },
+
+ /**
+ * This function stops the sound(s) associated with the selected dom element(s) and rewind them
+ * This is a non-desrtuctive call
+ **/
+ stopSound: function() {
+ $(this).each(function(){
+ var gameQuery = this.gameQuery;
+ if(gameQuery.sounds) {
+ for(var i = gameQuery.sounds.length-1 ; i >= 0; i --) {
+ gameQuery.sounds[i].stop();
+ }
+ }
+ });
+ return this;
+ },
+
+ /**
+ * This function pauses the sound(s) associated with the selected dom element(s)
+ * This is a non-desrtuctive call
+ **/
+ pauseSound: function() {
+ $(this).each(function(){
+ var gameQuery = this.gameQuery;
+ if(gameQuery.sounds) {
+ for(var i = gameQuery.sounds.length-1 ; i >= 0; i --) {
+ gameQuery.sounds[i].pause();
+ }
+ }
+ });
+ return this;
+ },
+
+ /**
+ * this function mute or unmute the selected sound or all the sounds if none is specified
+ **/
+ muteSound: function(muted) {
+ $(this).each(function(){
+ var gameQuery = this.gameQuery;
+ if(gameQuery.sounds) {
+ for(var i = gameQuery.sounds.length-1 ; i >= 0; i --) {
+ gameQuery.sounds[i].muted(muted);
+ }
+ }
+ });
+ return this;
+ },
+
+ /**
+ * Register a callback to be trigered every "rate"
+ * This is a non-desrtuctive call
+ **/
+ registerCallback: function(fn, rate) {
+ $.gameQuery.resourceManager.registerCallback(fn, rate);
+ return this;
+ },
+
+ /**
+ * @DEPRECATED: use loadCallback() instead
+ * Set the id of the div to use as a loading bar while the games media are loaded during the preload.
+ * If a callback function is given it will be called each time the loading progression changes with
+ * the precentage passed as unique argument.
+ * This is a non-desrtuctive call
+ **/
+ setLoadBar: function(elementId, finalwidth, callback) {
+ $.gameQuery.loadbar = {id: elementId, width: finalwidth, callback: callback};
+ return this;
+ },
+
+ /**
+ * This function retreive a list of object in collision with the subject:
+ * - if 'this' is a sprite or a group, the function will retrieve the list of sprites (not groups) that touch it
+ * - if 'this' is the playground, the function will return a list of all pair of collisioning elements. They are represented
+ * by a jQuery object containing a series of paire. Each paire represents two object colliding.(not yet implemented)
+ * For now all abject are considered to be boxes.
+ * This IS a desrtuctive call and should be terminated with end() to go back one level up in the chaining
+ **/
+ collision: function(filter){
+ var resultList = [];
+
+ //retrieve 'this' offset by looking at the parents
+ var itsParent = this[0].parentNode, offsetX = 0, offsetY = 0;
+ while (itsParent != $.gameQuery.playground[0]){
+ if(itsParent.gameQuery){
+ offsetX += itsParent.gameQuery.posx;
+ offsetY += itsParent.gameQuery.posy;
+ }
+ itsParent = itsParent.parentNode;
+ }
+
+ // retrieve the gameQuery object
+ var gameQuery = this[0].gameQuery;
+
+
+ // retrieve the playground's absolute position and size information
+ var pgdGeom = {top: 0, left: 0, bottom: $.playground().height(), right: $.playground().width()};
+
+ // Does 'this' is inside the playground ?
+ if( (gameQuery.boundingCircle.y + gameQuery.boundingCircle.radius + offsetY < pgdGeom.top) ||
+ (gameQuery.boundingCircle.x + gameQuery.boundingCircle.radius + offsetX < pgdGeom.left) ||
+ (gameQuery.boundingCircle.y - gameQuery.boundingCircle.radius + offsetY > pgdGeom.bottom) ||
+ (gameQuery.boundingCircle.x - gameQuery.boundingCircle.radius + offsetX > pgdGeom.right)){
+ return this.pushStack(new $([]));
+ }
+
+ if(this == $.gameQuery.playground){
+ //TODO Code the "all against all" collision detection and find a nice way to return a list of pairs of elements
+ } else {
+ // we must find all the element that touches 'this'
+ var elementsToCheck = new Array();
+ elementsToCheck.push($.gameQuery.sceengraph.children(filter).get());
+ elementsToCheck[0].offsetX = 0;
+ elementsToCheck[0].offsetY = 0;
+
+ for(var i = 0, len = elementsToCheck.length; i < len; i++) {
+ var subLen = elementsToCheck[i].length;
+ while(subLen--){
+ var elementToCheck = elementsToCheck[i][subLen];
+ // is it a gameQuery generated element?
+ if(elementToCheck.gameQuery){
+ // we don't want to check groups
+ if(!elementToCheck.gameQuery.group && !elementToCheck.gameQuery.tileSet){
+ // does it touches the selection?
+ if(this[0]!=elementToCheck){
+ // check bounding circle collision
+ // 1) distance between center:
+ var distance = Math.sqrt(Math.pow(offsetY + gameQuery.boundingCircle.y - elementsToCheck[i].offsetY - elementToCheck.gameQuery.boundingCircle.y, 2) + Math.pow(offsetX + gameQuery.boundingCircle.x - elementsToCheck[i].offsetX - elementToCheck.gameQuery.boundingCircle.x, 2));
+ if(distance - gameQuery.boundingCircle.radius - elementToCheck.gameQuery.boundingCircle.radius <= 0){
+ // check real collision
+ if($.gameQuery.collide(gameQuery, {x: offsetX, y: offsetY}, elementToCheck.gameQuery, {x: elementsToCheck[i].offsetX, y: elementsToCheck[i].offsetY})) {
+ // add to the result list if collision detected
+ resultList.push(elementsToCheck[i][subLen]);
+ }
+ }
+ }
+ }
+ // Add the children nodes to the list
+ var eleChildren = $(elementToCheck).children(filter);
+ if(eleChildren.length){
+ elementsToCheck.push(eleChildren.get());
+ elementsToCheck[len].offsetX = elementToCheck.gameQuery.posx + elementsToCheck[i].offsetX;
+ elementsToCheck[len].offsetY = elementToCheck.gameQuery.posy + elementsToCheck[i].offsetY;
+ len++;
+ }
+ }
+ }
+ }
+ return this.pushStack($(resultList));
+ }
+ },
+
+ /**
+ * This is an internal function doing the combine action of rotate and scale
+ * Both argument are mandatory. To get the values back use .rotate() or
+ * .scale()
+ **/
+ transform: function(angle, factor) {
+ var gameQuery = this[0].gameQuery;
+ // Mark transformed and compute bounding box
+ $.gameQuery.update(gameQuery,{angle: angle, factor: factor});
+
+ if(this.css("MozTransform")) {
+ // For firefox from 3.5
+ var transform = "rotate("+angle+"deg) scale("+factor+")";
+ this.css("MozTransform",transform);
+ } else if(this.css("WebkitTransform")!==null && this.css("WebkitTransform")!==undefined) {
+ // For safari from 3.1 (and chrome)
+ var transform = "rotate("+angle+"deg) scale("+factor+")";
+ this.css("WebkitTransform",transform);
+ } else if(this.css("filter")!==undefined){
+ var angle_rad = Math.PI * 2 / 360 * angle;
+ // For ie from 5.5
+ var cos = Math.cos(angle_rad) * factor;
+ var sin = Math.sin(angle_rad) * factor;
+ var previousWidth = this.width();
+ var previousHeight = this.height();
+ this.css("filter","progid:DXImageTransform.Microsoft.Matrix(M11="+cos+",M12="+(-sin)+",M21="+sin+",M22="+cos+",SizingMethod='auto expand',FilterType='nearest neighbor')");
+ var newWidth = this.width();
+ var newHeight = this.height();
+ this.css("left", ""+(gameQuery.posx-(newWidth-previousWidth)/2)+"px");
+ this.css("top", ""+(gameQuery.posy-(newHeight-previousHeight)/2)+"px");
+ }
+ return this;
+ },
+
+ /**
+ * This function rotates the selected element(s) clock-wise. The argument is a degree.
+ **/
+ rotate: function(angle){
+ var gameQuery = this[0].gameQuery;
+
+ if(angle !== undefined) {
+ return this.transform(angle % 360, this.scale());
+ } else {
+ var ang = gameQuery.angle;
+ return ang ? ang : 0;
+ }
+ },
+
+ /**
+ * This function change the scale of the selected element(s). The passed argument is a ratio:
+ * 1.0 = original size
+ * 0.5 = half the original size
+ * 2.0 = twice the original size
+ **/
+ scale: function(factor){
+ var gameQuery = this[0].gameQuery;
+
+ if(factor !== undefined) {
+ return this.transform(this.rotate(), factor);
+ } else {
+ var fac = gameQuery.factor;
+ return fac ? fac : 1;
+ }
+ }
+ });
+
+
+ // cssHooks to track changes to sprites
+ $.cssHooks["left"] = {
+ set: function(elem, value) {
+ $.gameQuery.update(elem, {left: value});
+ return value;
+ }
+ }
+
+ $.cssHooks["top"] = {
+ set: function(elem, value) {
+ $.gameQuery.update(elem, {top: value});
+ return value;
+ }
+ }
+
+ $.cssHooks["width"] = {
+ set: function(elem, value) {
+ $.gameQuery.update(elem, {width: value});
+ return value;
+ }
+ }
+
+ $.cssHooks["height"] = {
+ set: function(elem, value) {
+ $.gameQuery.update(elem, {height: value});
+ return value;
+ }
+ }
+})(jQuery); \ No newline at end of file
diff --git a/landscape/abovewaterislandbg.png b/landscape/abovewaterislandbg.png
new file mode 100755
index 0000000..7b9a707
--- /dev/null
+++ b/landscape/abovewaterislandbg.png
Binary files differ
diff --git a/landscape/abovewaterislandcorner.png b/landscape/abovewaterislandcorner.png
new file mode 100755
index 0000000..d80a272
--- /dev/null
+++ b/landscape/abovewaterislandcorner.png
Binary files differ
diff --git a/landscape/bush.png b/landscape/bush.png
new file mode 100755
index 0000000..120c93b
--- /dev/null
+++ b/landscape/bush.png
Binary files differ
diff --git a/landscape/island1bg.png b/landscape/island1bg.png
new file mode 100755
index 0000000..8d08038
--- /dev/null
+++ b/landscape/island1bg.png
Binary files differ
diff --git a/landscape/island1fg.png b/landscape/island1fg.png
new file mode 100755
index 0000000..b916a46
--- /dev/null
+++ b/landscape/island1fg.png
Binary files differ
diff --git a/landscape/island_bush.png b/landscape/island_bush.png
new file mode 100755
index 0000000..ac2a2ae
--- /dev/null
+++ b/landscape/island_bush.png
Binary files differ
diff --git a/landscape/palmtree.png b/landscape/palmtree.png
new file mode 100755
index 0000000..5f5b16b
--- /dev/null
+++ b/landscape/palmtree.png
Binary files differ
diff --git a/landscape/scotch.gif b/landscape/scotch.gif
new file mode 100755
index 0000000..06c8b50
--- /dev/null
+++ b/landscape/scotch.gif
Binary files differ
diff --git a/landscape/underwaterislandbg.png b/landscape/underwaterislandbg.png
new file mode 100755
index 0000000..2bbd105
--- /dev/null
+++ b/landscape/underwaterislandbg.png
Binary files differ
diff --git a/landscape/underwaterislandcorner.png b/landscape/underwaterislandcorner.png
new file mode 100755
index 0000000..4dc4082
--- /dev/null
+++ b/landscape/underwaterislandcorner.png
Binary files differ
diff --git a/landscape/watercorner.png b/landscape/watercorner.png
new file mode 100755
index 0000000..9a303ca
--- /dev/null
+++ b/landscape/watercorner.png
Binary files differ
diff --git a/manrunning.gif b/manrunning.gif
new file mode 100755
index 0000000..a36fab7
--- /dev/null
+++ b/manrunning.gif
Binary files differ
diff --git a/manrunning2.gif b/manrunning2.gif
new file mode 100755
index 0000000..bae37b4
--- /dev/null
+++ b/manrunning2.gif
Binary files differ
diff --git a/manstanding.gif b/manstanding.gif
new file mode 100755
index 0000000..66b84f5
--- /dev/null
+++ b/manstanding.gif
Binary files differ
diff --git a/manstanding2.gif b/manstanding2.gif
new file mode 100755
index 0000000..3bd9647
--- /dev/null
+++ b/manstanding2.gif
Binary files differ
diff --git a/particle.html b/particle.html
new file mode 100755
index 0000000..fe535f9
--- /dev/null
+++ b/particle.html
@@ -0,0 +1,109 @@
+<!doctype html>
+<html>
+<head>
+<title>PARTICLES</title>
+<style type="text/css">
+html,body{height: 100%;width:100%; overflow:hidden;}
+#container
+ {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 100%;width:100%;
+background-image: -webkit-gradient(
+ linear,
+ left bottom,
+ left top,
+ color-stop(0.23, rgb(43,42,40)),
+ color-stop(0.62, rgb(0,0,0))
+);
+background-image: -moz-linear-gradient(
+ center bottom,
+ rgb(43,42,40) 23%,
+ rgb(0,0,0) 62%
+);
+
+ }
+.point
+ {
+ display: block;
+ position: absolute;
+ }
+</style>
+</head>
+<body>
+<div id="container"></div>
+</body>
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript">
+function Point (x,y,color)
+ {
+ var width = Math.floor( 10 * Math.random() + 5 )
+ var dx = (Math.random() * 2 - 1) * 20
+ var dy = (Math.random() * 2 - 1) * 20
+ var div = document.createElement('div')
+ div.className = "point"
+ div.style.width = width+"px"
+ div.style.height = width+"px"
+ div.style.background = color
+ div.style.left = x+"px"
+ div.style.top = y+"px"
+ document.getElementById("container").appendChild(div)
+ this.update = function ()
+ {
+ if (! div)
+ return false
+ width -= 1
+ if (width === 1)
+ {
+ // document.getElementById("container").removeChild(div)
+ div.style.background = choice(Particles.dead_colors)
+ div = false
+ }
+ else
+ {
+ x += dx
+ y += dy
+ dy += 2
+ div.style.width = width+"px"
+ div.style.height = width+"px"
+ div.style.left = x+"px"
+ div.style.top = y+"px"
+ }
+ }
+ }
+function choice(list){return list[ Math.floor( Math.random() * list.length )]}
+var Particles =
+ {
+ list: [],
+ count: 20,
+ delay: 90,
+ colors: ["#f33","#ff0","#3df","#33f","#83b","#d3d"],
+ dead_colors: ["#000","#080808","#111","#181818","#222","#333","#444","#555","#666"],
+ update: function ()
+ {
+ var update_count = 0
+ for (var i = 0; i < Particles.list.length; i++)
+ {
+ if (! Particles.list[i].update())
+ update_count += 1
+ }
+ if (update_count === 0)
+ Particles.list = []
+ },
+ click: function (e)
+ {
+ console.log("CLICKED "+e.pageX+ " "+ e.pageY)
+ count = Particles.count * Math.random() + Particles.count/2
+ for (var i = 0; i < count; i++)
+ Particles.list.push ( new Point (e.pageX, e.pageY, choice(Particles.colors) ) )
+ },
+ init: function ()
+ {
+ $("#container").bind("click", Particles.click)
+ setInterval(Particles.update, Particles.delay)
+ },
+ }
+Particles.init()
+</script>
+</html>
diff --git a/possible/.htaccess b/possible/.htaccess
new file mode 100755
index 0000000..8c53c63
--- /dev/null
+++ b/possible/.htaccess
@@ -0,0 +1 @@
+DirectoryIndex /cgi-bin/im/images
diff --git a/possible/1298527286040-dumpfm-pepper-1298436051425-dumpfm-pepper-chevre_1.png b/possible/1298527286040-dumpfm-pepper-1298436051425-dumpfm-pepper-chevre_1.png
new file mode 100755
index 0000000..0402d4d
--- /dev/null
+++ b/possible/1298527286040-dumpfm-pepper-1298436051425-dumpfm-pepper-chevre_1.png
Binary files differ
diff --git a/possible/1298590356231-dumpfm-pepper-fingercheese.png b/possible/1298590356231-dumpfm-pepper-fingercheese.png
new file mode 100755
index 0000000..93e4a36
--- /dev/null
+++ b/possible/1298590356231-dumpfm-pepper-fingercheese.png
Binary files differ
diff --git a/possible/1300591584954-dumpfm-pepper-nantucket_paradigm.png b/possible/1300591584954-dumpfm-pepper-nantucket_paradigm.png
new file mode 100755
index 0000000..ba7354a
--- /dev/null
+++ b/possible/1300591584954-dumpfm-pepper-nantucket_paradigm.png
Binary files differ
diff --git a/possible/1301351326112-dumpfm-pepper-glitter_wom2.gif b/possible/1301351326112-dumpfm-pepper-glitter_wom2.gif
new file mode 100755
index 0000000..3475ab7
--- /dev/null
+++ b/possible/1301351326112-dumpfm-pepper-glitter_wom2.gif
Binary files differ
diff --git a/possible/1302286721060-dumpfm-pepper-cell_phone_glitter.gif b/possible/1302286721060-dumpfm-pepper-cell_phone_glitter.gif
new file mode 100755
index 0000000..d08c4e5
--- /dev/null
+++ b/possible/1302286721060-dumpfm-pepper-cell_phone_glitter.gif
Binary files differ
diff --git a/possible/plasmus5.gif b/possible/plasmus5.gif
new file mode 100755
index 0000000..3463049
--- /dev/null
+++ b/possible/plasmus5.gif
Binary files differ
diff --git a/possible/plasmusuk.gif b/possible/plasmusuk.gif
new file mode 100755
index 0000000..fa91b3b
--- /dev/null
+++ b/possible/plasmusuk.gif
Binary files differ
diff --git a/sand.png b/sand.png
new file mode 100755
index 0000000..c034d2e
--- /dev/null
+++ b/sand.png
Binary files differ
diff --git a/sea.png b/sea.png
new file mode 100755
index 0000000..c35cc9f
--- /dev/null
+++ b/sea.png
Binary files differ
diff --git a/sky.png b/sky.png
new file mode 100755
index 0000000..890faf2
--- /dev/null
+++ b/sky.png
Binary files differ
diff --git a/splash.gif b/splash.gif
new file mode 100755
index 0000000..3cf8b98
--- /dev/null
+++ b/splash.gif
Binary files differ
diff --git a/sprites/.htaccess b/sprites/.htaccess
new file mode 100755
index 0000000..8c53c63
--- /dev/null
+++ b/sprites/.htaccess
@@ -0,0 +1 @@
+DirectoryIndex /cgi-bin/im/images
diff --git a/sprites/breaststroke.gif b/sprites/breaststroke.gif
new file mode 100755
index 0000000..b70b06f
--- /dev/null
+++ b/sprites/breaststroke.gif
Binary files differ
diff --git a/sprites/breaststroke1.png b/sprites/breaststroke1.png
new file mode 100755
index 0000000..cc7fc96
--- /dev/null
+++ b/sprites/breaststroke1.png
Binary files differ
diff --git a/sprites/breaststroke2.png b/sprites/breaststroke2.png
new file mode 100755
index 0000000..75a1b54
--- /dev/null
+++ b/sprites/breaststroke2.png
Binary files differ
diff --git a/sprites/breaststroke3.png b/sprites/breaststroke3.png
new file mode 100755
index 0000000..e6293df
--- /dev/null
+++ b/sprites/breaststroke3.png
Binary files differ
diff --git a/sprites/cannonball.png b/sprites/cannonball.png
new file mode 100755
index 0000000..60ee1da
--- /dev/null
+++ b/sprites/cannonball.png
Binary files differ
diff --git a/sprites/cannonball2.png b/sprites/cannonball2.png
new file mode 100755
index 0000000..6ab8e79
--- /dev/null
+++ b/sprites/cannonball2.png
Binary files differ
diff --git a/sprites/diving1.png b/sprites/diving1.png
new file mode 100755
index 0000000..65f7789
--- /dev/null
+++ b/sprites/diving1.png
Binary files differ
diff --git a/sprites/diving2.gif b/sprites/diving2.gif
new file mode 100755
index 0000000..b27b12c
--- /dev/null
+++ b/sprites/diving2.gif
Binary files differ
diff --git a/sprites/diving2.png b/sprites/diving2.png
new file mode 100755
index 0000000..476b2d2
--- /dev/null
+++ b/sprites/diving2.png
Binary files differ
diff --git a/sprites/float.gif b/sprites/float.gif
new file mode 100755
index 0000000..9835cc0
--- /dev/null
+++ b/sprites/float.gif
Binary files differ
diff --git a/sprites/float1.png b/sprites/float1.png
new file mode 100755
index 0000000..a4bd5f3
--- /dev/null
+++ b/sprites/float1.png
Binary files differ
diff --git a/sprites/float2.png b/sprites/float2.png
new file mode 100755
index 0000000..ca9b08a
--- /dev/null
+++ b/sprites/float2.png
Binary files differ
diff --git a/sprites/float3.png b/sprites/float3.png
new file mode 100755
index 0000000..bd5ab1d
--- /dev/null
+++ b/sprites/float3.png
Binary files differ
diff --git a/sprites/jumping.png b/sprites/jumping.png
new file mode 100755
index 0000000..834df7f
--- /dev/null
+++ b/sprites/jumping.png
Binary files differ
diff --git a/sprites/jumping2.png b/sprites/jumping2.png
new file mode 100755
index 0000000..69d35bb
--- /dev/null
+++ b/sprites/jumping2.png
Binary files differ
diff --git a/sprites/mandiving1.gif b/sprites/mandiving1.gif
new file mode 100755
index 0000000..b27b12c
--- /dev/null
+++ b/sprites/mandiving1.gif
Binary files differ
diff --git a/sprites/manrunningsprite.png b/sprites/manrunningsprite.png
new file mode 100755
index 0000000..66a67dc
--- /dev/null
+++ b/sprites/manrunningsprite.png
Binary files differ
diff --git a/sprites/manrunningsprite_left.png b/sprites/manrunningsprite_left.png
new file mode 100755
index 0000000..0016053
--- /dev/null
+++ b/sprites/manrunningsprite_left.png
Binary files differ
diff --git a/sprites/manstandingsprite.png b/sprites/manstandingsprite.png
new file mode 100755
index 0000000..94933ab
--- /dev/null
+++ b/sprites/manstandingsprite.png
Binary files differ
diff --git a/sprites/manstandingsprite_brown.png b/sprites/manstandingsprite_brown.png
new file mode 100755
index 0000000..ddf9204
--- /dev/null
+++ b/sprites/manstandingsprite_brown.png
Binary files differ
diff --git a/sprites/manstandingsprite_left.png b/sprites/manstandingsprite_left.png
new file mode 100755
index 0000000..52f9729
--- /dev/null
+++ b/sprites/manstandingsprite_left.png
Binary files differ
diff --git a/sprites/orig/manrunning.png b/sprites/orig/manrunning.png
new file mode 100755
index 0000000..7827444
--- /dev/null
+++ b/sprites/orig/manrunning.png
Binary files differ
diff --git a/sprites/orig/manrunningsprite.png b/sprites/orig/manrunningsprite.png
new file mode 100755
index 0000000..82b9ba1
--- /dev/null
+++ b/sprites/orig/manrunningsprite.png
Binary files differ
diff --git a/sprites/orig/manrunningsprite_left.png b/sprites/orig/manrunningsprite_left.png
new file mode 100755
index 0000000..dd29c7b
--- /dev/null
+++ b/sprites/orig/manrunningsprite_left.png
Binary files differ
diff --git a/sprites/orig/manstandingsprite.png b/sprites/orig/manstandingsprite.png
new file mode 100755
index 0000000..ff41388
--- /dev/null
+++ b/sprites/orig/manstandingsprite.png
Binary files differ
diff --git a/sprites/orig/manstandingsprite_left.png b/sprites/orig/manstandingsprite_left.png
new file mode 100755
index 0000000..083cf70
--- /dev/null
+++ b/sprites/orig/manstandingsprite_left.png
Binary files differ
diff --git a/sprites/orig/sand.png b/sprites/orig/sand.png
new file mode 100755
index 0000000..06a6b8f
--- /dev/null
+++ b/sprites/orig/sand.png
Binary files differ
diff --git a/sprites/orig/sky.png b/sprites/orig/sky.png
new file mode 100755
index 0000000..890faf2
--- /dev/null
+++ b/sprites/orig/sky.png
Binary files differ
diff --git a/sprites/running2.gif b/sprites/running2.gif
new file mode 100755
index 0000000..bae37b4
--- /dev/null
+++ b/sprites/running2.gif
Binary files differ
diff --git a/sprites/splash.png b/sprites/splash.png
new file mode 100755
index 0000000..77484a3
--- /dev/null
+++ b/sprites/splash.png
Binary files differ
diff --git a/sprites/splash2.png b/sprites/splash2.png
new file mode 100755
index 0000000..4f6cb0e
--- /dev/null
+++ b/sprites/splash2.png
Binary files differ
diff --git a/sprites/standing2.gif b/sprites/standing2.gif
new file mode 100755
index 0000000..3bd9647
--- /dev/null
+++ b/sprites/standing2.gif
Binary files differ
diff --git a/sprites/swimming1.gif b/sprites/swimming1.gif
new file mode 100755
index 0000000..0373c02
--- /dev/null
+++ b/sprites/swimming1.gif
Binary files differ
diff --git a/sprites/swimming1.png b/sprites/swimming1.png
new file mode 100755
index 0000000..645ae45
--- /dev/null
+++ b/sprites/swimming1.png
Binary files differ
diff --git a/sprites/swimming2.png b/sprites/swimming2.png
new file mode 100755
index 0000000..8d2b2dd
--- /dev/null
+++ b/sprites/swimming2.png
Binary files differ
diff --git a/sprites/swimtrans.png b/sprites/swimtrans.png
new file mode 100755
index 0000000..2f20766
--- /dev/null
+++ b/sprites/swimtrans.png
Binary files differ
diff --git a/swimtrans.gif b/swimtrans.gif
new file mode 100755
index 0000000..5203e7d
--- /dev/null
+++ b/swimtrans.gif
Binary files differ
diff --git a/swimtrans.png b/swimtrans.png
new file mode 100755
index 0000000..0377391
--- /dev/null
+++ b/swimtrans.png
Binary files differ
diff --git a/v1.html b/v1.html
new file mode 100755
index 0000000..4ca89af
--- /dev/null
+++ b/v1.html
@@ -0,0 +1,230 @@
+<!doctype html>
+<html>
+<head>
+<title></title>
+<style type="text/css">
+body
+ {
+ background-color: #fff;
+ }
+#playground
+ {
+ border: 1px solid red;
+ }
+
+</style>
+</head>
+<body>
+
+<div id="playground">
+</div>
+
+</body>
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript" src="jquery.gamequery-0.5.1.js"></script>
+<script type="text/javascript">
+var PLAYGROUND_WIDTH = 900
+var PLAYGROUND_HEIGHT = 600
+var REFRESH_RATE = 30
+
+$(function ()
+ {
+ var KEY =
+ {
+ LEFT: 37,
+ UP: 38,
+ RIGHT: 39,
+ DOWN: 40,
+ }
+ var DUDE_STATE =
+ {
+ IDLE_RIGHT: 0,
+ IDLE_LEFT: 1,
+ RUN_RIGHT: 2,
+ RUN_LEFT: 3,
+ // JUMPING_RIGHT: 4,
+ // JUMPING_LEFT: 5,
+ }
+
+ $("#playground").playground({height: PLAYGROUND_HEIGHT, width: PLAYGROUND_WIDTH, refreshRate: REFRESH_RATE, keyTracker: false})
+ $.each(KEY, function (k,v) { $.gameQuery.keyTracker[v] = false })
+
+ function changeAnimation (sprite, dude, newAnimation, oldAnimation)
+ {
+ if (newAnimation === oldAnimation)
+ return
+ dude.currentState = newAnimation
+ // if (dude.currentState == DUDE_STATE.JUMPING_RIGHT || dude.currentState == DUDE_STATE.JUMPING_LEFT)
+
+ newAnim = dude.animations[newAnimation]
+ oldAnim = dude.animations[oldAnimation]
+ sprite.setAnimation(newAnim.animation)
+ .width(newAnim.width)
+ .height(newAnim.height)
+ .css("top", sprite.position().top + newAnim.deltaY - oldAnim.deltaY)
+ .css("left", sprite.position().left + newAnim.deltaX - oldAnim.deltaX)
+ }
+ function animate (sprite)
+ {
+ sprite = $(sprite)
+ actor = sprite.data("actor")
+ }
+ var sky = new $.gameQuery.Animation({imageURL: "./sky.png"})
+ var sand = new $.gameQuery.Animation({imageURL: "./sand.png"})
+ $.playground()
+ .addSprite( "sky",
+ {
+ posx: 0,
+ posy: 0,
+ width: 1024,
+ height: 600,
+ animation: sky,
+ })
+ .addSprite( "sand",
+ {
+ posx: 0,
+ posy: PLAYGROUND_HEIGHT - 115,
+ width: 1018,
+ height: 115,
+ animation: sand,
+ })
+ .addGroup("actors").end()
+ $("#sceengraph").css("background-color", "#88dddd")
+
+ DUDE_WIDTH = 282
+ DUDE_HEIGHT = 463
+ var dude =
+ {
+ currentState: DUDE_STATE.IDLE_RIGHT,
+ // jumping: false,
+ position: 250,
+ width: DUDE_WIDTH,
+ animations:
+ [
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/orig/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-1,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/orig/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-1,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/orig/manrunningsprite.png",
+ numberOfFrame: 15,
+ delta: 456,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: -20,
+ width: 283,
+ height: 456,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/orig/manrunningsprite_left.png",
+ numberOfFrame: 15,
+ delta: 456,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: -20,
+ width: 283,
+ height: 456,
+ },
+ ],
+ }
+ $("#actors").addSprite("dude",
+ {
+ posx: 250,
+ posy: PLAYGROUND_HEIGHT - DUDE_HEIGHT - 115 + 65,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT,
+ animation: dude.animations[0].animation,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ callback: animate,
+ })
+ $("#dude").data("actor", dude)
+
+
+ $(document).bind("keydown", function (e)
+ {
+ // if (dude.jumping)
+ // return
+ switch (e.keyCode)
+ {
+ // case KEY.UP:
+ // dude.jumping = true
+ // break
+ case KEY.RIGHT:
+ changeAnimation($("#dude"), dude, DUDE_STATE.RUN_RIGHT, dude.currentState)
+ break
+ case KEY.LEFT:
+ changeAnimation($("#dude"), dude, DUDE_STATE.RUN_LEFT, dude.currentState)
+ break
+ }
+ })
+ $(document).bind("keyup", function (e)
+ {
+ // if (dude.jumping)
+ // return
+ switch (e.keyCode)
+ {
+ case KEY.RIGHT:
+ changeAnimation($("#dude"), dude, DUDE_STATE.IDLE_RIGHT, dude.currentState)
+ break
+ case KEY.LEFT:
+ changeAnimation($("#dude"), dude, DUDE_STATE.IDLE_LEFT, dude.currentState)
+ break
+ }
+ })
+
+ $.playground().registerCallback( function ()
+ {
+ if (dude.currentState === DUDE_STATE.RUN_RIGHT)
+ {
+ dude.position += 20
+ if (dude.position > PLAYGROUND_WIDTH)
+ dude.position = -dude.width
+ $("#dude").css("left", dude.position)
+ }
+ else if (dude.currentState === DUDE_STATE.RUN_LEFT)
+ {
+ dude.position -= 20
+ if (dude.position < -dude.width + 80)
+ dude.position = PLAYGROUND_WIDTH
+ $("#dude").css("left", dude.position)
+ }
+ }, REFRESH_RATE)
+ $.playground().startGame(function ()
+ {
+ })
+ })
+
+</script>
+</html>
diff --git a/v2.html b/v2.html
new file mode 100755
index 0000000..42c9150
--- /dev/null
+++ b/v2.html
@@ -0,0 +1,420 @@
+<!doctype html>
+<html>
+<head>
+<title></title>
+<style type="text/css">
+body
+ {
+ background-color: #fff;
+ padding: 0; margin: 0;
+ }
+#playground
+ {
+ }
+</style>
+</head>
+<body>
+
+<div id="playground">
+</div>
+
+</body>
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript" src="jquery.gamequery-0.5.1.js"></script>
+<script type="text/javascript">
+var PLAYGROUND_WIDTH = $(window).width() // 900
+var PLAYGROUND_HEIGHT = $(window).height() // 600
+var REFRESH_RATE = 30
+
+$(function ()
+ {
+ var KEY_LEFT = 37
+ var KEY_UP = 38
+ var KEY_RIGHT = 39
+ var KEY_DOWN = 40
+ var KEYTRACK =
+ {
+ KEY_LEFT: false,
+ KEY_UP: false,
+ KEY_RIGHT: false,
+ KEY_DOWN: false,
+ }
+ var IDLE = 0
+ var RUNNING = 1
+ var JUMPING = 2
+ var RUNNING_AND_JUMPING = 3
+ var SWIMMING = 4
+ var DIVING = 5
+
+ var RIGHT = 0
+ var LEFT = 1
+
+ var DUDE_STATE =
+ {
+ IDLE_RIGHT: 0,
+ IDLE_LEFT: 1,
+ RUN_RIGHT: 2,
+ RUN_LEFT: 3,
+ JUMPING_RIGHT: 4,
+ JUMPING_LEFT: 5,
+ RUNNING_AND_JUMPING_RIGHT: 6,
+ RUNNING_AND_JUMPING_LEFT: 7,
+ }
+
+ $("#playground").playground({height: PLAYGROUND_HEIGHT, width: PLAYGROUND_WIDTH, refreshRate: REFRESH_RATE, keyTracker: false})
+
+ function update_animation (sprite, actor)
+ {
+ new_state = actor.activity * 2 + actor.orientation
+ if (actor.state === new_state)
+ return
+ old_anim = actor.animations[actor.state]
+ new_anim = actor.animations[new_state]
+ actor.state = new_state
+ dude.y += new_anim.deltaY - old_anim.deltaY
+ dude.x += new_anim.deltaX - old_anim.deltaX
+ sprite.setAnimation(new_anim.animation)
+ .width(new_anim.width)
+ .height(new_anim.height)
+ .css("top", sprite.position().top + new_anim.deltaY - old_anim.deltaY)
+ .css("left", sprite.position().left + new_anim.deltaX - old_anim.deltaX)
+ }
+ var FLOOR_HEIGHT = 115
+ var sky = new $.gameQuery.Animation({imageURL: "./sky.png"})
+ var sand = new $.gameQuery.Animation({imageURL: "./sand.png"})
+ $.playground()
+ .addSprite( "sky",
+ {
+ posx: 0,
+ posy: 0,
+ width: PLAYGROUND_WIDTH,
+ height: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ animation: sky,
+ })
+ .addSprite( "sand",
+ {
+ posx: 0,
+ posy: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ width: PLAYGROUND_WIDTH,
+ height: FLOOR_HEIGHT,
+ animation: sand,
+ })
+ .addGroup("actors").end()
+ $("#sceengraph").css("background-color", "#88dddd")
+
+ MAX_YSPEED = 10
+ RUN_SPEED = 10
+ GRAVITY = 1
+ TERMINAL_VELOCITY = 10
+ JUMP_POWER = 10
+
+ FLOOR_DEPTH = 30
+ DUDE_WIDTH = 140
+ DUDE_HEIGHT = 231
+ DUDE_START_X = 250
+ DUDE_START_Y = PLAYGROUND_HEIGHT - DUDE_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH + TERMINAL_VELOCITY
+ var dude =
+ {
+ state: DUDE_STATE.IDLE_RIGHT,
+ activity: IDLE,
+ orientation: RIGHT,
+ can_jump: true,
+ running_while_jumping: true,
+ xspeed: 0,
+ yspeed: 0,
+ x: DUDE_START_X,
+ y: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-10,
+ animations:
+ [
+ // IDLE
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite_left.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ // JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING AND JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ ],
+ }
+ $("#actors").addSprite("dude",
+ {
+ posx: DUDE_START_X,
+ posy: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ animation: dude.animations[0].animation,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ // callback: animate,
+ })
+ $("#dude").data("actor", dude)
+
+ $(window).bind("blur", function (e)
+ {
+ $.each(KEYTRACK, function (k,v) { KEYTRACK[k] = false })
+ })
+ $(document).bind("keydown", function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ dude.orientation = RIGHT
+ break
+ case KEY_LEFT:
+ dude.orientation = LEFT
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+ $(document).bind("keyup", function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ break
+ case KEY_LEFT:
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+
+ WATER_LINE = 10000
+ function actor_has_landed (actor)
+ {
+ if (actor.x < WATER_LINE)
+ return (actor.y + actor.height) > (PLAYGROUND_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH - TERMINAL_VELOCITY)
+ else
+ return true
+ }
+ $.playground().registerCallback( function ()
+ {
+ switch (dude.activity)
+ {
+ case IDLE:
+ dude.can_jump = true
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.activity = RUNNING
+ }
+ break
+ case RUNNING:
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = RUNNING_AND_JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.orientation = LEFT
+ dude.xspeed = -1 * RUN_SPEED
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.orientation = RIGHT
+ dude.xspeed = RUN_SPEED
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = IDLE
+ dude.xspeed = 0
+ }
+ break
+ case JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.xspeed = 0
+ dude.yspeed = 0
+ dude.activity = IDLE
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = -1 * RUN_SPEED
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = RUN_SPEED
+ }
+ break
+ case RUNNING_AND_JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.yspeed = 0
+ if (KEYTRACK[KEY_UP])
+ dude.yspeed -= JUMP_POWER
+ else
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.orientation = LEFT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.orientation = RIGHT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = JUMPING
+ }
+ break
+ }
+ dude.x += dude.xspeed
+ dude.y += dude.yspeed
+ $("#dude").css({"top": dude.y, "left": dude.x})
+ update_animation($("#dude"), dude)
+ }, REFRESH_RATE)
+ $.playground().startGame(function ()
+ {
+ })
+ })
+
+</script>
+</html>
diff --git a/v3.html b/v3.html
new file mode 100755
index 0000000..8b378d5
--- /dev/null
+++ b/v3.html
@@ -0,0 +1,501 @@
+<!doctype html>
+<html>
+<head>
+<title></title>
+<style type="text/css">
+body
+ {
+ background-color: #fff;
+ padding: 0; margin: 0;
+ }
+#playground
+ {
+ }
+#hud
+ {
+ font-family: sans-serif;
+ position: fixed;
+ top: 10px;
+ right: 10px;
+ width: 300px;
+ font-size: 14px
+ padding: 5px;
+ opacity: 0.7;
+ color: #000;
+ background: #fff;
+ z-index: 666;
+ }
+</style>
+</head>
+<body>
+
+<div id="playground">
+</div>
+
+<div id="hud"></div>
+
+</body>
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript" src="jquery.gamequery-0.5.1.js"></script>
+<script type="text/javascript">
+var PLAYGROUND_WIDTH = $(window).width() // 900
+var PLAYGROUND_HEIGHT = $(window).height() // 600
+var REFRESH_RATE = 30
+
+$(function ()
+ {
+ var KEY_LEFT = 37
+ var KEY_UP = 38
+ var KEY_RIGHT = 39
+ var KEY_DOWN = 40
+ var KEYTRACK =
+ {
+ KEY_LEFT: false,
+ KEY_UP: false,
+ KEY_RIGHT: false,
+ KEY_DOWN: false,
+ }
+ var IDLE = 0
+ var RUNNING = 1
+ var JUMPING = 2
+ var RUNNING_AND_JUMPING = 3
+ var SWIMMING = 4
+ var DIVING = 5
+
+ var RIGHT = 0
+ var LEFT = 1
+
+ var DUDE_STATE =
+ {
+ IDLE_RIGHT: 0,
+ IDLE_LEFT: 1,
+ RUN_RIGHT: 2,
+ RUN_LEFT: 3,
+ JUMPING_RIGHT: 4,
+ JUMPING_LEFT: 5,
+ RUNNING_AND_JUMPING_RIGHT: 6,
+ RUNNING_AND_JUMPING_LEFT: 7,
+ }
+
+ $("#playground").playground({height: PLAYGROUND_HEIGHT, width: PLAYGROUND_WIDTH, refreshRate: REFRESH_RATE, keyTracker: false})
+
+ function update_animation (sprite, actor)
+ {
+ new_state = actor.activity * 2 + actor.orientation
+ if (actor.state === new_state)
+ return
+ old_anim = actor.animations[actor.state]
+ new_anim = actor.animations[new_state]
+ actor.state = new_state
+ dude.y += new_anim.deltaY - old_anim.deltaY
+ dude.x += new_anim.deltaX - old_anim.deltaX
+ sprite.setAnimation(new_anim.animation)
+ .width(new_anim.width)
+ .height(new_anim.height)
+ .css("top", sprite.position().top + new_anim.deltaY - old_anim.deltaY)
+ .css("left", sprite.position().left + new_anim.deltaX - old_anim.deltaX)
+ }
+ var stage =
+ {
+ x: 0,
+ y: 0,
+ sea_distance: 2000,
+ scroll: function ()
+ {
+ $("#sand").css({"left": stage.x})
+ $("#sea").css({"left": stage.sea_distance + stage.x})
+ },
+ }
+ var FLOOR_HEIGHT = 115
+ var sky = new $.gameQuery.Animation({imageURL: "./sky.png"})
+ var sand = new $.gameQuery.Animation({imageURL: "./sand.png"})
+ var sea = new $.gameQuery.Animation({imageURL: "./sea.png"})
+ $.playground()
+ .addSprite( "sky",
+ {
+ posx: 0,
+ posy: 0,
+ width: PLAYGROUND_WIDTH,
+ height: PLAYGROUND_HEIGHT,
+ animation: sky,
+ })
+ .addSprite( "sand",
+ {
+ posx: 0,
+ posy: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ width: stage.sea_distance,
+ height: FLOOR_HEIGHT,
+ animation: sand,
+ })
+ .addSprite( "sea",
+ {
+ posx: stage.sea_distance,
+ posy: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ width: PLAYGROUND_WIDTH,
+ height: FLOOR_HEIGHT,
+ animation: sea,
+ })
+ .addGroup("actors").end()
+ $("#sceengraph").css("background-color", "#88dddd")
+
+ MAX_YSPEED = 10
+ RUN_SPEED = 10
+ GRAVITY = 1
+ TERMINAL_VELOCITY = 10
+ JUMP_POWER = 10
+
+ FLOOR_DEPTH = 30
+ DUDE_WIDTH = 140
+ DUDE_HEIGHT = 231
+ DUDE_START_X = 250
+ DUDE_START_Y = PLAYGROUND_HEIGHT - DUDE_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH + TERMINAL_VELOCITY
+ var dude =
+ {
+ state: DUDE_STATE.IDLE_RIGHT,
+ activity: IDLE,
+ orientation: RIGHT,
+ can_jump: true,
+ running_while_jumping: true,
+ xspeed: 0,
+ yspeed: 0,
+ x: DUDE_START_X,
+ y: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-10,
+ animations:
+ [
+ // IDLE
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite_left.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ // JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING AND JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ ],
+ }
+ $("#actors").addSprite("dude",
+ {
+ posx: DUDE_START_X,
+ posy: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ animation: dude.animations[0].animation,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ // callback: animate,
+ })
+ $("#dude").data("actor", dude)
+
+ $(window).bind("blur", function (e)
+ {
+ $.each(KEYTRACK, function (k,v) { KEYTRACK[k] = false })
+ })
+ $(document).bind("keydown", function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ dude.orientation = RIGHT
+ break
+ case KEY_LEFT:
+ dude.orientation = LEFT
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+ $(document).bind("keyup", function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ break
+ case KEY_LEFT:
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+
+ WATER_LINE = 10000
+ function actor_has_landed (actor)
+ {
+ if (actor.x < WATER_LINE)
+ return (actor.y + actor.height) > (PLAYGROUND_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH - TERMINAL_VELOCITY)
+ else
+ return true
+ }
+ $.playground().registerCallback( function ()
+ {
+ switch (dude.activity)
+ {
+ case IDLE:
+ dude.can_jump = true
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.activity = RUNNING
+ }
+ break
+ case RUNNING:
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = RUNNING_AND_JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.orientation = LEFT
+ dude.xspeed = -1 * RUN_SPEED
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.orientation = RIGHT
+ dude.xspeed = RUN_SPEED
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = IDLE
+ dude.xspeed = 0
+ }
+ break
+ case JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.xspeed = 0
+ dude.yspeed = 0
+ dude.activity = IDLE
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = -1 * RUN_SPEED
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = RUN_SPEED
+ }
+ break
+ case RUNNING_AND_JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.yspeed = 0
+ if (KEYTRACK[KEY_UP])
+ dude.yspeed -= JUMP_POWER
+ else
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.orientation = LEFT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.orientation = RIGHT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = JUMPING
+ }
+ break
+ }
+
+ if (stage.x === 0)
+ {
+ if (KEYTRACK[KEY_LEFT] || dude.x < 310)
+ dude.x += dude.xspeed
+ else
+ {
+ stage.x -= dude.xspeed
+ if (stage.x > 0)
+ stage.x = 0
+ }
+ if (dude.x < 0)
+ {
+ dude.x = 0
+ dude.activity = IDLE
+ }
+ }
+ else if (stage.x > -1* (stage.sea_distance - 550)) // || dude.orientation === LEFT)
+ {
+ stage.x -= dude.xspeed
+ }
+ else
+ {
+ dude.x += dude.xspeed
+ if (dude.x > 400)
+ {
+ dude.x = 400
+ if (dude.activity === JUMPING)
+ {
+ }
+ else if (dude.activity === RUNNING_AND_JUMPING)
+ {
+ dude.activity = JUMPING
+ }
+ else
+ dude.activity = IDLE
+ }
+ else if (dude.x < 350)
+ stage.x -= dude.xspeed
+ }
+ dude.y += dude.yspeed
+ $("#dude").css({"top": dude.y, "left": dude.x})
+ update_animation($("#dude"), dude)
+ stage.scroll ()
+ $("#hud").html(
+ [
+ "dude @ ", dude.x, " ", dude.y, "<br/>",
+ "stage @ ", stage.x, " ", stage.y, "<br/>",
+ ].join(" "))
+ }, REFRESH_RATE)
+ $.playground().startGame(function ()
+ {
+ })
+ })
+
+</script>
+</html>
diff --git a/v4.html b/v4.html
new file mode 100755
index 0000000..a39163a
--- /dev/null
+++ b/v4.html
@@ -0,0 +1,629 @@
+<!doctype html>
+<html>
+<head>
+<title></title>
+<style type="text/css">
+@font-face
+ {
+ font-family: Commodore;
+ src: url("fonts/Commodore-Rounded-v1.2.ttf");
+ }
+body
+ {
+ background-color: #fff;
+ padding: 0; margin: 0;
+ }
+#playground
+ {
+ }
+#hud
+ {
+ font-family: Commodore, sans-serif;
+ position: fixed;
+ top: 10px;
+ right: 10px;
+ width: 300px;
+ font-size: 14px
+ padding: 5px;
+ opacity: 0.7;
+ color: #000;
+ background: #fff;
+ z-index: 666;
+ display: none;
+ }
+#message
+ {
+ position: fixed;
+ bottom: 400px;
+ left: 20px;
+ width: 600px;
+ height: 100px;
+ font-size: 36px;
+ font-family: Commodore, sans-serif;
+ padding: 20px;
+ background-color: white;
+ color: black;
+ border: 4px solid black;
+ display: none;
+ }
+#message-corner
+ {
+ position: fixed;
+ bottom: 354px;
+ left: 80px;
+ height: 50px;
+ width: 50px;
+ display: none;
+ }
+#black-arrow
+ {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 0;
+ height: 0;
+ border-bottom: 46px solid transparent;
+ border-top: 46px solid black;
+ border-left: 46px solid transparent;
+ border-right: 46px solid transparent;
+ }
+#white-arrow
+ {
+ position: absolute;
+ top: 0;
+ left: 6px;
+ width: 0;
+ height: 0;
+ border-bottom: 40px solid transparent;
+ border-top: 40px solid white;
+ border-left: 40px solid transparent;
+ border-right: 40px solid transparent;
+ }
+</style>
+</head>
+<body>
+
+<div id="playground">
+</div>
+
+<div id="message">
+</div>
+<div id="message-corner">
+ <div id="black-arrow"></div>
+ <div id="white-arrow"></div>
+</div>
+<div id="hud"></div>
+
+</body>
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript" src="jquery.gamequery-0.5.1.js"></script>
+<script type="text/javascript">
+var PLAYGROUND_WIDTH = $(window).width() // 900
+var PLAYGROUND_HEIGHT = $(window).height() // 600
+var REFRESH_RATE = 30
+
+$(function ()
+ {
+ var KEY_LEFT = 37
+ var KEY_UP = 38
+ var KEY_RIGHT = 39
+ var KEY_DOWN = 40
+ var KEYTRACK =
+ {
+ KEY_LEFT: false,
+ KEY_UP: false,
+ KEY_RIGHT: false,
+ KEY_DOWN: false,
+ }
+ var IDLE = 0
+ var RUNNING = 1
+ var JUMPING = 2
+ var RUNNING_AND_JUMPING = 3
+ var SWIMMING = 4
+ var DIVING = 5
+
+ var RIGHT = 0
+ var LEFT = 1
+
+ var DUDE_STATE =
+ {
+ IDLE_RIGHT: 0,
+ IDLE_LEFT: 1,
+ RUN_RIGHT: 2,
+ RUN_LEFT: 3,
+ JUMPING_RIGHT: 4,
+ JUMPING_LEFT: 5,
+ RUNNING_AND_JUMPING_RIGHT: 6,
+ RUNNING_AND_JUMPING_LEFT: 7,
+ }
+
+ $("#playground").playground({height: PLAYGROUND_HEIGHT, width: PLAYGROUND_WIDTH, refreshRate: REFRESH_RATE, keyTracker: false})
+
+ function update_animation (sprite, actor)
+ {
+ new_state = actor.activity * 2 + actor.orientation
+ if (actor.state === new_state)
+ return
+ old_anim = actor.animations[actor.state]
+ new_anim = actor.animations[new_state]
+ actor.state = new_state
+ dude.y += new_anim.deltaY - old_anim.deltaY
+ dude.x += new_anim.deltaX - old_anim.deltaX
+ sprite.setAnimation(new_anim.animation)
+ .width(new_anim.width)
+ .height(new_anim.height)
+ .css("top", sprite.position().top + new_anim.deltaY - old_anim.deltaY)
+ .css("left", sprite.position().left + new_anim.deltaX - old_anim.deltaX)
+ }
+ var stage =
+ {
+ x: 0,
+ y: 0,
+ biffx: 20,
+ sea_distance: 2000,
+ scroll: function ()
+ {
+ $("#sand").css({"left": stage.x})
+ $("#biff").css({"left": stage.biffx + stage.x})
+ $("#sea").css({"left": stage.sea_distance + stage.x})
+ },
+ }
+ var FLOOR_HEIGHT = 115
+ var sky = new $.gameQuery.Animation({imageURL: "./sky.png"})
+ var sand = new $.gameQuery.Animation({imageURL: "./sand.png"})
+ var sea = new $.gameQuery.Animation({imageURL: "./sea.png"})
+ $.playground()
+ .addSprite( "sky",
+ {
+ posx: 0,
+ posy: 0,
+ width: PLAYGROUND_WIDTH,
+ height: PLAYGROUND_HEIGHT,
+ animation: sky,
+ })
+ .addSprite( "sand",
+ {
+ posx: 0,
+ posy: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ width: stage.sea_distance,
+ height: FLOOR_HEIGHT,
+ animation: sand,
+ })
+ .addSprite( "sea",
+ {
+ posx: stage.sea_distance,
+ posy: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ width: PLAYGROUND_WIDTH,
+ height: FLOOR_HEIGHT,
+ animation: sea,
+ })
+ .addGroup("actors").end()
+ $("#sceengraph").css("background-color", "#88dddd")
+
+ MAX_YSPEED = 10
+ RUN_SPEED = 10
+ GRAVITY = 1
+ TERMINAL_VELOCITY = 10
+ JUMP_POWER = 10
+
+ FLOOR_DEPTH = 30
+ DUDE_WIDTH = 140
+ DUDE_HEIGHT = 231
+ DUDE_START_X = 300
+ DUDE_START_Y = PLAYGROUND_HEIGHT - DUDE_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH + TERMINAL_VELOCITY
+ var dude =
+ {
+ state: DUDE_STATE.IDLE_RIGHT,
+ activity: IDLE,
+ orientation: RIGHT,
+ can_jump: true,
+ running_while_jumping: true,
+ xspeed: 0,
+ yspeed: 0,
+ x: DUDE_START_X,
+ y: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-10,
+ animations:
+ [
+ // IDLE
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite_left.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ // JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING AND JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ ],
+ }
+ BIFF_START_X = 20
+ var biff =
+ {
+ state: DUDE_STATE.IDLE_RIGHT,
+ activity: IDLE,
+ orientation: RIGHT,
+ can_jump: true,
+ running_while_jumping: true,
+ xspeed: 0,
+ yspeed: 0,
+ spoke: false,
+ x: BIFF_START_X,
+ y: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-10,
+ animations:
+ [
+ // IDLE
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_brown.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ ],
+ }
+ $("#actors").addSprite("biff",
+ {
+ posx: BIFF_START_X,
+ posy: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ animation: biff.animations[0].animation,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ // callback: animate,
+ })
+ $("#biff").data("actor", biff)
+
+ $("#actors").addSprite("dude",
+ {
+ posx: DUDE_START_X,
+ posy: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ animation: dude.animations[0].animation,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ // callback: animate,
+ })
+ $("#dude").data("actor", dude)
+
+
+ $(window).bind("blur", function (e)
+ {
+ $.each(KEYTRACK, function (k,v) { KEYTRACK[k] = false })
+ })
+ $(document).bind("keydown", function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ dude.orientation = RIGHT
+ break
+ case KEY_LEFT:
+ dude.orientation = LEFT
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+ $(document).bind("keyup", function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ break
+ case KEY_LEFT:
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+
+ WATER_LINE = 10000
+ function actor_has_landed (actor)
+ {
+ if (actor.x < WATER_LINE)
+ return (actor.y + actor.height) > (PLAYGROUND_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH - TERMINAL_VELOCITY)
+ else
+ return true
+ }
+ $.playground().registerCallback( function ()
+ {
+ switch (dude.activity)
+ {
+ case IDLE:
+ dude.can_jump = true
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.activity = RUNNING
+ }
+ break
+ case RUNNING:
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = RUNNING_AND_JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.orientation = LEFT
+ dude.xspeed = -1 * RUN_SPEED
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.orientation = RIGHT
+ dude.xspeed = RUN_SPEED
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = IDLE
+ dude.xspeed = 0
+ }
+ break
+ case JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.xspeed = 0
+ dude.yspeed = 0
+ dude.activity = IDLE
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = -1 * RUN_SPEED
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = RUN_SPEED
+ }
+ break
+ case RUNNING_AND_JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.yspeed = 0
+ if (KEYTRACK[KEY_UP])
+ dude.yspeed -= JUMP_POWER
+ else
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.orientation = LEFT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.orientation = RIGHT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = JUMPING
+ }
+ break
+ }
+
+ if (stage.x === 0)
+ {
+ if (KEYTRACK[KEY_LEFT] || dude.x < 310)
+ dude.x += dude.xspeed
+ else
+ {
+ stage.x -= dude.xspeed
+ if (stage.x > 0)
+ stage.x = 0
+ }
+ if (dude.x < 160)
+ {
+ dude.x = 160
+ if (dude.activity === JUMPING)
+ {
+ }
+ else if (dude.activity === RUNNING_AND_JUMPING)
+ {
+ dude.activity = JUMPING
+ }
+ else
+ dude.activity = IDLE
+ }
+ if (dude.x < 170)
+ {
+ $("#message").show(400, function(){$("#message").html("what up doe?"); })
+ $("#message-corner").show(200)
+ biff.spoke = true
+ }
+ else if (dude.x > 190)
+ {
+ $("#message-corner").hide(100)
+ $("#message").hide(400).html("")
+ }
+ }
+ else if (stage.x > -1* (stage.sea_distance - 550)) // || dude.orientation === LEFT)
+ {
+ stage.x -= dude.xspeed
+ }
+ else
+ {
+ dude.x += dude.xspeed
+ if (dude.x > 400)
+ {
+ dude.x = 400
+ if (dude.activity === JUMPING)
+ {
+ }
+ else if (dude.activity === RUNNING_AND_JUMPING)
+ {
+ dude.activity = JUMPING
+ }
+ else
+ dude.activity = IDLE
+ }
+ else if (dude.x < 350)
+ stage.x -= dude.xspeed
+ }
+ dude.y += dude.yspeed
+ $("#dude").css({"top": dude.y, "left": dude.x})
+ update_animation($("#dude"), dude)
+ stage.scroll ()
+ $("#hud").html(
+ [
+ "dude @ ", dude.x, " ", dude.y, "<br/>",
+ "stage @ ", stage.x, " ", stage.y, "<br/>",
+ ].join(" "))
+ }, REFRESH_RATE)
+ $.playground().startGame(function ()
+ {
+ })
+ })
+
+</script>
+</html>
diff --git a/v5.html b/v5.html
new file mode 100755
index 0000000..b0d10ca
--- /dev/null
+++ b/v5.html
@@ -0,0 +1,632 @@
+<!doctype html>
+<html>
+<head>
+<title></title>
+<style type="text/css">
+@font-face
+ {
+ font-family: Commodore;
+ src: url("fonts/Commodore-Rounded-v1.2.ttf");
+ }
+body
+ {
+ background-color: #fff;
+ padding: 0; margin: 0;
+ }
+#playground
+ {
+ }
+#hud
+ {
+ font-family: Commodore, sans-serif;
+ position: fixed;
+ top: 10px;
+ right: 10px;
+ width: 300px;
+ font-size: 14px
+ padding: 5px;
+ opacity: 0.7;
+ color: #000;
+ background: #fff;
+ z-index: 666;
+ display: none;
+ }
+#message
+ {
+ position: fixed;
+ bottom: 400px;
+ left: 20px;
+ width: 600px;
+ height: 100px;
+ font-size: 36px;
+ font-family: Commodore, sans-serif;
+ padding: 20px;
+ background-color: white;
+ color: black;
+ border: 4px solid black;
+ display: none;
+ }
+#message-corner
+ {
+ position: fixed;
+ bottom: 354px;
+ left: 80px;
+ height: 50px;
+ width: 50px;
+ display: none;
+ }
+#black-arrow
+ {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 0;
+ height: 0;
+ border-bottom: 46px solid transparent;
+ border-top: 46px solid black;
+ border-left: 46px solid transparent;
+ border-right: 46px solid transparent;
+ }
+#white-arrow
+ {
+ position: absolute;
+ top: 0;
+ left: 6px;
+ width: 0;
+ height: 0;
+ border-bottom: 40px solid transparent;
+ border-top: 40px solid white;
+ border-left: 40px solid transparent;
+ border-right: 40px solid transparent;
+ }
+</style>
+</head>
+<body>
+
+<div id="playground">
+</div>
+
+<div id="message">
+</div>
+<div id="message-corner">
+ <div id="black-arrow"></div>
+ <div id="white-arrow"></div>
+</div>
+<div id="hud"></div>
+
+</body>
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript" src="jquery.gamequery-0.5.1.js"></script>
+<script type="text/javascript">
+var PLAYGROUND_WIDTH = $(window).width() // 900
+var PLAYGROUND_HEIGHT = $(window).height() // 600
+var REFRESH_RATE = 30
+
+$(function ()
+ {
+ var KEY_LEFT = 37
+ var KEY_UP = 38
+ var KEY_RIGHT = 39
+ var KEY_DOWN = 40
+ var KEYTRACK =
+ {
+ KEY_LEFT: false,
+ KEY_UP: false,
+ KEY_RIGHT: false,
+ KEY_DOWN: false,
+ }
+ var IDLE = 0
+ var RUNNING = 1
+ var JUMPING = 2
+ var RUNNING_AND_JUMPING = 3
+ var SWIMMING = 4
+ var DIVING = 5
+
+ var RIGHT = 0
+ var LEFT = 1
+
+ var DUDE_STATE =
+ {
+ IDLE_RIGHT: 0,
+ IDLE_LEFT: 1,
+ RUN_RIGHT: 2,
+ RUN_LEFT: 3,
+ JUMPING_RIGHT: 4,
+ JUMPING_LEFT: 5,
+ RUNNING_AND_JUMPING_RIGHT: 6,
+ RUNNING_AND_JUMPING_LEFT: 7,
+ }
+
+ $("#playground").playground({height: PLAYGROUND_HEIGHT, width: PLAYGROUND_WIDTH, refreshRate: REFRESH_RATE, keyTracker: false})
+
+ function update_animation (sprite, actor)
+ {
+ new_state = actor.activity * 2 + actor.orientation
+ if (actor.state === new_state)
+ return
+ old_anim = actor.animations[actor.state]
+ new_anim = actor.animations[new_state]
+ actor.state = new_state
+ dude.y += new_anim.deltaY - old_anim.deltaY
+ dude.x += new_anim.deltaX - old_anim.deltaX
+ sprite.setAnimation(new_anim.animation)
+ .width(new_anim.width)
+ .height(new_anim.height)
+ .css("top", sprite.position().top + new_anim.deltaY - old_anim.deltaY)
+ .css("left", sprite.position().left + new_anim.deltaX - old_anim.deltaX)
+ }
+ var stage =
+ {
+ x: 0,
+ y: 0,
+ biffx: 20,
+ sea_distance: 2000,
+ scroll: function ()
+ {
+ $("#sand").css({"left": stage.x})
+ $("#biff").css({"left": stage.biffx + stage.x})
+ $("#sea").css({"left": stage.sea_distance + stage.x})
+ },
+ }
+ var FLOOR_HEIGHT = 115
+ var sky = new $.gameQuery.Animation({imageURL: "./sky.png"})
+ var sand = new $.gameQuery.Animation({imageURL: "./sand.png"})
+ var sea = new $.gameQuery.Animation({imageURL: "./sea.png"})
+ $.playground()
+ .addSprite( "sky",
+ {
+ posx: 0,
+ posy: 0,
+ width: PLAYGROUND_WIDTH,
+ height: PLAYGROUND_HEIGHT,
+ animation: sky,
+ })
+ .addSprite( "sand",
+ {
+ posx: 0,
+ posy: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ width: stage.sea_distance,
+ height: FLOOR_HEIGHT,
+ animation: sand,
+ })
+ .addSprite( "sea",
+ {
+ posx: stage.sea_distance,
+ posy: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ width: PLAYGROUND_WIDTH,
+ height: FLOOR_HEIGHT,
+ animation: sea,
+ })
+ .addGroup("actors").end()
+ $("#sceengraph").css("background-color", "#88dddd")
+
+ MAX_YSPEED = 10
+ RUN_SPEED = 10
+ GRAVITY = 1
+ TERMINAL_VELOCITY = 10
+ JUMP_POWER = 10
+
+ FLOOR_DEPTH = 30
+ DUDE_WIDTH = 140
+ DUDE_HEIGHT = 231
+ DUDE_START_X = 300
+ DUDE_START_Y = PLAYGROUND_HEIGHT - DUDE_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH + TERMINAL_VELOCITY
+ var dude =
+ {
+ state: DUDE_STATE.IDLE_RIGHT,
+ activity: IDLE,
+ orientation: RIGHT,
+ can_jump: true,
+ running_while_jumping: true,
+ xspeed: 0,
+ yspeed: 0,
+ x: DUDE_START_X,
+ y: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-10,
+ animations:
+ [
+ // IDLE
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite_left.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ // JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING AND JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ ],
+ }
+ BIFF_HEIGHT = 500
+ BIFF_WIDTH = 500
+ BIFF_START_X = 20
+ BIFF_START_Y = PLAYGROUND_HEIGHT - BIFF_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH + TERMINAL_VELOCITY + 30
+ var biff =
+ {
+ state: DUDE_STATE.IDLE_RIGHT,
+ activity: IDLE,
+ orientation: RIGHT,
+ can_jump: true,
+ running_while_jumping: true,
+ xspeed: 0,
+ yspeed: 0,
+ spoke: false,
+ x: BIFF_START_X,
+ y: BIFF_START_Y,
+ width: BIFF_WIDTH,
+ height: BIFF_HEIGHT,
+ animations:
+ [
+ // IDLE
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "/im/17/1299880975157dumpfmpepperglitter_hand_askin_left_1310538093_1310593206.gif",
+ numberOfFrame: 1,
+ delta: BIFF_HEIGHT,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: BIFF_WIDTH,
+ height: BIFF_HEIGHT,
+ },
+ ],
+ }
+ $("#actors").addSprite("biff",
+ {
+ posx: BIFF_START_X,
+ posy: BIFF_START_Y,
+ width: BIFF_WIDTH,
+ height: BIFF_HEIGHT,
+ animation: biff.animations[0].animation,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ // callback: animate,
+ })
+ $("#biff").data("actor", biff)
+
+ $("#actors").addSprite("dude",
+ {
+ posx: DUDE_START_X,
+ posy: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ animation: dude.animations[0].animation,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ // callback: animate,
+ })
+ $("#dude").data("actor", dude)
+
+
+ $(window).bind("blur", function (e)
+ {
+ $.each(KEYTRACK, function (k,v) { KEYTRACK[k] = false })
+ })
+ $(document).bind("keydown", function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ dude.orientation = RIGHT
+ break
+ case KEY_LEFT:
+ dude.orientation = LEFT
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+ $(document).bind("keyup", function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ break
+ case KEY_LEFT:
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+
+ WATER_LINE = 10000
+ function actor_has_landed (actor)
+ {
+ if (actor.x < WATER_LINE)
+ return (actor.y + actor.height) > (PLAYGROUND_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH - TERMINAL_VELOCITY)
+ else
+ return true
+ }
+ $.playground().registerCallback( function ()
+ {
+ switch (dude.activity)
+ {
+ case IDLE:
+ dude.can_jump = true
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.activity = RUNNING
+ }
+ break
+ case RUNNING:
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = RUNNING_AND_JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.orientation = LEFT
+ dude.xspeed = -1 * RUN_SPEED
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.orientation = RIGHT
+ dude.xspeed = RUN_SPEED
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = IDLE
+ dude.xspeed = 0
+ }
+ break
+ case JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.xspeed = 0
+ dude.yspeed = 0
+ dude.activity = IDLE
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = -1 * RUN_SPEED
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = RUN_SPEED
+ }
+ break
+ case RUNNING_AND_JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.yspeed = 0
+ if (KEYTRACK[KEY_UP])
+ dude.yspeed -= JUMP_POWER
+ else
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.orientation = LEFT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.orientation = RIGHT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = JUMPING
+ }
+ break
+ }
+
+ if (stage.x === 0)
+ {
+ if (KEYTRACK[KEY_LEFT] || dude.x < 310)
+ dude.x += dude.xspeed
+ else
+ {
+ stage.x -= dude.xspeed
+ if (stage.x > 0)
+ stage.x = 0
+ }
+ if (dude.x < 160)
+ {
+ dude.x = 160
+ if (dude.activity === JUMPING)
+ {
+ }
+ else if (dude.activity === RUNNING_AND_JUMPING)
+ {
+ dude.activity = JUMPING
+ }
+ else
+ dude.activity = IDLE
+ }
+ if (dude.x < 170)
+ {
+ $("#message").show(400, function(){$("#message").html("what up doe?"); })
+ $("#message-corner").show(200)
+ biff.spoke = true
+ }
+ else if (dude.x > 190)
+ {
+ $("#message-corner").hide(100)
+ $("#message").hide(400).html("")
+ }
+ }
+ else if (stage.x > -1* (stage.sea_distance - 550)) // || dude.orientation === LEFT)
+ {
+ stage.x -= dude.xspeed
+ }
+ else
+ {
+ dude.x += dude.xspeed
+ if (dude.x > 400)
+ {
+ dude.x = 400
+ if (dude.activity === JUMPING)
+ {
+ }
+ else if (dude.activity === RUNNING_AND_JUMPING)
+ {
+ dude.activity = JUMPING
+ }
+ else
+ dude.activity = IDLE
+ }
+ else if (dude.x < 350)
+ stage.x -= dude.xspeed
+ }
+ dude.y += dude.yspeed
+ $("#dude").css({"top": dude.y, "left": dude.x})
+ update_animation($("#dude"), dude)
+ stage.scroll ()
+ $("#hud").html(
+ [
+ "dude @ ", dude.x, " ", dude.y, "<br/>",
+ "stage @ ", stage.x, " ", stage.y, "<br/>",
+ ].join(" "))
+ }, REFRESH_RATE)
+ $.playground().startGame(function ()
+ {
+ })
+ })
+
+</script>
+</html>
diff --git a/v6.html b/v6.html
new file mode 100755
index 0000000..a15faae
--- /dev/null
+++ b/v6.html
@@ -0,0 +1,736 @@
+<!doctype html>
+<html>
+<head>
+<title></title>
+<style type="text/css">
+@font-face
+ {
+ font-family: Commodore;
+ src: url("fonts/Commodore-Rounded-v1.2.ttf");
+ }
+body
+ {
+ background-color: #fff;
+ padding: 0; margin: 0;
+ }
+#playground
+ {
+ }
+#hud
+ {
+ font-family: Commodore, sans-serif;
+ position: fixed;
+ top: 10px;
+ right: 10px;
+ width: 300px;
+ font-size: 14px
+ padding: 5px;
+ opacity: 0.7;
+ color: #000;
+ background: #fff;
+ z-index: 666;
+ }
+#message
+ {
+ position: fixed;
+ bottom: 400px;
+ left: 20px;
+ width: 600px;
+ height: 100px;
+ font-size: 36px;
+ font-family: Commodore, sans-serif;
+ padding: 20px;
+ background-color: white;
+ color: black;
+ border: 4px solid black;
+ display: none;
+ }
+#message-corner
+ {
+ position: fixed;
+ bottom: 354px;
+ left: 80px;
+ height: 50px;
+ width: 50px;
+ display: none;
+ }
+#black-arrow
+ {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 0;
+ height: 0;
+ border-bottom: 46px solid transparent;
+ border-top: 46px solid black;
+ border-left: 46px solid transparent;
+ border-right: 46px solid transparent;
+ }
+#white-arrow
+ {
+ position: absolute;
+ top: 0;
+ left: 6px;
+ width: 0;
+ height: 0;
+ border-bottom: 40px solid transparent;
+ border-top: 40px solid white;
+ border-left: 40px solid transparent;
+ border-right: 40px solid transparent;
+ }
+</style>
+</head>
+<body>
+
+<div id="playground">
+</div>
+
+<div id="message">
+</div>
+<div id="message-corner">
+ <div id="black-arrow"></div>
+ <div id="white-arrow"></div>
+</div>
+<div id="hud"></div>
+
+</body>
+<script type="text/javascript" src="/js/jquery.js"></script>
+<script type="text/javascript" src="jquery.gamequery-0.5.1.js"></script>
+<script type="text/javascript">
+var PLAYGROUND_WIDTH = $(window).width() // 900
+var PLAYGROUND_HEIGHT = $(window).height() // 600
+var REFRESH_RATE = 30
+
+$(function ()
+ {
+ var KEY_LEFT = 37
+ var KEY_UP = 38
+ var KEY_RIGHT = 39
+ var KEY_DOWN = 40
+ var KEYTRACK =
+ {
+ KEY_LEFT: false,
+ KEY_UP: false,
+ KEY_RIGHT: false,
+ KEY_DOWN: false,
+ }
+ var STATES = "IDLE RUNNING JUMPING RUNNING_AND_JUMPING SWIMMING DIVING CANNONBALL".split(" ")
+ var ORIENTATIONS = "RIGHT LEFT".split(" ")
+ var ENVIRONMENTS = "LAND WATER".split(" ")
+
+ var IDLE = 0
+ var RUNNING = 1
+ var JUMPING = 2
+ var RUNNING_AND_JUMPING = 3
+ var SWIMMING = 4
+ var DIVING = 5
+ var CANNONBALL = 6
+
+ var ON_LAND = 0
+ var ON_WATER = 1
+
+ var RIGHT = 0
+ var LEFT = 1
+
+ var DUDE_STATE =
+ {
+ IDLE_RIGHT: 0,
+ IDLE_LEFT: 1,
+ RUN_RIGHT: 2,
+ RUN_LEFT: 3,
+ JUMPING_RIGHT: 4,
+ JUMPING_LEFT: 5,
+ RUNNING_AND_JUMPING_RIGHT: 6,
+ RUNNING_AND_JUMPING_LEFT: 7,
+ SWIMMING_RIGHT: 8,
+ SWIMMING_LEFT: 9,
+ DIVING_RIGHT: 10,
+ DIVING_LEFT: 11,
+ CANNONBALL_RIGHT: 12,
+ CANNONBALL_LEFT: 13,
+ }
+
+ $("#playground").playground({height: PLAYGROUND_HEIGHT, width: PLAYGROUND_WIDTH, refreshRate: REFRESH_RATE, keyTracker: false})
+
+ function update_animation (sprite, actor)
+ {
+ new_state = actor.activity * 2 + actor.orientation
+ if (actor.state === new_state)
+ return
+ old_anim = actor.animations[actor.state]
+ new_anim = actor.animations[new_state]
+ actor.state = new_state
+ dude.y += new_anim.deltaY - old_anim.deltaY
+ dude.x += new_anim.deltaX - old_anim.deltaX
+ sprite.setAnimation(new_anim.animation)
+ .width(new_anim.width)
+ .height(new_anim.height)
+ .css("top", sprite.position().top + new_anim.deltaY - old_anim.deltaY)
+ .css("left", sprite.position().left + new_anim.deltaX - old_anim.deltaX)
+ }
+ var FLOOR_HEIGHT = 115
+ var stage =
+ {
+ x: 0,
+ y: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ biffx: 20,
+ sea_distance: 2000,
+ scroll: function ()
+ {
+ $("#sand").css({"left": stage.x, "top": stage.y })
+ $("#biff").css({"left": stage.biffx + stage.x, "top": stage.biffy + stage.y })
+ $("#sea").css({"left": stage.sea_distance + stage.x, "top": stage.y })
+ },
+ }
+ var sky = new $.gameQuery.Animation({imageURL: "./sky.png"})
+ var sand = new $.gameQuery.Animation({imageURL: "./sand.png"})
+ var sea = new $.gameQuery.Animation({imageURL: "./sea.png"})
+ $.playground()
+ .addSprite( "sky",
+ {
+ posx: 0,
+ posy: 0,
+ width: PLAYGROUND_WIDTH,
+ height: PLAYGROUND_HEIGHT,
+ animation: sky,
+ })
+ .addSprite( "sand",
+ {
+ posx: 0,
+ posy: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ width: stage.sea_distance,
+ height: 2000,
+ animation: sand,
+ })
+ .addSprite( "sea",
+ {
+ posx: stage.sea_distance,
+ posy: PLAYGROUND_HEIGHT - FLOOR_HEIGHT,
+ width: PLAYGROUND_WIDTH,
+ height: 2000,
+ animation: sea,
+ })
+ .addGroup("actors").end()
+ $("#sceengraph").css("background-color", "#88dddd")
+
+ MAX_YSPEED = 10
+ RUN_SPEED = 10
+ GRAVITY = 2
+ TERMINAL_VELOCITY = 20
+ JUMP_POWER = 30
+
+ FLOOR_DEPTH = 30
+ DUDE_WIDTH = 140
+ DUDE_HEIGHT = 231
+ DUDE_START_X = 300
+ DUDE_START_Y = PLAYGROUND_HEIGHT - DUDE_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH + TERMINAL_VELOCITY - 10
+ var dude =
+ {
+ state: DUDE_STATE.IDLE_RIGHT,
+ activity: IDLE,
+ orientation: RIGHT,
+ can_jump: true,
+ running_while_jumping: true,
+ xspeed: 0,
+ yspeed: 0,
+ x: DUDE_START_X,
+ y: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-10,
+ animations:
+ [
+ // IDLE
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite_left.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ // JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // RUNNING AND JUMPING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_left.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ // SWIMMING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite_left.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ // DIVING
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite_left.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ // CANNONBALL
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manrunningsprite_left.png",
+ numberOfFrame: 15,
+ delta: 226,
+ rate: REFRESH_RATE*1,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: 140,
+ height: 214,
+ },
+ ],
+ }
+ BIFF_START_X = 20
+ var biff =
+ {
+ state: DUDE_STATE.IDLE_RIGHT,
+ activity: IDLE,
+ orientation: RIGHT,
+ can_jump: true,
+ running_while_jumping: true,
+ xspeed: 0,
+ yspeed: 0,
+ spoke: false,
+ x: BIFF_START_X,
+ y: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-10,
+ animations:
+ [
+ // IDLE
+ {
+ animation: new $.gameQuery.Animation(
+ {
+ imageURL: "sprites/manstandingsprite_brown.png",
+ numberOfFrame: 8,
+ delta: DUDE_HEIGHT-2,
+ rate: REFRESH_RATE*1.5,
+ type: $.gameQuery.ANIMATION_VERTICAL | $.gameQuery.ANIMATION_CALLBACK
+ }),
+ deltaX: 0,
+ deltaY: 0,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ },
+ ],
+ }
+ $("#actors").addSprite("biff",
+ {
+ posx: BIFF_START_X,
+ posy: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ animation: biff.animations[0].animation,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ // callback: animate,
+ })
+ $("#biff").data("actor", biff)
+
+ $("#actors").addSprite("dude",
+ {
+ posx: DUDE_START_X,
+ posy: DUDE_START_Y,
+ width: DUDE_WIDTH,
+ height: DUDE_HEIGHT-20,
+ animation: dude.animations[0].animation,
+ geometry: $.gameQuery.GEOMETRY_RECTANGLE,
+ // callback: animate,
+ })
+ $("#dude").data("actor", dude)
+
+
+ $(window).bind("blur", function (e)
+ {
+ $.each(KEYTRACK, function (k,v) { KEYTRACK[k] = false })
+ })
+ $(document).bind("keydown", function (e)
+ {
+ KEYTRACK[e.keyCode] = true
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ dude.orientation = RIGHT
+ break
+ case KEY_LEFT:
+ dude.orientation = LEFT
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+ $(document).bind("keyup", function (e)
+ {
+ KEYTRACK[e.keyCode] = false
+ switch (e.keyCode)
+ {
+ case KEY_RIGHT:
+ break
+ case KEY_LEFT:
+ break
+ case KEY_UP:
+ break
+ case KEY_DOWN:
+ break
+ }
+ })
+
+ WATER_LINE = 10000
+ function actor_has_landed (actor)
+ {
+ if (actor.x < WATER_LINE)
+ return (actor.y + actor.height) > (PLAYGROUND_HEIGHT - FLOOR_HEIGHT + FLOOR_DEPTH - TERMINAL_VELOCITY + 10)
+ else
+ return true
+ }
+ $.playground().registerCallback( function ()
+ {
+ switch (dude.activity)
+ {
+ case IDLE:
+ dude.can_jump = true
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.activity = RUNNING
+ }
+ break
+ case RUNNING:
+ if (KEYTRACK[KEY_UP])
+ {
+ dude.yspeed -= JUMP_POWER
+ dude.activity = RUNNING_AND_JUMPING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.orientation = LEFT
+ dude.xspeed = -1 * RUN_SPEED
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.orientation = RIGHT
+ dude.xspeed = RUN_SPEED
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = IDLE
+ dude.xspeed = 0
+ }
+ break
+ case JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.xspeed = 0
+ dude.yspeed = 0
+ dude.activity = IDLE
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = -1 * RUN_SPEED
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.activity = RUNNING_AND_JUMPING
+ dude.xspeed = RUN_SPEED
+ }
+ break
+ case RUNNING_AND_JUMPING:
+ dude.yspeed = dude.yspeed + GRAVITY
+ if (dude.yspeed > TERMINAL_VELOCITY)
+ dude.yspeed = TERMINAL_VELOCITY
+ if (actor_has_landed(dude))
+ {
+ dude.yspeed = 0
+ if (KEYTRACK[KEY_UP])
+ dude.yspeed -= JUMP_POWER
+ else
+ dude.activity = RUNNING
+ }
+ else if (KEYTRACK[KEY_LEFT])
+ {
+ dude.xspeed = -1 * RUN_SPEED
+ dude.orientation = LEFT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x <= -dude.width + 80)
+ dude.x = PLAYGROUND_WIDTH
+ }
+ else if (KEYTRACK[KEY_RIGHT])
+ {
+ dude.xspeed = RUN_SPEED
+ dude.orientation = RIGHT
+ dude.activity = RUNNING_AND_JUMPING
+ if (dude.x >= PLAYGROUND_WIDTH)
+ dude.x = -dude.width
+ }
+ else
+ {
+ dude.activity = JUMPING
+ }
+ break
+ case SWIMMING:
+ break
+ case DIVING:
+ break
+ case CANNONBALL:
+ break
+ }
+
+ if (stage.x === 0)
+ {
+ if (KEYTRACK[KEY_LEFT] || dude.x < 310)
+ dude.x += dude.xspeed
+ else
+ {
+ stage.x -= dude.xspeed
+ if (stage.x > 0)
+ stage.x = 0
+ }
+ if (dude.x < 160)
+ {
+ dude.x = 160
+ if (dude.activity === JUMPING)
+ {
+ }
+ else if (dude.activity === RUNNING_AND_JUMPING)
+ {
+ dude.activity = JUMPING
+ }
+ else
+ dude.activity = IDLE
+ }
+ if (dude.x < 170)
+ {
+ $("#message").show(400, function(){$("#message").html("what up doe?"); })
+ $("#message-corner").show(200)
+ biff.spoke = true
+ }
+ else if (dude.x > 190)
+ {
+ $("#message-corner").hide(100)
+ $("#message").hide(400).html("")
+ }
+ }
+ else if (stage.x > -1* (stage.sea_distance - 550)) // || dude.orientation === LEFT)
+ {
+ stage.x -= dude.xspeed
+ }
+ else
+ {
+ dude.x += dude.xspeed
+ if (dude.x > 400)
+ {
+ dude.x = 400
+ if (dude.activity === DIVING)
+ {
+ }
+ else if (dude.activity === RUNNING_AND_JUMPING)
+ {
+ dude.activity = CANNONBALL
+ }
+ else
+ dude.activity = DIVING
+ }
+ else if (dude.x < 350)
+ stage.x -= dude.xspeed
+ }
+ dude.y += dude.yspeed
+ $("#dude").css({"top": dude.y, "left": dude.x})
+ update_animation($("#dude"), dude)
+ stage.scroll ()
+ $("#hud").html(
+ [
+ STATES[dude.activity], ORIENTATIONS[dude.orientation], "<br/>",
+ "dude @ ", dude.x, " ", dude.y, "<br/>",
+ "stage @ ", stage.x, " ", stage.y, "<br/>",
+ ].join(" "))
+ }, REFRESH_RATE)
+ $.playground().startGame(function ()
+ {
+ })
+ })
+
+</script>
+</html>