summaryrefslogtreecommitdiff
path: root/geometry5.html
diff options
context:
space:
mode:
authorJules <jules@asdf.us>2016-11-10 15:34:53 -0500
committerJules <jules@asdf.us>2016-11-10 15:34:53 -0500
commitdc06cab69f9e871aa8f7f519c964cf632d2217ea (patch)
tree1c9344a58185c55f90c9b0db7f87c478e5d9a947 /geometry5.html
meatheadzHEADmaster
Diffstat (limited to 'geometry5.html')
-rwxr-xr-xgeometry5.html1392
1 files changed, 1392 insertions, 0 deletions
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>
+