From 8f0d86418e9bf267ed19571fddfd859933e60171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=A1ez?= Date: Wed, 30 Oct 2024 18:53:16 -0300 Subject: [PATCH] refactor: context in one variable, expose context (#481) --- src/app/app.ts | 1 + src/app/frame.ts | 8 +- src/assets/aseprite.ts | 4 +- src/assets/asset.ts | 24 +++--- src/assets/bitmapFont.ts | 8 +- src/assets/font.ts | 8 +- src/assets/pedit.ts | 4 +- src/assets/shader.ts | 12 +-- src/assets/sound.ts | 10 +-- src/assets/sprite.ts | 14 ++-- src/assets/spriteAtlas.ts | 4 +- src/assets/utils.ts | 4 +- src/audio/burp.ts | 4 +- src/audio/play.ts | 10 +-- src/audio/playMusic.ts | 12 +-- src/audio/volume.ts | 6 +- src/components/draw/opacity.ts | 10 +-- src/components/draw/raycast.ts | 4 +- src/components/draw/text.ts | 2 +- src/components/level/sentry.ts | 4 +- src/components/misc/lifespan.ts | 6 +- src/components/misc/textInput.ts | 8 +- src/components/misc/timer.ts | 6 +- src/components/physics/area.ts | 40 +++++----- src/components/physics/body.ts | 53 ++++++------- src/components/transform/layer.ts | 8 +- src/components/transform/offscreen.ts | 9 ++- src/components/transform/pos.ts | 20 ++--- src/game/camera.ts | 24 +++--- src/game/events/events.ts | 32 ++++---- src/game/gravity.ts | 10 +-- src/game/initEvents.ts | 78 +++++++++---------- src/game/kaboom.ts | 8 +- src/game/layers.ts | 8 +- src/game/level.ts | 4 +- src/game/make.ts | 32 ++++---- src/game/object.ts | 4 +- src/game/scenes.ts | 32 ++++---- src/gfx/bg.ts | 10 +-- src/gfx/draw/drawDebug.ts | 30 ++++---- src/gfx/draw/drawFrame.ts | 6 +- src/gfx/draw/drawLine.ts | 10 +-- src/gfx/draw/drawLoadingScreen.ts | 6 +- src/gfx/draw/drawMasked.ts | 4 +- src/gfx/draw/drawPolygon.ts | 4 +- src/gfx/draw/drawRaw.ts | 16 ++-- src/gfx/draw/drawStenciled.ts | 4 +- src/gfx/draw/drawSubstracted.ts | 4 +- src/gfx/draw/drawUnscaled.ts | 14 ++-- src/gfx/formatText.ts | 12 +-- src/gfx/stack.ts | 36 ++++----- src/gfx/viewport.ts | 24 +++--- src/kaplay.ts | 106 ++++++++++++++++---------- src/types.ts | 34 ++++++++- 54 files changed, 454 insertions(+), 401 deletions(-) diff --git a/src/app/app.ts b/src/app/app.ts index a4d12b02..499b84a7 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1225,6 +1225,7 @@ export const initApp = (opt: { resizeObserver.observe(state.canvas); return { + state, dt, fixedDt, restDt, diff --git a/src/app/frame.ts b/src/app/frame.ts index 6329576a..f0ddcdfb 100644 --- a/src/app/frame.ts +++ b/src/app/frame.ts @@ -1,13 +1,13 @@ -import { app, debug } from "../kaplay"; +import { _k } from "../kaplay"; export function dt() { - return app.dt() * debug.timeScale; + return _k.app.dt(); } export function fixedDt() { - return app.fixedDt() * debug.timeScale; + return _k.app.fixedDt(); } export function restDt() { - return app.restDt() * debug.timeScale; + return _k.app.restDt(); } diff --git a/src/assets/aseprite.ts b/src/assets/aseprite.ts index 15f32cb3..367ad999 100644 --- a/src/assets/aseprite.ts +++ b/src/assets/aseprite.ts @@ -1,4 +1,4 @@ -import { assets } from "../kaplay"; +import { _k } from "../kaplay"; import { Quad } from "../math"; import { getFileName } from "../utils"; import { type Asset, fetchJSON } from "./asset"; @@ -41,7 +41,7 @@ export function loadAseprite( ? fetchJSON(jsonSrc) : Promise.resolve(jsonSrc); - return assets.sprites.add( + return _k.assets.sprites.add( name, resolveJSON.then((data: AsepriteData) => { const size = data.meta.size; diff --git a/src/assets/asset.ts b/src/assets/asset.ts index 19ca5ee1..5193e56f 100644 --- a/src/assets/asset.ts +++ b/src/assets/asset.ts @@ -1,7 +1,7 @@ import { SPRITE_ATLAS_HEIGHT, SPRITE_ATLAS_WIDTH } from "../constants"; import type { GfxCtx } from "../gfx/gfx"; import TexPacker from "../gfx/texPacker"; -import { assets } from "../kaplay"; +import { _k } from "../kaplay"; import { KEvent } from "../utils"; import type { BitmapFontData } from "./bitmapFont"; import type { FontData } from "./font"; @@ -139,13 +139,13 @@ export function fetchArrayBuffer(path: string) { // global load path prefix export function loadRoot(path?: string): string { if (path !== undefined) { - assets.urlPrefix = path; + _k.assets.urlPrefix = path; } - return assets.urlPrefix; + return _k.assets.urlPrefix; } export function loadJSON(name: string, url: string) { - return assets.custom.add(name, fetchJSON(fixURL(url))); + return _k.assets.custom.add(name, fetchJSON(fixURL(url))); } // wrapper around image loader to get a Promise @@ -162,24 +162,24 @@ export function loadImg(src: string): Promise { export function loadProgress(): number { const buckets = [ - assets.sprites, - assets.sounds, - assets.shaders, - assets.fonts, - assets.bitmapFonts, - assets.custom, + _k.assets.sprites, + _k.assets.sounds, + _k.assets.shaders, + _k.assets.fonts, + _k.assets.bitmapFonts, + _k.assets.custom, ]; return buckets.reduce((n, bucket) => n + bucket.progress(), 0) / buckets.length; } export function getAsset(name: string): Asset | null { - return assets.custom.get(name) ?? null; + return _k.assets.custom.get(name) ?? null; } // wrap individual loaders with global loader counter, for stuff like progress bar export function load(prom: Promise): Asset { - return assets.custom.add(null, prom); + return _k.assets.custom.add(null, prom); } // create assets diff --git a/src/assets/bitmapFont.ts b/src/assets/bitmapFont.ts index 5892fde5..00a37d8b 100644 --- a/src/assets/bitmapFont.ts +++ b/src/assets/bitmapFont.ts @@ -1,6 +1,6 @@ import { ASCII_CHARS } from "../constants"; import { Texture } from "../gfx"; -import { assets, gfx } from "../kaplay"; +import { _k } from "../kaplay"; import type { Quad } from "../math/math"; import type { TexFilter } from "../types"; import { type Asset, loadImg } from "./asset"; @@ -16,7 +16,7 @@ export interface GfxFont { export type BitmapFontData = GfxFont; export function getBitmapFont(name: string): Asset | null { - return assets.bitmapFonts.get(name) ?? null; + return _k.assets.bitmapFonts.get(name) ?? null; } export interface LoadBitmapFontOpt { @@ -36,12 +36,12 @@ export function loadBitmapFont( ): Asset { const fontSrc = fixURL(src); - return assets.bitmapFonts.add( + return _k.assets.bitmapFonts.add( name, loadImg(fontSrc) .then((img) => { return makeFont( - Texture.fromImage(gfx.ggl, img, opt), + Texture.fromImage(_k.gfx.ggl, img, opt), gw, gh, opt.chars ?? ASCII_CHARS, diff --git a/src/assets/font.ts b/src/assets/font.ts index 630dcdff..a8311356 100644 --- a/src/assets/font.ts +++ b/src/assets/font.ts @@ -6,7 +6,7 @@ import { } from "../constants"; import type { Texture } from "../gfx"; import type { DrawTextOpt } from "../gfx/draw/drawText"; -import { assets, globalOpt } from "../kaplay"; +import { _k } from "../kaplay"; import { rgb } from "../math/color"; import { Quad } from "../math/math"; import type { LoadFontOpt, Outline, TexFilter } from "../types"; @@ -58,7 +58,7 @@ export function resolveFont( | void { if (!src) { - return resolveFont(globalOpt.font ?? DEF_FONT); + return resolveFont(_k.globalOpt.font ?? DEF_FONT); } if (typeof src === "string") { const bfont = getBitmapFont(src); @@ -89,7 +89,7 @@ export function resolveFont( } export function getFont(name: string): Asset | null { - return assets.fonts.get(name) ?? null; + return _k.assets.fonts.get(name) ?? null; } // TODO: pass in null src to store opt for default fonts like "monospace" @@ -105,7 +105,7 @@ export function loadFont( ); document.fonts.add(font); - return assets.fonts.add( + return _k.assets.fonts.add( name, font.load().catch((err) => { throw new Error(`Failed to load font from "${fontSrc}": ${err}`); diff --git a/src/assets/pedit.ts b/src/assets/pedit.ts index d0b653b7..c5b029e1 100644 --- a/src/assets/pedit.ts +++ b/src/assets/pedit.ts @@ -1,4 +1,4 @@ -import { assets } from "../kaplay"; +import { _k } from "../kaplay"; import { type Asset, fetchJSON, loadImg } from "./asset"; import { loadSprite, type SpriteAnims, type SpriteData } from "./sprite"; import { fixURL } from "./utils"; @@ -16,7 +16,7 @@ export function loadPedit( ): Asset { src = fixURL(src); - return assets.sprites.add( + return _k.assets.sprites.add( name, new Promise(async (resolve) => { const data = typeof src === "string" diff --git a/src/assets/shader.ts b/src/assets/shader.ts index a9dc8f11..786b48ec 100644 --- a/src/assets/shader.ts +++ b/src/assets/shader.ts @@ -6,7 +6,7 @@ import { VERTEX_FORMAT, } from "../constants"; import { type GfxCtx } from "../gfx"; -import { assets, gfx } from "../kaplay"; +import { _k } from "../kaplay"; import { Color } from "../math/color"; import { Mat4, Vec2 } from "../math/math"; import type { RenderProps } from "../types"; @@ -170,7 +170,7 @@ export function resolveShader( src: RenderProps["shader"], ): ShaderData | Asset | null { if (!src) { - return gfx.defShader; + return _k.gfx.defShader; } if (typeof src === "string") { const shader = getShader(src); @@ -192,7 +192,7 @@ export function resolveShader( } export function getShader(name: string): Asset | null { - return assets.shaders.get(name) ?? null; + return _k.assets.shaders.get(name) ?? null; } export function loadShader( @@ -200,7 +200,7 @@ export function loadShader( vert?: string, frag?: string, ) { - return assets.shaders.addLoaded(name, makeShader(gfx.ggl, vert, frag)); + return _k.assets.shaders.addLoaded(name, makeShader(_k.gfx.ggl, vert, frag)); } export function loadShaderURL( @@ -216,7 +216,7 @@ export function loadShaderURL( : Promise.resolve(null); const load = Promise.all([resolveUrl(vert), resolveUrl(frag)]) .then(([vcode, fcode]: [string | null, string | null]) => { - return makeShader(gfx.ggl, vcode, fcode); + return makeShader(_k.gfx.ggl, vcode, fcode); }); - return assets.shaders.add(name, load); + return _k.assets.shaders.add(name, load); } diff --git a/src/assets/sound.ts b/src/assets/sound.ts index 98bc90ed..519910f5 100644 --- a/src/assets/sound.ts +++ b/src/assets/sound.ts @@ -1,4 +1,4 @@ -import { assets, audio } from "../kaplay"; +import { _k } from "../kaplay"; import { dataURLToArrayBuffer, isDataURL } from "../utils"; import { Asset, fetchArrayBuffer, loadProgress } from "./asset"; import { fixURL } from "./utils"; @@ -12,7 +12,7 @@ export class SoundData { static fromArrayBuffer(buf: ArrayBuffer): Promise { return new Promise((resolve, reject) => - audio.ctx.decodeAudioData(buf, resolve, reject) + _k.audio.ctx.decodeAudioData(buf, resolve, reject) ).then((buf) => new SoundData(buf as AudioBuffer)); } @@ -55,7 +55,7 @@ export function resolveSound( } export function getSound(name: string): Asset | null { - return assets.sounds.get(name) ?? null; + return _k.assets.sounds.get(name) ?? null; } // load a sound to asset manager @@ -64,7 +64,7 @@ export function loadSound( src: string | ArrayBuffer, ): Asset { src = fixURL(src); - return assets.sounds.add( + return _k.assets.sounds.add( name, typeof src === "string" ? SoundData.fromURL(src) @@ -80,5 +80,5 @@ export function loadMusic( const a = new Audio(musicUrl); a.preload = "auto"; - return assets.music[name as keyof typeof assets.music] = musicUrl; + return _k.assets.music[name as string] = musicUrl; } diff --git a/src/assets/sprite.ts b/src/assets/sprite.ts index d69f8bd6..036807fc 100644 --- a/src/assets/sprite.ts +++ b/src/assets/sprite.ts @@ -1,7 +1,7 @@ import { Asset, loadImg, loadProgress } from "../assets"; import type { DrawSpriteOpt } from "../gfx"; import type { Texture } from "../gfx/gfx"; -import { assets } from "../kaplay"; +import { _k } from "../kaplay"; import beanSpriteSrc from "../kassets/bean.png"; import { Quad } from "../math/math"; import { type ImageSource } from "../types"; @@ -132,7 +132,7 @@ export class SpriteData { data: ImageSource, opt: LoadSpriteOpt = {}, ): SpriteData { - const [tex, quad] = assets.packer.add(data); + const [tex, quad] = _k.assets.packer.add(data); const frames = opt.frames ? opt.frames.map((f) => new Quad( @@ -191,7 +191,7 @@ export function resolveSprite( } export function getSprite(name: string): Asset | null { - return assets.sprites.get(name) ?? null; + return _k.assets.sprites.get(name) ?? null; } // load a sprite to asset manager @@ -207,7 +207,7 @@ export function loadSprite( src = fixURL(src); if (Array.isArray(src)) { if (src.some((s) => typeof s === "string")) { - return assets.sprites.add( + return _k.assets.sprites.add( name, Promise.all(src.map((s) => { return typeof s === "string" @@ -217,7 +217,7 @@ export function loadSprite( ); } else { - return assets.sprites.addLoaded( + return _k.assets.sprites.addLoaded( name, createSpriteSheet(src as ImageSource[], opt), ); @@ -225,10 +225,10 @@ export function loadSprite( } else { if (typeof src === "string") { - return assets.sprites.add(name, SpriteData.from(src, opt)); + return _k.assets.sprites.add(name, SpriteData.from(src, opt)); } else { - return assets.sprites.addLoaded( + return _k.assets.sprites.addLoaded( name, SpriteData.fromImage(src, opt), ); diff --git a/src/assets/spriteAtlas.ts b/src/assets/spriteAtlas.ts index f06d32e7..a70fa3c6 100644 --- a/src/assets/spriteAtlas.ts +++ b/src/assets/spriteAtlas.ts @@ -1,5 +1,5 @@ import { SPRITE_ATLAS_HEIGHT, SPRITE_ATLAS_WIDTH } from "../constants"; -import { assets } from "../kaplay"; +import { _k } from "../kaplay"; import { Quad } from "../math"; import { type Asset, fetchJSON, load } from "./asset"; import { @@ -75,7 +75,7 @@ export function loadSpriteAtlas( info.height / h * quad.h, ); const spr = new SpriteData(atlas.tex, frames, info.anims); - assets.sprites.addLoaded(name, spr); + _k.assets.sprites.addLoaded(name, spr); map[name] = spr; } return map; diff --git a/src/assets/utils.ts b/src/assets/utils.ts index b2bc39f6..7ebf94c7 100644 --- a/src/assets/utils.ts +++ b/src/assets/utils.ts @@ -1,7 +1,7 @@ -import { assets } from "../kaplay"; +import { _k } from "../kaplay"; import { isDataURL } from "../utils"; export function fixURL(url: D): D { if (typeof url !== "string" || isDataURL(url)) return url; - return assets.urlPrefix + url as D; + return _k.assets.urlPrefix + url as D; } diff --git a/src/audio/burp.ts b/src/audio/burp.ts index e04fba7f..0f2b1154 100644 --- a/src/audio/burp.ts +++ b/src/audio/burp.ts @@ -1,7 +1,7 @@ -import { audio } from "../kaplay"; +import { _k } from "../kaplay"; import { type AudioPlay, type AudioPlayOpt, play } from "./play"; // core KAPLAY logic export function burp(opt?: AudioPlayOpt): AudioPlay { - return play(audio.burpSnd, opt); + return _k.k.play(_k.audio.burpSnd, opt); } diff --git a/src/audio/play.ts b/src/audio/play.ts index 71c628b0..7fa84124 100644 --- a/src/audio/play.ts +++ b/src/audio/play.ts @@ -1,5 +1,5 @@ import { Asset, resolveSound, type SoundData } from "../assets"; -import { assets, audio } from "../kaplay"; +import { _k } from "../kaplay"; import type { MusicData } from "../types"; import { KEvent, type KEventController } from "../utils"; import { playMusic } from "./playMusic"; @@ -133,11 +133,11 @@ export function play( | Asset, opt: AudioPlayOpt = {}, ): AudioPlay { - if (typeof src === "string" && assets.music[src]) { - return playMusic(assets.music[src], opt); + if (typeof src === "string" && _k.assets.music[src]) { + return playMusic(_k.assets.music[src], opt); } - const ctx = audio.ctx; + const ctx = _k.audio.ctx; let paused = opt.paused ?? false; let srcNode = ctx.createBufferSource(); const onEndEvents = new KEvent(); @@ -162,7 +162,7 @@ export function play( }; panNode.pan.value = opt.pan ?? 0; panNode.connect(gainNode); - gainNode.connect(audio.masterNode); + gainNode.connect(_k.audio.masterNode); gainNode.gain.value = opt.volume ?? 1; const start = (data: SoundData) => { diff --git a/src/audio/playMusic.ts b/src/audio/playMusic.ts index 30bde8b9..d1420c1e 100644 --- a/src/audio/playMusic.ts +++ b/src/audio/playMusic.ts @@ -1,4 +1,4 @@ -import { app, audio, debug, globalOpt } from "../kaplay"; +import { _k } from "../kaplay"; import { clamp } from "../math/math"; import { KEvent } from "../utils"; import type { AudioPlay, AudioPlayOpt } from "./play"; @@ -6,14 +6,14 @@ import type { AudioPlay, AudioPlayOpt } from "./play"; export function playMusic(url: string, opt: AudioPlayOpt = {}): AudioPlay { const onEndEvents = new KEvent(); const el = new Audio(url); - const src = audio.ctx.createMediaElementSource(el); + const src = _k.audio.ctx.createMediaElementSource(el); - src.connect(audio.masterNode); + src.connect(_k.audio.masterNode); function resumeAudioCtx() { - if (debug.paused) return; - if (app.isHidden() && !globalOpt.backgroundAudio) return; - audio.ctx.resume(); + if (_k.debug.paused) return; + if (_k.app.isHidden() && !_k.globalOpt.backgroundAudio) return; + _k.audio.ctx.resume(); } function play() { diff --git a/src/audio/volume.ts b/src/audio/volume.ts index 25d1ca55..f6644d68 100644 --- a/src/audio/volume.ts +++ b/src/audio/volume.ts @@ -1,9 +1,9 @@ -import { audio } from "../kaplay"; +import { _k } from "../kaplay"; // get / set master volume export function volume(v?: number): number { if (v !== undefined) { - audio.masterNode.gain.value = v; + _k.audio.masterNode.gain.value = v; } - return audio.masterNode.gain.value; + return _k.audio.masterNode.gain.value; } diff --git a/src/components/draw/opacity.ts b/src/components/draw/opacity.ts index 01096b55..f8c812f1 100644 --- a/src/components/draw/opacity.ts +++ b/src/components/draw/opacity.ts @@ -1,4 +1,4 @@ -import { game, k } from "../../kaplay"; +import { _k } from "../../kaplay"; import type { Comp, EaseFunc, TweenController } from "../../types"; import { toFixed } from "../../utils"; @@ -20,8 +20,8 @@ export function opacity(a: number): OpacityComp { return { id: "opacity", opacity: a ?? 1, - fadeIn(time = 1, easeFunc = k.easings.linear): TweenController { - return game.root.tween( + fadeIn(time = 1, easeFunc = _k.k.easings.linear): TweenController { + return _k.game.root.tween( 0, this.opacity, time, @@ -29,8 +29,8 @@ export function opacity(a: number): OpacityComp { easeFunc, ); }, - fadeOut(time = 1, easeFunc = k.easings.linear): TweenController { - return game.root.tween( + fadeOut(time = 1, easeFunc = _k.k.easings.linear): TweenController { + return _k.game.root.tween( this.opacity, 0, time, diff --git a/src/components/draw/raycast.ts b/src/components/draw/raycast.ts index 60de1a46..74d338ec 100644 --- a/src/components/draw/raycast.ts +++ b/src/components/draw/raycast.ts @@ -1,4 +1,4 @@ -import { game, k } from "../../kaplay"; +import { _k } from "../../kaplay"; import type { RaycastResult, Vec2 } from "../../math/math"; // this is not a component lol @@ -9,7 +9,7 @@ export function raycast( ) { let minHit: RaycastResult; - const shapes = game.root.get("area"); + const shapes = _k.game.root.get("area"); shapes.forEach(s => { if (exclude && exclude.some(tag => s.is(tag))) return; diff --git a/src/components/draw/text.ts b/src/components/draw/text.ts index a125a172..2a3067d8 100644 --- a/src/components/draw/text.ts +++ b/src/components/draw/text.ts @@ -10,7 +10,7 @@ import { formatText, type TextAlign, } from "../../gfx"; -import { k } from "../../kaplay"; +import { _k } from "../../kaplay"; import { Rect, vec2 } from "../../math/math"; import type { Comp, GameObj, KAPLAYCtx } from "../../types"; diff --git a/src/components/level/sentry.ts b/src/components/level/sentry.ts index 7639ee7e..77d1963b 100644 --- a/src/components/level/sentry.ts +++ b/src/components/level/sentry.ts @@ -1,5 +1,5 @@ import { dt } from "../../app"; -import { game, k } from "../../kaplay"; +import { _k } from "../../kaplay"; import { Vec2 } from "../../math/math"; import type { Comp, GameObj, QueryOpt } from "../../types"; import type { KEventController } from "../../utils/"; @@ -89,7 +89,7 @@ export function sentry( const get: SentryCandidatesCb = typeof candidates === "function" ? candidates : () => { - return game.root.query(candidates); + return _k.game.root.query(candidates); }; const checkFrequency = opts.checkFrequency || 1; const directionVector = typeof opts.direction === "number" diff --git a/src/components/misc/lifespan.ts b/src/components/misc/lifespan.ts index 0d2fe005..e3a43731 100644 --- a/src/components/misc/lifespan.ts +++ b/src/components/misc/lifespan.ts @@ -1,4 +1,4 @@ -import { game } from "../../kaplay"; +import { _k } from "../../kaplay"; import easings from "../../math/easings"; import type { EmptyComp, GameObj } from "../../types"; import type { OpacityComp } from "../draw/opacity"; @@ -24,10 +24,10 @@ export function lifespan(time: number, opt: LifespanCompOpt = {}): EmptyComp { id: "lifespan", require: ["opacity"], async add(this: GameObj) { - await game.root.wait(time); + await _k.game.root.wait(time); this.opacity = this.opacity ?? 1; if (fade > 0) { - await game.root.tween( + await _k.game.root.tween( this.opacity, 0, fade, diff --git a/src/components/misc/textInput.ts b/src/components/misc/textInput.ts index 863d9989..b211cbaa 100644 --- a/src/components/misc/textInput.ts +++ b/src/components/misc/textInput.ts @@ -1,4 +1,4 @@ -import { k } from "../../kaplay"; +import { _k } from "../../kaplay"; import type { Comp, GameObj, KAPLAYCtx } from "../../types"; import type { KEventController } from "../../utils"; import type { TextComp } from "../draw/text"; @@ -28,12 +28,12 @@ export function textInput( hasFocus: hasFocus, require: ["text"], add(this: GameObj) { - charEv = k.onCharInput((character) => { + charEv = _k.k.onCharInput((character) => { if ( this.hasFocus && (!maxInputLength || this.text.length < maxInputLength) ) { - if (k.isKeyDown("shift")) { + if (_k.k.isKeyDown("shift")) { this.text += character.toUpperCase(); } else { @@ -42,7 +42,7 @@ export function textInput( } }); - backEv = k.onKeyPressRepeat("backspace", () => { + backEv = _k.k.onKeyPressRepeat("backspace", () => { if (this.hasFocus) { this.text = this.text.slice(0, -1); } diff --git a/src/components/misc/timer.ts b/src/components/misc/timer.ts index 410194f2..2dfcaca0 100644 --- a/src/components/misc/timer.ts +++ b/src/components/misc/timer.ts @@ -1,4 +1,4 @@ -import { k } from "../../kaplay"; +import { _k } from "../../kaplay"; import easings from "../../math/easings"; import { lerp } from "../../math/math"; import type { @@ -53,7 +53,7 @@ export function timer(): TimerComp { if (action) actions.push(action); let t = 0; const ev = this.onUpdate(() => { - t += k.dt(); + t += _k.app.state.dt; if (t >= time) { actions.forEach((f) => f()); ev.cancel(); @@ -105,7 +105,7 @@ export function timer(): TimerComp { let curTime = 0; const onEndEvents: Array<() => void> = []; const ev = this.onUpdate(() => { - curTime += k.dt(); + curTime += _k.app.state.dt; const t = Math.min(curTime / duration, 1); setValue(lerp(from, to, easeFunc(t))); if (t === 1) { diff --git a/src/components/physics/area.ts b/src/components/physics/area.ts index 8330b4e9..ed66090c 100644 --- a/src/components/physics/area.ts +++ b/src/components/physics/area.ts @@ -1,9 +1,9 @@ import { DEF_ANCHOR } from "../../constants"; import { isFixed } from "../../game/utils"; -import { anchorPt, getViewportScale } from "../../gfx"; -import { app, game, k } from "../../kaplay"; +import { anchorPt, drawCircle, drawPolygon, drawRect, getViewportScale, popTransform, pushTransform, pushTranslate } from "../../gfx"; +import { _k } from "../../kaplay"; import { rgb } from "../../math/color"; -import { Polygon, testPolygonPoint, Vec2, vec2 } from "../../math/math"; +import { Circle, Polygon, Rect, testPolygonPoint, Vec2, vec2 } from "../../math/math"; import type { Collision, Comp, @@ -225,7 +225,7 @@ export function area(opt: AreaCompOpt = {}): AreaComp { add(this: GameObj) { areaCount++; if (this.area.cursor) { - this.onHover(() => app.setCursor(this.area.cursor!)); + this.onHover(() => _k.app.setCursor(this.area.cursor!)); } this.onCollideUpdate((obj, col) => { @@ -261,8 +261,8 @@ export function area(opt: AreaCompOpt = {}): AreaComp { drawInspect(this: GameObj) { const a = this.localArea(); - k.pushTransform(); - k.pushTranslate(this.area.offset); + pushTransform(); + pushTranslate(this.area.offset); const opts = { outline: { @@ -274,30 +274,30 @@ export function area(opt: AreaCompOpt = {}): AreaComp { fixed: isFixed(this), }; - if (a instanceof k.Rect) { - k.drawRect({ + if (a instanceof Rect) { + drawRect({ ...opts, pos: a.pos, width: a.width * this.area.scale.x, height: a.height * this.area.scale.y, }); } - else if (a instanceof k.Polygon) { - k.drawPolygon({ + else if (a instanceof Polygon) { + drawPolygon({ ...opts, pts: a.pts, scale: this.area.scale, }); } - else if (a instanceof k.Circle) { - k.drawCircle({ + else if (a instanceof Circle) { + drawCircle({ ...opts, pos: a.center, radius: a.radius, }); } - k.popTransform(); + popTransform(); }, area: { @@ -308,13 +308,13 @@ export function area(opt: AreaCompOpt = {}): AreaComp { }, isClicked(): boolean { - return app.isMousePressed() && this.isHovering(); + return _k.app.isMousePressed() && this.isHovering(); }, isHovering(this: GameObj) { const mpos = isFixed(this) - ? k.mousePos() - : k.toWorld(k.mousePos()); + ? _k.k.mousePos() + : _k.k.toWorld(_k.k.mousePos()); return this.hasPoint(mpos); }, @@ -356,7 +356,7 @@ export function area(opt: AreaCompOpt = {}): AreaComp { f: () => void, btn: MouseButton = "left", ): KEventController { - const e = app.onMousePress(btn, () => { + const e = _k.app.onMousePress(btn, () => { if (this.isHovering()) { f(); } @@ -497,7 +497,7 @@ export function area(opt: AreaCompOpt = {}): AreaComp { const localArea = this.localArea(); if ( - !(localArea instanceof k.Polygon || localArea instanceof k.Rect) + !(localArea instanceof Polygon || localArea instanceof Rect) ) { throw new Error( "Only support polygon and rect shapes for now", @@ -509,7 +509,7 @@ export function area(opt: AreaCompOpt = {}): AreaComp { .translate(this.area.offset) .scale(vec2(this.area.scale ?? 1)); - if (localArea instanceof k.Rect) { + if (localArea instanceof Rect) { const offset = anchorPt(this.anchor || DEF_ANCHOR) .add(1, 1) .scale(-0.5) @@ -526,7 +526,7 @@ export function area(opt: AreaCompOpt = {}): AreaComp { return area; } else { - return area.transform(game.cam.transform); + return area.transform(_k.game.cam.transform); } }, diff --git a/src/components/physics/body.ts b/src/components/physics/body.ts index 23fb90ef..886bdf3c 100644 --- a/src/components/physics/body.ts +++ b/src/components/physics/body.ts @@ -1,7 +1,8 @@ -import { fixedDt } from "../../app"; +import { dt, fixedDt, restDt } from "../../app"; import { DEF_JUMP_FORCE, MAX_VEL } from "../../constants"; -import { game, k } from "../../kaplay"; -import { type Vec2, vec2 } from "../../math/math"; +import { getGravityDirection } from "../../game"; +import { _k } from "../../kaplay"; +import { lerp, type Vec2, vec2 } from "../../math/math"; import { calcTransform } from "../../math/various"; import type { Collision, Comp, GameObj } from "../../types"; import type { KEventController } from "../../utils/"; @@ -259,11 +260,11 @@ export function body(opt: BodyCompOpt = {}): BodyComp { ); this.onPhysicsResolve((col) => { - if (game.gravity) { + if (_k.game.gravity) { if (col.isBottom() && this.isFalling()) { // Clear the velocity in the direction of gravity, as we've hit something this.vel = this.vel.reject( - game.gravity.unit(), + _k.game.gravity.unit(), ); // We need the past platform to check if we already were on a platform const pastPlatform = curPlatform; @@ -287,7 +288,7 @@ export function body(opt: BodyCompOpt = {}): BodyComp { } else if (col.isTop() && this.isJumping()) { this.vel = this.vel.reject( - game.gravity.unit(), + _k.game.gravity.unit(), ); this.trigger("headbutt", col.target); col.target.trigger("headbutted", this); @@ -321,25 +322,25 @@ export function body(opt: BodyCompOpt = {}): BodyComp { } } - const dt = k.restDt(); + const dt = restDt(); if (dt) { // Check if no external changes were made if (this.pos.x == prevDrawPos.x) { // Interpolate physics steps - this.pos.x = k.lerp( + this.pos.x = lerp( prevPhysicsPos!.x, nextPhysicsPos!.x, - dt / k.fixedDt(), + dt / fixedDt(), ); // Copy to check for changes prevDrawPos.x = this.pos.x; } if (this.pos.y == prevDrawPos.y) { // Interpolate physics steps - this.pos.y = k.lerp( + this.pos.y = lerp( prevPhysicsPos!.y, nextPhysicsPos!.y, - dt / k.fixedDt(), + dt / fixedDt(), ); // Copy to check for changes prevDrawPos.y = this.pos.y; @@ -359,7 +360,7 @@ export function body(opt: BodyCompOpt = {}): BodyComp { prevPhysicsPos = null; } - if (game.gravity && !this.isStatic) { + if (_k.game.gravity && !this.isStatic) { // If we are falling over the edge of the current a platform if (willFall) { curPlatform = null; @@ -384,7 +385,7 @@ export function body(opt: BodyCompOpt = {}): BodyComp { // Apply gravity this.vel = this.vel.add( - game.gravity.scale(this.gravityScale * k.dt()), + _k.game.gravity.scale(this.gravityScale * dt()), ); // Clamp velocity @@ -396,30 +397,30 @@ export function body(opt: BodyCompOpt = {}): BodyComp { // Check if we have started to fall. // We do this by looking at the velocity vector along the direction of gravity if ( - prevVel.dot(game.gravity) < 0 - && this.vel.dot(game.gravity) >= 0 + prevVel.dot(_k.game.gravity) < 0 + && this.vel.dot(_k.game.gravity) >= 0 ) { this.trigger("fall"); } } // Apply velocity and position changes - this.vel.x += acc.x * k.dt(); - this.vel.y += acc.y * k.dt(); + this.vel.x += acc.x * dt(); + this.vel.y += acc.y * dt(); - this.vel.x *= 1 - this.drag * k.dt(); - this.vel.y *= 1 - this.drag * k.dt(); + this.vel.x *= 1 - this.drag * dt(); + this.vel.y *= 1 - this.drag * dt(); this.move(this.vel); // If we need to interpolate physics, prepare interpolation data - const dt = k.restDt(); - if (dt) { + const rDt = restDt(); + if (rDt) { // Save this position as previous prevPhysicsPos = this.pos.clone(); // Calculate next (future) position - const nextVel = this.vel.add(acc.scale(k.dt())); - nextPhysicsPos = this.pos.add(nextVel.scale(k.dt())); + const nextVel = this.vel.add(acc.scale(dt())); + nextPhysicsPos = this.pos.add(nextVel.scale(dt())); // Copy to check for changes prevDrawPos = this.pos.clone(); } @@ -446,11 +447,11 @@ export function body(opt: BodyCompOpt = {}): BodyComp { }, isFalling(): boolean { - return this.vel.dot(k.getGravityDirection()) > 0; + return this.vel.dot(getGravityDirection()) > 0; }, isJumping(): boolean { - return this.vel.dot(k.getGravityDirection()) < 0; + return this.vel.dot(getGravityDirection()) < 0; }, applyImpulse(impulse: Vec2) { @@ -465,7 +466,7 @@ export function body(opt: BodyCompOpt = {}): BodyComp { jump(force: number) { curPlatform = null; lastPlatformPos = null; - this.vel = k.getGravityDirection().scale( + this.vel = getGravityDirection().scale( -force || -this.jumpForce, ); }, diff --git a/src/components/transform/layer.ts b/src/components/transform/layer.ts index cfa18640..52aec883 100644 --- a/src/components/transform/layer.ts +++ b/src/components/transform/layer.ts @@ -1,4 +1,4 @@ -import { game } from "../../kaplay"; +import { _k } from "../../kaplay"; import type { Comp } from "../../types"; /** @@ -26,7 +26,7 @@ export interface LayerComp extends Comp { } export function layer(layer: string): LayerComp { - let _layerIndex = game.layers?.indexOf(layer); + let _layerIndex = _k.game.layers?.indexOf(layer); return { id: "layer", @@ -36,10 +36,10 @@ export function layer(layer: string): LayerComp { get layer(): string | null { if (!_layerIndex) return null; - return game.layers?.[_layerIndex] ?? null; + return _k.game.layers?.[_layerIndex] ?? null; }, set layer(value: string) { - _layerIndex = game.layers?.indexOf(value); + _layerIndex = _k.game.layers?.indexOf(value); if (_layerIndex == -1) throw Error("Invalid layer name"); }, diff --git a/src/components/transform/offscreen.ts b/src/components/transform/offscreen.ts index 0874186a..d05132dd 100644 --- a/src/components/transform/offscreen.ts +++ b/src/components/transform/offscreen.ts @@ -1,6 +1,7 @@ import { DEF_OFFSCREEN_DIS } from "../../constants"; -import { k } from "../../kaplay"; -import { Rect, vec2 } from "../../math/math"; +import { height, width } from "../../gfx"; +import { _k } from "../../kaplay"; +import { Rect, testRectPoint, vec2 } from "../../math/math"; import type { Comp, GameObj } from "../../types"; import type { KEventController } from "../../utils/"; import type { PosComp } from "./pos"; @@ -64,8 +65,8 @@ export function offscreen(opt: OffScreenCompOpt = {}): OffScreenComp { // This is not possible, screenPos() without arguments returns the pos if (!pos) return false; - const screenRect = new Rect(vec2(0), k.width(), k.height()); - return !k.testRectPoint(screenRect, pos) + const screenRect = new Rect(vec2(0), width(), height()); + return !testRectPoint(screenRect, pos) && screenRect.sdistToPoint(pos) > distance * distance; }, onExitScreen(this: GameObj, action: () => void): KEventController { diff --git a/src/components/transform/pos.ts b/src/components/transform/pos.ts index f9c9766a..4a1ae499 100644 --- a/src/components/transform/pos.ts +++ b/src/components/transform/pos.ts @@ -1,6 +1,8 @@ +import { dt } from "../../app"; +import { toScreen, toWorld } from "../../game"; import { isFixed } from "../../game/utils"; -import { getViewportScale } from "../../gfx"; -import { k } from "../../kaplay"; +import { drawCircle, getViewportScale } from "../../gfx"; +import { rgb } from "../../math"; import { Vec2, vec2, type Vec2Args } from "../../math/math"; import type { Comp, GameObj } from "../../types"; import type { FixedComp } from "./fixed"; @@ -80,7 +82,7 @@ export function pos(...args: Vec2Args): PosComp { // move with velocity (pixels per second) move(...args: Vec2Args) { - this.moveBy(vec2(...args).scale(k.dt())); + this.moveBy(vec2(...args).scale(dt())); }, // move to a destination, with optional speed @@ -100,7 +102,7 @@ export function pos(...args: Vec2Args): PosComp { } // @ts-ignore const diff = dest.sub(this.pos); - if (diff.len() <= speed * k.dt()) { + if (diff.len() <= speed * dt()) { this.pos = vec2(dest); return; } @@ -158,7 +160,7 @@ export function pos(...args: Vec2Args): PosComp { return isFixed(this) ? pos - : k.toScreen(pos); + : toScreen(pos); } }, @@ -167,14 +169,14 @@ export function pos(...args: Vec2Args): PosComp { const pos = this.toWorld(p); return isFixed(this) ? pos - : k.toScreen(pos); + : toScreen(pos); }, // Transform a screen point (relative to the camera) to a local point (relative to this) fromScreen(this: GameObj, p: Vec2): Vec2 { return isFixed(this) ? this.fromWorld(p) - : this.fromWorld(k.toWorld(p)); + : this.fromWorld(toWorld(p)); }, // Transform a point relative to this to a point relative to other @@ -194,8 +196,8 @@ export function pos(...args: Vec2Args): PosComp { }, drawInspect() { - k.drawCircle({ - color: k.rgb(255, 0, 0), + drawCircle({ + color: rgb(255, 0, 0), radius: 4 / getViewportScale(), }); }, diff --git a/src/game/camera.ts b/src/game/camera.ts index 2e8d2be7..da5f5b5b 100644 --- a/src/game/camera.ts +++ b/src/game/camera.ts @@ -1,36 +1,36 @@ import { color, fixed, opacity, rect } from "../components"; import { center, height, width } from "../gfx"; -import { game } from "../kaplay"; +import { _k } from "../kaplay"; import { type Color, rgb } from "../math/color"; import { type Mat4, type Vec2, vec2, type Vec2Args } from "../math/math"; import { destroy } from "."; export function camPos(...pos: Vec2Args): Vec2 { if (pos.length > 0) { - game.cam.pos = vec2(...pos); + _k.game.cam.pos = vec2(...pos); } - return game.cam.pos ? game.cam.pos.clone() : center(); + return _k.game.cam.pos ? _k.game.cam.pos.clone() : center(); } export function camScale(...scale: Vec2Args): Vec2 { if (scale.length > 0) { - game.cam.scale = vec2(...scale); + _k.game.cam.scale = vec2(...scale); } - return game.cam.scale.clone(); + return _k.game.cam.scale.clone(); } export function camRot(angle: number): number { if (angle !== undefined) { - game.cam.angle = angle; + _k.game.cam.angle = angle; } - return game.cam.angle; + return _k.game.cam.angle; } export function camFlash( flashColor: Color = rgb(255, 255, 255), fadeOutTime: number = 1, ) { - let flash = game.root.add([ + let flash = _k.game.root.add([ rect(width(), height()), color(flashColor), opacity(1), @@ -42,17 +42,17 @@ export function camFlash( } export function camTransform(): Mat4 { - return game.cam.transform.clone(); + return _k.game.cam.transform.clone(); } export function shake(intensity: number = 12) { - game.cam.shake += intensity; + _k.game.cam.shake += intensity; } export function toScreen(p: Vec2): Vec2 { - return game.cam.transform.multVec2(p); + return _k.game.cam.transform.multVec2(p); } export function toWorld(p: Vec2): Vec2 { - return game.cam.transform.invert().multVec2(p); + return _k.game.cam.transform.invert().multVec2(p); } diff --git a/src/game/events/events.ts b/src/game/events/events.ts index 22c8f092..8b28b5b7 100644 --- a/src/game/events/events.ts +++ b/src/game/events/events.ts @@ -1,6 +1,6 @@ // add an event to a tag -import { app, assets, game } from "../../kaplay"; +import { _k } from "../../kaplay"; import type { Collision, GameObj, Tag } from "../../types"; import { KEventController, overload2, Registry } from "../../utils"; import type { GameObjEventMap, GameObjEventNames } from "./eventMap"; @@ -14,12 +14,12 @@ export function on( tag: Tag, cb: (obj: GameObj, ...args: TupleWithoutFirst) => void, ): KEventController { - if (!game.objEvents.registers[ event]) { - game.objEvents.registers[ event] = + if (!_k.game.objEvents.registers[ event]) { + _k.game.objEvents.registers[ event] = new Registry() as any; } - return game.objEvents.on( event, (obj, ...args) => { + return _k.game.objEvents.on( event, (obj, ...args) => { if (obj.is(tag)) { cb(obj, ...args as TupleWithoutFirst); } @@ -28,7 +28,7 @@ export function on( export const onFixedUpdate = overload2( (action: () => void): KEventController => { - const obj = game.root.add([{ fixedUpdate: action }]); + const obj = _k.game.root.add([{ fixedUpdate: action }]); return { get paused() { return obj.paused; @@ -45,7 +45,7 @@ export const onFixedUpdate = overload2( ); export const onUpdate = overload2((action: () => void): KEventController => { - const obj = game.root.add([{ update: action }]); + const obj = _k.game.root.add([{ update: action }]); return { get paused() { return obj.paused; @@ -60,7 +60,7 @@ export const onUpdate = overload2((action: () => void): KEventController => { }); export const onDraw = overload2((action: () => void): KEventController => { - const obj = game.root.add([{ draw: action }]); + const obj = _k.game.root.add([{ draw: action }]); return { get paused() { return obj.hidden; @@ -75,13 +75,13 @@ export const onDraw = overload2((action: () => void): KEventController => { }); export const onAdd = overload2((action: (obj: GameObj) => void) => { - return game.events.on("add", action); + return _k.game.events.on("add", action); }, (tag: Tag, action: (obj: GameObj) => void) => { return on("add", tag, action); }); export const onDestroy = overload2((action: (obj: GameObj) => void) => { - return game.events.on("destroy", action); + return _k.game.events.on("destroy", action); }, (tag: Tag, action: (obj: GameObj) => void) => { return on("destroy", tag, action); }); @@ -112,12 +112,12 @@ export function onCollideEnd( } export function forAllCurrentAndFuture(t: Tag, action: (obj: GameObj) => void) { - game.root.get(t, { recursive: true }).forEach(action); + _k.game.root.get(t, { recursive: true }).forEach(action); onAdd(t, action); } export const onClick = overload2((action: () => void) => { - return app.onMousePress(action); + return _k.app.onMousePress(action); }, (tag: Tag, action: (obj: GameObj) => void) => { const events: KEventController[] = []; @@ -187,22 +187,22 @@ export function onHoverEnd( } export function onLoading(action: (progress: number) => void) { - game.events.on("loading", action); + _k.game.events.on("loading", action); } export function onResize(action: () => void) { - app.onResize(action); + _k.app.onResize(action); } export function onError(action: (err: Error) => void) { - game.events.on("error", action); + _k.game.events.on("error", action); } export function onLoad(cb: () => void): void { - if (assets.loaded) { + if (_k.assets.loaded) { cb(); } else { - game.events.on("load", cb); + _k.game.events.on("load", cb); } } diff --git a/src/game/gravity.ts b/src/game/gravity.ts index cfaa5e8f..54fd0c4a 100644 --- a/src/game/gravity.ts +++ b/src/game/gravity.ts @@ -1,24 +1,24 @@ -import { game } from "../kaplay"; +import { _k } from "../kaplay"; import { type Vec2, vec2 } from "../math"; export function setGravity(g: number) { // If g > 0 use either the current direction or use (0, 1) // Else null - game.gravity = g ? (game.gravity || vec2(0, 1)).unit().scale(g) : null; + _k.game.gravity = g ? (_k.game.gravity || vec2(0, 1)).unit().scale(g) : null; } export function getGravity() { // If gravity > 0 return magnitude // Else 0 - return game.gravity ? game.gravity.len() : 0; + return _k.game.gravity ? _k.game.gravity.len() : 0; } export function setGravityDirection(d: Vec2) { // If gravity > 0 keep magnitude, otherwise use 1 - game.gravity = d.unit().scale(game.gravity ? game.gravity.len() : 1); + _k.game.gravity = d.unit().scale(_k.game.gravity ? _k.game.gravity.len() : 1); } export function getGravityDirection() { // If gravity != null return unit vector, otherwise return (0, 1) - return game.gravity ? game.gravity.unit() : vec2(0, 1); + return _k.game.gravity ? _k.game.gravity.unit() : vec2(0, 1); } diff --git a/src/game/initEvents.ts b/src/game/initEvents.ts index cd334e4d..b3fb1325 100644 --- a/src/game/initEvents.ts +++ b/src/game/initEvents.ts @@ -1,77 +1,69 @@ import { burp } from "../audio"; import { FrameBuffer, updateViewport } from "../gfx"; -import { - app, - audio, - canvas, - debug, - gfx, - globalOpt, - gscale, - pixelDensity, +import {_k } from "../kaplay"; import { clamp } from "../math/math"; import { toFixed } from "../utils"; export function initEvents() { - app.onHide(() => { - if (!globalOpt.backgroundAudio) { - audio.ctx.suspend(); + _k.app.onHide(() => { + if (!_k.globalOpt.backgroundAudio) { + _k.audio.ctx.suspend(); } }); - app.onShow(() => { - if (!globalOpt.backgroundAudio && !debug.paused) { - audio.ctx.resume(); + _k.app.onShow(() => { + if (!_k.globalOpt.backgroundAudio && !_k.debug.paused) { + _k.audio.ctx.resume(); } }); - app.onResize(() => { - if (app.isFullscreen()) return; - const fixedSize = globalOpt.width && globalOpt.height; - if (fixedSize && !globalOpt.stretch && !globalOpt.letterbox) return; + _k.app.onResize(() => { + if (_k.app.isFullscreen()) return; + const fixedSize = _k.globalOpt.width && _k.globalOpt.height; + if (fixedSize && !_k.globalOpt.stretch && !_k.globalOpt.letterbox) return; - canvas.width = canvas.offsetWidth * pixelDensity; - canvas.height = canvas.offsetHeight * pixelDensity; + _k.canvas.width = _k.canvas.offsetWidth * _k.pixelDensity; + _k.canvas.height = _k.canvas.offsetHeight * _k.pixelDensity; updateViewport(); if (!fixedSize) { - gfx.frameBuffer.free(); - gfx.frameBuffer = new FrameBuffer( - gfx.ggl, - gfx.ggl.gl.drawingBufferWidth, - gfx.ggl.gl.drawingBufferHeight, + _k.gfx.frameBuffer.free(); + _k.gfx.frameBuffer = new FrameBuffer( + _k.gfx.ggl, + _k.gfx.ggl.gl.drawingBufferWidth, + _k.gfx.ggl.gl.drawingBufferHeight, ); - gfx.width = gfx.ggl.gl.drawingBufferWidth / pixelDensity / gscale; - gfx.height = gfx.ggl.gl.drawingBufferHeight / pixelDensity / gscale; + _k.gfx.width = _k.gfx.ggl.gl.drawingBufferWidth / _k.pixelDensity / _k.gscale; + _k.gfx.height = _k.gfx.ggl.gl.drawingBufferHeight / _k.pixelDensity / _k.gscale; } }); - if (globalOpt.debug !== false) { - app.onKeyPress( - globalOpt.debugKey ?? "f1", - () => debug.inspect = !debug.inspect, + if (_k.globalOpt.debug !== false) { + _k.app.onKeyPress( + _k.globalOpt.debugKey ?? "f1", + () => _k.debug.inspect = !_k.debug.inspect, ); - app.onKeyPress("f2", () => debug.clearLog()); - app.onKeyPress("f8", () => debug.paused = !debug.paused); - app.onKeyPress("f7", () => { - debug.timeScale = toFixed( - clamp(debug.timeScale - 0.2, 0, 2), + _k.app.onKeyPress("f2", () => _k.debug.clearLog()); + _k.app.onKeyPress("f8", () => _k.debug.paused = !_k.debug.paused); + _k.app.onKeyPress("f7", () => { + _k.debug.timeScale = toFixed( + clamp(_k.debug.timeScale - 0.2, 0, 2), 1, ); }); - app.onKeyPress("f9", () => { - debug.timeScale = toFixed( - clamp(debug.timeScale + 0.2, 0, 2), + _k.app.onKeyPress("f9", () => { + _k.debug.timeScale = toFixed( + clamp(_k.debug.timeScale + 0.2, 0, 2), 1, ); }); - app.onKeyPress("f10", () => debug.stepFrame()); + _k.app.onKeyPress("f10", () => _k.debug.stepFrame()); } // burp mode initialization - if (globalOpt.burp) { - app.onKeyPress("b", () => burp()); + if (_k.globalOpt.burp) { + _k.app.onKeyPress("b", () => burp()); } } diff --git a/src/game/kaboom.ts b/src/game/kaboom.ts index 6f20c9ea..32fd0a6c 100644 --- a/src/game/kaboom.ts +++ b/src/game/kaboom.ts @@ -1,5 +1,5 @@ import { anchor, boom, pos, scale, sprite, stay, timer } from "../components"; -import { boomSprite, game, kaSprite } from "../kaplay"; +import { _k } from "../kaplay"; import type { Vec2 } from "../math"; import type { CompList, GameObj } from "../types"; @@ -24,7 +24,7 @@ export interface BoomOpt { } export function addKaboom(p: Vec2, opt: BoomOpt = {}): GameObj { - const kaboom = game.root.add([ + const kaboom = _k.game.root.add([ pos(p), stay(), ]); @@ -33,7 +33,7 @@ export function addKaboom(p: Vec2, opt: BoomOpt = {}): GameObj { const s = opt.scale || 1; kaboom.add([ - sprite(boomSprite), + sprite(_k.boomSprite), scale(0), anchor("center"), boom(speed, s), @@ -41,7 +41,7 @@ export function addKaboom(p: Vec2, opt: BoomOpt = {}): GameObj { ]); const ka = kaboom.add([ - sprite(kaSprite), + sprite(_k.kaSprite), scale(0), anchor("center"), timer(), diff --git a/src/game/layers.ts b/src/game/layers.ts index 3ca875c9..279a83f0 100644 --- a/src/game/layers.ts +++ b/src/game/layers.ts @@ -1,7 +1,7 @@ -import { game } from "../kaplay"; +import { _k } from "../kaplay"; export const layers = function(layerNames: string[], defaultLayer: string) { - if (game.layers) { + if (_k.game.layers) { throw Error("Layers can only be assigned once."); } const defaultLayerIndex = layerNames.indexOf(defaultLayer); @@ -10,6 +10,6 @@ export const layers = function(layerNames: string[], defaultLayer: string) { "The default layer name should be present in the layers list.", ); } - game.layers = layerNames; - game.defaultLayerIndex = defaultLayerIndex; + _k.game.layers = layerNames; + _k.game.defaultLayerIndex = defaultLayerIndex; }; diff --git a/src/game/level.ts b/src/game/level.ts index f6ee913c..10f14e76 100644 --- a/src/game/level.ts +++ b/src/game/level.ts @@ -1,5 +1,5 @@ import { pos, type PosComp, tile } from "../components"; -import { game } from "../kaplay"; +import { _k } from "../kaplay"; import { raycastGrid, type RaycastResult, @@ -67,7 +67,7 @@ export function addLevel( } // TODO: custom parent - const level = game.root.add([ + const level = _k.game.root.add([ pos(opt.pos ?? vec2(0)), ]) as GameObj; diff --git a/src/game/make.ts b/src/game/make.ts index d88e39a9..99633f1c 100644 --- a/src/game/make.ts +++ b/src/game/make.ts @@ -15,7 +15,7 @@ import { pushTransform, pushTranslate, } from "../gfx"; -import { app, game, gfx, k } from "../kaplay"; +import { _k } from "../kaplay"; import { Mat4 } from "../math/math"; import { calcTransform } from "../math/various"; import { @@ -81,7 +81,7 @@ export function make(comps: CompList = []): GameObj { this.children.push(obj); // TODO: trigger add for children obj.trigger("add", obj); - game.events.trigger("add", obj); + _k.game.events.trigger("add", obj); return obj; }, @@ -103,7 +103,7 @@ export function make(comps: CompList = []): GameObj { const trigger = (o: GameObj) => { o.trigger("destroy"); - game.events.trigger("destroy", o); + _k.game.events.trigger("destroy", o); o.children.forEach((child) => trigger(child)); }; @@ -147,22 +147,22 @@ export function make(comps: CompList = []): GameObj { flush(); this.canvas.bind(); } - const f = gfx.fixed; - if (this.fixed) gfx.fixed = true; + const f = _k.gfx.fixed; + if (this.fixed) _k.gfx.fixed = true; pushTransform(); pushTranslate(this.pos); pushScale(this.scale); pushRotate(this.angle); const children = this.children.sort((o1, o2) => { - const l1 = o1.layerIndex ?? game.defaultLayerIndex; - const l2 = o2.layerIndex ?? game.defaultLayerIndex; + const l1 = o1.layerIndex ?? _k.game.defaultLayerIndex; + const l2 = o2.layerIndex ?? _k.game.defaultLayerIndex; return (l1 - l2) || (o1.z ?? 0) - (o2.z ?? 0); }); // TODO: automatically don't draw if offscreen if (this.mask) { const maskFunc = { - intersect: k.drawMasked, - subtract: k.drawSubtracted, + intersect: _k.k.drawMasked, + subtract: _k.k.drawSubtracted, }[this.mask]; if (!maskFunc) { throw new Error(`Invalid mask func: "${this.mask}"`); @@ -178,7 +178,7 @@ export function make(comps: CompList = []): GameObj { children.forEach((child) => child.draw()); } popTransform(); - gfx.fixed = f; + _k.gfx.fixed = f; if (this.canvas) { flush(); this.canvas.unbind(); @@ -357,12 +357,12 @@ export function make(comps: CompList = []): GameObj { // TODO: handle when object add / remove tags // TODO: clean up when obj destroyed - events.push(k.onAdd((obj) => { + events.push(_k.k.onAdd((obj) => { if (isChild(obj) && obj.is(t)) { list.push(obj); } })); - events.push(k.onDestroy((obj) => { + events.push(_k.k.onDestroy((obj) => { if (isChild(obj) && obj.is(t)) { const idx = list.findIndex((o) => o.id === obj.id); if (idx !== -1) { @@ -477,7 +477,7 @@ export function make(comps: CompList = []): GameObj { }, exists(this: GameObj): boolean { - return game.root.isAncestorOf(this); + return _k.game.root.isAncestorOf(this); }, is(tag: Tag | Tag[]): boolean { @@ -510,7 +510,7 @@ export function make(comps: CompList = []): GameObj { trigger(name: string, ...args: unknown[]): void { events.trigger(name, ...args); - game.objEvents.trigger(name, this, ...args); + _k.game.objEvents.trigger(name, this, ...args); }, destroy() { @@ -596,7 +596,7 @@ export function make(comps: CompList = []): GameObj { for (const e of evs) { obj[e] = (...args: [any]) => { - const ev = app[e]?.(...args); + const ev = _k.app[e]?.(...args); inputEvents.push(ev); obj.onDestroy(() => ev.cancel()); @@ -605,7 +605,7 @@ export function make(comps: CompList = []): GameObj { // not neccesary -> ev.cancel(); inputEvents.splice(inputEvents.indexOf(ev), 1); // create a new event with the same arguments - const newEv = app[e]?.(...args); + const newEv = _k.app[e]?.(...args); // Replace the old event handler with the new one // old KEventController.cancel() => new KEventController.cancel() diff --git a/src/game/object.ts b/src/game/object.ts index 8bbfc692..fad16ed5 100644 --- a/src/game/object.ts +++ b/src/game/object.ts @@ -1,4 +1,4 @@ -import { game } from "../kaplay"; +import { _k } from "../kaplay"; import type { GameObj } from "../types"; export function destroy(obj: GameObj) { @@ -6,5 +6,5 @@ export function destroy(obj: GameObj) { } export function getTreeRoot(): GameObj { - return game.root; + return _k.game.root; } diff --git a/src/game/scenes.ts b/src/game/scenes.ts index 70768607..7bc2326a 100644 --- a/src/game/scenes.ts +++ b/src/game/scenes.ts @@ -1,4 +1,4 @@ -import { app, game } from "../kaplay"; +import { _k } from "../kaplay"; import { Mat4, vec2 } from "../math/math"; import type { KEventController } from "../utils"; import { initEvents } from "./initEvents"; @@ -10,37 +10,37 @@ export type SceneName = string; export type SceneDef = (...args: any) => void; export function scene(id: SceneName, def: SceneDef) { - game.scenes[id] = def; + _k.game.scenes[id] = def; } export function go(name: SceneName, ...args: unknown[]) { - if (!game.scenes[name]) { + if (!_k.game.scenes[name]) { throw new Error(`Scene not found: ${name}`); } - game.events.onOnce("frameEnd", () => { - game.events.trigger("sceneLeave", name); - app.events.clear(); - game.events.clear(); - game.objEvents.clear(); + _k.game.events.onOnce("frameEnd", () => { + _k.game.events.trigger("sceneLeave", name); + _k.app.events.clear(); + _k.game.events.clear(); + _k.game.objEvents.clear(); - [...game.root.children].forEach((obj) => { + [..._k.game.root.children].forEach((obj) => { if ( !obj.stay || (obj.scenesToStay && !obj.scenesToStay.includes(name)) ) { - game.root.remove(obj); + _k.game.root.remove(obj); } else { obj.trigger("sceneEnter", name); } }); - game.root.clearEvents(); + _k.game.root.clearEvents(); initEvents(); // cam - game.cam = { + _k.game.cam = { pos: null, scale: vec2(1), angle: 0, @@ -48,18 +48,18 @@ export function go(name: SceneName, ...args: unknown[]) { transform: new Mat4(), }; - game.scenes[name](...args); + _k.game.scenes[name](...args); }); - game.currentScene = name; + _k.game.currentScene = name; } export function onSceneLeave( action: (newScene?: string) => void, ): KEventController { - return game.events.on("sceneLeave", action); + return _k.game.events.on("sceneLeave", action); } export function getSceneName() { - return game.currentScene; + return _k.game.currentScene; } diff --git a/src/gfx/bg.ts b/src/gfx/bg.ts index c958e3bb..a10a0c75 100644 --- a/src/gfx/bg.ts +++ b/src/gfx/bg.ts @@ -1,14 +1,14 @@ -import { gfx } from "../kaplay"; +import { _k } from "../kaplay"; import { type ColorArgs, rgb } from "../math"; export function setBackground(...args: ColorArgs) { const color = rgb(...args); const alpha = args[3] ?? 1; - gfx.bgColor = color; - gfx.bgAlpha = alpha; + _k.gfx.bgColor = color; + _k.gfx.bgAlpha = alpha; - gfx.ggl.gl.clearColor( + _k.gfx.ggl.gl.clearColor( color.r / 255, color.g / 255, color.b / 255, @@ -17,5 +17,5 @@ export function setBackground(...args: ColorArgs) { } export function getBackground() { - return gfx.bgColor?.clone?.() ?? null; + return _k.gfx.bgColor?.clone?.() ?? null; } diff --git a/src/gfx/draw/drawDebug.ts b/src/gfx/draw/drawDebug.ts index 3c509ea9..67d90725 100644 --- a/src/gfx/draw/drawDebug.ts +++ b/src/gfx/draw/drawDebug.ts @@ -1,5 +1,5 @@ import { DBG_FONT, LOG_TIME } from "../../constants"; -import { app, debug, game, globalOpt } from "../../kaplay"; +import { _k } from "../../kaplay"; import { rgb } from "../../math/color"; import { vec2, wave } from "../../math/math"; import { formatText } from "../formatText"; @@ -20,17 +20,17 @@ import { drawTriangle } from "./drawTriangle"; import { drawUnscaled } from "./drawUnscaled"; export function drawDebug() { - if (debug.inspect) { + if (_k.debug.inspect) { let inspecting = null; - for (const obj of game.root.get("*", { recursive: true })) { + for (const obj of _k.game.root.get("*", { recursive: true })) { if (obj.c("area") && obj.isHovering()) { inspecting = obj; break; } } - game.root.drawInspect(); + _k.game.root.drawInspect(); if (inspecting) { const lines = []; @@ -50,10 +50,10 @@ export function drawDebug() { drawInspectText(contentToView(mousePos()), lines.join("\n")); } - drawInspectText(vec2(8), `FPS: ${debug.fps()}`); + drawInspectText(vec2(8), `FPS: ${_k.debug.fps()}`); } - if (debug.paused) { + if (_k.debug.paused) { drawUnscaled(() => { // top right corner pushTransform(); @@ -90,7 +90,7 @@ export function drawDebug() { }); } - if (debug.timeScale !== 1) { + if (_k.debug.timeScale !== 1) { drawUnscaled(() => { // bottom right corner pushTransform(); @@ -101,7 +101,7 @@ export function drawDebug() { // format text first to get text size const ftxt = formatText({ - text: debug.timeScale.toFixed(1), + text: _k.debug.timeScale.toFixed(1), font: DBG_FONT, size: 16, color: rgb(255, 255, 255), @@ -123,7 +123,7 @@ export function drawDebug() { // fast forward / slow down icon for (let i = 0; i < 2; i++) { - const flipped = debug.timeScale < 1; + const flipped = _k.debug.timeScale < 1; drawTriangle({ p1: vec2(-ftxt.width - pad * (flipped ? 2 : 3.5), -pad), p2: vec2( @@ -147,7 +147,7 @@ export function drawDebug() { }); } - if (debug.curRecording) { + if (_k.debug.curRecording) { drawUnscaled(() => { pushTransform(); pushTranslate(0, height()); @@ -156,7 +156,7 @@ export function drawDebug() { drawCircle({ radius: 12, color: rgb(255, 0, 0), - opacity: wave(0, 1, app.time() * 4), + opacity: wave(0, 1, _k.app.time() * 4), fixed: true, }); @@ -164,7 +164,7 @@ export function drawDebug() { }); } - if (debug.showLog && game.logs.length > 0) { + if (_k.debug.showLog && _k.game.logs.length > 0) { drawUnscaled(() => { pushTransform(); pushTranslate(0, height()); @@ -173,7 +173,7 @@ export function drawDebug() { const pad = 8; const logs = []; - for (const log of game.logs) { + for (const log of _k.game.logs) { let str = ""; const style = log.msg instanceof Error ? "error" : "info"; str += `[time]${log.time.toFixed(2)}[/time]`; @@ -182,9 +182,9 @@ export function drawDebug() { logs.push(str); } - game.logs = game.logs + _k.game.logs = _k.game.logs .filter((log) => - app.time() - log.time < (globalOpt.logTime || LOG_TIME) + _k.app.time() - log.time < (_k.globalOpt.logTime || LOG_TIME) ); const ftext = formatText({ diff --git a/src/gfx/draw/drawFrame.ts b/src/gfx/draw/drawFrame.ts index 855dcb35..25e8b35a 100644 --- a/src/gfx/draw/drawFrame.ts +++ b/src/gfx/draw/drawFrame.ts @@ -1,11 +1,11 @@ import { dt } from "../../app/frame"; -import { game } from "../../kaplay"; +import { _k } from "../../kaplay"; import { lerp, Mat4, rand, Vec2 } from "../../math/math"; import { center, flush } from "../stack"; export function drawFrame() { // calculate camera matrix - const cam = game.cam; + const cam = _k.game.cam; const shake = Vec2.fromAngle(rand(0, 360)).scale(cam.shake); cam.shake = lerp(cam.shake, 0, 5 * dt()); @@ -15,6 +15,6 @@ export function drawFrame() { .rotate(cam.angle) .translate((cam.pos ?? center()).scale(-1).add(shake)); - game.root.draw(); + _k.game.root.draw(); flush(); } diff --git a/src/gfx/draw/drawLine.ts b/src/gfx/draw/drawLine.ts index 6ac72d7a..f05e7418 100644 --- a/src/gfx/draw/drawLine.ts +++ b/src/gfx/draw/drawLine.ts @@ -1,4 +1,4 @@ -import { gfx } from "../../kaplay"; +import { _k } from "../../kaplay"; import { Color } from "../../math/color"; import { deg2rad, Vec2, vec2 } from "../../math/math"; import type { RenderProps } from "../../types"; @@ -54,7 +54,7 @@ export function drawLine(opt: DrawLineOpt) { verts, [0, 1, 3, 1, 2, 3], opt.fixed, - gfx.defTex, + _k.gfx.defTex, opt.shader, opt.uniform ?? undefined, ); @@ -260,7 +260,7 @@ export function _drawLinesBevel(opt: DrawLinesOpt) { verts, indices, opt.fixed, - gfx.defTex, + _k.gfx.defTex, opt.shader, opt.uniform ?? undefined, ); @@ -445,7 +445,7 @@ export function _drawLinesRound(opt: DrawLinesOpt) { verts, indices, opt.fixed, - gfx.defTex, + _k.gfx.defTex, opt.shader, opt.uniform ?? undefined, ); @@ -600,7 +600,7 @@ export function _drawLinesMiter(opt: DrawLinesOpt) { verts, indices, opt.fixed, - gfx.defTex, + _k.gfx.defTex, opt.shader, opt.uniform ?? undefined, ); diff --git a/src/gfx/draw/drawLoadingScreen.ts b/src/gfx/draw/drawLoadingScreen.ts index ce635725..0cf6ed85 100644 --- a/src/gfx/draw/drawLoadingScreen.ts +++ b/src/gfx/draw/drawLoadingScreen.ts @@ -1,5 +1,5 @@ import { loadProgress } from "../../assets"; -import { game } from "../../kaplay"; +import { _k } from "../../kaplay"; import { rgb } from "../../math/color"; import { vec2 } from "../../math/math"; import { height, width } from "../stack"; @@ -9,8 +9,8 @@ import { drawUnscaled } from "./drawUnscaled"; export function drawLoadScreen() { const progress = loadProgress(); - if (game.events.numListeners("loading") > 0) { - game.events.trigger("loading", progress); + if (_k.game.events.numListeners("loading") > 0) { + _k.game.events.trigger("loading", progress); } else { drawUnscaled(() => { diff --git a/src/gfx/draw/drawMasked.ts b/src/gfx/draw/drawMasked.ts index aca863f1..edb134c2 100644 --- a/src/gfx/draw/drawMasked.ts +++ b/src/gfx/draw/drawMasked.ts @@ -1,8 +1,8 @@ -import { gfx } from "../../kaplay"; +import { _k } from "../../kaplay"; import { drawStenciled } from "./drawStenciled"; export function drawMasked(content: () => void, mask: () => void) { - const gl = gfx.ggl.gl; + const gl = _k.gfx.ggl.gl; drawStenciled(content, mask, gl.EQUAL); } diff --git a/src/gfx/draw/drawPolygon.ts b/src/gfx/draw/drawPolygon.ts index 3acb082e..928592ae 100644 --- a/src/gfx/draw/drawPolygon.ts +++ b/src/gfx/draw/drawPolygon.ts @@ -1,4 +1,4 @@ -import { gfx } from "../../kaplay"; +import { _k } from "../../kaplay"; import { Color } from "../../math/color"; import { triangulate, Vec2 } from "../../math/math"; import type { DrawPolygonOpt } from "../../types"; @@ -61,7 +61,7 @@ export function drawPolygon(opt: DrawPolygonOpt) { verts, opt.indices ?? indices, opt.fixed, - opt.uv ? opt.tex : gfx.defTex, + opt.uv ? opt.tex : _k.gfx.defTex, opt.shader, opt.uniform ?? undefined, ); diff --git a/src/gfx/draw/drawRaw.ts b/src/gfx/draw/drawRaw.ts index ef498a16..497e04b2 100644 --- a/src/gfx/draw/drawRaw.ts +++ b/src/gfx/draw/drawRaw.ts @@ -1,5 +1,5 @@ import { Asset, resolveShader, type Uniform } from "../../assets"; -import { game, gfx } from "../../kaplay"; +import { _k } from "../../kaplay"; import { screen2ndc } from "../../math/various"; import type { RenderProps, Vertex } from "../../types"; import type { Texture } from "../gfx"; @@ -12,17 +12,17 @@ export function drawRaw( shaderSrc?: RenderProps["shader"], uniform: Uniform = {}, ) { - const parsedTex = tex ?? gfx.defTex; - const parsedShader = shaderSrc ?? gfx.defShader; + const parsedTex = tex ?? _k.gfx.defTex; + const parsedShader = shaderSrc ?? _k.gfx.defShader; const shader = resolveShader(parsedShader); if (!shader || shader instanceof Asset) { return; } - const transform = (gfx.fixed || fixed) - ? gfx.transform - : game.cam.transform.mult(gfx.transform); + const transform = (_k.gfx.fixed || fixed) + ? _k.gfx.transform + : _k.game.cam.transform.mult(_k.gfx.transform); const vv: number[] = []; @@ -42,8 +42,8 @@ export function drawRaw( ); } - gfx.renderer.push( - gfx.ggl.gl.TRIANGLES, + _k.gfx.renderer.push( + _k.gfx.ggl.gl.TRIANGLES, vv, indices, shader, diff --git a/src/gfx/draw/drawStenciled.ts b/src/gfx/draw/drawStenciled.ts index 5c13a150..d6b68f9d 100644 --- a/src/gfx/draw/drawStenciled.ts +++ b/src/gfx/draw/drawStenciled.ts @@ -1,4 +1,4 @@ -import { gfx } from "../../kaplay"; +import { _k } from "../../kaplay"; import { flush } from "../stack"; export function drawStenciled( @@ -6,7 +6,7 @@ export function drawStenciled( mask: () => void, test: number, ) { - const gl = gfx.ggl.gl; + const gl = _k.gfx.ggl.gl; flush(); gl.clear(gl.STENCIL_BUFFER_BIT); diff --git a/src/gfx/draw/drawSubstracted.ts b/src/gfx/draw/drawSubstracted.ts index 2d237302..a26a0268 100644 --- a/src/gfx/draw/drawSubstracted.ts +++ b/src/gfx/draw/drawSubstracted.ts @@ -1,8 +1,8 @@ -import { gfx } from "../../kaplay"; +import { _k } from "../../kaplay"; import { drawStenciled } from "./drawStenciled"; export function drawSubtracted(content: () => void, mask: () => void) { - const gl = gfx.ggl.gl; + const gl = _k.gfx.ggl.gl; drawStenciled(content, mask, gl.NOTEQUAL); } diff --git a/src/gfx/draw/drawUnscaled.ts b/src/gfx/draw/drawUnscaled.ts index 14025755..ad0ffe28 100644 --- a/src/gfx/draw/drawUnscaled.ts +++ b/src/gfx/draw/drawUnscaled.ts @@ -1,14 +1,14 @@ -import { gfx } from "../../kaplay"; +import { _k } from "../../kaplay"; import { flush } from "../stack"; export function drawUnscaled(content: () => void) { flush(); - const ow = gfx.width; - const oh = gfx.height; - gfx.width = gfx.viewport.width; - gfx.height = gfx.viewport.height; + const ow = _k.gfx.width; + const oh = _k.gfx.height; + _k.gfx.width = _k.gfx.viewport.width; + _k.gfx.height = _k.gfx.viewport.height; content(); flush(); - gfx.width = ow; - gfx.height = oh; + _k.gfx.width = ow; + _k.gfx.height = oh; } diff --git a/src/gfx/formatText.ts b/src/gfx/formatText.ts index 6eb7f323..7eb73fd0 100644 --- a/src/gfx/formatText.ts +++ b/src/gfx/formatText.ts @@ -5,7 +5,7 @@ import { FONT_ATLAS_HEIGHT, FONT_ATLAS_WIDTH, } from "../constants"; -import { fontCacheC2d, fontCacheCanvas, gfx } from "../kaplay"; +import { _k } from "../kaplay"; import { Color } from "../math/color"; import { Quad, Vec2, vec2 } from "../math/math"; import { type Outline, type TexFilter } from "../types"; @@ -141,7 +141,7 @@ export function formatText(opt: DrawTextOpt): FormattedText { // TODO: customizable font tex filter const atlas: FontAtlas = fontAtlases[fontName] ?? { font: { - tex: new Texture(gfx.ggl, FONT_ATLAS_WIDTH, FONT_ATLAS_HEIGHT, { + tex: new Texture(_k.gfx.ggl, FONT_ATLAS_WIDTH, FONT_ATLAS_HEIGHT, { filter: opts.filter, }), map: {}, @@ -160,18 +160,18 @@ export function formatText(opt: DrawTextOpt): FormattedText { for (const ch of chars) { if (!atlas.font.map[ch]) { // TODO: use assets.packer to pack font texture - const c2d = fontCacheC2d; + const c2d = _k.fontCacheC2d; if (!c2d) throw new Error("fontCacheC2d is not defined."); - if (!fontCacheCanvas) { + if (!_k.fontCacheCanvas) { throw new Error("fontCacheCanvas is not defined."); } c2d.clearRect( 0, 0, - fontCacheCanvas.width, - fontCacheCanvas.height, + _k.fontCacheCanvas.width, + _k.fontCacheCanvas.height, ); c2d.font = `${font.size}px ${fontName}`; c2d.textBaseline = "top"; diff --git a/src/gfx/stack.ts b/src/gfx/stack.ts index 09e9f42e..ae23ed8a 100644 --- a/src/gfx/stack.ts +++ b/src/gfx/stack.ts @@ -1,4 +1,4 @@ -import { app, gfx } from "../kaplay"; +import { _k } from "../kaplay"; import { type Mat4, Vec2, vec2, type Vec2Args } from "../math/math"; export function pushTranslate(...args: Vec2Args | [undefined]) { @@ -6,15 +6,15 @@ export function pushTranslate(...args: Vec2Args | [undefined]) { const p = vec2(...args); if (p.x === 0 && p.y === 0) return; - gfx.transform.translate(p); + _k.gfx.transform.translate(p); } export function pushTransform() { - gfx.transformStack.push(gfx.transform.clone()); + _k.gfx.transformStack.push(_k.gfx.transform.clone()); } export function pushMatrix(m: Mat4) { - gfx.transform = m.clone(); + _k.gfx.transform = m.clone(); } export function pushScale( @@ -24,59 +24,59 @@ export function pushScale( const p = vec2(...args); if (p.x === 1 && p.y === 1) return; - gfx.transform.scale(p); + _k.gfx.transform.scale(p); } export function pushRotate(a: number | undefined) { if (!a) return; - gfx.transform.rotate(a); + _k.gfx.transform.rotate(a); } export function popTransform() { - if (gfx.transformStack.length > 0) { + if (_k.gfx.transformStack.length > 0) { // if there's more than 1 element, it will return obviously a Mat4 - gfx.transform = gfx.transformStack.pop()!; + _k.gfx.transform = _k.gfx.transformStack.pop()!; } } export function flush() { - gfx.renderer.flush(); + _k.gfx.renderer.flush(); } // get game width export function width(): number { - return gfx.width; + return _k.gfx.width; } // get game height export function height(): number { - return gfx.height; + return _k.gfx.height; } export function getViewportScale() { - return (gfx.viewport.width + gfx.viewport.height) - / (gfx.width + gfx.height); + return (_k.gfx.viewport.width + _k.gfx.viewport.height) + / (_k.gfx.width + _k.gfx.height); } // transform a point from content space to view space export function contentToView(pt: Vec2) { return new Vec2( - pt.x * gfx.viewport.width / gfx.width, - pt.y * gfx.viewport.height / gfx.height, + pt.x * _k.gfx.viewport.width / _k.gfx.width, + pt.y * _k.gfx.viewport.height / _k.gfx.height, ); } // transform a point from window space to content space export function windowToContent(pt: Vec2) { return new Vec2( - (pt.x - gfx.viewport.x) * width() / gfx.viewport.width, - (pt.y - gfx.viewport.y) * height() / gfx.viewport.height, + (pt.x - _k.gfx.viewport.x) * width() / _k.gfx.viewport.width, + (pt.y - _k.gfx.viewport.y) * height() / _k.gfx.viewport.height, ); } export function mousePos() { - return windowToContent(app.mousePos()); + return windowToContent(_k.app.mousePos()); } export function center(): Vec2 { diff --git a/src/gfx/viewport.ts b/src/gfx/viewport.ts index a9e498e5..9815febc 100644 --- a/src/gfx/viewport.ts +++ b/src/gfx/viewport.ts @@ -1,4 +1,4 @@ -import { gfx, globalOpt, pixelDensity } from "../kaplay"; +import { _k } from "../kaplay"; // update viewport based on user setting and fullscreen state export function updateViewport() { @@ -7,24 +7,24 @@ export function updateViewport() { // window size (will be the same as view size except letterbox mode) // canvas size - const pd = pixelDensity; - const canvasWidth = gfx.ggl.gl.drawingBufferWidth / pd; - const canvasHeight = gfx.ggl.gl.drawingBufferHeight / pd; + const pd = _k.pixelDensity; + const canvasWidth = _k.gfx.ggl.gl.drawingBufferWidth / pd; + const canvasHeight = _k.gfx.ggl.gl.drawingBufferHeight / pd; - if (globalOpt.letterbox) { - if (!globalOpt.width || !globalOpt.height) { + if (_k.globalOpt.letterbox) { + if (!_k.globalOpt.width || !_k.globalOpt.height) { throw new Error( "Letterboxing requires width and height defined.", ); } const rc = canvasWidth / canvasHeight; - const rg = globalOpt.width / globalOpt.height; + const rg = _k.globalOpt.width / _k.globalOpt.height; if (rc > rg) { const sw = canvasHeight * rg; const x = (canvasWidth - sw) / 2; - gfx.viewport = { + _k.gfx.viewport = { x: x, y: 0, width: sw, @@ -34,7 +34,7 @@ export function updateViewport() { else { const sh = canvasWidth / rg; const y = (canvasHeight - sh) / 2; - gfx.viewport = { + _k.gfx.viewport = { x: 0, y: y, width: canvasWidth, @@ -45,15 +45,15 @@ export function updateViewport() { return; } - if (globalOpt.stretch) { - if (!globalOpt.width || !globalOpt.height) { + if (_k.globalOpt.stretch) { + if (!_k.globalOpt.width || !_k.globalOpt.height) { throw new Error( "Stretching requires width and height defined.", ); } } - gfx.viewport = { + _k.gfx.viewport = { x: 0, y: 0, width: canvasWidth, diff --git a/src/kaplay.ts b/src/kaplay.ts index f779ce8f..2ef4cf51 100644 --- a/src/kaplay.ts +++ b/src/kaplay.ts @@ -159,6 +159,7 @@ import type { Debug, GameObj, KAPLAYCtx, + KAPLAYInternal, KAPLAYOpt, KAPLAYPlugin, MergePlugins, @@ -219,7 +220,7 @@ import { } from "./components"; import { dt, fixedDt, restDt } from "./app"; -import { type AudioCtx, burp, initAudio, play, volume } from "./audio"; +import { burp, initAudio, play, volume } from "./audio"; import { addKaboom, @@ -230,7 +231,6 @@ import { camScale, camTransform, destroy, - type Game, getGravity, getGravityDirection, getSceneName, @@ -269,21 +269,25 @@ import { import boomSpriteSrc from "./kassets/boom.png"; import kaSpriteSrc from "./kassets/ka.png"; -export let k: KAPLAYCtx; -export let globalOpt: KAPLAYOpt; -export let gfx: AppGfxCtx; -export let game: Game; -export let app: App; -export let assets: ReturnType; -export let fontCacheCanvas: HTMLCanvasElement | null; -export let fontCacheC2d: CanvasRenderingContext2D | null; -export let debug: Debug; -export let audio: AudioCtx; -export let pixelDensity: number; -export let canvas: HTMLCanvasElement; -export let gscale: number; -export let kaSprite: Asset; -export let boomSprite: Asset; +// Internal data, shared between all modules +export const _k = { + k: null, + globalOpt: null, + gfx: null, + game: null, + app: null, + assets: null, + fontCacheCanvas: null, + fontCacheC2d: null, + debug: null, + audio: null, + pixelDensity: null, + canvas: null, + gscale: null, + kaSprite: null, + boomSprite: null, +} as unknown as KAPLAYInternal; + /** * Initialize KAPLAY context. The starting point of all KAPLAY games. @@ -328,7 +332,12 @@ const kaplay = < ): TPlugins extends [undefined] ? KAPLAYCtx : KAPLAYCtx & MergePlugins => { - globalOpt = gopt; + if(_k.k) { + console.warn("KAPLAY already initialized, you are calling kaplay() multiple times, it may lead bugs!"); + _k.k.quit(); + } + + _k.globalOpt = gopt; const root = gopt.root ?? document.body; // if root is not defined (which falls back to ) we assume user is using kaboom on a clean page, and modify to better fit a full screen canvas @@ -341,11 +350,13 @@ const kaplay = < } // create a if user didn't provide one - canvas = gopt.canvas + const canvas = gopt.canvas ?? root.appendChild(document.createElement("canvas")); + _k.canvas = canvas; // global pixel scale - gscale = gopt.scale ?? 1; + const gscale = gopt.scale ?? 1; + _k.gscale = gscale; const fixedSize = gopt.width && gopt.height && !gopt.stretch && !gopt.letterbox; @@ -384,21 +395,24 @@ const kaplay = < canvas.style.cssText = styles.join(";"); - pixelDensity = gopt.pixelDensity || 1; + const pixelDensity = gopt.pixelDensity || 1; + _k.pixelDensity = pixelDensity; canvas.width *= pixelDensity; canvas.height *= pixelDensity; // make canvas focusable canvas.tabIndex = 0; - fontCacheCanvas = document.createElement("canvas"); + const fontCacheCanvas = document.createElement("canvas"); fontCacheCanvas.width = MAX_TEXT_CACHE_SIZE; fontCacheCanvas.height = MAX_TEXT_CACHE_SIZE; - fontCacheC2d = fontCacheCanvas.getContext("2d", { + _k.fontCacheCanvas = fontCacheCanvas; + const fontCacheC2d = fontCacheCanvas.getContext("2d", { willReadFrequently: true, }); + _k.fontCacheC2d = fontCacheC2d; - app = initApp({ + const app = initApp({ canvas: canvas, touchToMouse: gopt.touchToMouse, gamepads: gopt.gamepads, @@ -406,6 +420,7 @@ const kaplay = < maxFPS: gopt.maxFPS, buttons: gopt.buttons, }); + _k.app = app; const gc: Array<() => void> = []; @@ -426,11 +441,14 @@ const kaplay = < texFilter: gopt.texFilter, }); - gfx = initAppGfx(gopt, ggl); - audio = initAudio(); - assets = initAssets(ggl); - - game = initGame(); + const gfx = initAppGfx(gopt, ggl); + _k.gfx = gfx; + const audio = initAudio(); + _k.audio = audio; + const assets = initAssets(ggl); + _k.assets = assets; + const game = initGame(); + _k.game = game; game.root.use(timer()); @@ -527,7 +545,7 @@ const kaplay = < let debugPaused = false; - debug = { + const debug: Debug = { inspect: false, timeScale: 1, showLog: true, @@ -566,6 +584,8 @@ const kaplay = < }, }; + _k.debug = debug; + function getData(key: string, def?: T): T | null { try { return JSON.parse(window.localStorage[key]); @@ -588,24 +608,24 @@ const kaplay = < plugin: KAPLAYPlugin, ...args: any ): KAPLAYCtx & T { - const funcs = plugin(k); + const funcs = plugin(ctx); let funcsObj: T; if (typeof funcs === "function") { const plugWithOptions = funcs(...args); - funcsObj = plugWithOptions(k); + funcsObj = plugWithOptions(ctx); } else { funcsObj = funcs; } for (const key in funcsObj) { - k[key as keyof typeof k] = funcsObj[key]; + ctx[key as keyof typeof ctx] = funcsObj[key]; if (gopt.global !== false) { window[key as any] = funcsObj[key]; } } - return k as KAPLAYCtx & T; + return ctx as unknown as KAPLAYCtx & T; } function record(frameRate?: number): Recording { @@ -681,8 +701,11 @@ const kaplay = < const query = game.root.query.bind(game.root); const tween = game.root.tween.bind(game.root); - kaSprite = loadSprite(null, kaSpriteSrc); - boomSprite = loadSprite(null, boomSpriteSrc); + const kaSprite = loadSprite(null, kaSpriteSrc); + const boomSprite = loadSprite(null, boomSpriteSrc); + + _k.kaSprite = kaSprite; + _k.boomSprite = boomSprite; function fixedUpdateFrame() { // update every obj @@ -999,7 +1022,8 @@ const kaplay = < initEvents(); // the exported ctx handle - k = { + const ctx: KAPLAYCtx = { + _k, VERSION, // asset load loadRoot, @@ -1324,6 +1348,8 @@ const kaplay = < KEventController, }; + _k.k = ctx; + const plugins = gopt.plugins as KAPLAYPlugin>[]; if (plugins) { @@ -1332,8 +1358,8 @@ const kaplay = < // export everything to window if global is set if (gopt.global !== false) { - for (const key in k) { - ( window[ key]) = k[key as keyof KAPLAYCtx]; + for (const key in ctx) { + ( window[ key]) = ctx[key as keyof KAPLAYCtx]; } } @@ -1341,7 +1367,7 @@ const kaplay = < app.canvas.focus(); } - return k as TPlugins extends [undefined] ? KAPLAYCtx + return ctx as unknown as TPlugins extends [undefined] ? KAPLAYCtx : KAPLAYCtx & MergePlugins; }; diff --git a/src/types.ts b/src/types.ts index da8ff74d..178ded25 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,8 +1,9 @@ -import type { ButtonBinding, ButtonBindingDevice, ButtonsDef } from "./app"; +import type { App, ButtonBinding, ButtonBindingDevice, ButtonsDef } from "./app"; import type { AsepriteData, Asset, BitmapFontData, + initAssets, LoadBitmapFontOpt, LoadSpriteOpt, LoadSpriteSrc, @@ -13,7 +14,7 @@ import type { Uniform, } from "./assets"; import type { FontData } from "./assets/font"; -import type { AudioPlay, AudioPlayOpt } from "./audio"; +import type { AudioCtx, AudioPlay, AudioPlayOpt } from "./audio"; import type { AgentComp, AgentCompOpt, @@ -84,6 +85,7 @@ import type { } from "./components/draw/particles"; import type { BoomOpt, + Game, GameObjEventMap, GameObjEventNames, LevelOpt, @@ -92,6 +94,7 @@ import type { TupleWithoutFirst, } from "./game"; import type { + AppGfxCtx, DrawBezierOpt, DrawCircleOpt, DrawCurveOpt, @@ -126,6 +129,27 @@ import type { import type { NavMesh } from "./math/navigationmesh"; import type { KEvent, KEventController, KEventHandler } from "./utils/"; +/** + * Sensitive KAPLAY data + */ +export type KAPLAYInternal = { + k: KAPLAYCtx; + globalOpt: KAPLAYOpt; + gfx: AppGfxCtx; + game: Game; + app: App; + assets: ReturnType; + fontCacheCanvas: HTMLCanvasElement | null; + fontCacheC2d: CanvasRenderingContext2D | null; + debug: Debug; + audio: AudioCtx; + pixelDensity: number; + canvas: HTMLCanvasElement; + gscale: number; + kaSprite: Asset; + boomSprite: Asset; +} + /** * Context handle that contains every kaboom function. * @@ -135,6 +159,12 @@ export interface KAPLAYCtx< TButtonDef extends ButtonsDef = {}, TButton extends string = string, > { + /** + * Internal data that should not be accessed directly. + * + * @group Misc + */ + _k: KAPLAYInternal; /** * Assemble a game object from a list of components, and add it to the game *