Browse Source

I don't even know

master
mortie 6 years ago
parent
commit
6a6aaebf4f

+ 1
- 0
.gitignore View File

@@ -1 +1,2 @@
conf.js
node_modules

BIN
assets/common/audio/chomp.mp3 View File


BIN
assets/common/audio/flap.mp3 View File


BIN
assets/common/audio/hurt.mp3 View File


BIN
assets/common/audio/loss.mp3 View File


assets/nsfw/images/background.jpg → assets/common/images/background.jpg View File


assets/nsfw/images/fire.png → assets/common/images/fire.png View File


BIN
assets/common/images/wall-overlap.png View File


assets/nsfw/images/wall.png → assets/common/images/wall.png View File


assets/nsfw/soundtracks/track1.mp3 → assets/common/soundtracks/track1.mp3 View File


assets/nsfw/soundtracks/track2.mp3 → assets/common/soundtracks/track2.mp3 View File


assets/nsfw/soundtracks/track3.mp3 → assets/common/soundtracks/track3.mp3 View File


BIN
assets/nsfw/images/player.png View File


BIN
assets/nsfw/images/player_flipped.png View File


BIN
assets/sfw/images/background.jpg View File


BIN
assets/sfw/images/fire.png View File


BIN
assets/sfw/images/player_flipped.png View File


BIN
assets/sfw/images/wall.png View File


BIN
assets/sfw/soundtracks/track1.mp3 View File


BIN
assets/sfw/soundtracks/track2.mp3 View File


BIN
assets/sfw/soundtracks/track3.mp3 View File


+ 24
- 0
css/style.css View File

@@ -5,3 +5,27 @@ body {
canvas {
position: absolute;
}

#done-screen {
position: absolute;
background-color: rgba(255, 255, 255, 0.7);
border: 1px solid black;
border-radius: 20px;

text-align: center;
font-size: 2em;

left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
margin: auto;

width: 300px;
height: 150px;

padding-top: 50px;
}
#done-screen.hidden {
display: none;
}

+ 8
- 1
index.html View File

@@ -5,10 +5,17 @@
<title>Flappy Dick</title>
<link rel="stylesheet" href="css/style.css">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0">

</head>
<body>
<canvas id="canvas"></canvas>

<div id="done-screen" class="hidden">
Your score: <span id="score"></span>
<div>
<button id="restart">Restart</button>
</div>
</div>

<script src="conf.js"></script>
<script src="js/util.js"></script>
<script src="js/vec2.js"></script>

+ 37
- 13
js/assets.js View File

@@ -1,17 +1,27 @@
var assetsPath = "assets/"+conf.assets;
var commonPath = "assets/common";

var assets = {
imgs: {
player: new ImageSource("player"),
player: new ImageSource("theme:player"),
player_flipped: new ImageSource("theme:player_flipped"),
background: new ImageSource("background", null, ".jpg"),
wall: new ImageSource("wall")
wall: new ImageSource("wall"),
wall_overlap: new ImageSource("wall-overlap"),
},

audio: {
hurt: new AudioSource("audio/hurt"),
loss: new AudioSource("audio/loss"),
flap: new AudioSource("audio/flap"),
chomp: new AudioSource("audio/chomp"),
},

soundtracks: {
soundtrack1: new AudioSource("soundtracks/track1"),
soundtrack2: new AudioSource("soundtracks/track2"),
soundtrack3: new AudioSource("soundtracks/track3")
}
soundtrack3: new AudioSource("soundtracks/track3"),
},
};

