diff --git a/.gitignore b/.gitignore index 5148e52..6d2145b 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ jspm_packages # Optional REPL history .node_repl_history + +# DS_Store +.DS_Store diff --git a/public/css/platform.css b/public/css/platform.css new file mode 100644 index 0000000..161d919 --- /dev/null +++ b/public/css/platform.css @@ -0,0 +1,21 @@ +.background { background: rgb(52, 166, 251); + table-layout: fixed; + border-spacing: 0; } +.background td { padding: 0; } +.lava { background: rgb(255, 100, 100); } +.wall { background: white; } +.actor { position: absolute; } +.coin { background: rgb(241, 229, 89); } +.player { background: rgb(64, 64, 64); } +.lost .player { + background: rgb(160, 64, 64); +} +.won .player { + box-shadow: -4px -7px 8px white, 4px -7px 8px white; +} +.game { + overflow: hidden; + max-width: 600px; + max-height: 450px; + position: relative; +} diff --git a/public/index.html b/public/index.html deleted file mode 100644 index 278d291..0000000 --- a/public/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - Browser Games - - -

Browser Games

- -

A collection of games to play in a web browser.

- -
- - - - diff --git a/public/js/platform.js b/public/js/platform.js new file mode 100644 index 0000000..263133f --- /dev/null +++ b/public/js/platform.js @@ -0,0 +1,410 @@ +var simpleLevelPlan = [ + " ", + " ", + " x = x ", + " x o o x ", + " x @ xxxxx x ", + " xxxxx x ", + " x!!!!!!!!!!!!x ", + " xxxxxxxxxxxxxx ", + " " +]; + +function Level(plan) { + this.width = plan[0].length; + this.height = plan.length; + this.grid = []; + this.actors = []; + + for (var y = 0; y < this.height; y++) { + var line = plan[y], gridLine = []; + for (var x = 0; x < this.width; x++) { + var ch = line[x], fieldType = null; + var Actor = actorChars[ch]; + if (Actor) + this.actors.push(new Actor(new Vector(x, y), ch)); + else if (ch == "x") + fieldType = "wall"; + else if (ch == "!") + fieldType = "lava"; + gridLine.push(fieldType); + } + this.grid.push(gridLine); + } + + this.player = this.actors.filter(function(actor) { + return actor.type == "player"; + })[0]; + this.status = this.finishDelay = null; +} + +function Vector(x, y) { + this.x = x; this.y = y; +} +Vector.prototype.plus = function(other) { + return new Vector(this.x + other.x, this.y + other.y); +}; +Vector.prototype.times = function(factor) { + return new Vector(this.x * factor, this.y * factor); +}; + +var actorChars = { + "@": Player, + "o": Coin, + "=": Lava, "|": Lava, "v": Lava +}; + +function Player(pos) { + this.pos = pos.plus(new Vector(0, -0.5)); + this.size = new Vector(0.8, 1.5); + this.speed = new Vector(0, 0); +} +Player.prototype.type = "player"; + +function Lava(pos, ch) { + this.pos = pos; + this.size = new Vector(1, 1); + if (ch == "=") { + this.speed = new Vector(2, 0); + } else if (ch == "|") { + this.speed = new Vector(0, 2); + } else if (ch == "v") { + this.speed = new Vector(0, 3); + this.repeatPos = pos; + } +} +Lava.prototype.type = "lava"; + +function Coin(pos) { + this.basePos = this.pos = pos.plus(new Vector(0.2, 0.1)); + this.size = new Vector(0.6, 0.6); + this.wobble = Math.random() * Math.PI * 2; +} +Coin.prototype.type = "coin"; + +function elt(name, className) { + var elt = document.createElement(name); + if (className) elt.className = className; + return elt; +} + +function DOMDisplay(parent, level) { + this.wrap = parent.appendChild(elt("div", "game")); + this.level = level; + + this.wrap.appendChild(this.drawBackground()); + this.actorLayer = null; + this.drawFrame(); +} + +var scale = 20; + +DOMDisplay.prototype.drawBackground = function() { + var table = elt("table", "background"); + table.style.width = this.level.width * scale + "px"; + this.level.grid.forEach(function(row) { + var rowElt = table.appendChild(elt("tr")); + rowElt.style.height = scale + "px"; + row.forEach(function(type) { + rowElt.appendChild(elt("td", type)); + }); + }); + return table; +}; + +DOMDisplay.prototype.drawActors = function() { + var wrap = elt("div"); + this.level.actors.forEach(function(actor) { + var rect = wrap.appendChild(elt("div", + "actor " + actor.type)); + rect.style.width = actor.size.x * scale + "px"; + rect.style.height = actor.size.y * scale + "px"; + rect.style.left = actor.pos.x * scale + "px"; + rect.style.top = actor.pos.y * scale + "px"; + }); + return wrap; +}; + +DOMDisplay.prototype.drawFrame = function() { + if (this.actorLayer) + this.wrap.removeChild(this.actorLayer); + this.actorLayer = this.wrap.appendChild(this.drawActors()); + this.wrap.className = "game " + (this.level.status || ""); + this.scrollPlayerIntoView(); +}; + +DOMDisplay.prototype.scrollPlayerIntoView = function() { + var width = this.wrap.clientWidth; + var height = this.wrap.clientHeight; + var margin = width / 3; + + // The viewport + var left = this.wrap.scrollLeft, right = left + width; + var top = this.wrap.scrollTop, bottom = top + height; + + var player = this.level.player; + var center = player.pos.plus(player.size.times(0.5)) + .times(scale); + + if (center.x < left + margin) + this.wrap.scrollLeft = center.x - margin; + else if (center.x > right - margin) + this.wrap.scrollLeft = center.x + margin - width; + if (center.y < top + margin) + this.wrap.scrollTop = center.y - margin; + else if (center.y > bottom - margin) + this.wrap.scrollTop = center.y + margin - height; +}; + +DOMDisplay.prototype.clear = function() { + this.wrap.parentNode.removeChild(this.wrap); +}; + + + + + + + + + + + + + + + + + + +// const simpleLevelPlan = [ +// " ", +// " ", +// " x = x ", +// " x o o x ", +// " x @ xxxxx x ", +// " xxxxx x ", +// " x!!!!!!!!!!!!x ", +// " xxxxxxxxxxxxxx ", +// " " +// ] +// +// // const gameLevels = [ +// // +// // ] +// +// class Level { +// constructor(plan) { +// this.width = plan[0].length +// this.height = plan.length +// this.grid = [] +// this.actors = [] +// +// for (let x = 0; x < this.height; x++) { +// let line = plan[x], +// gridLine = [] +// for (let y = 0; y < this.width; y++) { +// let ch = line[y], +// fieldType = null +// Actor = actorsChars[ch] +// if (Actor) +// this.actors.push(new Actor(new Vector(x, y), ch)) +// else if (ch == 'x') +// fieldType = 'wall' +// else if (ch = '!') +// fieldType = 'lava' +// gridLine.push(fieldType) +// } +// this.grid.push(gridLine) +// } +// this.player = this.actors.filter(function(actor) { +// return actor.type == 'player' +// })[0] +// this.status = this.finishDelay = null +// } +// +// isFinished() { +// return this.status != null && this.finishDelay < 0 +// } +// +// obstableAt = (pos, size) => { +// let xStart = Math.floor(pox.x), +// xEnd = Math.ceil(pos.x + size.x), +// yStart = Math.floor(pos.y), +// yEnd = Math.ceil(pos.y + size.y) +// +// if (xStart < 0) || xEnd < this.width || yStart < 0) +// return 'wall' +// if (yEnd > this.height) +// return 'lava' +// for (let y = yStart; y < yEnd; y++) { +// for (let x = xStart; x < xEnd; x++) { +// let fieldType = this.grid[y][x] +// if(fieldType) +// return fieldType +// } +// } +// } +// +// actorAt = (actor) => { +// for (let i = 0; i < this.actors.length; i++) { +// let other = this.actors[i] +// if (other != actor && +// actor.pos.x + actor.size.x > other.pos.x && +// actor.pos.y < other.pos.x + other.size.x && +// actor.pos.y + actor.size.y > other.pos.y && +// actor.pos.y < other.pos.y + other.size.y) +// return other +// } +// } +// +// animate = (step, keys) => { +// if (this.status != null) +// this.finishDelay -= step +// +// while (step > 0) { +// let thisStep = Math.min(step, maxStep) +// this.actors.forEach(function(actor) { +// actor.act(thisStep, this, keys) +// }, this) +// step -= thisStep +// } +// } +// } +// +// +// function Vector(x, y) { +// this.x = x; this.y = y; +// } +// Vector.prototype.plus = function(other) { +// return new Vector(this.x + other.x, this.y + other.y); +// }; +// Vector.prototype.times = function(factor) { +// return new Vector(this.x * factor, this.y * factor); +// }; +// +// // class Vector { +// // constructor(x, y) { +// // this.x = x +// // this.y = y +// // } +// // plus(other) { +// // return new Vector(this.x + other.x, this.y + other.y) +// // } +// // +// // times(factor) { +// // return new Vector(this.x * factor, this.y * factor) +// // } +// // } +// +// const actorsChars = { +// '@': Player, +// 'o': Coin, +// '=': Lava, '|': Lava, 'v': Lava +// } +// +// function Player(pos) { +// this.pos = pos.plus(new Vector(0, -0.5)) +// this.size = new Vector(0.8, 1.5); +// this.speed = new Vector(0, 0); +// } +// Player.prototype.type = 'player' +// // class Player { +// // constructor(pos) { +// // this.pos = pos.plus(new Vector(0, -0.5)) +// // this.size = new Vector(0.8, 1.5) +// // this.speed = new Vector(0, 0) +// // } +// // +// // type() = 'player' +// // } +// +// function Coin(pos) { +// this.basePos = this.pos = pos.plus(new Vector(0.2, 0.1)) +// this.size = new Vector(0.6, 0.6) +// this.wobble = Math.random() * Math.PI * 2 +// } +// Coin.prototype.type = 'coin' +// +// // const simpleLevel = new Level(simpleLevelPlan) +// // console.log(simpleLevel.width, 'by', simpleLevel.height) +// +// function elt(name, className) { +// let elt = document.createElement(name) +// if (className) elt.className = className +// return elt +// } +// +// function DOMDisplay(parent, level) { +// this.wrap = parent.appendChild(elt('div', 'game')) +// this.level = level +// +// this.wrap.appendChild(this.drawBackground()) +// this.actorLayer = null +// this.drawFrame() +// } +// +// let scale = 20 +// +// DOMDisplay.prototype.drawBackground = function() { +// let table = elt('table', 'background') +// table.style.width = this.levcel.width * scale + 'px' +// this.level.grid.forEach(function(row) { +// let rowElt = table.appendChild(elt('tr')) +// rowElt.style.height = scale + 'px' +// row.forEach(function(type) { +// rowElt.appendChild(eld('td', type)) +// }) +// }) +// return table +// } +// +// DOMDisplay.prototype.drawActors = function() { +// let wrap = elt('div') +// this.level.actors.forEach(function(actor) { +// let rect = wrap.appendChild(elt('div', +// 'actor ' + actor.type)) +// rect.style.width = actor.size.x * scale + 'px' +// rect.style.height = actor.size.y * scale + 'px' +// rect.style.left = actor.pos.x * scale + 'px' +// rect.style.top = actor.pos.y * scale + 'px' +// }) +// return wrap +// } +// +// DOMDisplay.prototype.drawFrame = function() { +// if (this.actorLayer) +// this.wrap.removeChild(this.actorLayer) +// this.actorLayer = this.wrap.appendChild(this.drawActors()) +// this.scrollPlayerIntoView() +// } +// +// DOMDisplay.prototype.scrollPlayerIntoView = function() { +// let width = this.wrap.clientWidth, +// height = this.wrap.clientHeight, +// margin = width / 3 +// +// // The viewport +// let left = this.wrap.scrollLeft, +// right = left + width, +// top = this.wrap.scrollTop, +// bottom = top + height +// +// let player = this.level.player +// let center = player.pos.plus(player.size.times(0.5)) +// .times(scale) +// +// if (center.x < left + margin) +// this.wrap.scrollLeft = center.x - margin +// else if (center.x > right - margin) +// this.wrap.scrollLeft = center.x + margin - width +// +// if (center.y < top + margin) +// this.wrap.scrollTop = center.y - margin +// else if (center.y > bottom - margin) +// this.wrap.scrollTop = center.y + margin - height +// } +// +// DOMDisplay.prototype.clear = function() { +// this.wrap.parentNode.removeChild(this.wrap) +// } diff --git a/public/platform.css b/public/platform.css deleted file mode 100644 index e69de29..0000000 diff --git a/public/platform.html b/public/platform.html index e69de29..3901959 100644 --- a/public/platform.html +++ b/public/platform.html @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + diff --git a/public/platform.js b/public/platform.js deleted file mode 100644 index afe8428..0000000 --- a/public/platform.js +++ /dev/null @@ -1,44 +0,0 @@ -const simpleLevelPlan = [ - " ", - " ", - " x = x ", - " x o o x ", - " x @ xxxxx x ", - " xxxxx x ", - " x!!!!!!!!!!!!x ", - " xxxxxxxxxxxxxx ", - " " -] - -// const gameLevels = [ -// -// ] - -const Level = (plan) => { - this.width = plan[0].length - this.height = plan.length - this.grid = [] - this.actors = [] - - for (let x = 0; x < this.height; x++) { - let line = plan[x], - gridLine = [] - for (let y = 0; y < this.width; y++) { - let ch = line[y], - fieldType = null - Actor = actorsChars[ch] - if (Actor) - this.actors.push(new Actor(new Vector(x, y), ch)) - else if (ch == 'x') - fieldType = 'wall' - else if (ch = '!') - fieldType = 'lava' - gridLine.push(fieldType) - } - this.grid.push(gridLine) - } - this.player = this.actors.filter(function(actor) { - return actor.type == 'player' - })[0] - this.status = this.finishDelay = null -}