diff options
| -rwxr-xr-x | beach.png | bin | 0 -> 7057 bytes | |||
| -rwxr-xr-x | breaststroke3.gif | bin | 0 -> 26789 bytes | |||
| -rwxr-xr-x | breaststroke3.png | bin | 0 -> 25902 bytes | |||
| -rwxr-xr-x | cannonball.gif | bin | 0 -> 7811 bytes | |||
| -rwxr-xr-x | etc/manjumping.png | bin | 0 -> 51799 bytes | |||
| -rwxr-xr-x | etc/manrunning.png | bin | 0 -> 35352 bytes | |||
| -rwxr-xr-x | etc/manrunningsprite.png | bin | 0 -> 43462 bytes | |||
| -rwxr-xr-x | etc/manrunningsprite_left.png | bin | 0 -> 44258 bytes | |||
| -rwxr-xr-x | etc/manstandingsprite.png | bin | 0 -> 276454 bytes | |||
| -rwxr-xr-x | etc/manstandingsprite_left.png | bin | 0 -> 296104 bytes | |||
| -rwxr-xr-x | float3.gif | bin | 0 -> 35506 bytes | |||
| -rwxr-xr-x | float3.png | bin | 0 -> 29261 bytes | |||
| -rwxr-xr-x | fonts/Commodore-64-v6.3.TTF | bin | 0 -> 51008 bytes | |||
| -rwxr-xr-x | fonts/Commodore-Angled-v1.2.ttf | bin | 0 -> 19660 bytes | |||
| -rwxr-xr-x | fonts/Commodore-Rounded-v1.2.ttf | bin | 0 -> 20084 bytes | |||
| -rwxr-xr-x | geometry.html | 502 | ||||
| -rwxr-xr-x | geometry2.html | 671 | ||||
| -rwxr-xr-x | geometry3.html | 957 | ||||
| -rwxr-xr-x | geometry4.html | 1158 | ||||
| -rwxr-xr-x | geometry5.html | 1392 | ||||
| -rwxr-xr-x | geometry6.html | 1393 | ||||
| -rwxr-xr-x | guru.gif | bin | 0 -> 736302 bytes | |||
| -rwxr-xr-x | guru2.gif | bin | 0 -> 269271 bytes | |||
| -rwxr-xr-x | index.html | 1393 | ||||
| -rwxr-xr-x | jquery.gamequery-0.5.1.js | 1164 | ||||
| -rwxr-xr-x | landscape/abovewaterislandbg.png | bin | 0 -> 3103 bytes | |||
| -rwxr-xr-x | landscape/abovewaterislandcorner.png | bin | 0 -> 833 bytes | |||
| -rwxr-xr-x | landscape/bush.png | bin | 0 -> 1038 bytes | |||
| -rwxr-xr-x | landscape/island1bg.png | bin | 0 -> 11927 bytes | |||
| -rwxr-xr-x | landscape/island1fg.png | bin | 0 -> 8827 bytes | |||
| -rwxr-xr-x | landscape/island_bush.png | bin | 0 -> 3687 bytes | |||
| -rwxr-xr-x | landscape/palmtree.png | bin | 0 -> 2484 bytes | |||
| -rwxr-xr-x | landscape/scotch.gif | bin | 0 -> 1073 bytes | |||
| -rwxr-xr-x | landscape/underwaterislandbg.png | bin | 0 -> 3154 bytes | |||
| -rwxr-xr-x | landscape/underwaterislandcorner.png | bin | 0 -> 1020 bytes | |||
| -rwxr-xr-x | landscape/watercorner.png | bin | 0 -> 1323 bytes | |||
| -rwxr-xr-x | manrunning.gif | bin | 0 -> 38238 bytes | |||
| -rwxr-xr-x | manrunning2.gif | bin | 0 -> 39286 bytes | |||
| -rwxr-xr-x | manstanding.gif | bin | 0 -> 96794 bytes | |||
| -rwxr-xr-x | manstanding2.gif | bin | 0 -> 96467 bytes | |||
| -rwxr-xr-x | particle.html | 109 | ||||
| -rwxr-xr-x | possible/.htaccess | 1 | ||||
| -rwxr-xr-x | possible/1298527286040-dumpfm-pepper-1298436051425-dumpfm-pepper-chevre_1.png | bin | 0 -> 198177 bytes | |||
| -rwxr-xr-x | possible/1298590356231-dumpfm-pepper-fingercheese.png | bin | 0 -> 62725 bytes | |||
| -rwxr-xr-x | possible/1300591584954-dumpfm-pepper-nantucket_paradigm.png | bin | 0 -> 473270 bytes | |||
| -rwxr-xr-x | possible/1301351326112-dumpfm-pepper-glitter_wom2.gif | bin | 0 -> 26055 bytes | |||
| -rwxr-xr-x | possible/1302286721060-dumpfm-pepper-cell_phone_glitter.gif | bin | 0 -> 192883 bytes | |||
| -rwxr-xr-x | possible/plasmus5.gif | bin | 0 -> 4770 bytes | |||
| -rwxr-xr-x | possible/plasmusuk.gif | bin | 0 -> 9221 bytes | |||
| -rwxr-xr-x | sand.png | bin | 0 -> 16415 bytes | |||
| -rwxr-xr-x | sea.png | bin | 0 -> 16413 bytes | |||
| -rwxr-xr-x | sky.png | bin | 0 -> 16415 bytes | |||
| -rwxr-xr-x | splash.gif | bin | 0 -> 8623 bytes | |||
| -rwxr-xr-x | sprites/.htaccess | 1 | ||||
| -rwxr-xr-x | sprites/breaststroke.gif | bin | 0 -> 22092 bytes | |||
| -rwxr-xr-x | sprites/breaststroke1.png | bin | 0 -> 17789 bytes | |||
| -rwxr-xr-x | sprites/breaststroke2.png | bin | 0 -> 22166 bytes | |||
| -rwxr-xr-x | sprites/breaststroke3.png | bin | 0 -> 24502 bytes | |||
| -rwxr-xr-x | sprites/cannonball.png | bin | 0 -> 7935 bytes | |||
| -rwxr-xr-x | sprites/cannonball2.png | bin | 0 -> 15809 bytes | |||
| -rwxr-xr-x | sprites/diving1.png | bin | 0 -> 24887 bytes | |||
| -rwxr-xr-x | sprites/diving2.gif | bin | 0 -> 22901 bytes | |||
| -rwxr-xr-x | sprites/diving2.png | bin | 0 -> 20356 bytes | |||
| -rwxr-xr-x | sprites/float.gif | bin | 0 -> 31839 bytes | |||
| -rwxr-xr-x | sprites/float1.png | bin | 0 -> 28688 bytes | |||
| -rwxr-xr-x | sprites/float2.png | bin | 0 -> 27392 bytes | |||
| -rwxr-xr-x | sprites/float3.png | bin | 0 -> 25589 bytes | |||
| -rwxr-xr-x | sprites/jumping.png | bin | 0 -> 51799 bytes | |||
| -rwxr-xr-x | sprites/jumping2.png | bin | 0 -> 25301 bytes | |||
| -rwxr-xr-x | sprites/mandiving1.gif | bin | 0 -> 22901 bytes | |||
| -rwxr-xr-x | sprites/manrunningsprite.png | bin | 0 -> 57391 bytes | |||
| -rwxr-xr-x | sprites/manrunningsprite_left.png | bin | 0 -> 58053 bytes | |||
| -rwxr-xr-x | sprites/manstandingsprite.png | bin | 0 -> 80808 bytes | |||
| -rwxr-xr-x | sprites/manstandingsprite_brown.png | bin | 0 -> 48270 bytes | |||
| -rwxr-xr-x | sprites/manstandingsprite_left.png | bin | 0 -> 80890 bytes | |||
| -rwxr-xr-x | sprites/orig/manrunning.png | bin | 0 -> 35352 bytes | |||
| -rwxr-xr-x | sprites/orig/manrunningsprite.png | bin | 0 -> 43462 bytes | |||
| -rwxr-xr-x | sprites/orig/manrunningsprite_left.png | bin | 0 -> 44258 bytes | |||
| -rwxr-xr-x | sprites/orig/manstandingsprite.png | bin | 0 -> 276454 bytes | |||
| -rwxr-xr-x | sprites/orig/manstandingsprite_left.png | bin | 0 -> 296104 bytes | |||
| -rwxr-xr-x | sprites/orig/sand.png | bin | 0 -> 16415 bytes | |||
| -rwxr-xr-x | sprites/orig/sky.png | bin | 0 -> 16415 bytes | |||
| -rwxr-xr-x | sprites/running2.gif | bin | 0 -> 39286 bytes | |||
| -rwxr-xr-x | sprites/splash.png | bin | 0 -> 9418 bytes | |||
| -rwxr-xr-x | sprites/splash2.png | bin | 0 -> 20453 bytes | |||
| -rwxr-xr-x | sprites/standing2.gif | bin | 0 -> 96467 bytes | |||
| -rwxr-xr-x | sprites/swimming1.gif | bin | 0 -> 22195 bytes | |||
| -rwxr-xr-x | sprites/swimming1.png | bin | 0 -> 16883 bytes | |||
| -rwxr-xr-x | sprites/swimming2.png | bin | 0 -> 20921 bytes | |||
| -rwxr-xr-x | sprites/swimtrans.png | bin | 0 -> 9156 bytes | |||
| -rwxr-xr-x | swimtrans.gif | bin | 0 -> 9399 bytes | |||
| -rwxr-xr-x | swimtrans.png | bin | 0 -> 8335 bytes | |||
| -rwxr-xr-x | v1.html | 230 | ||||
| -rwxr-xr-x | v2.html | 420 | ||||
| -rwxr-xr-x | v3.html | 501 | ||||
| -rwxr-xr-x | v4.html | 629 | ||||
| -rwxr-xr-x | v5.html | 632 | ||||
| -rwxr-xr-x | v6.html | 736 |
98 files changed, 11889 insertions, 0 deletions
diff --git a/beach.png b/beach.png Binary files differnew file mode 100755 index 0000000..5654de7 --- /dev/null +++ b/beach.png diff --git a/breaststroke3.gif b/breaststroke3.gif Binary files differnew file mode 100755 index 0000000..08512d0 --- /dev/null +++ b/breaststroke3.gif diff --git a/breaststroke3.png b/breaststroke3.png Binary files differnew file mode 100755 index 0000000..2323195 --- /dev/null +++ b/breaststroke3.png diff --git a/cannonball.gif b/cannonball.gif Binary files differnew file mode 100755 index 0000000..b8bf1f0 --- /dev/null +++ b/cannonball.gif diff --git a/etc/manjumping.png b/etc/manjumping.png Binary files differnew file mode 100755 index 0000000..834df7f --- /dev/null +++ b/etc/manjumping.png diff --git a/etc/manrunning.png b/etc/manrunning.png Binary files differnew file mode 100755 index 0000000..7827444 --- /dev/null +++ b/etc/manrunning.png diff --git a/etc/manrunningsprite.png b/etc/manrunningsprite.png Binary files differnew file mode 100755 index 0000000..82b9ba1 --- /dev/null +++ b/etc/manrunningsprite.png diff --git a/etc/manrunningsprite_left.png b/etc/manrunningsprite_left.png Binary files differnew file mode 100755 index 0000000..dd29c7b --- /dev/null +++ b/etc/manrunningsprite_left.png diff --git a/etc/manstandingsprite.png b/etc/manstandingsprite.png Binary files differnew file mode 100755 index 0000000..ff41388 --- /dev/null +++ b/etc/manstandingsprite.png diff --git a/etc/manstandingsprite_left.png b/etc/manstandingsprite_left.png Binary files differnew file mode 100755 index 0000000..083cf70 --- /dev/null +++ b/etc/manstandingsprite_left.png diff --git a/float3.gif b/float3.gif Binary files differnew file mode 100755 index 0000000..e428263 --- /dev/null +++ b/float3.gif diff --git a/float3.png b/float3.png Binary files differnew file mode 100755 index 0000000..77cc5ff --- /dev/null +++ b/float3.png diff --git a/fonts/Commodore-64-v6.3.TTF b/fonts/Commodore-64-v6.3.TTF Binary files differnew file mode 100755 index 0000000..5ce242d --- /dev/null +++ b/fonts/Commodore-64-v6.3.TTF diff --git a/fonts/Commodore-Angled-v1.2.ttf b/fonts/Commodore-Angled-v1.2.ttf Binary files differnew file mode 100755 index 0000000..a9f5d41 --- /dev/null +++ b/fonts/Commodore-Angled-v1.2.ttf diff --git a/fonts/Commodore-Rounded-v1.2.ttf b/fonts/Commodore-Rounded-v1.2.ttf Binary files differnew file mode 100755 index 0000000..eee50a3 --- /dev/null +++ b/fonts/Commodore-Rounded-v1.2.ttf 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 Binary files differnew file mode 100755 index 0000000..1800002 --- /dev/null +++ b/guru.gif diff --git a/guru2.gif b/guru2.gif Binary files differnew file mode 100755 index 0000000..b1caf81 --- /dev/null +++ b/guru2.gif 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 Binary files differnew file mode 100755 index 0000000..7b9a707 --- /dev/null +++ b/landscape/abovewaterislandbg.png diff --git a/landscape/abovewaterislandcorner.png b/landscape/abovewaterislandcorner.png Binary files differnew file mode 100755 index 0000000..d80a272 --- /dev/null +++ b/landscape/abovewaterislandcorner.png diff --git a/landscape/bush.png b/landscape/bush.png Binary files differnew file mode 100755 index 0000000..120c93b --- /dev/null +++ b/landscape/bush.png diff --git a/landscape/island1bg.png b/landscape/island1bg.png Binary files differnew file mode 100755 index 0000000..8d08038 --- /dev/null +++ b/landscape/island1bg.png diff --git a/landscape/island1fg.png b/landscape/island1fg.png Binary files differnew file mode 100755 index 0000000..b916a46 --- /dev/null +++ b/landscape/island1fg.png diff --git a/landscape/island_bush.png b/landscape/island_bush.png Binary files differnew file mode 100755 index 0000000..ac2a2ae --- /dev/null +++ b/landscape/island_bush.png diff --git a/landscape/palmtree.png b/landscape/palmtree.png Binary files differnew file mode 100755 index 0000000..5f5b16b --- /dev/null +++ b/landscape/palmtree.png diff --git a/landscape/scotch.gif b/landscape/scotch.gif Binary files differnew file mode 100755 index 0000000..06c8b50 --- /dev/null +++ b/landscape/scotch.gif diff --git a/landscape/underwaterislandbg.png b/landscape/underwaterislandbg.png Binary files differnew file mode 100755 index 0000000..2bbd105 --- /dev/null +++ b/landscape/underwaterislandbg.png diff --git a/landscape/underwaterislandcorner.png b/landscape/underwaterislandcorner.png Binary files differnew file mode 100755 index 0000000..4dc4082 --- /dev/null +++ b/landscape/underwaterislandcorner.png diff --git a/landscape/watercorner.png b/landscape/watercorner.png Binary files differnew file mode 100755 index 0000000..9a303ca --- /dev/null +++ b/landscape/watercorner.png diff --git a/manrunning.gif b/manrunning.gif Binary files differnew file mode 100755 index 0000000..a36fab7 --- /dev/null +++ b/manrunning.gif diff --git a/manrunning2.gif b/manrunning2.gif Binary files differnew file mode 100755 index 0000000..bae37b4 --- /dev/null +++ b/manrunning2.gif diff --git a/manstanding.gif b/manstanding.gif Binary files differnew file mode 100755 index 0000000..66b84f5 --- /dev/null +++ b/manstanding.gif diff --git a/manstanding2.gif b/manstanding2.gif Binary files differnew file mode 100755 index 0000000..3bd9647 --- /dev/null +++ b/manstanding2.gif 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 Binary files differnew file mode 100755 index 0000000..0402d4d --- /dev/null +++ b/possible/1298527286040-dumpfm-pepper-1298436051425-dumpfm-pepper-chevre_1.png diff --git a/possible/1298590356231-dumpfm-pepper-fingercheese.png b/possible/1298590356231-dumpfm-pepper-fingercheese.png Binary files differnew file mode 100755 index 0000000..93e4a36 --- /dev/null +++ b/possible/1298590356231-dumpfm-pepper-fingercheese.png diff --git a/possible/1300591584954-dumpfm-pepper-nantucket_paradigm.png b/possible/1300591584954-dumpfm-pepper-nantucket_paradigm.png Binary files differnew file mode 100755 index 0000000..ba7354a --- /dev/null +++ b/possible/1300591584954-dumpfm-pepper-nantucket_paradigm.png diff --git a/possible/1301351326112-dumpfm-pepper-glitter_wom2.gif b/possible/1301351326112-dumpfm-pepper-glitter_wom2.gif Binary files differnew file mode 100755 index 0000000..3475ab7 --- /dev/null +++ b/possible/1301351326112-dumpfm-pepper-glitter_wom2.gif diff --git a/possible/1302286721060-dumpfm-pepper-cell_phone_glitter.gif b/possible/1302286721060-dumpfm-pepper-cell_phone_glitter.gif Binary files differnew file mode 100755 index 0000000..d08c4e5 --- /dev/null +++ b/possible/1302286721060-dumpfm-pepper-cell_phone_glitter.gif diff --git a/possible/plasmus5.gif b/possible/plasmus5.gif Binary files differnew file mode 100755 index 0000000..3463049 --- /dev/null +++ b/possible/plasmus5.gif diff --git a/possible/plasmusuk.gif b/possible/plasmusuk.gif Binary files differnew file mode 100755 index 0000000..fa91b3b --- /dev/null +++ b/possible/plasmusuk.gif diff --git a/sand.png b/sand.png Binary files differBinary files differBinary files differnew file mode 100755 index 0000000..c034d2e --- /dev/null +++ b/sand.png diff --git a/splash.gif b/splash.gif Binary files differnew file mode 100755 index 0000000..3cf8b98 --- /dev/null +++ b/splash.gif 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 Binary files differnew file mode 100755 index 0000000..b70b06f --- /dev/null +++ b/sprites/breaststroke.gif diff --git a/sprites/breaststroke1.png b/sprites/breaststroke1.png Binary files differnew file mode 100755 index 0000000..cc7fc96 --- /dev/null +++ b/sprites/breaststroke1.png diff --git a/sprites/breaststroke2.png b/sprites/breaststroke2.png Binary files differnew file mode 100755 index 0000000..75a1b54 --- /dev/null +++ b/sprites/breaststroke2.png diff --git a/sprites/breaststroke3.png b/sprites/breaststroke3.png Binary files differnew file mode 100755 index 0000000..e6293df --- /dev/null +++ b/sprites/breaststroke3.png diff --git a/sprites/cannonball.png b/sprites/cannonball.png Binary files differnew file mode 100755 index 0000000..60ee1da --- /dev/null +++ b/sprites/cannonball.png diff --git a/sprites/cannonball2.png b/sprites/cannonball2.png Binary files differnew file mode 100755 index 0000000..6ab8e79 --- /dev/null +++ b/sprites/cannonball2.png diff --git a/sprites/diving1.png b/sprites/diving1.png Binary files differnew file mode 100755 index 0000000..65f7789 --- /dev/null +++ b/sprites/diving1.png diff --git a/sprites/diving2.gif b/sprites/diving2.gif Binary files differnew file mode 100755 index 0000000..b27b12c --- /dev/null +++ b/sprites/diving2.gif diff --git a/sprites/diving2.png b/sprites/diving2.png Binary files differnew file mode 100755 index 0000000..476b2d2 --- /dev/null +++ b/sprites/diving2.png diff --git a/sprites/float.gif b/sprites/float.gif Binary files differnew file mode 100755 index 0000000..9835cc0 --- /dev/null +++ b/sprites/float.gif diff --git a/sprites/float1.png b/sprites/float1.png Binary files differnew file mode 100755 index 0000000..a4bd5f3 --- /dev/null +++ b/sprites/float1.png diff --git a/sprites/float2.png b/sprites/float2.png Binary files differnew file mode 100755 index 0000000..ca9b08a --- /dev/null +++ b/sprites/float2.png diff --git a/sprites/float3.png b/sprites/float3.png Binary files differnew file mode 100755 index 0000000..bd5ab1d --- /dev/null +++ b/sprites/float3.png diff --git a/sprites/jumping.png b/sprites/jumping.png Binary files differnew file mode 100755 index 0000000..834df7f --- /dev/null +++ b/sprites/jumping.png diff --git a/sprites/jumping2.png b/sprites/jumping2.png Binary files differnew file mode 100755 index 0000000..69d35bb --- /dev/null +++ b/sprites/jumping2.png diff --git a/sprites/mandiving1.gif b/sprites/mandiving1.gif Binary files differnew file mode 100755 index 0000000..b27b12c --- /dev/null +++ b/sprites/mandiving1.gif diff --git a/sprites/manrunningsprite.png b/sprites/manrunningsprite.png Binary files differnew file mode 100755 index 0000000..66a67dc --- /dev/null +++ b/sprites/manrunningsprite.png diff --git a/sprites/manrunningsprite_left.png b/sprites/manrunningsprite_left.png Binary files differnew file mode 100755 index 0000000..0016053 --- /dev/null +++ b/sprites/manrunningsprite_left.png diff --git a/sprites/manstandingsprite.png b/sprites/manstandingsprite.png Binary files differnew file mode 100755 index 0000000..94933ab --- /dev/null +++ b/sprites/manstandingsprite.png diff --git a/sprites/manstandingsprite_brown.png b/sprites/manstandingsprite_brown.png Binary files differnew file mode 100755 index 0000000..ddf9204 --- /dev/null +++ b/sprites/manstandingsprite_brown.png diff --git a/sprites/manstandingsprite_left.png b/sprites/manstandingsprite_left.png Binary files differnew file mode 100755 index 0000000..52f9729 --- /dev/null +++ b/sprites/manstandingsprite_left.png diff --git a/sprites/orig/manrunning.png b/sprites/orig/manrunning.png Binary files differnew file mode 100755 index 0000000..7827444 --- /dev/null +++ b/sprites/orig/manrunning.png diff --git a/sprites/orig/manrunningsprite.png b/sprites/orig/manrunningsprite.png Binary files differnew file mode 100755 index 0000000..82b9ba1 --- /dev/null +++ b/sprites/orig/manrunningsprite.png diff --git a/sprites/orig/manrunningsprite_left.png b/sprites/orig/manrunningsprite_left.png Binary files differnew file mode 100755 index 0000000..dd29c7b --- /dev/null +++ b/sprites/orig/manrunningsprite_left.png diff --git a/sprites/orig/manstandingsprite.png b/sprites/orig/manstandingsprite.png Binary files differnew file mode 100755 index 0000000..ff41388 --- /dev/null +++ b/sprites/orig/manstandingsprite.png diff --git a/sprites/orig/manstandingsprite_left.png b/sprites/orig/manstandingsprite_left.png Binary files differnew file mode 100755 index 0000000..083cf70 --- /dev/null +++ b/sprites/orig/manstandingsprite_left.png diff --git a/sprites/orig/sand.png b/sprites/orig/sand.png Binary files differnew file mode 100755 index 0000000..06a6b8f --- /dev/null +++ b/sprites/orig/sand.png diff --git a/sprites/orig/sky.png b/sprites/orig/sky.png Binary files differnew file mode 100755 index 0000000..890faf2 --- /dev/null +++ b/sprites/orig/sky.png diff --git a/sprites/running2.gif b/sprites/running2.gif Binary files differnew file mode 100755 index 0000000..bae37b4 --- /dev/null +++ b/sprites/running2.gif diff --git a/sprites/splash.png b/sprites/splash.png Binary files differnew file mode 100755 index 0000000..77484a3 --- /dev/null +++ b/sprites/splash.png diff --git a/sprites/splash2.png b/sprites/splash2.png Binary files differnew file mode 100755 index 0000000..4f6cb0e --- /dev/null +++ b/sprites/splash2.png diff --git a/sprites/standing2.gif b/sprites/standing2.gif Binary files differnew file mode 100755 index 0000000..3bd9647 --- /dev/null +++ b/sprites/standing2.gif diff --git a/sprites/swimming1.gif b/sprites/swimming1.gif Binary files differnew file mode 100755 index 0000000..0373c02 --- /dev/null +++ b/sprites/swimming1.gif diff --git a/sprites/swimming1.png b/sprites/swimming1.png Binary files differnew file mode 100755 index 0000000..645ae45 --- /dev/null +++ b/sprites/swimming1.png diff --git a/sprites/swimming2.png b/sprites/swimming2.png Binary files differnew file mode 100755 index 0000000..8d2b2dd --- /dev/null +++ b/sprites/swimming2.png diff --git a/sprites/swimtrans.png b/sprites/swimtrans.png Binary files differnew file mode 100755 index 0000000..2f20766 --- /dev/null +++ b/sprites/swimtrans.png diff --git a/swimtrans.gif b/swimtrans.gif Binary files differnew file mode 100755 index 0000000..5203e7d --- /dev/null +++ b/swimtrans.gif diff --git a/swimtrans.png b/swimtrans.png Binary files differnew file mode 100755 index 0000000..0377391 --- /dev/null +++ b/swimtrans.png @@ -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> @@ -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> @@ -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> @@ -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> @@ -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> @@ -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> |