/*
@@ -21,10 +31,13 @@ function AudioSource(src, ext) {
makeEventListener(this);
var ext = ext || ".mp3";

this.audio = document.createElement("audio");
this.elems = [];
for (var i = 0; i < 10; ++i)
this.elems[i] = new Audio(commonPath+"/"+src+ext);
this.ready = false;
this.index = 0;

this.audio.addEventListener("canplaythrough", function() {
this.elems[0].addEventListener("canplaythrough", function() {
if (this.ready)
return;

@@ -32,18 +45,21 @@ function AudioSource(src, ext) {
this.emit("load");
}.bind(this));

this.audio.addEventListener("ended", function() {
this.elems[0].addEventListener("ended", function() {
this.emit("ended");
}.bind(this));

this.audio.src = assetsPath+"/"+src+ext;
this.elems[0].onerror = function() {
console.error("Error with", src);
}
}
AudioSource.prototype.play = function() {
this.audio.currentTime = 0;
this.audio.play();
this.elems[this.index++].play();
this.index %= this.elems.length;
}
AudioSource.prototype.pause = function() {
this.audio.pause();
for (var i in this.elems)
this.elmes[i].pause();
}

/*
@@ -52,6 +68,12 @@ AudioSource.prototype.pause = function() {
function ImageSource(src, frameh, ext) {
var ext = ext || ".png";

if (src.indexOf("theme:") == 0) {
src = assetsPath+"/images/"+src.split(":")[1];
} else {
src = commonPath+"/images/"+src;
}

this.img = document.createElement("img");
this.ready = false;
this.width = 0;
@@ -60,7 +82,6 @@ function ImageSource(src, frameh, ext) {
this.steps = 1;

this.img.onload = function() {
console.log(this);
this.ready = true;
this.width = this.img.width;
this.height = this.img.height;
@@ -78,7 +99,10 @@ function ImageSource(src, frameh, ext) {
}
}.bind(this);

this.img.src = assetsPath+"/images/"+src+ext;
this.img.src = src+ext
this.img.onerror = function() {
console.error("error with", src);
}
}
ImageSource.prototype.draw = function(ctx, step) {
if (!step) step = 0;

+ 45
- 11
js/entities.js View File

@@ -24,8 +24,7 @@ Background.prototype.update = function() {
if (this.img.ready && this.img2x === 0)
this.img2x = this.img1x + this.img.width * 2;

if (this.game.started)
this.force.add({ x: 0.09, y: 0 });
this.vel.set({ x: this.game.ids.player.vel.x * 0.9, y: 0 });

if (this.img1x + this.img.width * 2 + this.pos.x < this.game.camera.x) {
this.img1x = this.img2x;
@@ -54,8 +53,14 @@ Background.prototype.draw = function(ctx){
*/

