Files
2023-02-19 01:05:41 +01:00

393 lines
9.4 KiB
JavaScript

//-------------------------------------------------------------------------
// 2. GAME CONSTANTS AND VARIABLES
//-------------------------------------------------------------------------
// ! Globales Test-Objekt
let globalObject = {
lifes: 3,
hitpoints: 3,
maxHitpoints: 5,
collected: null,
killed: null,
ammo: 10,
maxAmmo: 10,
oxygen: 70,
upgrades: {
jumpboots: false,
oxygenTank1: false,
oxygenTank2: false,
},
get maxOxygen() {
if (this.upgrades.oxygenTank2) {
return 240
}
if (this.upgrades.oxygenTank1) {
return 120
} else return 60
},
}
// * Import tiles and level map //
const tileAtlas1 = new Image()
tileAtlas1.src = './img/tiles.png'
const tileAtlas2 = new Image()
tileAtlas2.src = './img/Grotto-escape-2-files/PNG/environment-tiles.png'
const tileAtlasBg = new Image()
tileAtlasBg.src = './img/Grotto-escape-2-files/PNG/environment-background.png'
let tileSize = 16
let tileOutputSize = 2 // can set to 1 for 32px or higher
const level1Atlas = {
tileAtlas: tileAtlas1,
offset: 1,
tileSize: 16,
tileOutputSize: 2,
updatedTileSize: tileSize * tileOutputSize,
atlasCol: 8,
atlasRow: 5,
mapIndex: 0,
sourceX: 0,
sourceY: 0,
}
const level2Atlas = {
tileAtlas: tileAtlas2,
offset: 1,
tileSize: 16,
tileOutputSize: 2,
updatedTileSize: tileSize * tileOutputSize,
atlasCol: 42,
atlasRow: 16,
mapIndex: 0,
sourceX: 0,
sourceY: 0,
}
const backgroundAtlas = {
tileAtlas: tileAtlasBg,
offset: 673,
tileSize: 16,
tileOutputSize: 2,
updatedTileSize: tileSize * tileOutputSize,
atlasCol: 28,
atlasRow: 10,
mapIndex: 0,
sourceX: 0,
sourceY: 0,
}
// * end of Import tiles and level map //
// * Test Sprite Imports
const playerSpriteAtlas = new Image()
playerSpriteAtlas.src = './img/player.png'
const playerAtlas = {
tileAtlas: playerSpriteAtlas,
tileSize: 16,
tileOutputSize: 2,
updatedTileSize: tileSize * tileOutputSize,
atlasCol: 4,
atlasRow: 2,
mapIndex: 0,
sourceX: 0,
sourceY: 0,
}
const enemySpriteAtlas = new Image()
enemySpriteAtlas.src = './img/enemies.png'
const enemyAtlas = {
tileAtlas: enemySpriteAtlas,
tileSize: 16,
tileOutputSize: 2,
updatedTileSize: tileSize * tileOutputSize,
atlasCol: 4,
atlasRow: 3,
mapIndex: 0,
sourceX: 0,
sourceY: 0,
}
const itemsSpriteAtlas = new Image()
itemsSpriteAtlas.src = './img/items.png'
const itemsAtlas = {
tileAtlas: itemsSpriteAtlas,
tileSize: 16,
tileOutputSize: 2,
updatedTileSize: tileSize * tileOutputSize,
atlasCol: 4,
atlasRow: 4,
mapIndex: 0,
sourceX: 0,
sourceY: 0,
}
const meterSpriteAtlas = new Image()
meterSpriteAtlas.src = './img/meter.png'
const meterAtlas = {
tileAtlas: meterSpriteAtlas,
tileSize: 7,
tileOutputSize: 2,
updatedTileSize: tileSize * tileOutputSize,
atlasCol: 4,
atlasRow: 6,
mapIndex: 0,
sourceX: 0,
sourceY: 0,
}
// * End Test Sprite Imports
// * Das currentLevel Objekt sollte durch irgendeine Funktion befüllt werden, wenn ein Level gewechselt wird.
let levelObject = {
level1: {
scalingFactor: 8,
levelData: level1,
levelAtlas: level2Atlas,
backgroundAtlas: backgroundAtlas,
foregroundAtlas: level2Atlas,
playerStartCoordinates: { x: 96, y: 480 }, // * Für wenn man das Level durch eine Tür erneut betritt.
},
level2: {
scalingFactor: 4,
levelData: level2,
levelAtlas: level2Atlas,
backgroundAtlas: backgroundAtlas,
foregroundAtlas: level2Atlas,
playerStartCoordinates: { x: 96, y: 480 }, // * Für wenn man das Level durch eine Tür erneut betritt.
},
level3: {
scalingFactor: 8,
levelData: level3,
levelAtlas: level2Atlas,
backgroundAtlas: backgroundAtlas,
foregroundAtlas: level2Atlas,
playerStartCoordinates: { x: 96, y: 480 }, // * Für wenn man das Level durch eine Tür erneut betritt.
},
}
let currentLevel = levelObject.level1 // ! hier kann ich noch eine function draus machen, die das currentLevel immer auf dem aktuellen Stand hält. Vorläufig erstmal mit einem Button-Press
let mapWidth = currentLevel.levelData.width
let mapHeight = currentLevel.levelData.height
let MAP = { tw: mapWidth, th: mapHeight }
let TILE = 16
let METER = TILE
let GRAVITY = 60
let MAXDX = 15, // * default max horizontal speed (15 tiles per second)
MAXDY = 60, // * default max vertical speed (60 tiles per second)
ACCEL = 1 / 2, // * default take 1/2 second to reach maxdx (horizontal acceleration)
FRICTION = 1 / 6, // * default take 1/6 second to stop from maxdx (horizontal friction)
IMPULSE = 1500, // * default player jump impulse
COLOR = {
BLACK: '#000000',
YELLOW: '#ECD078',
BRICK: '#D95B43',
PINK: '#C02942',
PURPLE: '#542437',
GREY: '#333',
SLATE: '#53777A',
GOLD: 'gold',
},
COLORS = [COLOR.YELLOW, COLOR.BRICK, COLOR.PINK, COLOR.PURPLE, COLOR.GREY],
KEY = {
SPACE: ' ',
LEFT: 'ArrowLeft',
UP: 'ArrowUp',
RIGHT: 'ArrowRight',
DOWN: 'ArrowDown',
PAUSE: 'p',
ENTER: 'Enter',
X: 'x',
Y: 'y',
L: 'l',
}
const ammoType = {
width: 4,
height: 4,
distance: 100,
velocity: 3,
}
let fps = 60,
step = 1 / fps,
canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
player = {},
monsters = [],
pickups = [],
treasure = [],
vehicles = [],
doors = [], // ! Hier sammel ich alle Door Objekte.
liquids = [], // ! Alle Bereich, die mit Wasser gefüllt sind.
bullets = [],
cells = [], // ! vielleicht kann ich hieraus aber auch einfach ein Objekt machen, das Arrays für collCells, bgCells und fgCells beinhaltet
bgCells = [], // * Die sind für die background cells.
fgCells = [], // * Die sind für die foreground cells.
lqCells = [],
paused = false,
showDevInfo = false
canvas.width = mapWidth * TILE
canvas.height = mapHeight * TILE
let width = (canvas.width = mapWidth * TILE) // * Das ist clever, weil ich so der Canvas immer von der Map Size abhängig ist. Zusammen mit ctx.scale und ctx.translate bekomme ich so auch eine Camera hin!
let height = (canvas.height = mapHeight * TILE)
let scalingFactor = currentLevel.scalingFactor // * 8 fühlt sich ungefähr nach 8bit Grafik an.
let scaledCanvas = {
width: canvas.width / scalingFactor,
height: canvas.height / scalingFactor,
}
let t2p = function (t) {
return t * TILE
},
p2t = function (p) {
return Math.floor(p / TILE)
},
cell = function (x, y) {
return tcell(p2t(x), p2t(y), mapWidth)
},
tcell = function (tx, ty, mapWidth) {
// ! Hier brauche ich entweder eine allgemeinere Funktion oder noch weiter für bgCells ud fgCells.
return cells[tx + ty * mapWidth]
},
bgTcell = function (tx, ty, mapWidth) {
return bgCells[tx + ty * mapWidth]
},
fgTcell = function (tx, ty, mapWidth) {
return fgCells[tx + ty * mapWidth]
},
lqTcell = function (tx, ty, mapWidth) {
return !!lqCells && lqCells[tx + ty * mapWidth]
}
// * Init Level Funtion
function _initLevel(newLevel) {
monsters = []
treasure = []
pickups = []
doors = []
liquids = []
cells = []
currentLevel = newLevel
player.collected = 0
mapWidth = currentLevel.levelData.width
mapHeight = currentLevel.levelData.height
canvas.width = mapWidth * TILE
canvas.height = mapHeight * TILE
scalingFactor = currentLevel.scalingFactor
scaledCanvas = {
width: canvas.width / scalingFactor,
height: canvas.height / scalingFactor,
}
setup(newLevel.levelData)
}
// * Const Sfx from audio files //
// ! Achtung: utils müssen in index.html vor den variables geladen werden.
let sfxVolume = 0.2
let musicVolume = 0.5
let sfx = {
jump: new sound('./audio/Jump.wav', sfxVolume),
pickup: new sound('./audio/Pickup_Coin.wav', sfxVolume),
lowHealth: new sound('./audio/LA_LowHealth.wav', sfxVolume),
die: new sound('./audio/Explosion.wav', sfxVolume),
takeDamage: new sound('./audio/Randomize3.wav', sfxVolume),
killMonster: new sound('./audio/Randomize.wav', sfxVolume),
powerup: new sound('./audio/Powerup.wav', sfxVolume),
openDoor: new sound('./audio/LA_Chest_Open.wav', sfxVolume),
shoot: new sound('./audio/Laser2.wav', sfxVolume),
explode: new sound('./audio/Explosion.wav', sfxVolume),
splash: new sound('./audio/Oracle_Rock_Shatter.wav', sfxVolume),
swim: new sound('./audio/SML2_Swim.ogg', sfxVolume),
click: new sound('./audio/click.wav', sfxVolume),
stomp: new sound('./audio/smb_stomp.wav', sfxVolume),
kick: new sound('./audio/smb_kick.wav', sfxVolume),
extraLife: new sound('./audio/smb_1-up.wav', sfxVolume),
smb_powerup: new sound('./audio/smb_powerup.wav', sfxVolume),
}
let theme = {
level1: new music('./audio/music/8BitCave.wav', musicVolume),
}
let submarine = {
collected: 0,
killed: 0,
maxHitpoints: 5,
currentHitpoints: 3,
vul: true,
hurt: false,
interact: false,
shooting: false,
swimming: false,
diving: false,
}
let globalPlayer = {
collected: 0,
killed: 0,
maxHitpoints: 5,
currentHitpoints: 3,
vul: true,
hurt: false,
interact: false,
shooting: false,
swimming: false,
diving: false,
sprites: {
idle: {
tiles: [5],
framerate: 5,
framebuffer: 8,
loop: true,
currentFrame: 0,
},
run: {
tiles: [0, 1, 2, 1],
framerate: 5,
framebuffer: 10,
loop: true,
currentFrame: 0,
},
jump: {
tiles: [4],
framerate: 5,
framebuffer: 8,
loop: true,
currentFrame: 0,
},
shoot: {
tiles: [3],
framerate: 5,
framebuffer: 8,
loop: true,
currentFrame: 0,
},
},
}