waves/public/assets/g/iwbtc/levels/level1.js
2025-04-09 17:11:14 -05:00

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,
},
],
};
})();