/* built with Studio Sketchpad: * https://sketchpad.cc * * observe the evolution of this sketch: * https://p5js.sketchpad.cc/sp/pad/view/ro.GrwKUsycNrY/rev.13 * * authors: * GoToLoop * license (unless otherwise specified): * creative commons attribution-share alike 3.0 license. * https://creativecommons.org/licenses/by-sa/3.0/ */ /** * Hoppy Beaver (v2.04) * Author: Pamela (2014/Feb) * Processing: GoToLoop (2016/Apr/08) * * forum.Processing.org/two/discussion/8997/hoppy-beaver * * www.KhanAcademy.org/computing/computer-programming/ * programming-games-visualizations/side-scroller/p/project-hoppy-beaver-extreme * * p5js.ProcessingTogether.com/sp/pad/export/ro.Cp2G$x5ApiPI5r * studio.ProcessingTogether.com/sp/pad/export/ro.9bTfM49wCIJza */ "use strict" const KHAN = 'http:/' + '/www.KaSandbox.org/third_party/' + 'javascript-khansrc/live-editor/build/images/' const REMOTE = true //const REMOTE = false const PATH = REMOTE && KHAN || '' const STICKS = 200, TURFS = 30, FPS = 60, WEIGHT = 2.5 const sticks = Array(STICKS), turfs = Array(TURFS) let beaver, score, bg, soil, win, lose function preload() { Beaver.falling = loadImage(PATH + 'creatures/Hopper-Happy.png') Beaver.jumping = loadImage(PATH + 'creatures/Hopper-Jumping.png') Grass.lawn = loadImage(PATH + 'cute/GrassBlock.png') } function setup() { createCanvas(500, 400) frameRate(FPS).strokeWeight(WEIGHT).rectMode(CORNER).imageMode(CORNER) textSize(Score.SIZE).textAlign(CENTER, CENTER) Beaver.falling.resize(Beaver.SIZE, Beaver.SIZE) Beaver.jumping.resize(Beaver.SIZE, Beaver.SIZE) Grass.lawn.resize(Grass.SIZE, Grass.SIZE) beaver = new Beaver(width>>1, height - Beaver.GROUND) Stick.counter = score = new Score(80, 20) for (let y = round(height*.85), i = 0; i !== TURFS; ++i) turfs[i] = new Grass(i*Grass.GAP, y) Object.freeze(turfs) for (let y = round(height*.65), i = 0; i !== STICKS; ++i) sticks[i] = new Stick(i*Stick.GAP + width, round(random(20, y))) Object.freeze(sticks) bg = Object.freeze(color(0xE0, 0xFF, 0xFF)) soil = Object.freeze(color(0x80, 0x50, 0x2A)) win = Object.freeze(color('green')) lose = Object.freeze(color('red')) Stick.ink = Object.freeze(color(0x5A, 0x4A, 0)) Score.ink = Object.freeze(color('blue')) Object.freeze(Object.freeze(Beaver).prototype) Object.freeze(Object.freeze(Grass).prototype) Object.freeze(Object.freeze(Stick).prototype) Object.freeze(Object.freeze(Score).prototype) } function draw() { background(bg).stroke(0).fill(soil).rect(0, height*.9, width, height*.1) for (let i = 0; i !== TURFS; turfs[i++].script()); fill(Stick.ink) for (let s, i = 0; i !== STICKS; beaver.gotStick(s = sticks[i++]) ? (s.x = -Stick.W, ++score.collected, ++score.dead) : s.script()); keyIsPressed|mouseIsPressed && beaver.jump() || beaver.fall() beaver.display() noStroke().fill(Score.ink), score.display(STICKS) if (score.dead === STICKS) { const won = score.collected/STICKS >= Score.PERCENT fill(won && win || lose) text(won && 'YOU WIN!!!' || 'Collect More Next Time...', width>>1, height>>1) } } class Beaver { constructor(x, y) { this.x = x, this.y = y, this.isJumping = false } static get SIZE() { return 40 } static get GROUND() { return 50 } // Beaver.SIZE + 10 static get SPD() { return 5 } display() { image(this.isJumping && Beaver.jumping || Beaver.falling, this.x, this.y) } fall() { this.y = min(this.y + Beaver.SPD, height - Beaver.GROUND) return this.isJumping = false } jump() { this.y = max(this.y - Beaver.SPD, 0) return this.isJumping = true } gotStick(s) { return this.x+Beaver.SIZE > s.x & this.x < s.x+Stick.W & this.y+Beaver.SIZE > s.y & this.y < s.y+Stick.H } } class Grass { constructor(x, y) { this.x = x, this.y = y } static get SIZE() { return 20 } static get GAP() { return 20 } static get SCROLL() { return 2 } script() { this.update(), this.display() } update() { (this.x -= Grass.SCROLL) < -Grass.SIZE && (this.x = width) } display() { image(Grass.lawn, this.x, this.y) } } class Stick { constructor(x, y) { this.x = x, this.y = y } static get W() { return 10 } static get H() { return 50 } static get GAP() { return 40 } static get SCROLL() { return 2 } script() { if (this.x > -Stick.W) this.update() <= -Stick.W? ++Stick.counter.dead : this.x < width && this.display() } update() { return this.x -= Stick.SCROLL } display() { rect(this.x, this.y, Stick.W, Stick.H) } } class Score { constructor(x, y) { this.x = x, this.y = y, this.collected = this.dead = 0 } static get SIZE() { return 18 } static get PERCENT() { return .9 } display(total) { text('Score: ' + nf(this.collected, 3) + '/' + total, this.x, this.y) } }