717 lines
19 KiB
JavaScript
717 lines
19 KiB
JavaScript
"use strict";
|
|
|
|
(function()
|
|
{
|
|
function spawnSpike(game)
|
|
{
|
|
if(this.spike && this.spike.timer)
|
|
{
|
|
// there is already a spike that is moving
|
|
return;
|
|
}
|
|
|
|
this.spike = game.addObject({
|
|
image: "spikeUp",
|
|
killing: true,
|
|
x: this.x,
|
|
y: this.y,
|
|
tickFunction: moveHiddenSpike,
|
|
zIndex: -1,
|
|
});
|
|
|
|
this.spike.timer = 64;
|
|
}
|
|
|
|
function moveHiddenSpike(game)
|
|
{
|
|
if(this.timer)
|
|
{
|
|
this.y += Math.rectangle(64)(this.timer);
|
|
this.timer--;
|
|
}
|
|
else
|
|
{
|
|
game.removeObject(this);
|
|
}
|
|
}
|
|
|
|
function startObject(id)
|
|
{
|
|
return function(game)
|
|
{
|
|
var obj = game.objectMap[id];
|
|
|
|
obj.active = true;
|
|
obj.timer = 0;
|
|
|
|
// remove the trigger
|
|
game.removeObject(this);
|
|
}
|
|
}
|
|
|
|
function movePlatform(game)
|
|
{
|
|
if(this.active)
|
|
{
|
|
if(this.timer % 2 === 0)
|
|
{
|
|
game.moveObjectDown(this, -1);
|
|
}
|
|
|
|
if(this.y > 400)
|
|
{
|
|
game.moveObjectRight(this, -Math.rectangle(260)(this.timer + 65));
|
|
}
|
|
else
|
|
{
|
|
game.moveObjectRight(this, 1);
|
|
}
|
|
|
|
if(this.x < -40)
|
|
{
|
|
game.removeObject(this);
|
|
}
|
|
|
|
this.timer++;
|
|
}
|
|
}
|
|
|
|
function movePlatform2(game)
|
|
{
|
|
if(this.active)
|
|
{
|
|
if(this.timer < 95)
|
|
{
|
|
game.moveObjectRight(this, -2);
|
|
}
|
|
else if(this.timer < 185)
|
|
{
|
|
//game.moveObjectDown(this,
|
|
// 2 * Math.rectangle(85)(this.timer - 95));
|
|
|
|
game.moveObjectRight(this, 3);
|
|
}
|
|
else if(this.timer < 325)
|
|
{
|
|
if(this.timer % 2)
|
|
{
|
|
game.moveObjectDown(this, -1);
|
|
game.moveObjectRight(this, -1);
|
|
}
|
|
}
|
|
else if(this.timer < 480)
|
|
{
|
|
game.moveObjectRight(this, -2);
|
|
}
|
|
else if(this.timer < 500)
|
|
{
|
|
game.moveObjectDown(this, 6);
|
|
}
|
|
else if(this.timer < 600)
|
|
{
|
|
game.moveObjectDown(this, -1);
|
|
game.moveObjectRight(this,
|
|
Math.round(2 * Math.triangle(80)(this.timer)));
|
|
}
|
|
else if(this.timer < 750)
|
|
{
|
|
game.moveObjectRight(this, -1);
|
|
}
|
|
else if(this.timer < 790)
|
|
{
|
|
game.moveObjectDown(this, -1);
|
|
}
|
|
else if(this.timer < 850)
|
|
{
|
|
|
|
}
|
|
else if(this.timer < 950)
|
|
{
|
|
game.moveObjectRight(this, 3);
|
|
}
|
|
else if(this.timer < 1000)
|
|
{
|
|
game.moveObjectDown(this, -1);
|
|
}
|
|
else if(this.timer < 1022)
|
|
{
|
|
game.moveObjectRight(this, 4);
|
|
}
|
|
else if(this.timer < 1050)
|
|
{
|
|
|
|
}
|
|
else if(this.timer < 1150)
|
|
{
|
|
game.moveObjectDown(this, -1);
|
|
}
|
|
else if(this.timer < 1230)
|
|
{
|
|
game.moveObjectRight(this, 1);
|
|
}
|
|
else if(this.timer < 1300)
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
game.moveObjectRight(this, -Math.ceil((this.timer - 1300) / 18));
|
|
}
|
|
|
|
|
|
this.timer++;
|
|
}
|
|
}
|
|
|
|
function badPlatform(game)
|
|
{
|
|
game.removeObject(this);
|
|
|
|
}
|
|
|
|
function transitionUp(game)
|
|
{
|
|
if(game.viewportY === 600)
|
|
{
|
|
game.viewportY = 0;
|
|
}
|
|
}
|
|
|
|
function transitionDown(game)
|
|
{
|
|
if(game.viewportY === 0)
|
|
{
|
|
game.viewportY = 600;
|
|
}
|
|
}
|
|
|
|
function additionalJump(game)
|
|
{
|
|
game.canJump = true;
|
|
game.removeObject(this);
|
|
|
|
game.audio.play("Mega_Man_Blast_Sound.ogg");
|
|
}
|
|
|
|
|
|
function moveApple(game)
|
|
{
|
|
this.y += Math.rectangle(100)(game.tickCount);
|
|
}
|
|
|
|
function redOrb(game)
|
|
{
|
|
var f = game.addObject({
|
|
tickFunction: shake,
|
|
});
|
|
|
|
f.timer = 0;
|
|
|
|
game.removeObject(this);
|
|
}
|
|
|
|
function shake(game)
|
|
{
|
|
if(this.timer % 4 === 2)
|
|
{
|
|
game.viewportY -= 2;
|
|
}
|
|
else if(this.timer % 4 === 0)
|
|
{
|
|
game.viewportY += 2;
|
|
}
|
|
|
|
if(this.timer % 10 === 0)
|
|
{
|
|
game.objectMap["exitBlock"].y--;
|
|
game.objectMap["exitSpike"].y--;
|
|
}
|
|
|
|
this.timer++;
|
|
|
|
if(this.timer > 1500)
|
|
{
|
|
game.removeObject(this);
|
|
}
|
|
}
|
|
|
|
|
|
function tickFunction(game)
|
|
{
|
|
}
|
|
|
|
function nextLevel(game)
|
|
{
|
|
game.nextLevel("2up.js");
|
|
|
|
game.removeObject(this);
|
|
}
|
|
|
|
function loadState(game, state)
|
|
{
|
|
if(state === 0xbeeeef)
|
|
{
|
|
game.posY = 224;
|
|
game.posX = 37;
|
|
game.viewportY = 0;
|
|
|
|
game.removeObjectById("saveState1");
|
|
}
|
|
else
|
|
{
|
|
console.log("invalid state: " + state);
|
|
}
|
|
}
|
|
|
|
function saveState1(game)
|
|
{
|
|
game.saveState(0xbeeeef);
|
|
game.removeObject(this);
|
|
|
|
game.audio.play("Mega_Man_Beam_Sound.ogg", false, false);
|
|
}
|
|
|
|
return {
|
|
|
|
resourceDir: "res/original/",
|
|
musicDir : "res/music/",
|
|
|
|
startPosition: { x: 37, y: 900 },
|
|
startViewport: { x: 0, y: 600 },
|
|
|
|
width: 900,
|
|
height: 1360,
|
|
|
|
characterWidth : 25,
|
|
characterHeight: 21,
|
|
|
|
backgroundMusic : "Fire_Man_Stage.ogg",
|
|
deathMusic : "28.ogg",
|
|
|
|
jumpMusic1 : "jump1.ogg",
|
|
jumpMusic2 : "jump2.ogg",
|
|
|
|
loadState: loadState,
|
|
|
|
init: function(game) {},
|
|
|
|
//physics : {
|
|
// jumpInitialSpeed : -1.5,
|
|
// jumpGravity : .015,
|
|
// jumpTicks : 400,
|
|
|
|
// fallSpeedCap : 3,
|
|
// fallGravity : .045,
|
|
|
|
// moveSpeed : 1,
|
|
|
|
// // in ms
|
|
// timePerTick : 5,
|
|
//},
|
|
|
|
physics : {
|
|
jumpInitialSpeed : -5,
|
|
jumpGravity : .15,
|
|
jumpTicks : 100,
|
|
|
|
fallSpeedCap : 4.5,
|
|
fallGravity : 0.3,
|
|
|
|
moveSpeed : 2,
|
|
|
|
timePerTick : 12,
|
|
},
|
|
|
|
|
|
backgroundColor : "#ddf",
|
|
|
|
images : {
|
|
"gameOver" : "309.png",
|
|
1: "338.png",
|
|
3: "5.png",
|
|
"apple": "269.png",
|
|
|
|
"gradient": "down_gradient_black.png",
|
|
|
|
|
|
"charR1": "1.png",
|
|
"charR2": "2.png",
|
|
"charR3": "3.png",
|
|
"charR4": "4.png",
|
|
"charL1": "18.png",
|
|
"charL2": "19.png",
|
|
"charL3": "20.png",
|
|
"charL4": "21.png",
|
|
|
|
"charMR1": "250.png",
|
|
"charMR2": "247.png",
|
|
"charMR3": "251.png",
|
|
"charMR4": "249.png",
|
|
"charMR5": "252.png",
|
|
"charMR6": "250.png",
|
|
|
|
"charML1": "255.png",
|
|
"charML2": "248.png",
|
|
"charML3": "256.png",
|
|
"charML4": "248.png",
|
|
"charML5": "257.png",
|
|
"charML6": "255.png",
|
|
|
|
"charFR1": "14.png",
|
|
"charFR2": "15.png",
|
|
"charFL1": "17.png",
|
|
"charFL2": "16.png",
|
|
|
|
"charJumpingLeft" : "7.png",
|
|
"charJumpingRight" : "12.png",
|
|
|
|
"charHitmap": "char_hitmap.png",
|
|
|
|
"spikeUp": "161.png",
|
|
"spikeLeft": "163.png",
|
|
"spikeRight": "162.png",
|
|
"spikeDown": "164.png",
|
|
|
|
"platform": "259.png",
|
|
"platform2": "341.png",
|
|
|
|
"jumpOrb": "844.png",
|
|
"redOrb": "red_orb.png",
|
|
"blueOrb": "blue_orb.png",
|
|
},
|
|
|
|
animations : {
|
|
|
|
"charFallingLeft" : {
|
|
time : 2,
|
|
images : ["charFL1", "charFL2"],
|
|
},
|
|
"charFallingRight" : {
|
|
time : 2,
|
|
images : ["charFR1", "charFR2"],
|
|
},
|
|
|
|
"charRight" : {
|
|
time : 6,
|
|
images : ["charR1", "charR2", "charR3", "charR4"],
|
|
},
|
|
"charLeft" : {
|
|
time : 6,
|
|
images : ["charL1", "charL2", "charL3"],
|
|
},
|
|
|
|
"charMovingRight" : {
|
|
time : 2,
|
|
images : ["charMR1", "charMR2", "charMR3", "charMR4", "charMR5", "charMR6"],
|
|
},
|
|
"charMovingLeft" : {
|
|
time : 2,
|
|
images : ["charML1", "charML2", "charML3", "charML4", "charML5", "charML6"],
|
|
},
|
|
},
|
|
|
|
|
|
tickFunction : tickFunction,
|
|
|
|
|
|
// The list of all objects in the game. Basically speaking, everything is an
|
|
// object. Use this if you want to create the ground, draw an image
|
|
// somewhere and create enemies. Every object is a JS object and can have
|
|
// the following properties:
|
|
//
|
|
// - image:
|
|
// Optional. An image from the list of images defined above. If left out,
|
|
// the object is invisible
|
|
//
|
|
// - blocking:
|
|
// Optional, default: false. If set to true, the object blocks the player
|
|
// character, he can stand on it but cannot walk through
|
|
//
|
|
// - killing:
|
|
// Optional, default: false. If set to true, the object kills the player
|
|
//
|
|
// - trigger:
|
|
// Optional. A function that is called, when the player enters this
|
|
// object. Note: The function will be called on every tick as long as the
|
|
// player is inside of the object, you have to take care of this for
|
|
// yourself. If not set, nothing happens when the player is inside of the
|
|
// object
|
|
//
|
|
// - retrigger:
|
|
// Boolean, optional, default false. If set to true, the trigger
|
|
// function above will be called on every tick, as long as the
|
|
// character is standing inside of the trigger. Otherwise, it will
|
|
// only be called once every time the character enters the trigger.
|
|
//
|
|
// - shape:
|
|
// Optional if the object has an image. Determines where the object blocks
|
|
// the player or triggers functions. If left out, the shape is determined
|
|
// by the non-transparent pixels of the image.
|
|
// Type: An object with a .getBitmap() method, that returns the shape of
|
|
// the object as a bitmap.
|
|
//
|
|
// - position:
|
|
// The position of the object(s). A list of objects or a single object
|
|
// with x and y property. Both coordinates can be a list or a number. If
|
|
// both are lists, the cartesian product is calculated to determine all
|
|
// points. Example:
|
|
// [{x: 3, y: 4}, {x: 9, y: [3,4,5]]
|
|
// -> [{x: 3, y: 4}, {x: 9, y: 3}, {x: 9, y: 4}, {x: 9, y: 5},
|
|
// [{x: [1,2], y:[1,2]}
|
|
// -> [{x: 1, y: 1}, {x: 2, y: 1}, {x: 1, y: 2}, {x: 2, y: 2},
|
|
//
|
|
// - dynamic:
|
|
// Optional, default false. If set to true, the object can be changed or
|
|
// removed later. It will appear in game.objects. Dynamic objects take
|
|
// more performance.
|
|
//
|
|
// - id:
|
|
// Optional. Implies dynamic, you don't have to set dynamic if you give an
|
|
// id. The object will be exported to level.objectMap[id]
|
|
//
|
|
// - zIndex:
|
|
// Optional, default 0. Cannot be used on non-static objects. Determines
|
|
// how objects overlay each other. Objects are drawn in this order:
|
|
// 1. Every dynamic object with a negative zIndex, ordered by zIndex
|
|
// 2. Every non-dynamic object in the order they appear
|
|
// 3. The character
|
|
// 4. Every dynamic object with a positive zIndex, ordered by zIndex
|
|
//
|
|
// - tickFunction:
|
|
// Optional. A function that gets called on every tick of the game with
|
|
// this set as the object and the game as first parameter.
|
|
//
|
|
// - init:
|
|
// Optional. A function that gets called once the game is (re-)started.
|
|
|
|
objects : [
|
|
|
|
|
|
{
|
|
image: 3,
|
|
blocking: true,
|
|
position: [
|
|
{ x: 32, y: 984 },
|
|
{ x: range(0, 800, 32), y: 1168 },
|
|
{ x: 0, y: range(0, 1168, 32) },
|
|
{ x: 768, y: range(0, 1104, 32) },
|
|
{ x: 260, y: [984, 1016] },
|
|
{ x: 32, y: 850 },
|
|
{ x: range(128, 800, 32), y: 384 },
|
|
{ x: [292, 324], y: 1016 },
|
|
{ x: range(292, 420, 32), y: 1016 },
|
|
{ x: 324, y: range(920, 1016, 32) },
|
|
{ x: 206, y: 550 },
|
|
{ x: 32, y: 500 },
|
|
{ x: 32, y: 384 },
|
|
{ x: range(32, 320, 32), y: 0 },
|
|
{ x: range(352, 800, 32), y: 0 },
|
|
|
|
{ x: 309, y: 102 },
|
|
|
|
{ x: 100, y: 1030 },
|
|
{ x: 544, y: 964 },
|
|
{ x: 132, y: 1030 },
|
|
{ x: 192, y: 1030 },
|
|
{ x: 512, y: 964 },
|
|
|
|
],
|
|
},
|
|
|
|
{
|
|
image: "gradient",
|
|
position: { x: 320, y: 0 },
|
|
},
|
|
|
|
{
|
|
image: "spikeLeft",
|
|
killing: true,
|
|
position: [
|
|
{ x: 736, y: range(416, 1104, 32) },
|
|
{ x: 96, y: 384 },
|
|
{ x: 736, y: range(32, 356, 32) },
|
|
{ x: 256, y: 250 },
|
|
{ x: 416, y: 108 },
|
|
{ x: 480, y: 224 },
|
|
{ x: 640, y: 160 },
|
|
],
|
|
},
|
|
{
|
|
image: "spikeRight",
|
|
killing: true,
|
|
position: [
|
|
{ x: 288, y: 250 },
|
|
{ x: 448, y: 108 },
|
|
{ x: 512, y: 224 },
|
|
{ x: 672, y: 160 },
|
|
],
|
|
},
|
|
{
|
|
image: "spikeDown",
|
|
killing: true,
|
|
position: [
|
|
{ x: range(128, 734, 32), y: 416 },
|
|
|
|
{ x: range(32, 320, 32), y: 32 },
|
|
{ x: range(352, 736, 32), y: 32 },
|
|
]
|
|
},
|
|
{
|
|
image: "spikeUp",
|
|
killing: true,
|
|
position: [
|
|
{ x: range(32, 734, 32), y: 1136 },
|
|
{ x: range(128, 736, 32), y: 352 },
|
|
{ x: [292, 356], y: 984 },
|
|
{ x: 324, y: 890 },
|
|
],
|
|
},
|
|
|
|
{
|
|
trigger: spawnSpike,
|
|
shape: new Line(0, 0, 32, 0),
|
|
position: [
|
|
{ x: 132, y: 1029 },
|
|
{ x: 100, y: 1029 },
|
|
{ x: 192, y: 1029 },
|
|
{ x: 528, y: 963 },
|
|
],
|
|
},
|
|
|
|
{
|
|
image: 3,
|
|
trigger: badPlatform,
|
|
dynamic: true,
|
|
|
|
position: [
|
|
{ x: 170, y: 168 },
|
|
{ x: 435, y: 70 },
|
|
]
|
|
},
|
|
|
|
{
|
|
dynamic: true,
|
|
trigger: redOrb,
|
|
image: "redOrb",
|
|
position: { x: 317, y: 76 },
|
|
},
|
|
|
|
{
|
|
trigger: startObject("platform1"),
|
|
shape: new Line(0, 0, 32, 0),
|
|
position: { x: 690, y: 845 },
|
|
},
|
|
|
|
|
|
{
|
|
trigger: transitionUp,
|
|
shape: new Line(0, 0, 800, 0),
|
|
position: { x: 0, y: 588 }
|
|
},
|
|
{
|
|
trigger: transitionDown,
|
|
shape: new Line(0, 0, 800, 0),
|
|
position: { x: 0, y: 615 }
|
|
},
|
|
|
|
|
|
{
|
|
id: "platform1",
|
|
image: "platform2",
|
|
blocking: true,
|
|
position: { x: 700, y: 850 },
|
|
tickFunction: movePlatform,
|
|
},
|
|
|
|
{
|
|
id: "platform2",
|
|
image: "platform2",
|
|
blocking: true,
|
|
position: { x: 650, y: 330 },
|
|
tickFunction: movePlatform2,
|
|
},
|
|
|
|
{
|
|
trigger: startObject("platform2"),
|
|
position: { x: 300, y: 288 },
|
|
shape: new Line(0, 0, 0, 100),
|
|
},
|
|
|
|
//{
|
|
// image: 3,
|
|
// dynamic: true,
|
|
// blocking: true,
|
|
// position: [
|
|
// { x: 100, y: 1030 },
|
|
// { x: 544, y: 964 },
|
|
// { x: 132, y: 1030 },
|
|
// { x: 192, y: 1030 },
|
|
// { x: 512, y: 964 },
|
|
// ],
|
|
//},
|
|
|
|
{
|
|
id: "bottomApple",
|
|
image: "apple",
|
|
killing: true,
|
|
position: { x: 775, y: 1130 }
|
|
},
|
|
|
|
{
|
|
dynamic: true,
|
|
trigger: additionalJump,
|
|
image: "jumpOrb",
|
|
position: [
|
|
{ x: [565, 485, 405, 325], y: 500 },
|
|
{ x: [230, 300], y: 310 },
|
|
{ x: 340, y: 275 }, // hard mode: y: 260
|
|
],
|
|
},
|
|
|
|
{
|
|
dynamic: true,
|
|
killing: true,
|
|
image: "apple",
|
|
tickFunction: moveApple,
|
|
position: { x: 466, y: 880 },
|
|
},
|
|
|
|
{
|
|
id: "saveState1",
|
|
trigger: saveState1,
|
|
position: { x: 40, y: 360 },
|
|
image: "blueOrb",
|
|
},
|
|
|
|
{
|
|
id: "exitBlock",
|
|
position: { x: 320, y: 0 },
|
|
image: 3,
|
|
},
|
|
|
|
{
|
|
id: "exitSpike",
|
|
position: { x: 320, y: 32 },
|
|
image: "spikeDown",
|
|
killing: true,
|
|
},
|
|
|
|
{
|
|
position: { x: 319, y: -300 },
|
|
blocking: true,
|
|
shape: new Line(0, 0, 0, 300),
|
|
},
|
|
|
|
{
|
|
position: { x: 500, y: -300 },
|
|
shape: new Line(0, 0, 0, 300),
|
|
trigger: nextLevel,
|
|
},
|
|
|
|
|
|
],
|
|
};
|
|
|
|
})();
|
|
|