diff options
| author | Maksymilian Jopek <maks@jopek.eu> | 2023-02-27 22:35:28 +0100 |
|---|---|---|
| committer | Maksymilian Jopek <maks@jopek.eu> | 2023-02-27 22:35:28 +0100 |
| commit | 4db4b5791cd1359519933871ab65412acafb71d7 (patch) | |
| tree | 24c9b78757e23793384481691745c8d3ff0db621 | |
| parent | 9f7331ca8b60cd91ee2493fa1872410c5755d1bd (diff) | |
| download | 1942-4db4b5791cd1359519933871ab65412acafb71d7.tar.gz 1942-4db4b5791cd1359519933871ab65412acafb71d7.tar.zst 1942-4db4b5791cd1359519933871ab65412acafb71d7.zip | |
v1.1.0
Refactor of loading screen
Faster loading time by concurently awaiting all promises
Minor bug fix
Added litle help menu at the start of the game
| -rw-r--r-- | index.html | 7 | ||||
| -rw-r--r-- | pnpm-lock.yaml | 2 | ||||
| -rw-r--r-- | src/Events.ts | 5 | ||||
| -rw-r--r-- | src/Images.ts | 65 | ||||
| -rw-r--r-- | src/consts.ts | 1 | ||||
| -rw-r--r-- | src/drawables/TopBar.ts | 2 | ||||
| -rw-r--r-- | src/main.ts | 38 | ||||
| -rw-r--r-- | src/static/prstart-webfont.woff | bin | 0 -> 15652 bytes | |||
| -rw-r--r-- | src/static/prstart-webfont.woff2 | bin | 0 -> 11720 bytes | |||
| -rw-r--r-- | src/static/prstart.ttf | bin | 0 -> 21320 bytes | |||
| -rw-r--r-- | src/style.css | 61 |
11 files changed, 149 insertions, 32 deletions
@@ -8,8 +8,11 @@ <title>1942</title> </head> -<body bgcolor="black"> - <canvas width="320" height="200" style="background-color: grey;"></canvas> +<body> + <div class="h-gradient">GAME IS LOADING</div> + <canvas width="320" height="200"></canvas> + <button>START THE GAME</button> + <h1 class="help">/ is fire button, WSAD to move, spacebar to roll</h1> <script type="module" src="/src/main.ts"></script> </body> diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11f11cf..64db052 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: 5.3 +lockfileVersion: 5.4 specifiers: typescript: ^4.5.4 diff --git a/src/Events.ts b/src/Events.ts index b6b09ef..dbb80a4 100644 --- a/src/Events.ts +++ b/src/Events.ts @@ -4,6 +4,9 @@ // up: boolean; // down: boolean; // fire: boolean; + +import { helpTxt } from "./consts"; + // } export const keys = { right: false, @@ -27,7 +30,7 @@ function setKey(key: string, val: boolean, repeat: boolean) { else if (["a", "h"].includes(key)) { keys.left = val; keys.lastx = "left" } else if (["s", "j"].includes(key)) { keys.down = val; keys.lasty = "down" } else if (["d", "l"].includes(key)) { keys.right = val; keys.lastx = "right" } - else if (["m", ";", "/"].includes(key)) { keys.fire = val; keys.repeat = repeat } + else if (["m", ";", "/"].includes(key)) { keys.fire = val; keys.repeat = repeat; helpTxt.style.display = "none"; } else if ([" "].includes(key)) keys.roll = val; // else if (["r"].includes(key)) location.reload(); // else if (["f"].includes(key)) keys.fps = 50; diff --git a/src/Images.ts b/src/Images.ts index 3721ac0..f67ef30 100644 --- a/src/Images.ts +++ b/src/Images.ts @@ -153,17 +153,36 @@ export const IMGS = { selector: {} as HTMLImageElement, empty: {} as HTMLImageElement, }; -export const URL = "/maks/szkola/apkKli/1942/" +export const URL = "" // window.IMGS = IMGS; -export default async function loadAllImages() { +export async function loadAllImages() { + const prImgs = [] for (const key in IMGS) { if (["empty", "font", "start"].includes(key)) continue; - IMGS[key as keyof typeof IMGS] = await asyncImageLoader(URL + "src/imgs/" + toKebabCase(key) + ".png") as any + + prImgs.push(asyncImageLoader(URL + "src/imgs/" + toKebabCase(key) + ".png")) + // IMGS[key as keyof typeof IMGS] = await asyncImageLoader(URL + "src/imgs/" + toKebabCase(key) + ".png") as any + } + const imgs = await Promise.all(prImgs) + for (const [i, key] of Object.keys(IMGS).entries()) { + if (["empty", "font", "start"].includes(key)) continue; + IMGS[key as keyof typeof IMGS] = imgs[i] } + + const prLetters = {} as { [key: string]: Promise<HTMLImageElement>[] } + const letters = {} as { [key: string]: HTMLImageElement[] } for (const color of ['yellow', 'white', 'blue', 'red', 'green', 'purple']) { // for (const color of ['white', 'yellow']) { + prLetters[color] = [] as Promise<HTMLImageElement>[] for (const char of allChars) { - (((IMGS.font as any)[color] as any)[char]) = await asyncImageLoader(URL + "src/imgs/font/" + color + "/" + encodeURIComponent(char) + ".png") as any + prLetters[color].push(asyncImageLoader(URL + "src/imgs/font/" + color + "/" + encodeURIComponent(char) + ".png") as any) + // (((IMGS.font as any)[color] as any)[char]) = await asyncImageLoader(URL + "src/imgs/font/" + color + "/" + encodeURIComponent(char) + ".png") as any + } + } + for (const color in prLetters) { + letters[color] = await Promise.all(prLetters[color]) + for (const [i, char] of allChars.entries()) { + IMGS.font[color as keyof typeof IMGS.font][char] = letters[color][i] } } IMGS.font[' '] = await asyncImageLoader(URL + "src/imgs/font/ .png") @@ -175,12 +194,20 @@ export default async function loadAllImages() { IMGS.font.red[' '] = await asyncImageLoader(URL + "src/imgs/font/ .png") IMGS.font.green[' '] = await asyncImageLoader(URL + "src/imgs/font/ .png") IMGS.font.purple[' '] = await asyncImageLoader(URL + "src/imgs/font/ .png") + // Only numbers for (const c of allChars.filter(ch => !alphabet.includes(ch))) { IMGS.font.small.white[c] = await asyncImageLoader(URL + "src/imgs/font/small/white/" + c + ".png"); } - for (let i = 1; i <= 215; i++) - IMGS.start[i] = await asyncImageLoader(URL + "src/imgs/start/" + i + ".png"); + + const prBg = [] + for (let i = 1; i <= 215; i++) { + prBg.push(asyncImageLoader(URL + "src/imgs/start/" + i + ".png")); + } + const bg = await Promise.all(prBg) + for (let i = 1; i <= 215; i++) { + IMGS.start[i] = bg[i]; + } } async function asyncImageLoader(url: string): Promise<HTMLImageElement> { return new Promise((resolve, reject) => { @@ -190,11 +217,11 @@ async function asyncImageLoader(url: string): Promise<HTMLImageElement> { image.onerror = () => { console.log("img did not load", url); reject() } }) } -async function asyncSoundLoader(url: string): Promise<HTMLAudioElement> { +async function asyncSoundLoader(url: string): Promise<Sound> { return new Promise((resolve, reject) => { const image = new Audio(url) image.src = url - image.oncanplaythrough = () => resolve(image) + image.oncanplaythrough = () => resolve(image as Sound) image.onerror = () => { console.log("img did not load", url); reject() } }) } @@ -214,12 +241,26 @@ export const SOUNDS = { rvCheck: {} as Sound, } export async function loadAllSounds() { + const sounds = [] for (const key in SOUNDS) { - const toBeSound = await asyncSoundLoader(URL + "src/audios/" + toKebabCase(key) + ".mp3") as Sound - toBeSound.playFromBegin = function() { this.currentTime = 0; this.play() } - if (["mainTheme", "win", "name"].includes(key)) toBeSound.loop = true; - SOUNDS[key as keyof typeof SOUNDS] = toBeSound; + sounds.push(asyncSoundLoader(URL + "src/audios/" + toKebabCase(key) + ".mp3")) + } + const responses = await Promise.all(sounds) + for (const [i, key] of Object.keys(SOUNDS).entries()) { + let sound = responses[i] + sound.playFromBegin = function() { this.currentTime = 0; this.play() } + if (["mainTheme", "win", "name"].includes(key)) sound.loop = true; + SOUNDS[key as keyof typeof SOUNDS] = sound; } + // for (const sound of sounds) { + + // } + //for (const key in SOUNDS) { + // const toBeSound = await asyncSoundLoader(URL + "src/audios/" + toKebabCase(key) + ".mp3") as Sound + // toBeSound.playFromBegin = function() { this.currentTime = 0; this.play() } + // if (["mainTheme", "win", "name"].includes(key)) toBeSound.loop = true; + // SOUNDS[key as keyof typeof SOUNDS] = toBeSound; + //} } export function getSmallDeathAnim(t: Enemy) { diff --git a/src/consts.ts b/src/consts.ts index 9b67159..5f1cc62 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -1,6 +1,7 @@ export const canvas = document.querySelector<HTMLCanvasElement>('canvas')! export const ctx = canvas.getContext("2d")! ctx.imageSmoothingEnabled = false; +export const helpTxt = document.getElementsByTagName("h1")[0]! export const PLAYER_SIZE = 20; // canvas-dot export const PLAYER_VEL = 3; // canvas-dot / frame diff --git a/src/drawables/TopBar.ts b/src/drawables/TopBar.ts index 4bd525a..5009f19 100644 --- a/src/drawables/TopBar.ts +++ b/src/drawables/TopBar.ts @@ -43,7 +43,7 @@ export class TopBar extends Drawable { }); if (this.bgd >= 2580) { // 9 41 - [..."shooting down ".split(''), ...(this.shootedDown / 32).toFixed(0).toString().padStart(3, '0').split(''), '%'].forEach((char, i) => { + [..."shooting down ".split(''), ...(this.shootedDown * 100 / 32).toFixed(0).toString().padStart(3, '0').split(''), '%'].forEach((char, i) => { ctx.drawImage(IMGS.font.white[char], 9 + i * 17, 41, 15, 8) }); [..."bonus".split('')].forEach((char, i) => { diff --git a/src/main.ts b/src/main.ts index e20e14f..9708334 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,25 +1,33 @@ import "./style.css"; import "./Events"; -import loadAllImages, { loadAllSounds, SOUNDS } from "./Images"; +import { loadAllImages, loadAllSounds } from "./Images"; import { start } from "./game"; +import { canvas, helpTxt } from "./consts"; + +const btn = document.getElementsByTagName("button")[0] +const txt = document.getElementsByTagName("div")[0] -const btn = document.createElement("button"); async function init() { - await loadAllSounds(); - await loadAllImages(); try { - SOUNDS.win.volume = 0; - await SOUNDS.win.play() - SOUNDS.win.pause() - SOUNDS.win.volume = 1 - SOUNDS.win.currentTime = 0; - start(); - } catch (error) { - console.log(error); + await loadAllSounds(); + await loadAllImages(); + // SOUNDS.win.volume = 0; + // await SOUNDS.win.play() + // SOUNDS.win.pause() + // SOUNDS.win.volume = 1 + // SOUNDS.win.currentTime = 0; - btn.innerText = "Start da game" - btn.onclick = () => { btn.remove(); start(); } - document.body.appendChild(btn) + txt.innerText = "GAME IS READY TO BE PLAYED" + btn.classList.add("visible") + btn.onclick = () => { + btn.remove(); + txt.remove(); + canvas.style.display = "block"; + helpTxt.style.display = "block"; + start(); + } + } catch (error) { + console.error(error); } } document.body.onload = init; diff --git a/src/static/prstart-webfont.woff b/src/static/prstart-webfont.woff Binary files differnew file mode 100644 index 0000000..01c8d57 --- /dev/null +++ b/src/static/prstart-webfont.woff diff --git a/src/static/prstart-webfont.woff2 b/src/static/prstart-webfont.woff2 Binary files differnew file mode 100644 index 0000000..46cb196 --- /dev/null +++ b/src/static/prstart-webfont.woff2 diff --git a/src/static/prstart.ttf b/src/static/prstart.ttf Binary files differnew file mode 100644 index 0000000..40ca6b6 --- /dev/null +++ b/src/static/prstart.ttf diff --git a/src/style.css b/src/style.css index 026f6a1..9ebb486 100644 --- a/src/style.css +++ b/src/style.css @@ -1,6 +1,10 @@ body { display: grid; height: 100vh; + background: black; + /*background: linear-gradient(45deg, #79d570, #a28fff);*/ + font-family: 'prstart'; + color: white; } canvas { --scale: 3; @@ -10,4 +14,61 @@ canvas { image-rendering: pixelated; image-rendering: crisp-edges; border: 1px solid black; + display: none; +} +.help { + position: absolute; + bottom: 2rem; + left: 50%; + transform: translateX(-50%); + width: max-content; + display: none; +} + +.h-gradient { + font-size: 4rem; + text-align: center; + background: linear-gradient(-45deg, #6355a4, #e89a3e); + /* #f7ff6c */ + background-size: 300%; + letter-spacing: 0.1rem; + font-weight: 900; + font-size: 4rem; + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + animation: bg-animation 6s ease-in-out infinite; + place-self: center; +} +@keyframes bg-animation { + 0% { background-position: 0px 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0px 50%; } +} + +button { + font-family: 'prstart'; + font-size: 3rem; + color: white; + padding: 2rem; + border-top-left-radius: 4rem; + border-bottom-right-radius: 4rem; + border-top-right-radius: 1rem; + border-bottom-left-radius: 1rem; + /*background-color: #6355a4;*/ + background: linear-gradient(-45deg, #6355a4, #e89a3e); + place-self: center; + opacity: 0; +} +button.visible { + opacity: 1; + transition: opacity 1s ease-in-out; +} + +@font-face { + font-family: 'prstart'; + src: url('/src/static/prstart-webfont.woff2') format('woff2'), + url('/src/static/prstart-webfont.woff') format('woff'); + font-weight: normal; + font-style: normal; } |
