like2d 2.3.0 → 2.5.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.
@@ -52,300 +52,217 @@ export class ImageHandle {
52
52
  }
53
53
  }
54
54
  function parseColor(color) {
55
- if (typeof color === 'string') {
55
+ if (typeof color === 'string')
56
56
  return color;
57
- }
58
57
  const [r, g, b, a = 1] = color;
59
58
  return `rgba(${r * 255}, ${g * 255}, ${b * 255}, ${a})`;
60
59
  }
61
- export class Graphics {
62
- constructor(ctx) {
63
- Object.defineProperty(this, "ctx", {
64
- enumerable: true,
65
- configurable: true,
66
- writable: true,
67
- value: void 0
68
- });
69
- Object.defineProperty(this, "screenCtx", {
70
- enumerable: true,
71
- configurable: true,
72
- writable: true,
73
- value: void 0
74
- });
75
- Object.defineProperty(this, "canvases", {
76
- enumerable: true,
77
- configurable: true,
78
- writable: true,
79
- value: new Map()
80
- });
81
- Object.defineProperty(this, "backgroundColor", {
82
- enumerable: true,
83
- configurable: true,
84
- writable: true,
85
- value: [0, 0, 0, 1]
86
- });
87
- Object.defineProperty(this, "images", {
88
- enumerable: true,
89
- configurable: true,
90
- writable: true,
91
- value: new Map()
92
- });
93
- Object.defineProperty(this, "defaultFont", {
94
- enumerable: true,
95
- configurable: true,
96
- writable: true,
97
- value: '16px sans-serif'
98
- });
99
- this.screenCtx = ctx;
100
- this.ctx = ctx;
101
- ctx.font = this.defaultFont;
102
- }
103
- applyColor(color) {
104
- return parseColor(color ?? [1, 1, 1, 1]);
105
- }
106
- setStrokeProps(props) {
107
- if (!this.ctx)
108
- return;
109
- // Always reset to defaults first, then apply any custom props
110
- this.ctx.lineWidth = props?.lineWidth ?? 1;
111
- this.ctx.lineCap = props?.lineCap ?? 'butt';
112
- this.ctx.lineJoin = props?.lineJoin ?? 'miter';
113
- this.ctx.miterLimit = props?.miterLimit ?? 10;
114
- }
115
- clear() {
116
- if (!this.ctx)
117
- return;
118
- this.ctx.fillStyle = parseColor(this.backgroundColor);
119
- this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
60
+ function applyColor(color) {
61
+ return parseColor(color ?? [1, 1, 1, 1]);
62
+ }
63
+ function setStrokeProps(ctx, props) {
64
+ ctx.lineWidth = props?.lineWidth ?? 1;
65
+ ctx.lineCap = props?.lineCap ?? 'butt';
66
+ ctx.lineJoin = props?.lineJoin ?? 'miter';
67
+ ctx.miterLimit = props?.miterLimit ?? 10;
68
+ }
69
+ export function newState(ctx) {
70
+ return {
71
+ screenCtx: ctx,
72
+ currentCtx: ctx,
73
+ canvases: new Map(),
74
+ };
75
+ }
76
+ export function clear(s, color = [0, 0, 0, 1]) {
77
+ const ctx = s.currentCtx;
78
+ ctx.fillStyle = parseColor(color);
79
+ ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
80
+ }
81
+ export function rectangle(s, mode, color, rect, props) {
82
+ const ctx = s.currentCtx;
83
+ const [x, y, w, h] = rect;
84
+ const c = applyColor(color);
85
+ if (mode === 'fill') {
86
+ ctx.fillStyle = c;
87
+ ctx.fillRect(x, y, w, h);
120
88
  }
121
- setBackgroundColor(color) {
122
- this.backgroundColor = color;
123
- this.clear();
89
+ else {
90
+ setStrokeProps(ctx, props);
91
+ ctx.strokeStyle = c;
92
+ ctx.strokeRect(x, y, w, h);
124
93
  }
125
- rectangle(mode, color, rect, props) {
126
- if (!this.ctx)
127
- return;
128
- const [x, y, width, height] = rect;
129
- const parsedColor = this.applyColor(color);
130
- if (mode === 'fill') {
131
- this.ctx.fillStyle = parsedColor;
132
- this.ctx.fillRect(x, y, width, height);
133
- }
134
- else {
135
- this.setStrokeProps(props);
136
- this.ctx.strokeStyle = parsedColor;
137
- this.ctx.strokeRect(x, y, width, height);
138
- }
139
- }
140
- circle(mode, color, position, radii, props) {
141
- if (!this.ctx)
142
- return;
143
- const [x, y] = position;
144
- const parsedColor = this.applyColor(color);
145
- const [rx, ry] = typeof radii === 'number' ? [radii, radii] : radii;
146
- const [startAngle, endAngle] = props?.arc ?? [0, Math.PI * 2];
147
- const rotation = props?.angle ?? 0;
148
- this.ctx.save();
149
- this.ctx.translate(x, y);
150
- this.ctx.rotate(rotation);
151
- this.ctx.scale(rx, ry);
152
- this.ctx.beginPath();
153
- this.ctx.arc(0, 0, 1, startAngle, endAngle);
154
- this.ctx.closePath();
155
- this.ctx.restore();
156
- if (mode === 'fill') {
157
- this.ctx.fillStyle = parsedColor;
158
- this.ctx.fill();
159
- }
160
- else {
161
- this.setStrokeProps(props);
162
- this.ctx.strokeStyle = parsedColor;
163
- this.ctx.stroke();
164
- }
165
- }
166
- line(color, points, props) {
167
- if (!this.ctx || points.length < 2)
168
- return;
169
- const parsedColor = this.applyColor(color);
170
- this.setStrokeProps(props);
171
- this.ctx.beginPath();
172
- const [[x0, y0], ...rest] = points;
173
- this.ctx.moveTo(x0, y0);
174
- rest.forEach(([x, y]) => this.ctx.lineTo(x, y));
175
- this.ctx.strokeStyle = parsedColor;
176
- this.ctx.stroke();
94
+ }
95
+ export function circle(s, mode, color, position, radii, props) {
96
+ const ctx = s.currentCtx;
97
+ const [x, y] = position;
98
+ const c = applyColor(color);
99
+ const [rx, ry] = typeof radii === 'number' ? [radii, radii] : radii;
100
+ const [startAngle, endAngle] = props?.arc ?? [0, Math.PI * 2];
101
+ const rotation = props?.angle ?? 0;
102
+ ctx.save();
103
+ ctx.translate(x, y);
104
+ ctx.rotate(rotation);
105
+ ctx.scale(rx, ry);
106
+ ctx.beginPath();
107
+ ctx.arc(0, 0, 1, startAngle, endAngle);
108
+ ctx.closePath();
109
+ ctx.restore();
110
+ if (mode === 'fill') {
111
+ ctx.fillStyle = c;
112
+ ctx.fill();
177
113
  }
178
- print(color, text, position, props) {
179
- if (!this.ctx)
180
- return;
181
- const [x, y] = position;
182
- const { font = this.defaultFont, limit, align = 'left' } = props ?? {};
183
- this.ctx.fillStyle = parseColor(color);
184
- this.ctx.font = font;
185
- if (limit !== undefined) {
186
- const lines = this.wrapText(text, limit);
187
- const lineHeight = this.getFontHeight();
188
- lines.forEach((line, index) => {
189
- const lineWidth = this.ctx.measureText(line).width;
190
- const drawX = align === 'center' ? x + (limit - lineWidth) / 2 :
191
- align === 'right' ? x + limit - lineWidth : x;
192
- this.ctx.fillText(line, drawX, y + index * lineHeight);
193
- });
194
- }
195
- else {
196
- this.ctx.fillText(text, x, y);
197
- }
114
+ else {
115
+ setStrokeProps(ctx, props);
116
+ ctx.strokeStyle = c;
117
+ ctx.stroke();
198
118
  }
199
- wrapText(text, maxWidth) {
200
- if (!this.ctx)
201
- return [text];
202
- const words = text.split(' ');
203
- const [first, ...rest] = words;
204
- const lines = [];
205
- let currentLine = first ?? '';
206
- rest.forEach((word) => {
207
- const width = this.ctx.measureText(currentLine + ' ' + word).width;
208
- if (width < maxWidth) {
209
- currentLine += ' ' + word;
210
- }
211
- else {
212
- lines.push(currentLine);
213
- currentLine = word;
214
- }
119
+ }
120
+ export function line(s, color, points, props) {
121
+ const ctx = s.currentCtx;
122
+ if (points.length < 2)
123
+ return;
124
+ setStrokeProps(ctx, props);
125
+ ctx.beginPath();
126
+ const [[x0, y0], ...rest] = points;
127
+ ctx.moveTo(x0, y0);
128
+ rest.forEach(([x, y]) => ctx.lineTo(x, y));
129
+ ctx.strokeStyle = applyColor(color);
130
+ ctx.stroke();
131
+ }
132
+ export function print(s, color, text, position, props) {
133
+ const ctx = s.currentCtx;
134
+ const [x, y] = position;
135
+ const { font = '16px sans-serif', limit, align = 'left' } = props ?? {};
136
+ ctx.fillStyle = parseColor(color);
137
+ ctx.font = font;
138
+ if (limit !== undefined) {
139
+ const lines = wrapText(ctx, text, limit);
140
+ const lineHeight = getFontHeight(ctx);
141
+ lines.forEach((line, i) => {
142
+ const lineWidth = ctx.measureText(line).width;
143
+ const drawX = align === 'center' ? x + (limit - lineWidth) / 2
144
+ : align === 'right' ? x + limit - lineWidth
145
+ : x;
146
+ ctx.fillText(line, drawX, y + i * lineHeight);
215
147
  });
216
- lines.push(currentLine);
217
- return lines;
218
- }
219
- getFontHeight() {
220
- if (!this.ctx)
221
- return 16;
222
- const match = this.ctx.font.match(/(\d+)px/);
223
- return match ? parseInt(match[1]) : 16;
224
148
  }
225
- setFont(size, font = 'sans-serif') {
226
- if (!this.ctx)
227
- return;
228
- this.defaultFont = `${size}px ${font}`;
229
- this.ctx.font = this.defaultFont;
149
+ else {
150
+ ctx.fillText(text, x, y);
230
151
  }
231
- getFont() {
232
- return this.defaultFont;
233
- }
234
- newImage(path) {
235
- let handle = this.images.get(path);
236
- if (!handle) {
237
- handle = new ImageHandle(path);
238
- this.images.set(path, handle);
239
- }
240
- return handle;
241
- }
242
- draw(handle, position, props) {
243
- if (!this.ctx)
244
- return;
245
- const imageHandle = this.images.get(handle.path);
246
- if (!imageHandle?.isReady())
247
- return;
248
- const element = imageHandle.getElement();
249
- if (!element)
250
- return;
251
- const [x, y] = position;
252
- const { r = 0, scale = 1, origin = 0, quad } = props ?? {};
253
- const [sx, sy] = typeof scale === 'number' ? [scale, scale] : scale;
254
- const [ox, oy] = typeof origin === 'number' ? [origin, origin] : origin;
255
- this.ctx.save();
256
- this.ctx.translate(x, y);
257
- this.ctx.rotate(r);
258
- this.ctx.scale(sx, sy);
259
- if (quad) {
260
- const [qx, qy, qw, qh] = quad;
261
- this.ctx.drawImage(element, qx, qy, qw, qh, -ox, -oy, qw, qh);
152
+ }
153
+ function wrapText(ctx, text, maxWidth) {
154
+ const words = text.split(' ');
155
+ const [first, ...rest] = words;
156
+ const lines = [];
157
+ let current = first ?? '';
158
+ rest.forEach(word => {
159
+ if (ctx.measureText(current + ' ' + word).width < maxWidth) {
160
+ current += ' ' + word;
262
161
  }
263
162
  else {
264
- this.ctx.drawImage(element, -ox, -oy);
163
+ lines.push(current);
164
+ current = word;
265
165
  }
266
- this.ctx.restore();
166
+ });
167
+ lines.push(current);
168
+ return lines;
169
+ }
170
+ function getFontHeight(ctx) {
171
+ const match = ctx.font.match(/(\d+)px/);
172
+ return match ? parseInt(match[1]) : 16;
173
+ }
174
+ export function drawImage(s, handle, position, props) {
175
+ const ctx = s.currentCtx;
176
+ if (!handle.isReady())
177
+ return;
178
+ const element = handle.getElement();
179
+ if (!element)
180
+ return;
181
+ const [x, y] = position;
182
+ const { r = 0, scale = 1, origin = 0, quad } = props ?? {};
183
+ const [sx, sy] = typeof scale === 'number' ? [scale, scale] : scale;
184
+ const [ox, oy] = typeof origin === 'number' ? [origin, origin] : origin;
185
+ ctx.save();
186
+ ctx.translate(x, y);
187
+ ctx.rotate(r);
188
+ ctx.scale(sx, sy);
189
+ if (quad) {
190
+ const [qx, qy, qw, qh] = quad;
191
+ ctx.drawImage(element, qx, qy, qw, qh, -ox, -oy, qw, qh);
267
192
  }
268
- getCanvasSize() {
269
- const width = this.ctx?.canvas.width ?? 800;
270
- const height = this.ctx?.canvas.height ?? 600;
271
- return [width, height];
193
+ else {
194
+ ctx.drawImage(element, -ox, -oy);
272
195
  }
273
- newCanvas(size) {
274
- const [width, height] = size;
275
- const element = document.createElement('canvas');
276
- element.width = width;
277
- element.height = height;
278
- const ctx = element.getContext('2d');
279
- if (!ctx) {
280
- throw new Error('Failed to create canvas context');
281
- }
282
- const canvas = { size, element, ctx };
283
- this.canvases.set(canvas, true);
284
- return canvas;
196
+ ctx.restore();
197
+ }
198
+ export function getCanvasSize(s) {
199
+ return [s.currentCtx.canvas.width, s.currentCtx.canvas.height];
200
+ }
201
+ export function newCanvas(s, size) {
202
+ const [w, h] = size;
203
+ const element = document.createElement('canvas');
204
+ element.width = w;
205
+ element.height = h;
206
+ const ctx = element.getContext('2d');
207
+ if (!ctx)
208
+ throw new Error('Failed to create canvas context');
209
+ const canvas = { size, element, ctx };
210
+ s.canvases.set(canvas, true);
211
+ return canvas;
212
+ }
213
+ export function setCanvas(s, canvas) {
214
+ s.currentCtx = canvas?.ctx ?? s.screenCtx;
215
+ }
216
+ export function clip(s, rect) {
217
+ const ctx = s.currentCtx;
218
+ ctx.beginPath();
219
+ if (rect) {
220
+ const [x, y, w, h] = rect;
221
+ ctx.rect(x, y, w, h);
285
222
  }
286
- setCanvas(canvas) {
287
- if (canvas) {
288
- this.ctx = canvas.ctx;
289
- }
290
- else {
291
- this.ctx = this.screenCtx;
292
- }
223
+ else {
224
+ ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
293
225
  }
294
- clip(rect) {
295
- if (!this.ctx)
296
- return;
297
- if (rect) {
298
- const [x, y, w, h] = rect;
299
- this.ctx.beginPath();
300
- this.ctx.rect(x, y, w, h);
301
- this.ctx.clip();
302
- }
303
- else {
304
- this.ctx.beginPath();
305
- this.ctx.rect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
306
- this.ctx.clip();
307
- }
226
+ ctx.clip();
227
+ }
228
+ export function polygon(s, mode, color, points, props) {
229
+ const ctx = s.currentCtx;
230
+ if (points.length < 3)
231
+ return;
232
+ const c = applyColor(color);
233
+ ctx.beginPath();
234
+ const [[x0, y0], ...rest] = points;
235
+ ctx.moveTo(x0, y0);
236
+ rest.forEach(([x, y]) => ctx.lineTo(x, y));
237
+ ctx.closePath();
238
+ if (mode === 'fill') {
239
+ ctx.fillStyle = c;
240
+ ctx.fill();
308
241
  }
309
- polygon(mode, color, points, props) {
310
- if (!this.ctx || points.length < 3)
311
- return;
312
- const parsedColor = this.applyColor(color);
313
- this.ctx.beginPath();
314
- const [[x0, y0], ...rest] = points;
315
- this.ctx.moveTo(x0, y0);
316
- rest.forEach(([x, y]) => this.ctx.lineTo(x, y));
317
- this.ctx.closePath();
318
- if (mode === 'fill') {
319
- this.ctx.fillStyle = parsedColor;
320
- this.ctx.fill();
321
- }
322
- else {
323
- this.setStrokeProps(props);
324
- this.ctx.strokeStyle = parsedColor;
325
- this.ctx.stroke();
326
- }
242
+ else {
243
+ setStrokeProps(ctx, props);
244
+ ctx.strokeStyle = c;
245
+ ctx.stroke();
327
246
  }
328
- arc(mode, x, y, radius, angle1, angle2, props) {
329
- if (!this.ctx)
330
- return;
331
- const color = this.applyColor(props?.color);
332
- this.ctx.beginPath();
333
- this.ctx.arc(x, y, radius, angle1, angle2);
334
- if (mode === 'fill') {
335
- this.ctx.fillStyle = color;
336
- this.ctx.fill();
337
- }
338
- else {
339
- this.setStrokeProps(props);
340
- this.ctx.strokeStyle = color;
341
- this.ctx.stroke();
247
+ }
248
+ export function points(s, color, pts) {
249
+ const ctx = s.currentCtx;
250
+ ctx.fillStyle = applyColor(color);
251
+ pts.forEach(([x, y]) => ctx.fillRect(x, y, 1, 1));
252
+ }
253
+ export function newImage(path) {
254
+ return new ImageHandle(path);
255
+ }
256
+ const graphicsFns = {
257
+ clear, rectangle, circle, line, print,
258
+ draw: drawImage, getCanvasSize, newCanvas, setCanvas,
259
+ clip, polygon, points,
260
+ };
261
+ export function bindGraphics(s) {
262
+ return new Proxy({}, {
263
+ get(_, prop) {
264
+ const fn = graphicsFns[prop];
265
+ return fn ? (...args) => fn(s, ...args) : undefined;
342
266
  }
343
- }
344
- points(color, points) {
345
- if (!this.ctx)
346
- return;
347
- const parsedColor = this.applyColor(color);
348
- this.ctx.fillStyle = parsedColor;
349
- points.forEach(([x, y]) => this.ctx.fillRect(x, y, 1, 1));
350
- }
267
+ });
351
268
  }
@@ -0,0 +1,54 @@
1
+ import type { Audio } from './audio';
2
+ import type { Timer } from './timer';
3
+ import type { Input } from './input';
4
+ import type { Keyboard } from './keyboard';
5
+ import type { Mouse } from './mouse';
6
+ import type { Gamepad } from './gamepad';
7
+ import type { Vector2 } from './vector2';
8
+ import type { CanvasMode, PartialCanvasMode } from './canvas-config';
9
+ import type { BoundGraphics } from './graphics';
10
+ /**
11
+ * The Like interface provides access to all core systems and APIs
12
+ * that are passed to game callbacks (load, update, draw, etc.).
13
+ *
14
+ * This is the main interface for interacting with the engine's subsystems.
15
+ */
16
+ export interface Like {
17
+ /** Audio system for managing and playing sounds */
18
+ readonly audio: Audio;
19
+ /** Timer system for tracking time, delta, and FPS */
20
+ readonly timer: Timer;
21
+ /** Input system for action-based input handling */
22
+ readonly input: Input;
23
+ /** Keyboard input handling */
24
+ readonly keyboard: Keyboard;
25
+ /** Mouse input handling */
26
+ readonly mouse: Mouse;
27
+ /** Gamepad input handling */
28
+ readonly gamepad: Gamepad;
29
+ /** Graphics context for rendering operations */
30
+ readonly gfx: BoundGraphics;
31
+ /**
32
+ * Set the canvas display mode.
33
+ * @param mode - Partial canvas mode configuration
34
+ */
35
+ setMode(mode: PartialCanvasMode): void;
36
+ /**
37
+ * Get the current canvas mode configuration.
38
+ * @returns The current canvas mode or undefined if not available
39
+ */
40
+ getMode(): CanvasMode | undefined;
41
+ /**
42
+ * Get the current canvas size in pixels.
43
+ * @returns The canvas size as a Vector2 [width, height]
44
+ */
45
+ getCanvasSize(): Vector2;
46
+ }
47
+ export type { Audio, Source, SourceOptions } from './audio';
48
+ export type { Timer } from './timer';
49
+ export type { Input, InputBinding, InputType } from './input';
50
+ export type { Keyboard } from './keyboard';
51
+ export type { Mouse, MousePositionTransform } from './mouse';
52
+ export type { Gamepad, StickPosition, ButtonCallback } from './gamepad';
53
+ export type { CanvasMode, PartialCanvasMode } from './canvas-config';
54
+ //# sourceMappingURL=like.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"like.d.ts","sourceRoot":"","sources":["../../src/core/like.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,WAAW,IAAI;IACnB,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,6BAA6B;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAE5B;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAEvC;;;OAGG;IACH,OAAO,IAAI,UAAU,GAAG,SAAS,CAAC;IAElC;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC;CAC1B;AAGD,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC5D,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAC7D,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACxE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ export interface PlayerState {
2
+ pos: [number, number];
3
+ speed: number;
4
+ }
5
+ export interface MovementInput {
6
+ left: boolean;
7
+ right: boolean;
8
+ up: boolean;
9
+ down: boolean;
10
+ }
11
+ /**
12
+ * Calculate new player position based on input and delta time.
13
+ * Handles movement in 4 directions with speed scaling and boundary clamping.
14
+ */
15
+ export declare function updatePlayerPosition(player: PlayerState, input: MovementInput, dt: number, minBounds: [number, number], maxBounds: [number, number]): [number, number];
16
+ //# sourceMappingURL=player-movement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player-movement.d.ts","sourceRoot":"","sources":["../../src/core/player-movement.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,aAAa,EACpB,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,CAAC,MAAM,EAAE,MAAM,CAAC,CAalB"}
@@ -0,0 +1,20 @@
1
+ import { Vec2 } from '../core/vector2';
2
+ /**
3
+ * Calculate new player position based on input and delta time.
4
+ * Handles movement in 4 directions with speed scaling and boundary clamping.
5
+ */
6
+ export function updatePlayerPosition(player, input, dt, minBounds, maxBounds) {
7
+ let moveDelta = [0, 0];
8
+ if (input.left)
9
+ moveDelta = Vec2.add(moveDelta, [-1, 0]);
10
+ if (input.right)
11
+ moveDelta = Vec2.add(moveDelta, [1, 0]);
12
+ if (input.up)
13
+ moveDelta = Vec2.add(moveDelta, [0, -1]);
14
+ if (input.down)
15
+ moveDelta = Vec2.add(moveDelta, [0, 1]);
16
+ // Apply movement with speed scaling
17
+ const newPos = Vec2.add(player.pos, Vec2.mul(moveDelta, player.speed * dt));
18
+ // Keep player in bounds
19
+ return Vec2.clamp(newPos, minBounds, maxBounds);
20
+ }
package/dist/engine.d.ts CHANGED
@@ -1,42 +1,23 @@
1
- import type { Graphics } from './core/graphics';
2
- import type { Audio } from './core/audio';
3
- import type { Input } from './core/input';
4
- import type { Timer } from './core/timer';
5
- import type { Keyboard } from './core/keyboard';
6
- import type { Mouse } from './core/mouse';
7
- import type { Gamepad } from './core/gamepad';
8
1
  import type { Like2DEvent } from './core/events';
9
- import type { CanvasConfig } from './core/canvas-config';
10
- export type EngineDeps = {
11
- graphics: Graphics;
12
- input: Input;
13
- timer: Timer;
14
- audio: Audio;
15
- keyboard: Keyboard;
16
- mouse: Mouse;
17
- gamepad: Gamepad;
18
- };
2
+ import type { PartialCanvasMode } from './core/canvas-config';
3
+ import type { Like } from './core/like';
4
+ export type { CanvasMode, PartialCanvasMode } from './core/canvas-config';
19
5
  export declare class Engine {
20
6
  private canvas;
21
7
  private ctx;
22
- private deps;
23
8
  private isRunning;
24
9
  private lastTime;
25
10
  private container;
26
11
  private canvasManager;
27
12
  private onEvent;
13
+ readonly like: Like;
28
14
  constructor(container: HTMLElement);
29
- setScaling(config: CanvasConfig): void;
30
- setDeps(deps: EngineDeps): void;
31
- dispose(): void;
15
+ private handleFullscreenChange;
16
+ setMode(mode: PartialCanvasMode): void;
32
17
  private dispatchEvent;
33
- start(onEvent: (event: Like2DEvent) => void): void;
18
+ start(onEvent: (event: Like2DEvent) => void): Promise<void>;
34
19
  stop(): void;
35
- setSize(width: number, height: number): void;
36
- getTime(): number;
37
- getCanvas(): HTMLCanvasElement;
38
- getContext(): CanvasRenderingContext2D;
39
- transformMousePosition(cssX: number, cssY: number): [number, number];
40
- toggleFullscreen(): void;
20
+ dispose(): void;
21
+ getCanvasSize(): [number, number];
41
22
  }
42
23
  //# sourceMappingURL=engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,OAAO,CAA+C;gBAElD,SAAS,EAAE,WAAW;IAmBlC,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAItC,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAI/B,OAAO,IAAI,IAAI;IAWf,OAAO,CAAC,aAAa;IAMrB,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI;IA+C3C,IAAI;IAIJ,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAKrC,OAAO,IAAI,MAAM;IAIjB,SAAS,IAAI,iBAAiB;IAI9B,UAAU,IAAI,wBAAwB;IAItC,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAIpE,gBAAgB,IAAI,IAAI;CAOzB"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE1E,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,OAAO,CAA+C;IAG9D,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;gBAER,SAAS,EAAE,WAAW;IAgElC,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAgBtC,OAAO,CAAC,aAAa;IAMf,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI;IAgCjD,IAAI;IAIJ,OAAO,IAAI,IAAI;IAWf,aAAa,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;CAGlC"}