Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pizza Undelivery #81

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ae338bd
Implement noise generator with a rendering test
nikigawlik Aug 16, 2019
775830b
Implement 3d rendering demo with car overlay
nikigawlik Aug 17, 2019
40aafb8
Improve performance of renderer
nikigawlik Aug 18, 2019
cd2eb11
Sample color from floor texture
nikigawlik Aug 18, 2019
ba5d61e
Add textures, wrap city
nikigawlik Aug 19, 2019
c35b43b
whatever
nikigawlik Aug 25, 2019
c20a13f
Optimize renderer
nikigawlik Sep 5, 2019
6e30c86
Remove import, json -> object in generator
nikigawlik Sep 6, 2019
c9aa3af
Remove unnecessary modules in index.html
nikigawlik Sep 6, 2019
fe63a14
Remove old build folder
nikigawlik Sep 6, 2019
ed6dff3
Add gitignore
nikigawlik Sep 6, 2019
fa76940
Remove unused export from key handler
nikigawlik Sep 6, 2019
363a256
Add webpack/gulp config
nikigawlik Sep 6, 2019
200e143
Create new audio track
nikigawlik Sep 10, 2019
8425e69
Make car not spawn in walls
nikigawlik Sep 11, 2019
58282be
Implement basic pizza rendering
nikigawlik Sep 11, 2019
0e6eebe
upgrade the music with glitchy sounds
nikigawlik Sep 11, 2019
0733d56
Remove unused images
nikigawlik Sep 11, 2019
f04968a
Implement super basic gameplay loop
nikigawlik Sep 11, 2019
7ebbbef
Change pcg to contained map
nikigawlik Sep 11, 2019
d973f6f
Add polish and improve map gen
nikigawlik Sep 12, 2019
73e4ca7
Implement real game flow and UIs
nikigawlik Sep 12, 2019
1e188eb
Fix build proces
nikigawlik Sep 12, 2019
798792d
Bring back the fixed car graphics
nikigawlik Sep 12, 2019
d340898
Implement audio sfx
nikigawlik Sep 12, 2019
a63942e
Add map regen button, small fixes
nikigawlik Sep 12, 2019
1a5f4bb
Merge branch 'master' of https://github.com/nilsgawlik/entry into sub…
nikigawlik Sep 12, 2019
f841dcd
Set manifest data and add images for submitting
nikigawlik Sep 12, 2019
8f7cb59
Fix image paths in manifest file
nikigawlik Sep 12, 2019
1a92cdc
Dummy commit to trigger validation process
nikigawlik Sep 12, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
node_modules/
build*/
.DS_Store
51 changes: 51 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const { src, dest } = require('gulp');
const webpack = require('webpack-stream');
const TerserPlugin = require('terser-webpack-plugin');

function defaultTask(cb) {
// place code for your default task here

src(['modules/*.js'])
.pipe(webpack({
// Any configuration options...
output: {
filename: 'bundle.js'
},
optimization: {
minimizer: [
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true, // Must be set to true if using source-maps in production
terserOptions: {
// https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
ecma: 6,
warnings: true,
parse: {},
compress: {},
mangle: {
properties: {
reserved: ["keyIsDown", "clamp", "iterateQGrid"], // for some reason webpack cant handle these exports
// debug: "",
undeclared: true,
}
}, // Note `mangle.properties` is `false` by default.
module: false,
output: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
}
}),
],
}
}))
.pipe(dest('build'))

cb();
}

exports.default = defaultTask
Binary file added images/spritesheet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="style.css">
<meta charset="utf-8"/>
<script type="module" src="modules/game.js"></script>
<template id="game-over-template">
<div class="game-overlay">
<h2>CONGRATULATIONS!!!</h2>
<p>You made it to</p>
<h2>LEVEL <span id=lnum></span></h2>
<button>restart</button>
</div>
</template>
<template id="title-template">
<div class="game-overlay">
<h2>PIZZA UNDELIVERY</h2>
<p>In this game you have to pick up the pizzas and bring them <em>back</em> to the pizzeria!</p>
<p>Drive with the <em>arrow keys</em> or the <em>WASD</em> keys.</p>
<h2>LEVEL: <input type="number" value=1 name="level" min="1" max="15"></h2>
<p><button>generate new map</button></p>
<p><button><b>GO!!!</b></button></p>
</div>
</template>
</head>
<body>
<main>
<canvas width="192" height="108" class="game"></canvas>
</main>
</body>
<footer>
<p></p>
</footer>
16 changes: 8 additions & 8 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "Title of the game",
"description": "Description of the game, including controls and optional extras for Coil subscribers if you participate in the Web Monetization category.",
"name": "Pizza Undelivery",
"description": "Here you bring pizzas back to the pizzeria, instead of the other way around. This retro style racing game is about navigating a randomly generated 3D city in your 1986 Toyota Corolla, while listening to hand-coded floatbeat music and sound effects. Another highlight is the custom 3D rendering engine implemented in JavaScript (that might not work on slower machines, sorry).",
"images" : {
"image_large": "image-big.jpg",
"image_thumbnail": "image-small.jpg"
"image_large": "promo_images/image_large.png",
"image_thumbnail": "promo_images/image_thumbnail.png"
},
"categories": ["Desktop", "Mobile", "Server", "Web Monetization", "WebXR"],
"categories": ["Desktop"],
"user" : {
"name": "optional",
"website": "optional",
"twitter": "optional"
"name": "Nils Gawlik",
"website": "nilsgawlik.github.io",
"twitter": "@nilsgawlik"
}
}
191 changes: 191 additions & 0 deletions modules/audio.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
let random = Math.random;
let sign = Math.sign;
let sin = Math.sin;
let max = Math.max;
let atan = Math.atan;
const PI = Math.PI;

