frontend/1/mario/upkeep.js
2023-05-21 21:16:27 -04:00

196 lines
5.5 KiB
JavaScript

/* Upkeep.js */
// Contains functions associated with the upkeep
function upkeep() {
if(window.paused) return;
// window.nextupk = requestAnimationFrame(upkeep);
window.nextupk = setTimeout(upkeep, timer);
// Adjust for differences in performance
adjustFPS();
// Quadrants upkeep
determineAllQuadrants();
// Solids upkeep
maintainSolids();
// Character upkeep
maintainCharacters();
// Mario specific
maintainMario();
// Texts upkeep, if there are any
if(texts.length) maintainTexts();
// Events upkeep
TimeHandler.handleEvents();
// handleEvents();
refillCanvas();
}
function adjustFPS() {
window.time_now = now();
var time_diff = time_now - time_prev,
fps_actual = roundDigit(1000 / time_diff, .001);
window.fps = roundDigit((.7 * fps) + (.3 * fps_actual), .01);
window.realtime = fps_target / fps;
window.time_prev = time_now;
}
function pause(big) {
if(paused && !window.nextupk) return;
cancelAnimationFrame(nextupk);
pauseAllSounds();
paused = true;
if(big) play("Pause");
}
function unpause() {
if(!paused) return;
window.nextupk = requestAnimationFrame(upkeep);
paused = false;
resumeAllSounds();
}
// Solids by themselves don't really do much
function maintainSolids(update) {
for(var i = 0, solid; i < solids.length; ++i) {
solid = solids[i];
if(solid.alive) {
if(solid.movement) solid.movement(solid);
}
if(!solid.alive || solid.right < quads.delx)
deleteThing(solid, solids, i);
}
}
function maintainCharacters(update) {
var delx = gamescreen.right + quads.rightdiff,
character, i;
for(i = 0; i < characters.length; ++i) {
character = characters[i];
// Gravity
if(!character.resting) {
if(!character.nofall) character.yvel += character.gravity || map.gravity;
character.yvel = min(character.yvel, map.maxyvel);
} else character.yvel = 0;
// Position updating and collision detection
updatePosition(character);
determineThingQuadrants(character);
character.under = character.undermid = false;
determineThingCollisions(character);
// Resting tests
if(character.resting) {
if(!characterOnResting(character, character.resting)) {
character.resting = false; // Necessary for moving platforms :(
} else {
/*character.jumping = */character.yvel = false;
setBottom(character, character.resting.top);
}
}
// Movement or deletion
// To do: rethink this...
//// Good for performance if gamescreen.bottom - gamescreen.top is saved in screen and updated on shift
// To do: is map.shifting needed?
if(character.alive) {
if(character.type != "mario" && !map.shifting &&
(character.numquads == 0 || character.left > delx) && !character.outerok) {
// (character.top > gamescreen.bottom - gamescreen.top || character.left < + quads.width * -1)) {
deleteThing(character, characters, i);
}
else {
if(!character.nomove && character.movement)
character.movement(character);
// if(update) updateDisplay(character);
}
}
else if(!map.shifting) deleteThing(character, characters, i);
}
}
function maintainMario(update) {
if(!mario.alive) return;
// Mario is falling
if(mario.yvel > 0) {
if(!map.underwater) mario.keys.jump = 0;
// Jumping?
if(!mario.jumping) {
// Paddling? (from falling off a solid)
if(map.underwater) {
if(!mario.paddling) {
switchClass(mario, "paddling", "paddling");
mario.padding = true;
}
}
else {
addClass(mario, "jumping");
mario.jumping = true;
}
}
// Mario has fallen too far
if(!mario.piping && !mario.dying && mario.top > gamescreen.deathheight) {
// If the map has an exit loc (cloud world), transport there
if(map.exitloc) {
// Random maps will pretend he died
if(map.random) {
goToTransport(["Random", "Overworld", "Down"]);
marioDropsIn();
return;
}
// Otherwise just shift to the location
return shiftToLocation(map.exitloc);
}
// Otherwise, since Mario is below the gamescreen, kill him dead
clearMarioStats();
killMario(mario, 2);
}
}
// Mario is moving to the right
if(mario.xvel > 0) {
if(mario.right > gamescreen.middlex) {
// If Mario is to the right of the gamescreen's middle, move the gamescreen
if(mario.right > gamescreen.right - gamescreen.left)
mario.xvel = min(0, mario.xvel);
}
}
// Mario is moving to the left
else if(mario.left < 0) {
// Stop Mario from going to the left.
mario.xvel = max(0, mario.xvel);
}
// Mario is hitting something (stop jumping)
if(mario.under) mario.jumpcount = 0;
// Scrolloffset is how far over the middle mario's right is
// It's multiplied by 0 or 1 for map.canscroll
window.scrolloffset = (map.canscroll/* || (map.random && !map.noscroll)*/) * (mario.right - gamescreen.middlex);
if(scrolloffset > 0 && !map.shifting) {
scrollWindow(lastscroll = round(min(mario.scrollspeed, scrolloffset)));
}
else lastscroll = 0;
}
// Deletion checking is done by an interval set in shiftToLocation
// This simply does velocity
function maintainTexts() {
var element, me, i;
for(i = texts.length - 1; i >= 0; --i) {
me = texts[i];
element = me.element || me;
if(me.xvel) elementShiftLeft(element, me.xvel);
if(me.yvel) elementShiftTop(element, me.yvel);
}
}