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

396 lines
10 KiB
JavaScript

//-------------------------------------------------------------------------
// 4. RENDERING
//-------------------------------------------------------------------------
function render(ctx, frame, dt, thiscurrentLevel) {
// ? Kann ich mich eigentlich mit scale und translate noch weiter an Pico-8 orientieren und in den variables sowas wie scale = ctx.scale oder so erstellen?
// * Disable Image Smoothing
ctx.mozImageSmoothingEnabled = false
ctx.webkitImageSmoothingEnabled = false
ctx.msImageSmoothingEnabled = false
ctx.imageSmoothingEnabled = false
ctx.save()
ctx.scale(
Math.round(thiscurrentLevel.scalingFactor / 2),
Math.round(thiscurrentLevel.scalingFactor / 2)
)
ctx.clearRect(0, 0, width, height)
renderCamera()
//renderCameraWithBox()
renderBackground(ctx, thiscurrentLevel.backgroundAtlas, bgCells)
renderMap(ctx, thiscurrentLevel.levelAtlas, cells)
renderPlayer(ctx, playerAtlas, dt, frame)
renderBullets(ctx, itemsAtlas, dt, frame)
renderMonsters(ctx, enemyAtlas, dt, frame)
renderTreasure(ctx, itemsAtlas, dt, frame)
renderPickups(ctx, itemsAtlas, dt, frame)
renderVehicless(ctx, enemyAtlas, dt, frame)
renderForeground(ctx, thiscurrentLevel.foregroundAtlas, fgCells)
renderLiquids(ctx, thiscurrentLevel.foregroundAtlas, fgCells)
// * Draw CameraBox
//renderCameraBox()
ctx.restore()
renderPause()
renderHud(ctx, meterAtlas, dt, frame)
renderHudSprites()
//fadeScreen(frame, dt)
renderDevInfos()
}
// Map Limit Variables
// * Das hier ist die allgemeine Funktion um Tiles aus dem TileAtlas auf den Canvas zu malen.
function drawTile(levelAtlas, cell, dx, dy, opacity) {
levelAtlas.sourceY =
Math.floor(cell / levelAtlas.atlasCol) * levelAtlas.tileSize
levelAtlas.sourceX = (cell % levelAtlas.atlasCol) * levelAtlas.tileSize
// ? Wofür stehen die Werte sWidth, sHeight, dWidth, dHeight
ctx.globalAlpha = opacity
// ! Kann ich die ganzen festen Zahlen als Variablen aus der Map holen?
ctx.drawImage(
levelAtlas.tileAtlas,
levelAtlas.sourceX,
levelAtlas.sourceY,
16,
16,
dx * 16,
dy * 16,
16,
16
)
}
function renderBackground(ctx, levelAtlas) {
var x, y, cell
for (y = 0; y < mapHeight; y++) {
for (x = 0; x < mapWidth; x++) {
cell = bgTcell(x, y, mapWidth)
if (cell) {
drawTile(levelAtlas, cell - levelAtlas.offset, x, y)
}
}
}
}
function renderForeground(ctx, levelAtlas) {
var x, y, cell
for (y = 0; y < mapHeight; y++) {
for (x = 0; x < mapWidth; x++) {
cell = fgTcell(x, y, mapWidth)
if (cell) {
drawTile(levelAtlas, cell - levelAtlas.offset, x, y)
}
}
}
}
function renderLiquids(ctx, levelAtlas) {
var x, y, cell
for (y = 0; y < mapHeight; y++) {
for (x = 0; x < mapWidth; x++) {
cell = lqTcell(x, y, mapWidth)
if (cell) {
drawTile(levelAtlas, cell - levelAtlas.offset, x, y, 0.5)
}
}
}
}
function renderMap(ctx, levelAtlas) {
var x, y, cell
for (y = 0; y < mapHeight; y++) {
for (x = 0; x < mapWidth; x++) {
cell = tcell(x, y, mapWidth)
if (cell) {
drawTile(levelAtlas, cell - levelAtlas.offset, x, y)
}
}
}
}
// * Sprite Animation
function drawSprite(entity, spriteAtlas, dt, frame) {
/* entity.start.x === 48 &&
entity.start.y === 656 &&
console.log('log frame ', entity.sprites.idle)
*/
let sprites = entity.sprites
let isJumping = entity.jumping || entity.falling
let isRunning =
(entity.right === true && !isJumping) ||
(entity.left === true && !isJumping)
let isShooting = entity.shooting || false
let sprite =
!!sprites.run && isRunning
? sprites.run
: !!sprites.jump && isJumping
? sprites.jump
: !!sprites.shoot && isShooting
? sprites.shoot
: sprites.idle
const x = entity.bullet ? entity.x : entity.x + entity.dx * dt
const y = entity.bullet
? entity.y - entity.height * 2
: entity.y + entity.dy * dt
const flipped = entity.flipped
const width = entity.bullet ? entity.width * 4 : entity.width
const height = entity.bullet ? entity.height * 4 : entity.height
let spriteTile = sprite.tiles[sprite.currentFrame]
/* entity.pickups &&
console.log(
'log drawSprite currentFrame ',
sprite.tiles[sprite.currentFrame]
) */
// make an image position using the
// current row and colum
spriteAtlas.sourceY =
Math.floor(spriteTile / spriteAtlas.atlasCol) * spriteAtlas.tileSize
spriteAtlas.sourceX =
(spriteTile % spriteAtlas.atlasCol) * spriteAtlas.tileSize
ctx.save()
// * Flip Sprite
ctx.scale(flipped ? -1 : 1, 1)
let dx = flipped ? -x - width : x
ctx.drawImage(
spriteAtlas.tileAtlas,
spriteAtlas.sourceX,
spriteAtlas.sourceY,
16, // * source Höhe
16, // * source Breite
dx,
y,
width, // * player Höhe
height // * player Breite
)
ctx.restore()
updateFrames(frame, sprite)
// entity.treasure && console.log('log drawSprite ', entity)
}
function updateFrames(frame, sprite) {
/* entity.start.x === 48 &&
entity.start.y === 656 &&
console.log('log frame ', entity) */
if (frame % sprite.framebuffer === 0) {
if (sprite.currentFrame + 1 < sprite.tiles.length) sprite.currentFrame++
else if (sprite.loop) sprite.currentFrame = 0
}
}
// * Render Player
function renderPlayer(ctx, spriteAtlas, dt, frame) {
if (player.vul === false) {
ctx.globalAlpha = 0.25 + tweenTreasure(frame * 3, 60)
}
drawSprite(player, spriteAtlas, dt, frame)
ctx.globalAlpha = 1
}
function renderVehicless(ctx, spriteAtlas, dt, frame) {
ctx.fillStyle = COLOR.BRICK
var n, max, vehicle
for (n = 0, max = vehicles.length; n < max; n++) {
vehicle = vehicles[n]
if (vehicle.sprites === undefined && !vehicle.dead)
ctx.fillRect(
vehicle.x + vehicle.dx * dt,
vehicle.y + vehicle.dy * dt,
32,
32
)
if (vehicle.sprites !== undefined && !vehicle.dead) {
//drawSprite(vehicle, spriteAtlas, dt, frame)
}
}
}
function renderHud(ctx, spriteAtlas, dt, frame) {
var n, max
const hudScaling = scalingFactor / 2
const hitpoints = globalObject.hitpoints
const killed = globalObject.killed
const collected = globalObject.collected
ctx.fillStyle = COLOR.GOLD
for (n = 0, max = collected; n < max; n++)
ctx.fillRect(
t2p(1 + n) * hudScaling,
t2p(1) * hudScaling,
(TILE / 2) * hudScaling,
(TILE / 2) * hudScaling
)
ctx.fillStyle = COLOR.SLATE
for (n = 0, max = killed; n < max; n++)
ctx.fillRect(
t2p(1 + n) * hudScaling,
t2p(2) * hudScaling,
(TILE / 2) * hudScaling,
(TILE / 2) * hudScaling
)
// ! provisorische Hitpoint-Anzeige
ctx.fillStyle = 'red'
if (hitpoints === 1) {
ctx.globalAlpha = 0.25 + tweenTreasure(frame, 60)
}
for (n = 0, max = hitpoints; n < max; n++)
ctx.fillRect(
t2p(1 + n / 3) * hudScaling,
t2p(3) * hudScaling,
4 * hudScaling,
8 * hudScaling
)
// ! Der Atlas funktioniert so nicht weil die Tiles nicht quadratisch sind.
// drawSprite(t, spriteAtlas, dt, frame)
ctx.globalAlpha = 1
}
function fadeScreen(frame, dt) {
ctx.fillStyle = 'black'
ctx.globalAlpha = 0
let duration = 100
pulse = frame % duration
if (pulse < duration) {
opacity = pulse / duration
} else {
opacity = 0
}
ctx.fillRect(0, 0, width, height)
ctx.globalAlpha = opacity
//setInterval(show(), 800)
// console.log('log opacity ', opacity)
// console.log('log fade frame ', frame)
// console.log('log fade pulse ', pulse)
}
// * Render Pause Function
function renderPause() {
if (paused) {
ctx.save()
ctx.scale(scalingFactor / 2, scalingFactor / 2)
ctx.font = '12px C64 TrueType'
ctx.fillStyle = 'white'
ctx.textAlign = 'center'
ctx.fillText('- pause -', scaledCanvas.width, scaledCanvas.height)
ctx.restore()
}
}
function renderCameraBox() {
ctx.fillStyle = 'rgba(0, 0, 255, 0.2)'
ctx.fillRect(cameraBox.x, cameraBox.y, cameraBox.width, cameraBox.height)
}
function renderMonsters(ctx, spriteAtlas, dt, frame) {
ctx.fillStyle = COLOR.SLATE
var n, max, monster
for (n = 0, max = monsters.length; n < max; n++) {
monster = monsters[n]
if (monster.sprites === undefined && !monster.dead)
ctx.fillRect(
monster.x + monster.dx * dt,
monster.y + monster.dy * dt,
TILE,
TILE
)
if (monster.sprites !== undefined && !monster.dead) {
drawSprite(monster, spriteAtlas, dt, frame)
}
}
}
function renderPickups(ctx, spriteAtlas, dt, frame) {
//ctx.globalAlpha = 0.25 + tweenTreasure(frame, 60)
var n, max, p
for (n = 0, max = pickups.length; n < max; n++) {
p = pickups[n]
//console.log('log p.sprites.currentsprite ', p.sprites.currentFrame)
if (p.sprites !== undefined && !p.collected) {
drawSprite(p, spriteAtlas, dt, frame)
}
}
//ctx.globalAlpha = 1
}
function renderTreasure(ctx, spriteAtlas, dt, frame) {
ctx.fillStyle = COLOR.GOLD
ctx.globalAlpha = 0.25 + tweenTreasure(frame, 60)
var n, max, t
for (n = 0, max = treasure.length; n < max; n++) {
t = treasure[n]
//if (!t.collected) ctx.fillRect(t.x, t.y + TILE / 3, TILE, (TILE * 2) / 3)
if (t.sprites !== undefined && !t.collected) {
// console.log('log treasure entity ', t)
drawSprite(t, spriteAtlas, dt, frame)
}
}
ctx.globalAlpha = 1
}
function tweenTreasure(frame, duration) {
const half = duration / 2
pulse = frame % duration
return pulse < half ? pulse / half : 1 - (pulse - half) / half
}
function renderBullets(ctx, spriteAtlas, dt, frame) {
ctx.fillStyle = COLOR.GOLD
var n, max, bullet
for (n = 0, max = bullets.length; n < max; n++) {
bullet = bullets[n]
switch (bullet.ammoType) {
case 'simpleGun':
bullet.sprites = simpleBullet.sprites
break
case 'advancedGun':
bullet.sprites = simpleBullet.sprites
break
}
//console.log('log bullet ', bullet.sprites)
//console.log('log bullet spriteAtlas ', spriteAtlas)
if (bullet !== undefined) {
if (bullet.sprites === undefined) {
ctx.fillRect(bullet.x, bullet.y, ammoType.width, ammoType.height)
}
if (bullet.sprites !== undefined) {
// console.log('log bullet entity ', bullet)
drawSprite(bullet, spriteAtlas, dt, frame)
}
}
}
}