function Player(game) {
makeEnt(this, game, 100);
makeEnt(this, game, 100, "player");
this.img = assets.imgs.player;
this.img_flipped = assets.imgs.player_flipped;
this.hurt = assets.audio.hurt;
this.loss = assets.audio.loss;
this.flap = assets.audio.flap;
this.chomp = assets.audio.chomp;
this.hurtLoop = null;

game.started = false;
this.moves = true;
@@ -63,6 +68,7 @@ function Player(game) {
this.layer = 1;

this.invincible = false;
this.visible = true;
this.invincibleTimeout = null;
this.started = false;
this.rotation = 0;
@@ -88,7 +94,7 @@ Player.prototype.setBox = function() {
}
Player.prototype.rise = function() {
this.erectLevel += 1;
this.setInvincible(200);
this.setInvincible(200, false);
this.setBox();
}
Player.prototype.lower = function() {
@@ -96,25 +102,38 @@ Player.prototype.lower = function() {
return;

this.erectLevel -= 1;
if (this.erectLevel === 0)
if (this.erectLevel === 0) {
this.lose();
else
this.setInvincible(500);
} else {
this.hurt.play();
this.setInvincible(2000, true);
}

this.setBox();
}
Player.prototype.setInvincible = function(time) {
Player.prototype.setInvincible = function(time, hurt) {
clearTimeout(this.invincibleTimeout);

if (hurt) {
clearInterval(this.hurtLoop);
this.hurtLoop = setInterval(function() {
this.visible = !this.visible;
}.bind(this), 60);
}

this.invincible = true;
this.invincibleTimeout = setTimeout(function() {
this.invincible = false;
this.visible = true;
clearInterval(this.hurtLoop);
this.hurtLoop = null;
}.bind(this), time);
}
Player.prototype.onInput = function(name, down) {

// Jump
if (name === "jump" && down) {
this.flap.play();
this.game.started = true;
this.vel.y = -1.3;
}
@@ -144,9 +163,10 @@ Player.prototype.update = function() {

if (ent instanceof Obstacle && this.shape.collidesWith(ent.shape)) {
this.lower();
return;
this.vel.x = -1;
} else if (ent instanceof PowerUp && this.bigShape.collidesWith(ent.shape)) {
this.rise();
this.chomp.play();
ent.dead = true;
}
}
@@ -160,15 +180,23 @@ Player.prototype.move = function() {
this.rotation = this.vel.angle();
}
Player.prototype.lose = function() {
this.game.stop(this.pos.x / 10);
this.loss.play();
this.game.stop(this.pos.x / 100);
}
Player.prototype.draw = function(ctx) {
if (!this.visible)
return;

ctx.rotate(this.rotation);
var scale = 0.4 + this.erectLevel / 8;
ctx.scale(scale, scale);
ctx.translate(70, -50);
ctx.rotate(Math.PI / 2);
this.img.draw(ctx);

if (this.vel.y < 0)
this.img.draw(ctx);
else
this.img_flipped.draw(ctx);
}

/*
@@ -178,6 +206,7 @@ Player.prototype.draw = function(ctx) {
function Obstacle(game, x, y) {
makeEnt(this, game, 100);
this.img = assets.imgs.wall;
this.overlap = assets.imgs.wall_overlap;

this.collude = false;

@@ -195,6 +224,11 @@ Obstacle.prototype.draw = function(ctx) {
ctx.scale(0.9, 1.1);
this.img.draw(ctx);
}
Obstacle.prototype.drawOverlay =function(ctx) {
ctx.translate(-100, this.game.canvas.height / 2 - 340);
ctx.scale(0.9, 1.1);
this.overlap.draw(ctx);
}
Obstacle.prototype.update = function() {
if (this.game.camera.x > this.pos.x + 800)
this.dead = true;

+ 30
- 1
js/game.js View File

@@ -111,7 +111,7 @@ Shape.prototype.height = function() {
}

// Make entity from object
function makeEnt(obj, game, mass) {
function makeEnt(obj, game, mass, id) {
obj.pos = new Vec2();
obj.vel = new Vec2();
obj.force = new Vec2();
@@ -125,6 +125,10 @@ function makeEnt(obj, game, mass) {

obj.mass = mass || 0;
obj.forceScalar = 1 / obj.mass;

if (id) {
game.ids[id] = obj;
}
}

/*
@@ -141,6 +145,7 @@ function Game(canvas) {
this.worldgen = null;

this.entities = [];
this.ids = {};
this.layers = [];
this.inputListeners = [];

@@ -252,11 +257,15 @@ Game.prototype.update = function() {
}
}

ent.drawn = false;

if (ent.collude && ent.pos.x + ent.shape.width() < this.camera.x)
continue;
if (ent.collude && ent.pos.x > this.camera.x + this.canvas.width)
continue;

ent.drawn = true;

this.ctx.save();
this.ctx.translate(
ent.pos.x - this.camera.x,
@@ -266,6 +275,26 @@ Game.prototype.update = function() {
}
}

// Go through and draw overlap
for (var i = 0; i < this.layers.length; ++i) {
var layer = this.layers[i];
for (var j = 0; j < layer.length; ++j) {
var ent = layer[j];

if (!ent.drawn)
continue;
if (!ent.drawOverlay)
continue;

this.ctx.save();
this.ctx.translate(
ent.pos.x - this.camera.x,
ent.pos.y - this.camera.y);
ent.drawOverlay(this.ctx);
this.ctx.restore();
}
}

// Clear presses
for (var i in this.presses) {
this.presses[i] = false;

+ 7
- 2
js/script.js View File

@@ -27,6 +27,11 @@ function playSoundtrack(tracks) {
}
playSoundtrack(assets.soundtracks);

document.querySelector("#restart").addEventListener("click", function() {
document.querySelector("#done-screen").className = "hidden";
run();
});

function run() {
var game = new Game(document.getElementById("canvas"));
game.canvas.width = window.innerWidth;
@@ -37,8 +42,8 @@ function run() {
game.start(worldgen);

game.onstop = function(score) {
alert("You lost! Score: "+score);
run();
document.querySelector("#score").innerText = score;
document.querySelector("#done-screen").className = "";
}
}


+ 1
- 1
js/worldgen.js View File

@@ -7,8 +7,8 @@ function WorldGen(game) {
this.powerupCounter = randInt(WorldGen.range[0], WorldGen.range[1]);

// Spawn player and background
game.spawn(new Background(game));
game.spawn(new Player(game));
game.spawn(new Background(game));
}
WorldGen.range = [5, 12];


+ 15
- 0
package.json View File

@@ -0,0 +1,15 @@
{
"name": "flappydick",
"version": "1.0.0",
"description": "",
"main": "conf.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "gogs@git.mort.coffee:mort/flappydick.git"
},
"author": "Martin Dørum <martid0311@gmail.com> (http://mort.coffee)",
"license": "ISC"
}

BIN
xcf/wall-overlap.xcf View File


Loading…
Cancel
Save