diff --git a/src/assets/lantern.png b/src/assets/lantern.png new file mode 100644 index 0000000..ad910d2 Binary files /dev/null and b/src/assets/lantern.png differ diff --git a/src/main.js b/src/main.js index fcd4297..00f25bb 100644 --- a/src/main.js +++ b/src/main.js @@ -18,14 +18,13 @@ var container = new PIXI.Container(); var hud = new PIXI.Container(); var endC = new PIXI.Container(); endC.visible = false -app.stage.addChild(container); -app.stage.addChild(hud); -app.stage.addChild(endC); const resources = PIXI.loader.resources var player, state, objects, maxX, lastKey, PTS_WATER, PTS_COWS, END_TXT - +var lanterns +var moos +var shader, quad PIXI.loader .add("assets/player.png") .add("assets/player_still.png") @@ -34,6 +33,7 @@ PIXI.loader .add("assets/water.png") .add("assets/vodkaguy.png") .add("assets/grass.png") + .add("assets/lantern.png") .load(setup); function setup () { @@ -51,12 +51,27 @@ function setup () { PTS_WATER.y = 20 - PTS_WATER.x = 20 + PTS_WATER.x = 50 + + PTS_COWS.y = 50 - PTS_COWS.x = 20 + PTS_COWS.x = 50 hud.addChild(PTS_WATER) + const hudCow = new PIXI.Sprite(resources['assets/cow.png'].texture) + hudCow.width = 24 + hudCow.height = 24 + hudCow.y = 50 + hudCow.x = 20 + + const hudWater = new PIXI.Sprite(resources['assets/water.png'].texture) + hudWater.width = 24 + hudWater.height = 24 + hudWater.y = 20 + hudWater.x = 20 hud.addChild(PTS_COWS) + hud.addChild(hudCow) + hud.addChild(hudWater) const vodkaguy = new PIXI.Sprite(vodkaguyTexture) container.addChild(vodkaguy) @@ -159,6 +174,7 @@ function setup () { cow.vrot = 0 cow.ticks = 0 cow.type = 'cow' + cow.lastmoo = 0 container.addChild(cow) objects.push(cow) @@ -166,8 +182,6 @@ function setup () { maxX = Math.max(maxX, cow.x + cow.width) } - grass.x = maxX - for (let i = 0; i < waters; i++) { const water = new PIXI.Sprite(waterTexture) water.anchor.x = 0.5 @@ -189,12 +203,130 @@ function setup () { maxX = Math.max(maxX, water.x + water.width) } + + grass.x = maxX + +// 0 TAW maxX +// | | | | + // i want to have 10 lanterns ! + const LANTERN_COUNT = 10 + const availableWidth = (maxX - TARGET_AREA_WIDTH) - 50 + const lanternDist = availableWidth / (LANTERN_COUNT-1) + + lanterns = [] + for (let i = 0; i < LANTERN_COUNT; i++) { + // lantern on bottom + const lantern = new PIXI.Sprite(resources['assets/lantern.png'].texture) + lantern.anchor.set(.5, .5) + lantern.x = TARGET_AREA_WIDTH + (lantern.width / 2) + (i * lanternDist) + lantern.y = HEIGHT - lantern.height /2 + lanterns.push(lantern) + container.addChild(lantern) + } + for (let i = 0; i < LANTERN_COUNT; i++) { + // lantern on top + const lantern = new PIXI.Sprite(resources['assets/lantern.png'].texture) + lantern.anchor.set(.5, .5) + lantern.x = TARGET_AREA_WIDTH + (lantern.width / 2) + (i * lanternDist) + lantern.y = lantern.height /2 + + lanterns.push(lantern) + container.addChild(lantern) + } + container.addChild(player) endC.addChild(END_TXT) + + moos = [] + state = play; + + + // shader stuff + + // Build geometry. + const geometry = new PIXI.Geometry() + .addAttribute('aVertexPosition', // the attribute name + [ + -400, -300, // x, y + 400, -300, // x, y + 400, 300, + -400, 300 + ], // x, y + 2) // the size of the attribute + .addIndex([0, 1, 2, 0, 2, 3]); + + const vertexSrc = ` + precision mediump float; + attribute vec2 aVertexPosition; + + uniform mat3 translationMatrix; + uniform mat3 projectionMatrix; + + void main() { + gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + }`; + + + const fragmentSrc = ` + varying vec2 vUvs; + uniform vec2 playerPos; + uniform float time; + uniform vec2 lanternPositions[20]; + + void main() { + float minLight = .8; + float flickerspeed = 50.0; + float lightradius = 60.0 + sin(time * flickerspeed/4.0) * 5.0; + for (int i = 0; i < 20; i++) { + vec2 d = lanternPositions[i] - gl_FragCoord.xy; + float dist = length(d); + if (dist < lightradius) { + float L = (dist / lightradius) * .9; + if (L < minLight) { + minLight = L; + } + } + } + + flickerspeed = 7.0; + lightradius = 100.0 + sin(time * flickerspeed/4.0) * 5.0; + vec2 d = playerPos - gl_FragCoord.xy; + float dist = length(d); + if (dist < lightradius) { + float L = (dist / lightradius) * .9; + if (L < minLight) { + minLight = L; + } + } + + gl_FragColor = vec4( + sin(time*flickerspeed) *.1, + sin(time*flickerspeed) *.1, + sin(time*flickerspeed) *.1, + minLight + ); + }`; + + const uniforms = { + time: 0, + player_y: player.y + }; + + // Build the shader and the quad. + shader = PIXI.Shader.from(vertexSrc, fragmentSrc, uniforms); + quad = new PIXI.Mesh(geometry, shader); + quad.position.set(400, 300) + + app.stage.addChild(container); + app.stage.addChild(quad); + app.stage.addChild(hud); + app.stage.addChild(endC); + + //Start the game loop app.ticker.add(delta => gameLoop(delta)); } @@ -207,18 +339,17 @@ function gameLoop(delta){ function end(delta) { hud.visible = false endC.visible = true - if (player.scale.x < 250) { + if (player.scale.x < 290) { player.scale.x += 5 player.scale.y += 5 } else { - END_TXT.anchor.x = .5 - END_TXT.anchor.y = .5 - END_TXT.x = player.x - END_TXT.y = player.y + quad.visible = false + END_TXT.x = WIDTH / 2 - END_TXT.width / 2 + END_TXT.y = HEIGHT / 2 - END_TXT.height / 2 END_TXT.visible = true } } - +var time = 0 var blinkStart const BLINK_DUR = 250 @@ -332,6 +463,56 @@ function play(delta) { } } + for (const c of objects) { + if (c.type === 'cow') { + if (c.vrot > 0 && c.ticks > 0) { + if (c.lastmoo === 0 || (now - c.lastmoo > 500)) { + c.lastmoo = now + const moo = new PIXI.Text('!moooo', {fontFamily : 'Arial', fontSize: 14, fill : 0xff0000, align : 'center'}) + moo.x = c.x + moo.y = c.y + moo.anchor.set(.5, .5) + + let r = Math.random() + if (r < 1/3) { + moo.vx = 0 + } else if (r < 2/3) { + moo.vx = 1 + } else { + moo.vx = -1 + } + if (moo.vx === 0) { + r = Math.random() + moo.vy = r < .5 ? 1 : -1 + } else { + r = Math.random() + if (r < 1/3) { + moo.vy = 0 + } else if (r < 2/3) { + moo.vy = 1 + } else { + moo.vy = -1 + } + } + moo.rotation = Math.atan2(moo.vx, moo.vy) + + moo.alpha = 1 + moos.push(moo); + container.addChild(moo) + } + } + } + } + for (const obj of moos) { + obj.x += obj.vx + obj.y += obj.vy + obj.alpha -= .01 + if (obj.alpha <= 0) { + container.removeChild(obj) + } + } + moos = moos.filter(moo => moo.alpha > 0) + let ptsWater = 0 let ptsCows = 0 for (const obj of objects) { @@ -387,6 +568,22 @@ function play(delta) { if (ptsWater >= 20 && ptsCows >= 20) { state = end } + + time += 1 / 60; + quad.shader.uniforms.time = time; + quad.shader.uniforms.playerPos = [ + player.x + container.x, + HEIGHT - player.y + ]; + const lanternPositions = [] + lanterns.forEach(l => { + lanternPositions.push(l.x + container.x) + lanternPositions.push(HEIGHT - l.y) + }) + quad.shader.uniforms.lanternPositions = lanternPositions + + /// FFFFUFFUUUUUUUUU + // quad.scale.set(Math.cos(time) * 1 + 2, Math.sin(time * 0.7) * 1 + 2); } //The `keyboard` helper function