@hi-ashleyj/llama 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,7 @@ import { onMount } from "svelte";
3
3
  import { setupGame } from "../setup";
4
4
  import { Timing } from "./motions";
5
5
  import { Controller } from "./controller";
6
+ import { Mouse } from "./mouse";
6
7
  export let width = 1920;
7
8
  export let height = 1080;
8
9
  export let background = "#000000";
@@ -24,6 +25,8 @@ $: {
24
25
  const layers = new Set();
25
26
  const draw = function (delta, time) {
26
27
  for (let layer of layers) {
28
+ if (layer.isStatic())
29
+ continue;
27
30
  layer.draw(delta, time);
28
31
  }
29
32
  };
@@ -33,6 +36,7 @@ const assign = function (ctx) {
33
36
  };
34
37
  const timing = new Timing();
35
38
  const controller = new Controller();
39
+ const mouse = new Mouse();
36
40
  const frameEvents = new Set();
37
41
  const frameBeforeEvents = new Set();
38
42
  const frameAfterEvents = new Set();
@@ -47,6 +51,10 @@ export const context = {
47
51
  onKeyboardEvent: controller.on.bind(controller),
48
52
  isKeyboardPressed: controller.isPressed.bind(controller),
49
53
  getKeyboardStore: controller.getStore.bind(controller),
54
+ onMouseEvent: mouse.on.bind(mouse),
55
+ isMousePressed: mouse.isPressed.bind(mouse),
56
+ getMousePosition: mouse.getPosition.bind(mouse),
57
+ getMouseStore: mouse.getStore.bind(mouse),
50
58
  onFrame: (callback) => {
51
59
  frameEvents.add(callback);
52
60
  return () => frameEvents.delete(callback);
@@ -82,13 +90,21 @@ const loop = function (time) {
82
90
  onMount(() => {
83
91
  requestAnimationFrame(loop);
84
92
  controller.start();
93
+ mouse.start();
85
94
  });
95
+ let wiw = 0;
96
+ let wih = 0;
97
+ $: {
98
+ mouse.changeWindowDimensions(wiw, wih);
99
+ }
86
100
  </script>
87
101
 
88
102
  <div class="game" style:background-color={background}>
89
103
  <slot />
90
104
  </div>
91
105
 
106
+ <svelte:window bind:innerHeight={wih} bind:innerWidth={wiw}></svelte:window>
107
+
92
108
  <style>
93
109
  .game {
94
110
  position: relative;
@@ -1,6 +1,8 @@
1
1
  <script>import { setupLayer, getGame } from "../setup";
2
2
  import { onMount } from "svelte";
3
3
  export let zIndex = 0;
4
+ export let staticMode = false;
5
+ let hasRenderedOnce = false;
4
6
  let canvas;
5
7
  $: ctx = (typeof canvas !== "undefined") ? canvas.getContext("2d") : null;
6
8
  let targets = new Set();
@@ -15,10 +17,18 @@ let register = setupLayer({
15
17
  assign: (ctx) => {
16
18
  targets.add(ctx);
17
19
  return () => { targets.delete(ctx); };
20
+ },
21
+ requestFrame: () => {
22
+ if (!staticMode)
23
+ return;
24
+ draw();
18
25
  }
19
26
  });
20
27
  onMount(() => {
21
- return register({ draw });
28
+ return register({ draw, isStatic: () => { if (!hasRenderedOnce) {
29
+ hasRenderedOnce = true;
30
+ draw();
31
+ } return staticMode; } });
22
32
  });
23
33
  </script>
24
34
 
@@ -2,6 +2,7 @@ import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
4
  zIndex?: number | undefined;
5
+ staticMode?: boolean | undefined;
5
6
  };
6
7
  events: {
7
8
  [evt: string]: CustomEvent<any>;
@@ -0,0 +1,49 @@
1
+ <script>import { setupDrawable, getGame } from "../../setup";
2
+ import { onMount, createEventDispatcher } from "svelte";
3
+ import { MOUSE_ACTION } from "../mouse";
4
+ let tx = 0;
5
+ let ty = 0;
6
+ let tw = 0;
7
+ let th = 0;
8
+ let dispatch = createEventDispatcher();
9
+ let context = getGame();
10
+ const draw = function (_info, { x, y, w, h }) {
11
+ tx = x;
12
+ ty = y;
13
+ tw = w;
14
+ th = h;
15
+ };
16
+ let register = setupDrawable({});
17
+ onMount(() => {
18
+ let event = context.onMouseEvent(null, MOUSE_ACTION.DOWN, ({ key }) => {
19
+ let x = context.getMousePosition("mouse_x");
20
+ if (x < tx || x > tx + tw)
21
+ return;
22
+ let y = context.getMousePosition("mouse_y");
23
+ if (y < ty || y > ty + th)
24
+ return;
25
+ dispatch("click");
26
+ switch (key) {
27
+ case ("mouse_left"): {
28
+ dispatch("left");
29
+ dispatch("leftorright");
30
+ return;
31
+ }
32
+ case ("mouse_right"): {
33
+ dispatch("right");
34
+ dispatch("leftorright");
35
+ return;
36
+ }
37
+ case ("mouse_middle"): {
38
+ dispatch("middle");
39
+ }
40
+ }
41
+ dispatch("other");
42
+ });
43
+ let deregister = register({ draw });
44
+ return () => {
45
+ event();
46
+ deregister();
47
+ };
48
+ });
49
+ </script>
@@ -0,0 +1,21 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: Record<string, never>;
4
+ events: {
5
+ click: CustomEvent<any>;
6
+ left: CustomEvent<any>;
7
+ leftorright: CustomEvent<any>;
8
+ right: CustomEvent<any>;
9
+ middle: CustomEvent<any>;
10
+ other: CustomEvent<any>;
11
+ } & {
12
+ [evt: string]: CustomEvent<any>;
13
+ };
14
+ slots: {};
15
+ };
16
+ export type MouseClickableProps = typeof __propDef.props;
17
+ export type MouseClickableEvents = typeof __propDef.events;
18
+ export type MouseClickableSlots = typeof __propDef.slots;
19
+ export default class MouseClickable extends SvelteComponentTyped<MouseClickableProps, MouseClickableEvents, MouseClickableSlots> {
20
+ }
21
+ export {};
@@ -0,0 +1,55 @@
1
+ <script>import { setupDrawable, getGame } from "../../setup";
2
+ import { onMount, createEventDispatcher } from "svelte";
3
+ import { MOUSE_ACTION } from "../mouse";
4
+ let tx = 0;
5
+ let ty = 0;
6
+ let tw = 0;
7
+ let th = 0;
8
+ let dispatch = createEventDispatcher();
9
+ let context = getGame();
10
+ let mouseX = context.getMouseStore("mouse_x");
11
+ let mouseY = context.getMouseStore("mouse_y");
12
+ export let hover = false;
13
+ const draw = function (_info, { x, y, w, h }) {
14
+ tx = x;
15
+ ty = y;
16
+ tw = w;
17
+ th = h;
18
+ if ($mouseX < tx || $mouseX > tx + tw)
19
+ return hover = false;
20
+ if ($mouseY < ty || $mouseY > ty + th)
21
+ return hover = false;
22
+ hover = true;
23
+ };
24
+ let register = setupDrawable({});
25
+ onMount(() => {
26
+ let event = context.onMouseEvent(null, MOUSE_ACTION.DOWN, ({ key }) => {
27
+ if ($mouseX < tx || $mouseX > tx + tw)
28
+ return;
29
+ if ($mouseY < ty || $mouseY > ty + th)
30
+ return;
31
+ dispatch("click");
32
+ switch (key) {
33
+ case ("mouse_left"): {
34
+ dispatch("left");
35
+ dispatch("leftorright");
36
+ return;
37
+ }
38
+ case ("mouse_right"): {
39
+ dispatch("right");
40
+ dispatch("leftorright");
41
+ return;
42
+ }
43
+ case ("mouse_middle"): {
44
+ dispatch("middle");
45
+ }
46
+ }
47
+ dispatch("other");
48
+ });
49
+ let deregister = register({ draw });
50
+ return () => {
51
+ event();
52
+ deregister();
53
+ };
54
+ });
55
+ </script>
@@ -0,0 +1,23 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ hover?: boolean | undefined;
5
+ };
6
+ events: {
7
+ click: CustomEvent<any>;
8
+ left: CustomEvent<any>;
9
+ leftorright: CustomEvent<any>;
10
+ right: CustomEvent<any>;
11
+ middle: CustomEvent<any>;
12
+ other: CustomEvent<any>;
13
+ } & {
14
+ [evt: string]: CustomEvent<any>;
15
+ };
16
+ slots: {};
17
+ };
18
+ export type MouseEventAreaProps = typeof __propDef.props;
19
+ export type MouseEventAreaEvents = typeof __propDef.events;
20
+ export type MouseEventAreaSlots = typeof __propDef.slots;
21
+ export default class MouseEventArea extends SvelteComponentTyped<MouseEventAreaProps, MouseEventAreaEvents, MouseEventAreaSlots> {
22
+ }
23
+ export {};
@@ -0,0 +1,33 @@
1
+ <script>import { setupDrawable, getGame } from "../../setup";
2
+ import { onMount, createEventDispatcher } from "svelte";
3
+ import { MOUSE_ACTION } from "../mouse";
4
+ let tx = 0;
5
+ let ty = 0;
6
+ let tw = 0;
7
+ let th = 0;
8
+ let dispatch = createEventDispatcher();
9
+ let context = getGame();
10
+ const draw = function (_info, { x, y, w, h }) {
11
+ tx = x;
12
+ ty = y;
13
+ tw = w;
14
+ th = h;
15
+ };
16
+ let register = setupDrawable({});
17
+ onMount(() => {
18
+ let event = context.onMouseEvent("mouse_left", MOUSE_ACTION.DOWN, () => {
19
+ let x = context.getMousePosition("mouse_x");
20
+ if (x < tx || x > tx + tw)
21
+ return;
22
+ let y = context.getMousePosition("mouse_y");
23
+ if (y < ty || y > ty + th)
24
+ return;
25
+ dispatch("click");
26
+ });
27
+ let deregister = register({ draw });
28
+ return () => {
29
+ event();
30
+ deregister();
31
+ };
32
+ });
33
+ </script>
@@ -0,0 +1,16 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: Record<string, never>;
4
+ events: {
5
+ click: CustomEvent<any>;
6
+ } & {
7
+ [evt: string]: CustomEvent<any>;
8
+ };
9
+ slots: {};
10
+ };
11
+ export type MouseLeftClickProps = typeof __propDef.props;
12
+ export type MouseLeftClickEvents = typeof __propDef.events;
13
+ export type MouseLeftClickSlots = typeof __propDef.slots;
14
+ export default class MouseLeftClick extends SvelteComponentTyped<MouseLeftClickProps, MouseLeftClickEvents, MouseLeftClickSlots> {
15
+ }
16
+ export {};
@@ -0,0 +1,33 @@
1
+ import type { Writable } from "svelte/store";
2
+ export declare enum MOUSE_ACTION {
3
+ DOWN = "down",
4
+ UP = "up",
5
+ MOVE = "move"
6
+ }
7
+ type MouseEventBoolean = "mouse_left" | "mouse_middle" | "mouse_right";
8
+ type MouseEventNumber = "mouse_x" | "mouse_y";
9
+ export declare class Mouse {
10
+ constructor();
11
+ events: Set<{
12
+ key: string | null;
13
+ action: MOUSE_ACTION;
14
+ call: (e: {
15
+ key: string | null;
16
+ action: MOUSE_ACTION;
17
+ }) => any | void;
18
+ }>;
19
+ mouseState: Map<MouseEventBoolean | MouseEventNumber, boolean | number>;
20
+ mouseStores: Map<MouseEventBoolean | MouseEventNumber, Writable<boolean | number>>;
21
+ innerWidth: number;
22
+ innerHeight: number;
23
+ start(): void;
24
+ on(key: MouseEventBoolean | MouseEventNumber | null, action: MOUSE_ACTION, callback: (e: {
25
+ key: string | null;
26
+ action: MOUSE_ACTION;
27
+ }) => any | void): () => any;
28
+ getStore<T extends (MouseEventBoolean | MouseEventNumber)>(key: T): Writable<T extends MouseEventNumber ? number : boolean>;
29
+ isPressed(key: MouseEventBoolean): boolean;
30
+ getPosition(key: MouseEventNumber): number;
31
+ changeWindowDimensions(width: number, height: number): void;
32
+ }
33
+ export {};
@@ -0,0 +1,143 @@
1
+ import { writable } from "svelte/store";
2
+ export var MOUSE_ACTION;
3
+ (function (MOUSE_ACTION) {
4
+ MOUSE_ACTION["DOWN"] = "down";
5
+ MOUSE_ACTION["UP"] = "up";
6
+ // CLICK = "click",
7
+ MOUSE_ACTION["MOVE"] = "move";
8
+ })(MOUSE_ACTION || (MOUSE_ACTION = {}));
9
+ export class Mouse {
10
+ constructor() {
11
+ this.events = new Set();
12
+ this.mouseState = new Map();
13
+ this.mouseStores = new Map();
14
+ }
15
+ events;
16
+ mouseState;
17
+ mouseStores;
18
+ innerWidth = 0;
19
+ innerHeight = 0;
20
+ start() {
21
+ window.addEventListener("pointerdown", (e) => {
22
+ e.preventDefault();
23
+ let eKeyLowCase;
24
+ switch (e.button) {
25
+ case (0): {
26
+ eKeyLowCase = "mouse_left";
27
+ break;
28
+ }
29
+ case (2): {
30
+ eKeyLowCase = "mouse_right";
31
+ break;
32
+ }
33
+ case (1): {
34
+ eKeyLowCase = "mouse_middle";
35
+ break;
36
+ }
37
+ default: return;
38
+ }
39
+ this.mouseState.set(eKeyLowCase, true);
40
+ this.events.forEach(({ key, action, call }) => {
41
+ if ((key === eKeyLowCase || key === null) && action === MOUSE_ACTION.DOWN)
42
+ call({ key: eKeyLowCase, action });
43
+ });
44
+ if (this.mouseStores.has(eKeyLowCase)) {
45
+ this.mouseStores.get(eKeyLowCase)?.set(true);
46
+ }
47
+ });
48
+ window.addEventListener("pointerup", (e) => {
49
+ e.preventDefault();
50
+ let eKeyLowCase;
51
+ switch (e.button) {
52
+ case (0): {
53
+ eKeyLowCase = "mouse_left";
54
+ break;
55
+ }
56
+ case (1): {
57
+ eKeyLowCase = "mouse_right";
58
+ break;
59
+ }
60
+ case (2): {
61
+ eKeyLowCase = "mouse_middle";
62
+ break;
63
+ }
64
+ default: return;
65
+ }
66
+ this.mouseState.set(eKeyLowCase, false);
67
+ this.events.forEach(({ key, action, call }) => {
68
+ if ((key === eKeyLowCase || key === null) && action === MOUSE_ACTION.UP)
69
+ call({ key: eKeyLowCase, action });
70
+ });
71
+ if (this.mouseStores.has(eKeyLowCase)) {
72
+ this.mouseStores.get(eKeyLowCase)?.set(false);
73
+ }
74
+ });
75
+ window.addEventListener("pointermove", (e) => {
76
+ let rawX = e.offsetX;
77
+ let rawY = e.offsetY;
78
+ let adjustedX;
79
+ let adjustedY;
80
+ if (this.innerWidth / this.innerHeight > 16 / 9) {
81
+ // TODO: De Hard-code this
82
+ const scaleFactor = 1080 / this.innerHeight;
83
+ const realCanvasSize = 1920 / scaleFactor;
84
+ adjustedY = rawY * scaleFactor;
85
+ adjustedX = (rawX - ((this.innerWidth - realCanvasSize) / 2)) * scaleFactor;
86
+ }
87
+ else {
88
+ // TODO: De Hard-code this
89
+ const scaleFactor = 1920 / this.innerWidth;
90
+ const realCanvasSize = 1080 / scaleFactor;
91
+ adjustedX = rawX * scaleFactor;
92
+ adjustedY = (rawY - ((this.innerHeight - realCanvasSize) / 2)) * scaleFactor;
93
+ }
94
+ this.mouseState.set("mouse_x", adjustedX);
95
+ this.mouseState.set("mouse_y", adjustedY);
96
+ this.events.forEach(({ key, action, call }) => {
97
+ if ((key === "mouse_x" || key === null) && action === MOUSE_ACTION.MOVE)
98
+ call({ key: "mouse_x", action });
99
+ if ((key === "mouse_y" || key === null) && action === MOUSE_ACTION.MOVE)
100
+ call({ key: "mouse_y", action });
101
+ });
102
+ if (this.mouseStores.has("mouse_x")) {
103
+ this.mouseStores.get("mouse_x")?.set(adjustedX);
104
+ }
105
+ if (this.mouseStores.has("mouse_y")) {
106
+ this.mouseStores.get("mouse_y")?.set(adjustedY);
107
+ }
108
+ });
109
+ window.addEventListener("contextmenu", (e) => {
110
+ e.preventDefault();
111
+ });
112
+ }
113
+ on(key, action, callback) {
114
+ let obj = { key, action, call: callback };
115
+ this.events.add(obj);
116
+ return () => {
117
+ this.events.delete(obj);
118
+ };
119
+ }
120
+ getStore(key) {
121
+ if (this.mouseStores.has(key)) {
122
+ return this.mouseStores.get(key);
123
+ }
124
+ if (key === "mouse_x" || key === "mouse_y") {
125
+ let wr = writable(this.mouseState.get(key) ?? 0);
126
+ this.mouseStores.set(key, wr);
127
+ return wr;
128
+ }
129
+ let wr = writable(this.mouseState.get(key) ?? false);
130
+ this.mouseStores.set(key, wr);
131
+ return wr;
132
+ }
133
+ isPressed(key) {
134
+ return this.mouseState.get(key) ?? false;
135
+ }
136
+ getPosition(key) {
137
+ return this.mouseState.get(key) ?? 0;
138
+ }
139
+ changeWindowDimensions(width, height) {
140
+ this.innerHeight = height;
141
+ this.innerWidth = width;
142
+ }
143
+ }
package/index.d.ts CHANGED
@@ -1,6 +1,12 @@
1
1
  export { default as Game } from "./components/Game.svelte";
2
2
  export { default as Layer } from "./components/Layer.svelte";
3
3
  export { default as GameObject } from "./components/GameObject.svelte";
4
+ export { default as MouseLeftClick } from "./components/mouse/MouseLeftClick.svelte";
5
+ export { default as MouseClickable } from "./components/mouse/MouseClickable.svelte";
6
+ export { default as MouseEventArea } from "./components/mouse/MouseEventArea.svelte";
4
7
  export * as drawables from "./components/drawables/index";
5
- export { setupDrawable, getGame } from "./setup";
8
+ export { setupDrawable, getGame, getLayer, getTriggerLayerRender } from "./setup";
6
9
  export { resolve as resolveImage } from "./components/resources/images";
10
+ export { CONTROLLER_ACTION } from "./components/controller";
11
+ export { MOUSE_ACTION } from "./components/mouse";
12
+ export type { GameContext, DrawableContext, DrawableFunction, LayerContext } from "./types/index";
package/index.js CHANGED
@@ -1,6 +1,11 @@
1
1
  export { default as Game } from "./components/Game.svelte";
2
2
  export { default as Layer } from "./components/Layer.svelte";
3
3
  export { default as GameObject } from "./components/GameObject.svelte";
4
+ export { default as MouseLeftClick } from "./components/mouse/MouseLeftClick.svelte";
5
+ export { default as MouseClickable } from "./components/mouse/MouseClickable.svelte";
6
+ export { default as MouseEventArea } from "./components/mouse/MouseEventArea.svelte";
4
7
  export * as drawables from "./components/drawables/index";
5
- export { setupDrawable, getGame } from "./setup";
8
+ export { setupDrawable, getGame, getLayer, getTriggerLayerRender } from "./setup";
6
9
  export { resolve as resolveImage } from "./components/resources/images";
10
+ export { CONTROLLER_ACTION } from "./components/controller";
11
+ export { MOUSE_ACTION } from "./components/mouse";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hi-ashleyj/llama",
3
3
  "description": "A (Very Incomplete) 2D Canvas Game Engine powered by Svelte",
4
- "version": "0.6.0",
4
+ "version": "0.8.0",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
@@ -38,6 +38,10 @@
38
38
  "./components/drawables/Text.svelte": "./components/drawables/Text.svelte",
39
39
  "./components/drawables": "./components/drawables/index.js",
40
40
  "./components/motions": "./components/motions.js",
41
+ "./components/mouse/MouseClickable.svelte": "./components/mouse/MouseClickable.svelte",
42
+ "./components/mouse/MouseEventArea.svelte": "./components/mouse/MouseEventArea.svelte",
43
+ "./components/mouse/MouseLeftClick.svelte": "./components/mouse/MouseLeftClick.svelte",
44
+ "./components/mouse": "./components/mouse.js",
41
45
  "./components/resources/images": "./components/resources/images.js",
42
46
  "./drawables": "./drawables.js",
43
47
  ".": "./index.js",
package/setup.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  import type { GameContext, LayerContext, DrawableContext, DrawableFunction } from "./types";
2
2
  export declare const setupGame: (context: GameContext) => void;
3
- export declare const setupLayer: (context: LayerContext) => ({ draw }: {
3
+ export declare const setupLayer: (context: LayerContext) => ({ draw, isStatic }: {
4
4
  draw: () => any;
5
+ isStatic: () => boolean;
5
6
  }) => () => any;
7
+ export declare const getLayer: () => LayerContext;
8
+ export declare const getTriggerLayerRender: () => () => any;
6
9
  export declare const setupDrawable: ({ assign }: Partial<DrawableContext>) => ({ draw }: {
7
10
  draw: () => DrawableFunction;
8
11
  }) => () => any;
package/setup.js CHANGED
@@ -2,6 +2,7 @@ import { getContext, setContext } from 'svelte';
2
2
  const GAME = Symbol();
3
3
  const LAYER = Symbol();
4
4
  const DRAWABLE = Symbol();
5
+ const BOX = Symbol();
5
6
  export const setupGame = function (context) {
6
7
  if (getContext(GAME)) {
7
8
  throw new Error("Cannot Mount Game inside a Game");
@@ -21,6 +22,16 @@ export const setupLayer = function (context) {
21
22
  return game.assign(ctx);
22
23
  };
23
24
  };
25
+ export const getLayer = function () {
26
+ let layer = getContext(LAYER);
27
+ if (!layer)
28
+ throw new Error("Layer context does not exist!");
29
+ return layer;
30
+ };
31
+ export const getTriggerLayerRender = function () {
32
+ let layer = getLayer();
33
+ return layer.requestFrame;
34
+ };
24
35
  export const setupDrawable = function ({ assign }) {
25
36
  let parent = getContext(DRAWABLE);
26
37
  if (assign) {
@@ -1,9 +1,10 @@
1
1
  import { Writable } from 'svelte/store';
2
2
  import { Timing } from "../components/motions";
3
3
  import { Controller } from "../components/controller";
4
+ import { Mouse } from "../components/mouse";
4
5
 
5
6
  export type GameContext = {
6
- assign: (context: { draw: Function }) => () => any,
7
+ assign: (context: { draw: Function, isStatic: () => boolean }) => () => any,
7
8
  width: Writable<number>,
8
9
  height: Writable<number>,
9
10
  background: Writable<string>,
@@ -12,6 +13,10 @@ export type GameContext = {
12
13
  onKeyboardEvent: Controller["on"],
13
14
  isKeyboardPressed: Controller["isPressed"],
14
15
  getKeyboardStore: Controller["getStore"],
16
+ onMouseEvent: Mouse["on"],
17
+ isMousePressed: Mouse["isPressed"],
18
+ getMousePosition: Mouse["getPosition"],
19
+ getMouseStore: Mouse["getStore"],
15
20
  onFrame: (callback: Function) => () => any,
16
21
  onBeforeFrame: (callback: Function) => () => any,
17
22
  onAfterFrame: (callback: Function) => () => any,
@@ -20,6 +25,7 @@ export type GameContext = {
20
25
 
21
26
  export type LayerContext = {
22
27
  assign: (context: { draw: Function }) => () => any
28
+ requestFrame: () => any;
23
29
  };
24
30
 
25
31
  export type DrawableFunction = ({}: { width: number, height: number, ctx: CanvasRenderingContext2D }, ...more: any[] ) => any;