Files
n-gon-improved/js/index.js
2019-07-11 10:04:58 -07:00

275 lines
7.5 KiB
JavaScript

"use strict";
/* TODO: *******************************************
*****************************************************
run fast when shift is pressed
drains fieldMeter
give mobs more animal-like behaviors
like rainworld
give mobs something to do when they don't see player
explore map
eat power ups
drop power up (if killed after eating one)
mobs some times aren't aggressive
when low on life or after taking a large hit
mobs can fight each other
this might be hard to code
when not near other mobs they try to group up.
gun power ups
+explosion radius
+dmg
life steal
+bullet size
get bonus ammo / reduced ammo use
bullets pass through walls
unlimited ammo capacity
add in a max ammo capacity
mutators (as a power up)
infinite ammo
or just more ammo from drops?
or 50% chance to not use up a bullet?
increased fire rate for guns
how to make laser fire faster?
orbiting orb fires at random targets
missiles at random targets
low gravity
double jumps
higher horizontal run speed?
vampire damage
shield (recharges fast, but only upto 10% of life)
Active use abilities (can get ideas from spacetime)
blink (short distance teleport)
would reverse if they end up in solid wall
beacon teleport
push (push blocks, mobs, and bullets away from player)
invulnerability (force field that stops mobs and bullets)
burst of speed
intangible (can move through bodies, bullets, and mobs. Not map elements)
game mechanics
mechanics that support the physics engine
add rope/constraint
store/spawn bodies in player (like the game Starfall)
get ideas from game: limbo / inside
environmental hazards
laser
lava
button / switch
door
fizzler
moving platform
map zones
water
low friction ground
bouncy ground
give each foot a sensor to check for ground collisions
feet with not go into the ground even on slanted ground
this might be not worth it, but it might look really cool
track foot positions with velocity better as the player walks/crouch/runs
add bullet on damage effects
effects could:
add to the array mod.do new mob behaviors
add a damage over time
add a freeze
change mob traits
mass
friction
damage done
change things about the bullet
bounce the bullet again in a new direction
fire several bullets as shrapnel
increase the bullet size to do AOE dmg?? (how)
just run a for loop over all mobs, and do damage to the one that are close
bullets return to player
use a constraint? does bullet just start with a constraint or is it added on damage?
change the player
vampire bullets heal for the damage done
or give the player a shield??
or only heal if the mob dies (might be tricky)
remove standing on player actions
replace with check if player feet are in an area.
unused ideas
passive: walk through blocks (difficult to implement)
//collision info:
category mask
powerUp: 0x 100000 0x 100001
mobBull: 0x 010000 0x 001001
player: 0x 001000 0x 010011
bullet: 0x 000100 0x 000011
mob: 0x 000010 0x 001101
map: 0x 000001 0x 111111
body: 0x 000001 0x 011111
? hold: 0x 000001 0x 000001
*/
//set up canvas
var canvas = document.getElementById("canvas");
//using "const" causes problems in safari when an ID shares the same name.
const ctx = canvas.getContext("2d");
document.body.style.backgroundColor = "#fff";
//disable pop up menu on right click
document.oncontextmenu = function () {
return false;
}
function setupCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.width2 = canvas.width / 2; //precalculated because I use this often (in mouse look)
canvas.height2 = canvas.height / 2;
canvas.diagonal = Math.sqrt(canvas.width2 * canvas.width2 + canvas.height2 * canvas.height2);
ctx.font = "15px Arial";
ctx.lineJoin = "round";
ctx.lineCap = "round";
// ctx.lineCap='square';
game.setZoom();
}
setupCanvas();
window.onresize = () => {
setupCanvas();
};
//mouse move input
document.body.addEventListener("mousemove", (e) => {
game.mouse.x = e.clientX;
game.mouse.y = e.clientY;
});
document.body.addEventListener("mouseup", (e) => {
// game.buildingUp(e); //uncomment when building levels
game.mouseDown = false;
// console.log(e)
if (e.which === 3) {
game.mouseDownRight = false;
} else {
game.mouseDown = false;
}
});
document.body.addEventListener("mousedown", (e) => {
if (e.which === 3) {
game.mouseDownRight = true;
} else {
game.mouseDown = true;
}
});
//keyboard input
const keys = [];
document.body.addEventListener("keydown", (e) => {
keys[e.keyCode] = true;
game.keyPress();
});
document.body.addEventListener("keyup", (e) => {
keys[e.keyCode] = false;
});
document.body.addEventListener("wheel", (e) => {
if (e.deltaY > 0) {
game.nextGun();
} else {
game.previousGun();
}
}, {
passive: true
});
// window.addEventListener("gamepadconnected", function (e) {
// console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.",
// e.gamepad.index, e.gamepad.id,
// e.gamepad.buttons.length, e.gamepad.axes.length);
// });
game.loop = game.mouseLoop;
window.addEventListener("gamepadconnected", function (e) {
console.log('gamepad connected')
document.getElementById("gamepad").style.display = "inline";
game.gamepad.connected = true;
polGamepadCycle();
game.loop = game.gamepadLoop;
});
window.addEventListener("gamepaddisconnected", function (e) {
disconnectGamepad()
});
function disconnectGamepad() {
console.log('gamepad disconnected')
document.getElementById("gamepad").style.display = "none";
game.gamepad.connected = false;
game.loop = game.mouseLoop;
}
//this runs to get gamepad data even when paused
function polGamepadCycle() {
game.gamepad.cycle++
if (game.gamepad.connected) requestAnimationFrame(polGamepadCycle);
game.polGamepad()
}
// function playSound(id) {
// //play sound
// if (false) {
// //sounds are turned off for now
// // if (document.getElementById(id)) {
// var sound = document.getElementById(id); //setup audio
// sound.currentTime = 0; //reset position of playback to zero //sound.load();
// sound.play();
// }
// }
function shuffle(array) {
var currentIndex = array.length,
temporaryValue,
randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
//main loop ************************************************************
//**********************************************************************
function cycle() {
if (!game.paused) requestAnimationFrame(cycle);
const now = Date.now();
const elapsed = now - game.then; // calc elapsed time since last loop
if (elapsed > game.fpsInterval) { // if enough time has elapsed, draw the next frame
game.then = now - (elapsed % game.fpsInterval); // Get ready for next frame by setting then=now. Also, adjust for fpsInterval not being multiple of 16.67
game.loop();
}
}