diff --git a/index.html b/index.html index e5ee51e..1fa4973 100644 --- a/index.html +++ b/index.html @@ -2,25 +2,29 @@ Adventures with Anxiety! - +
-
-
-
-
-
-
-
-
+
+
+
- - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/scenes/demo.md b/scenes/demo.md new file mode 100644 index 0000000..a38c68f --- /dev/null +++ b/scenes/demo.md @@ -0,0 +1,47 @@ +# demo + +`SceneSetup.demo()` + +> Prepare for trouble! + +Oh no! + +(#demo-attacks) + +# demo-attacks + +[Attack 10 points](#demo-attack-low) + +[Attack 20 points](#demo-attack-med) + +[Attack 50%](#demo-attack-hi) + +# demo-attack-low + +`HP.attackHong("10p")` + +{{if HP.hong==0}} (#dead) {{/if}} + +(#demo-attacks) + +# demo-attack-med + +`HP.attackHong("20p")` + +{{if HP.hong==0}} (#dead) {{/if}} + +(#demo-attacks) + +# demo-attack-hi + +`HP.attackHong("50%")` + +{{if HP.hong==0}} (#dead) {{/if}} + +(#demo-attacks) + +# dead + +i am ded + +> u r ded diff --git a/woods.md b/scenes/woods.md similarity index 77% rename from woods.md rename to scenes/woods.md index 2e863b0..0819783 100644 --- a/woods.md +++ b/scenes/woods.md @@ -1,6 +1,9 @@ # woods -`document.body.style.background = "#ddd"` +``` +document.body.style.background = "#ddd" +publish("beebee", ["normal"]) +``` Two roads diverged in the woods and I... {{if _.eaten}} (this time try not to get eaten by wolves) {{/if}} @@ -13,11 +16,14 @@ Two roads diverged in the woods and I... # woods-less -`document.body.style.background = "#ff4040"` - And that's how I got lost in the woods and was eaten by wolves {{if _.eaten}} (...again.) {{/if}} +``` +document.body.style.background = "#ff4040" +publish("beebee", ["panic"]) +``` + `_.eaten = true` `_.played_less = true` @@ -38,6 +44,8 @@ And that's how I found my way back to civilization and was not eaten by wolves Good choice. +`publish("beebee", ["yay"])` + (#END) do NOT show this line diff --git a/scripts/game/BGAnxiety.js b/scripts/game/BGAnxiety.js new file mode 100644 index 0000000..e69de29 diff --git a/scripts/game/Beebee.js b/scripts/game/Beebee.js new file mode 100644 index 0000000..4eac0f8 --- /dev/null +++ b/scripts/game/Beebee.js @@ -0,0 +1,54 @@ +function Beebee(){ + + var self = this; + + // Sprite! + var beebeeImage = new Image(); + beebeeImage.src = "sprites/beebee.png"; + self.sprite = new Sprite({ + image: beebeeImage, + grid:{ + width: 1, + height: 2 + }, + frame:{ + width: 720, + height: 500 + }, + anchor:{ + x: 300, + y: 230 + }, + frameNames:[ + "normal", + "panic", + "yay" + ], + x: 300, + y: 430, + rotation: 0, + scale: 1, + squash: 1 + }); + + // Draw + var ticker = 1; + self.draw = function(ctx){ + + // Bouncing based on frame! + ticker += 1/20; + if(self.sprite.currentFrameName == "panic"){ + ticker += 1; + } + self.sprite.squash = 1 + Math.sin(ticker)*0.05; + + // Draw me! + self.sprite.draw(ctx); + + }; + + subscribe("beebee", function(frameName){ + self.sprite.gotoFrameByName(frameName); + }); + +} \ No newline at end of file diff --git a/game.js b/scripts/game/Game.js similarity index 80% rename from game.js rename to scripts/game/Game.js index 0a5a909..d398733 100644 --- a/game.js +++ b/scripts/game/Game.js @@ -1,16 +1,3 @@ -var xhr = new XMLHttpRequest(); -xhr.open('GET', 'woods.md?v='+Math.random()); -xhr.onload = function() { - if(xhr.status===200){ - Game.onload(xhr.responseText); - } -}; -xhr.send(); - -/*****************************/ -/*****************************/ -/*****************************/ - window._ = {}; window.Game = {}; @@ -69,21 +56,19 @@ Game.onload = function(data){ } +//////////////////////////////////////////////////////////////////////////////////////////////// +// SCENE MANAGEMENT //////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// + Game.start = function(){ window._ = {}; // global var, reset Game.goto(Game.startSectionID); }; Game.update = function(){ - - var wordsHeight = 80 + Game.wordsDOM.getBoundingClientRect().height; - var currentY = parseFloat(Game.wordsDOM.style.top) || 80; - var gotoY = (wordsHeight<260) ? 0 : wordsHeight-260; - gotoY = 80 - gotoY; - - var nextY = currentY*0.9 + gotoY*0.1; - Game.wordsDOM.style.top = nextY+"px"; - + Game.updateText(); + Game.updateCanvas(); + publish("update"); }; Game.goto = function(sectionID){ @@ -101,9 +86,8 @@ Game.goto = function(sectionID){ Game.executeNextLine(); }; -Game.executeNextLine = function(){ - var doNextLineImmediately = false; +Game.executeNextLine = function(){ // Parse handlebars var originalLine = Game.queue.shift(); @@ -112,7 +96,11 @@ Game.executeNextLine = function(){ // Execute line var promiseNext; - if(line!=""){ // none, don't execute... + if(line==""){ + // If no line, get immediate promise... + promiseNext = new pinkySwear(); + promiseNext(true, []); + }else{ // Execute based on what type it is! var lineType = Game.getLineType(line); @@ -122,11 +110,9 @@ Game.executeNextLine = function(){ break; case "choice": promiseNext = Game.executeChoice(line); - doNextLineImmediately = true; break; case "code": promiseNext = Game.executeCode(line); - doNextLineImmediately = true; break; } @@ -154,6 +140,21 @@ Game.addToQueue = function(line){ Game.queue.push(line); } + +//////////////////////////////////////////////////////////////////////////////////////////////// +// TEXT AND STUFF ////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// + +// Move the text DOM to latest +Game.updateText = function(){ + var wordsHeight = 80 + Game.wordsDOM.getBoundingClientRect().height; + var currentY = parseFloat(Game.wordsDOM.style.top) || 80; + var gotoY = (wordsHeight<260) ? 0 : wordsHeight-260; + gotoY = 80 - gotoY; + var nextY = currentY*0.9 + gotoY*0.1; + Game.wordsDOM.style.top = nextY+"px"; +}; + // Execute text! Just add it to text DOM. Game.executeText = function(line){ @@ -325,15 +326,45 @@ Game.parseLine = function(line){ }; - -/*****************************/ -/*****************************/ -/*****************************/ +//////////////////////////////////////////////////////////////////////////////////////////////// +// WHERE STUFF WILL BE DRAWN /////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// Game.canvas = document.querySelector("#game_canvas"); Game.canvas.width = 360 * 2; Game.canvas.height = 450 * 2; Game.canvas.style.width = Game.canvas.width/2 + "px"; Game.canvas.style.height = Game.canvas.height/2 + "px"; +Game.context = Game.canvas.getContext("2d"); + +// A blank scene +Game.resetScene = function(){ + Game.scene = {}; + Game.scene.children = []; +}; +Game.resetScene(); + +// Update & draw all the kids! +Game.updateCanvas = function(){ + + // For retina + var ctx = Game.context; + ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); + ctx.save(); + ctx.scale(2,2); + + // Update/Draw all kids + Game.scene.children.forEach(function(child){ + child.draw(ctx); + }); + + // Restore + ctx.restore(); + + // Draw HP + HP.draw(); + +}; + diff --git a/scripts/game/HP.js b/scripts/game/HP.js new file mode 100644 index 0000000..b5c600c --- /dev/null +++ b/scripts/game/HP.js @@ -0,0 +1,124 @@ +// Singleton - it's always there! +window.HP = new HitPoints(); + +// The Class! +function HitPoints(){ + + var self = this; + + // My DOM & canvas + self.dom = document.querySelector("#game_hp"); + self.canvas = document.createElement("canvas"); + self.canvas.width = 360 * 2; + self.canvas.height = 70 * 2; + self.canvas.style.width = self.canvas.width/2 + "px"; + self.canvas.style.height = self.canvas.height/2 + "px"; + self.context = self.canvas.getContext("2d"); + self.dom.appendChild(self.canvas); + + // My sprite + self.image = new Image(); + self.image.src = "sprites/hp.png"; + + // My stats + self.reset = function(){ + self.hong = 100; + self.beebee = 100; + }; + self.reset(); + + // Attack! + self.doDamage = function(str, target){ + + // Absolute or Relative Damage? + var num = parseFloat(str); + var isAbsolute = (str.slice(-1)=="p"); // p = absolute, % = relative + if(isAbsolute){ + self[target] -= num; + }else{ + var relativeDamage = Math.floor( self[target] * (num/100) ); + self[target] -= relativeDamage; + } + + // Floor bound + if(self[target]<0){ + self[target] = 0; + } + + }; + // TODO: SHAKING BASED ON AMOUNT OF ABSOLUTE DAMAGE. + self.attackHong = function(str){ + self.doDamage(str, "hong"); + self.leftShake = 30; + }; + self.attackBeebee = function(str){ + self.doDamage(str, "beebee"); + self.rightShake = 30; + }; + + // Draw + self.leftShake = 0; + self.leftWidth = 360; + self.rightShake = 0; + self.rightWidth = 360; + self.drawHalf = function(ctx, isRight){ + + ctx.save(); + + // Which side? + var side = isRight ? "right" : "left"; + var hp = isRight ? self.beebee : self.hong; + + // Shaking + if(self[side+"Shake"]>0){ + var amp = self[side+"Shake"]/7; + var shakeY = Math.sin(self[side+"Shake"]*1.3)*amp; + ctx.translate(0,shakeY); + self[side+"Shake"]--; + }else{ + self[side+"Shake"]=0; + } + + // BLACK + var sx=isRight ? 360 : 0, sy=0, sw=360, sh=150; + ctx.drawImage(self.image, sx,sy,sw,sh, sx/2,sy/2,sw/2,sh/2); // black + + // RED + var hpRatio = (hp+32)/(100+32); // 100,0 => 1,0.3 + sw = 360 * hpRatio; + sy = 150; + self[side+"Width"] = self[side+"Width"]*0.8 + sw*0.2; + sw = self[side+"Width"]; + if(sw>88){ + if(isRight){ + ctx.drawImage(self.image, sx+(360-sw),sy,sw,sh, 360/2,0,sw/2,sh/2); + }else{ + ctx.drawImage(self.image, sx,sy,sw,sh, (360-sw)/2,0,sw/2,sh/2); + } + } + if(self[side+"WhiteWidth"]>sw && self[side+"Shake"]<=0){ + self[side+"WhiteWidth"] -= 0.6; + } + + ctx.restore(); + + }; + self.draw = function(){ + + var ctx = self.context; + ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); + ctx.save(); + ctx.scale(2,2); + + // Draw Left & Right Sides + self.drawHalf(ctx, false); + self.drawHalf(ctx, true); + + // Draw "Timer" + var sx=0, sy=450, sw=720, sh=150; + ctx.drawImage(self.image, sx,sy,sw,sh, 0,0,sw/2,sh/2); + + ctx.restore(); + }; + +} \ No newline at end of file diff --git a/scripts/game/SceneSetup.js b/scripts/game/SceneSetup.js new file mode 100644 index 0000000..5c7f921 --- /dev/null +++ b/scripts/game/SceneSetup.js @@ -0,0 +1,16 @@ +/********************************** + +A big ol' singleton class that just makes it easy to create scenes. + +**********************************/ + +window.SceneSetup = {}; + +SceneSetup.demo = function(){ + + Game.resetScene(); + + var beebee = new Beebee(); + Game.scene.children.push(beebee); + +}; \ No newline at end of file diff --git a/scripts/game/Sprite.js b/scripts/game/Sprite.js new file mode 100644 index 0000000..0054f6f --- /dev/null +++ b/scripts/game/Sprite.js @@ -0,0 +1,100 @@ +/*************************************************** + +A sprite built off this config: +{ + image: image, + grid:{ // in frames + width: 2, + height: 2 + }, + frame:{ // in pixels + width: 100, + height: 100 + }, + anchor:{ // in pixels. optional. + x: 10, + y: 30 + }, + frameNames:[ // optional + "one", + "two", + "three" + ], + x: 0, // optional + y: 0, // optional + rotation: 0, // optional + scale: 1, // optinal + squash: 1, // optional +} + + +***************************************************/ + +function Sprite(config){ + + var self = this; + + // Sprite image & dimensions + self.image = config.image; + self.grid = config.grid; + self.frame = config.frame; + + // Sprite anchor + self.anchor = {}; + self.anchor.x = config.anchor.x || 0; + self.anchor.y = config.anchor.y || 0; + + // Current frame + self.currentFrame = 0; + self.currentFrameName = ""; + self.frameNames = config.frameNames || []; + self.gotoFrame = function(index){ + self.currentFrame = index; + self.currentFrameName = self.frameNames[self.currentFrame] || ""; + }; + self.gotoFrameByName = function(name){ + var index = self.frameNames.indexOf(name); + self.gotoFrame(index); + }; + self.gotoFrame(0); + + // Other transformations + self.x = config.x || 0; + self.y = config.y || 0; + self.rotation = config.rotation || 0; + self.scale = config.scale || 1; + self.squash = config.squash || 1; + + // Draw frame! + self.draw = function(ctx){ + + ctx.save(); + + // Which part of image to draw? + var sx = self.currentFrame % self.grid.width; + var sy = Math.floor((self.currentFrame - sx)/self.grid.width); + var fw = self.frame.width; + var fh = self.frame.height; + + // Translate... + var dx = self.x; + var dy = self.y; + ctx.translate(dx, dy); + + // Scale + var scaleX = self.scale * self.squash; + var scaleY = self.scale / self.squash; + ctx.scale(scaleX, scaleY); + + // Draw it! + ctx.drawImage( + self.image, + sx*fw, sy*fh, fw, fh, + -self.anchor.x, -self.anchor.y, fw/2, fh/2 + ); + + ctx.restore(); + + }; + +} \ No newline at end of file diff --git a/scripts/lib/minpubsub.min.js b/scripts/lib/minpubsub.min.js new file mode 100644 index 0000000..16454f2 --- /dev/null +++ b/scripts/lib/minpubsub.min.js @@ -0,0 +1,2 @@ +(function(b){var a={},e=b.c_||{};a.publish=function(f,c){for(var a=e[f],d=a?a.length:0;d--;)a[d].apply(b,c||[])};a.subscribe=function(a,c){e[a]||(e[a]=[]);e[a].push(c);return[a,c]};a.unsubscribe=function(a,c){var b=e[c?a:a[0]];c=c||a[1];for(var d=b?b.length:0;d--;)b[d]===c&&b.splice(d,1)};"object"===typeof module&&module.exports?module.exports=exports=a:"function"===typeof define&&define.amd?define(function(){return a}):"object"===typeof b&&(b.publish=a.publish,b.subscribe=a.subscribe,b.unsubscribe= +a.unsubscribe)})(this.window); \ No newline at end of file diff --git a/pinkyswear.min.js b/scripts/lib/pinkyswear.min.js similarity index 100% rename from pinkyswear.min.js rename to scripts/lib/pinkyswear.min.js diff --git a/scripts/main.js b/scripts/main.js new file mode 100644 index 0000000..e56f0ab --- /dev/null +++ b/scripts/main.js @@ -0,0 +1,8 @@ +var xhr = new XMLHttpRequest(); +xhr.open('GET', 'scenes/demo.md?v='+Math.random()); +xhr.onload = function() { + if(xhr.status===200){ + Game.onload(xhr.responseText); + } +}; +xhr.send(); \ No newline at end of file diff --git a/sprites/beebee.png b/sprites/beebee.png new file mode 100644 index 0000000..97626c7 Binary files /dev/null and b/sprites/beebee.png differ diff --git a/sprites/hp.png b/sprites/hp.png new file mode 100644 index 0000000..351b5a9 Binary files /dev/null and b/sprites/hp.png differ diff --git a/game.css b/styles/game.css similarity index 77% rename from game.css rename to styles/game.css index 7b7cac2..a30ecc0 100644 --- a/game.css +++ b/styles/game.css @@ -7,6 +7,13 @@ body{ background: #ddd; } +.no_select{ + -webkit-user-select: none; /* Safari 3.1+ */ + -moz-user-select: none; /* Firefox 2+ */ + -ms-user-select: none; /* IE 10+ */ + user-select: none; /* Standard syntax */ +} + #game_container{ position: absolute; @@ -107,38 +114,17 @@ body{ /***********************************/ /***********************************/ -#game_hp{ - position: absolute; - width: 360px; - height: 80px; - top: 0px; - left: 0px; - - background: rgb(204,204,204); - background: linear-gradient(180deg, rgba(204,204,204,1) 80%, rgba(204,204,204,0) 100%); +canvas{ + border: none; } -#game_hp > div{ - position: absolute; - top:25px; - width: 150px; - height: 20px; - background: #ff4040; -} -#game_hp > #hp_human{ - left: 20px; - transform: skew(15deg); -} -#game_hp > #hp_wolf{ - right: 20px; - transform: skew(-15deg); -} - -/***********************************/ -/***********************************/ -/***********************************/ - #game_canvas{ position: absolute; top:0; left:0; - border: none; +} + +#game_hp{ + position: absolute; + width: 360px; + height: 100px; + top:0; left:0; }