mirror of
https://github.com/pyscript/pyscript.git
synced 2022-05-01 19:47:48 +03:00
242 lines
5.5 KiB
JavaScript
242 lines
5.5 KiB
JavaScript
var requestAnimFrame = (function(){
|
|
return window.requestAnimationFrame ||
|
|
window.webkitRequestAnimationFrame ||
|
|
window.mozRequestAnimationFrame ||
|
|
window.oRequestAnimationFrame ||
|
|
window.msRequestAnimationFrame ||
|
|
function(callback){
|
|
window.setTimeout(callback, 1000 / 60);
|
|
};
|
|
})();
|
|
|
|
//create the canvas
|
|
var canvas = document.createElement("canvas");
|
|
var ctx = canvas.getContext('2d');
|
|
var updateables = [];
|
|
var fireballs = [];
|
|
var player = new Mario.Player([0,0]);
|
|
|
|
//we might have to get the size and calculate the scaling
|
|
//but this method should let us make it however big.
|
|
//Cool!
|
|
//TODO: Automatically scale the game to work and look good on widescreen.
|
|
//TODO: fiddling with scaled sprites looks BETTER, but not perfect. Hmm.
|
|
canvas.width = 762;
|
|
canvas.height = 720;
|
|
ctx.scale(3,3);
|
|
document.body.appendChild(canvas);
|
|
|
|
//viewport
|
|
var vX = 0,
|
|
vY = 0,
|
|
vWidth = 256,
|
|
vHeight = 240;
|
|
|
|
//load our images
|
|
resources.load([
|
|
'sprites/player.png',
|
|
'sprites/enemy.png',
|
|
'sprites/tiles.png',
|
|
'sprites/playerl.png',
|
|
'sprites/items.png',
|
|
'sprites/enemyr.png',
|
|
]);
|
|
|
|
resources.onReady(init);
|
|
var level;
|
|
var sounds;
|
|
var music;
|
|
|
|
//initialize
|
|
var lastTime;
|
|
function init() {
|
|
music = {
|
|
overworld: new Audio('sounds/aboveground_bgm.ogg'),
|
|
underground: new Audio('sounds/underground_bgm.ogg'),
|
|
clear: new Audio('sounds/stage_clear.wav'),
|
|
death: new Audio('sounds/mariodie.wav')
|
|
};
|
|
sounds = {
|
|
smallJump: new Audio('sounds/jump-small.wav'),
|
|
bigJump: new Audio('sounds/jump-super.wav'),
|
|
breakBlock: new Audio('sounds/breakblock.wav'),
|
|
bump: new Audio('sounds/bump.wav'),
|
|
coin: new Audio('sounds/coin.wav'),
|
|
fireball: new Audio('sounds/fireball.wav'),
|
|
flagpole: new Audio('sounds/flagpole.wav'),
|
|
kick: new Audio('sounds/kick.wav'),
|
|
pipe: new Audio('sounds/pipe.wav'),
|
|
itemAppear: new Audio('sounds/itemAppear.wav'),
|
|
powerup: new Audio('sounds/powerup.wav'),
|
|
stomp: new Audio('sounds/stomp.wav')
|
|
};
|
|
Mario.oneone();
|
|
lastTime = Date.now();
|
|
main();
|
|
}
|
|
|
|
var gameTime = 0;
|
|
|
|
//set up the game loop
|
|
function main() {
|
|
var now = Date.now();
|
|
var dt = (now - lastTime) / 1000.0;
|
|
|
|
update(dt);
|
|
render();
|
|
|
|
lastTime = now;
|
|
requestAnimFrame(main);
|
|
}
|
|
|
|
function update(dt) {
|
|
gameTime += dt;
|
|
|
|
handleInput(dt);
|
|
updateEntities(dt, gameTime);
|
|
|
|
checkCollisions();
|
|
}
|
|
|
|
function handleInput(dt) {
|
|
if (player.piping || player.dying || player.noInput) return; //don't accept input
|
|
|
|
if (input.isDown('RUN')){
|
|
player.run();
|
|
} else {
|
|
player.noRun();
|
|
}
|
|
if (input.isDown('JUMP')) {
|
|
player.jump();
|
|
} else {
|
|
//we need this to handle the timing for how long you hold it
|
|
player.noJump();
|
|
}
|
|
|
|
if (input.isDown('DOWN')) {
|
|
player.crouch();
|
|
} else {
|
|
player.noCrouch();
|
|
}
|
|
|
|
if (input.isDown('LEFT')) { // 'd' or left arrow
|
|
player.moveLeft();
|
|
}
|
|
else if (input.isDown('RIGHT')) { // 'k' or right arrow
|
|
player.moveRight();
|
|
} else {
|
|
player.noWalk();
|
|
}
|
|
}
|
|
|
|
//update all the moving stuff
|
|
function updateEntities(dt, gameTime) {
|
|
player.update(dt, vX);
|
|
updateables.forEach (function(ent) {
|
|
ent.update(dt, gameTime);
|
|
});
|
|
|
|
//This should stop the jump when he switches sides on the flag.
|
|
if (player.exiting) {
|
|
if (player.pos[0] > vX + 96)
|
|
vX = player.pos[0] - 96
|
|
}else if (level.scrolling && player.pos[0] > vX + 80) {
|
|
vX = player.pos[0] - 80;
|
|
}
|
|
|
|
if (player.powering.length !== 0 || player.dying) { return; }
|
|
level.items.forEach (function(ent) {
|
|
ent.update(dt);
|
|
});
|
|
|
|
level.enemies.forEach (function(ent) {
|
|
ent.update(dt, vX);
|
|
});
|
|
|
|
fireballs.forEach(function(fireball) {
|
|
fireball.update(dt);
|
|
});
|
|
level.pipes.forEach (function(pipe) {
|
|
pipe.update(dt);
|
|
});
|
|
}
|
|
|
|
//scan for collisions
|
|
function checkCollisions() {
|
|
if (player.powering.length !== 0 || player.dying) { return; }
|
|
player.checkCollisions();
|
|
|
|
//Apparently for each will just skip indices where things were deleted.
|
|
level.items.forEach(function(item) {
|
|
item.checkCollisions();
|
|
});
|
|
level.enemies.forEach (function(ent) {
|
|
ent.checkCollisions();
|
|
});
|
|
fireballs.forEach(function(fireball){
|
|
fireball.checkCollisions();
|
|
});
|
|
level.pipes.forEach (function(pipe) {
|
|
pipe.checkCollisions();
|
|
});
|
|
}
|
|
|
|
//draw the game!
|
|
function render() {
|
|
updateables = [];
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
ctx.fillStyle = level.background;
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
//scenery gets drawn first to get layering right.
|
|
for(var i = 0; i < 15; i++) {
|
|
for (var j = Math.floor(vX / 16) - 1; j < Math.floor(vX / 16) + 20; j++){
|
|
if (level.scenery[i][j]) {
|
|
renderEntity(level.scenery[i][j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//then items
|
|
level.items.forEach (function (item) {
|
|
renderEntity(item);
|
|
});
|
|
|
|
level.enemies.forEach (function(enemy) {
|
|
renderEntity(enemy);
|
|
});
|
|
|
|
|
|
|
|
fireballs.forEach(function(fireball) {
|
|
renderEntity(fireball);
|
|
})
|
|
|
|
//then we draw every static object.
|
|
for(var i = 0; i < 15; i++) {
|
|
for (var j = Math.floor(vX / 16) - 1; j < Math.floor(vX / 16) + 20; j++){
|
|
if (level.statics[i][j]) {
|
|
renderEntity(level.statics[i][j]);
|
|
}
|
|
if (level.blocks[i][j]) {
|
|
renderEntity(level.blocks[i][j]);
|
|
updateables.push(level.blocks[i][j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//then the player
|
|
if (player.invincibility % 2 === 0) {
|
|
renderEntity(player);
|
|
}
|
|
|
|
//Mario goes INTO pipes, so naturally they go after.
|
|
level.pipes.forEach (function(pipe) {
|
|
renderEntity(pipe);
|
|
});
|
|
}
|
|
|
|
function renderEntity(entity) {
|
|
entity.render(ctx, vX, vY);
|
|
}
|