export default class Audio {
constructor() {
// Create an audio context
this.ctx = new AudioContext();
this.master = this.ctx.createGain();
this.master.gain.setValueAtTime(0.5, this.ctx.currentTime); // keep it civil!
this.master.connect(this.ctx.destination);
}

playCrash(volume = 1) {
const srate = 8000;
const length = srate*1;
let buffer = this.ctx.createBuffer(1, length, srate);
let data = buffer.getChannelData(0);
let p1 = 90 + random() * 64;

for(let t = 0; t < length; t++) {
let tt = t;
t = t & ~(1 << ~~(t/p1));
let env = (1- t / length);
let env2 = (1- t / 2000);
// const env = 1-(t % (1<<12) / (1<<12));
let kick = sin(env**32*0x5f);
data[tt] = atan(
kick * env2**5
) / (PI/2) * volume
;
t = tt;
}

let source = this.ctx.createBufferSource();
source.buffer = buffer;
// source.loop = true;

source.connect(this.master);
source.start();
}

playCollect(volume = 1) {
const srate = 8000;
const length = 8000;
let buffer = this.ctx.createBuffer(1, length, srate);
let data = buffer.getChannelData(0);
let p1 = 1 + random();

for(let t = 0; t < length; t++) {
let tt = t;
// t = t & ~(1 << ~~(t/p1));
let env = (1- t / 8000);
data[tt] = atan(
sin(t * .02 * p1 * (t>>9) * (t>>10))
) / (PI/2) * 2 * volume * env**2
;
t = tt;
}

let source = this.ctx.createBufferSource();
source.buffer = buffer;
// source.loop = true;

source.connect(this.master);
source.start();
}


playLevelFinish(volume = 1) {
const srate = 8000;
const length = srate*2;
let buffer = this.ctx.createBuffer(1, length, srate);
let data = buffer.getChannelData(0);
let p1 = 1 + random();

for(let t = 0; t < length; t++) {
let tt = t;
// t = t & ~(1 << ~~(t/p1));
let env = (1 - t / length);
const env2 = 1-(t % (1<<10) / (1<<10));
data[tt] = atan(
sin(t * .05 * p1 * 2**((t>>10)%3)) * sin(env2)**3 * env**3
+
sin(t * .05 * p1) * env**5
) / (PI/2) * 2 * volume
+
data[max(tt-1000, 0)] * 0.4
;
t = tt;
}

let source = this.ctx.createBufferSource();
source.buffer = buffer;
// source.loop = true;

source.connect(this.master);
source.start();
}


start() {

const srate = 12000;
const length = 1 << 20;
let musicBuffer = this.ctx.createBuffer(1, length, srate);
let data = musicBuffer.getChannelData(0);

let flavor;

let b = 0;
for(let i = 0; i < 5; i++) {
b = b | ~~(random() * 4);
b = b << 2;
}
// look at those magic numbers!
let bs = [
773752, // very fast upbeat
773752, // very fast upbeat
773752|0x7f, // very fast upbeat
957758312, // fast ish

773752, // very fast upbeat
773752, // very fast upbeat
773752|0x7f, // very fast upbeat
957758312, // fast ish

792323628, // noisy? slow
792323628, // noisy? slow
957758312, // fast ish
957758312, // fast ish

1008437436, // fast ish synth
1008437436, // fast ish synth
773752|0x7f, // very fast upbeat
957758312, // fast ish

// -409420504, // interesting medium
// 792323628,// noisy? slow
// 345849296, // continuus subbase
// 1962361744, // fast tension
];
// let bs = [345849296,1962361744,957758312,792323628,773752,1008437436,773752,792323628,773752,792323628];

for(let t = 0; t < length; t++) {
const env = 1-(t % (1<<12) / (1<<12));
const env2 = 1-(t % (1<<15) / (1<<15));
const env3 = 1-(t % (1<<10) / (1<<10));
let hihat1 = (random()*2-1)*env**32 * 0.5;
let hihat2 = (random()*2-1)*env3**32 * 1.9;
let kick = sin(env**6*0x6f)*env;
let snare = (random()*2-1)*env**4;
if(t % (1<<15) == 0) flavor = ~~(random() * 2048);
if(t % (1<<16) == 0) {
// this is how magic numbers are originally made!
// for(let i = 0; i < 5; i++) {
// b = b | ~~(random() * 4);
// b = b << 2;
// }
// bs.push(b);
b = bs.shift();
};
let tt = t;
t = t & b;
data[tt] =
[[kick,hihat1,snare,hihat1][(t>>12)%4] * 0.4, [kick,snare,hihat1,hihat2][(t>>12)%4] * 0.4][max((t>>14)%4-2, 0)]
+ sign(sin((t&((1<<(5-(t>>14)%3+(t>>12)%6))-1))*(1/64)*PI*(1+env2*.25))) * 0.05
+ sign(sin((t&(flavor << 4))*(1/64)*PI)) * 0.05
// + sign(sin((t&([32,2,3,111][(t>>15)%4] << 4))*(1/64)*PI)) * 0.1
+ data[max(0, t - 2100)] * 0.4
+ data[max(0, t - 2000)] * 0.4
;
t = tt;
}

console.log(bs.toString());

let musicSource = this.ctx.createBufferSource();
musicSource.buffer = musicBuffer;
musicSource.loop = true;

musicSource.connect(this.master);
musicSource.start();
}

update() {
}
}
Loading