Skip to content

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Rybar committed Mar 5, 2022
0 parents commit 0d3b76e
Show file tree
Hide file tree
Showing 23 changed files with 1,472 additions and 0 deletions.
41 changes: 41 additions & 0 deletions ideas.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Things I want to learn/tackle in this game:
ray collisions / rotated collisions, "non tile" / "non AABB" collisions and response
procedural character animation
walks with multiple legs
bipedal
quadruped/spider
dynamic number of limbs
complex child/parent relationships, multi-sprite entities (bosses/big characters)
complex-looking enemy behavior using sensors
an elegant 2.5d solution with proper draw sorting
"tall tiles" ?
fun feature ideas:
tilemap-based objects
use small 4px or 8x tilemap designs as objects in game
some kind of dynamic lighting
pre-rendered light/dark copies of tilesheet graphics
dynamic tilemap effects
pre-rendered sprite rotations ?




top-down shooter roguelike where you can pilot multiple machines in the world
abandon them when damaged or need a smaller one to proceed
some roll, some walk, will have to swap to traverse some terrains / fit in tight spaces

a hunter/gatherer roguelike with a day/night cycle. At night monsters come to eat you.
single-map game, but big enough for a scrolling camera
arcade-like loop, less content creation, more iteration on fun-ness
See pico8 fisher game

a peaceful big-world exploration walkabout with lots of unique collectibles
multiple creature types, all peaceful
opportunity to code big multi-page inventory UI
crafting? -scope






Binary file added img/3x5font.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/smallFont.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<header>
<title>Shootervania</title>
<link rel="stylesheet" type="text/css" href="style.css">
</header>
<body>
<div id = 'gamebox'>
<canvas id = 'canvas'></canvas>
</div>
<!-- start with the browser check -->
<script src="js/browsercheck.js"></script>

<!-- core stuff -->
<script src="js/core/animation.js"></script>
<script src="js/core/spritesheet.js"></script>
<script src="js/core/AssetLoader.js"></script>
<script src="js/core/audio.js"></script>
<script src="js/core/graphics.js"></script>
<script src="js/core/Signal.js"></script>
<script src="js/core/util.js"></script>

<!--our one bit of external code, mr doobs FPS checker -->
<script src = 'js/stats.js'></script>

<!-- game states -->
<script src="js/screens/titleScreen.js"></script>
<script src="js/screens/gameScreen.js"></script>
<script src="js/screens/gameOverScreen.js"></script>
<script src="js/screens/creditsScreen.js"></script>

<!-- and finally our main entry point -->
<script src = "js/main.js"></script>
</body>
</html>
88 changes: 88 additions & 0 deletions js/core/AssetLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
const AssetLoader = function AssetLoader(){
this.images = {};
this.sounds = {};
return this;
}

AssetLoader.prototype.loadImages = function loadImages(names, callback) {

var n,
name,
result = {},
count = names.length,
self = this,
onload = function() {
if(--count == 0){
this.images = result;
callback();
}
}

for(n = 0 ; n < names.length ; n++) {
name = names[n];
result[name] = document.createElement('img');
result[name].addEventListener('load', onload);
result[name].src = "/img/" + name + ".png";
}

return result;
}

AssetLoader.prototype.loadFile = function loadFile(filePath, done){
let xhr = new XMLHttpRequest();
xhr.onload = function () {
return done(this.responseText)
}
xhr.open("GET", filePath, true);
xhr.send();
}

AssetLoader.prototype.soundLoader = function ({context, urlList, callback} = {}) {
this.context = context;
this.urlList = urlList;
this.onSoundsLoaded = callback;
this.loadCount = 0;
}

AssetLoader.prototype.loadBuffer = function(url, key) {
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";

var loader = this;

request.onload = function() {
loader.context.decodeAudioData(
request.response,
function(buffer) {
if (!buffer) {
alert('error decoding file data: ' + url);
return;
}

loader.sounds[key] = buffer;
console.log('loaded sound: ' + key);
if (++loader.loadCount == loader.urlList.length){
console.log('all sounds loaded');
loader.onSoundsLoaded(loader.sounds);
}

},
function(error) {
console.error('decodeAudioData error', error);
}
);
}

request.onerror = function() {
alert('SoundLoader: XHR error');
}

request.send();
}

AssetLoader.prototype.loadAudioBuffer = function() {
for (var i = 0; i < this.urlList.length; ++i)
this.loadBuffer(this.urlList[i].url, this.urlList[i].name);
}

30 changes: 30 additions & 0 deletions js/core/Signal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const Signal = function Signal(){
var target = document.createTextNode(null);
this.addEventListener = target.addEventListener.bind(target);
this.removeEventListener = target.removeEventListener.bind(target);
this.dispatchEvent = target.dispatchEvent.bind(target);

return this;
}

Signal.prototype.dispatch = function dispatch(eventName, params={}){
var event = new CustomEvent(eventName, {detail: params});
this.dispatchEvent(event);
}



/* Use examples:
signal.addEventListener('bulletHitWall', bulletSplode)
emit event in update:
signal.dispatch('bulletHitWall', {x: bullet.x, y: bullet.y })
function bulletSplode(event){
emitParticles(event.x, event.y);
}
*/
79 changes: 79 additions & 0 deletions js/core/animation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
class Animation {
constructor({spriteSheet, frames, frameRate, loop = true} = {}) {


this.spriteSheet = spriteSheet;


this.frames = frames;


this.frameRate = frameRate;


this.loop = loop;

let { width, height, margin = 0 } = spriteSheet.frame;


this.width = width;


this.height = height;


this.margin = margin;


this.currentFrame = 0;
this.accumulator = 0;
}


clone() {
return animationFactory(this);
}

reset() {
this.currentFrame = 0;
this.accumulator = 0;
}

update(dt = 1/60) {

// if the animation doesn't loop we stop at the last frame
if (!this.loop && this.currentFrame == this.frames.length-1){
return;
}

this.accumulator += dt;

// update to the next frame if it's time
while (this.accumulator * this.frameRate >= 1) {
this.currentFrame = ++this.currentFrame % this.frames.length;
this.accumulator -= 1 / this.frameRate;
}
}

render({x, y, width = this.width, height = this.height} = {}) {

// get the row and col of the frame
let row = this.frames[this.currentFrame] / this.spriteSheet._f | 0;
let col = this.frames[this.currentFrame] % this.spriteSheet._f | 0;

canvasContext.drawImage(
this.spriteSheet.image,
col * this.width + (col * 2 + 1) * this.margin,
row * this.height + (row * 2 + 1) * this.margin,
this.width, this.height,
x, y,
width, height
);
}
}

function animationFactory(properties) {
return new Animation(properties);
}
animationFactory.prototype = Animation.prototype;
animationFactory.class = Animation;
Loading

0 comments on commit 0d3b76e

Please sign in to comment.