Compare commits
No commits in common. "2b87a57d43fe407299d73ff7380f5251c112c5da" and "0320a74012f609ac3c975570684b0b09bcdd5f75" have entirely different histories.
2b87a57d43
...
0320a74012
@ -197,22 +197,6 @@ Registers a gameloop function, that is called on every tick.
|
|||||||
|
|
||||||
See also: [`Models.LoopFunc`](#Models-LoopFunc)
|
See also: [`Models.LoopFunc`](#Models-LoopFunc)
|
||||||
|
|
||||||
### `width`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.width -> number;
|
|
||||||
```
|
|
||||||
|
|
||||||
Get canvas width in pixels.
|
|
||||||
|
|
||||||
### `height`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.width -> number;
|
|
||||||
```
|
|
||||||
|
|
||||||
Get canvas height in pixels.
|
|
||||||
|
|
||||||
### `isPressed`
|
### `isPressed`
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
@ -327,22 +311,6 @@ lib.startGameLoop(function () {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: Sprite images have to be loaded. This is done asynchronously, meaning a sprite might not appear on the canvas after the first call to `drawSprite`.
|
|
||||||
|
|
||||||
Note: The sprite images are cached internally on it's `name`, `width` and `height` property. If these are values are different between calls, new sprite images will be loaded. This means that after a resize, the sprite may not appear immediately.
|
|
||||||
|
|
||||||
### `drawSpriteRotated`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.drawSpriteRotated(x: number, y: number, width: number, height: number, name: string, angle: number) -> void
|
|
||||||
```
|
|
||||||
|
|
||||||
Same as `drawSprite`, but the sprite is rotate according to the `angle` parameter, specified in radians (meaning a full rotation is `2 * Math.PI`.) The sprite is rotated around the **center**.
|
|
||||||
|
|
||||||
Note: Angles have a granularity/precision of 360 steps per rotation. This is becuse sprite images are cached internally on `angle` in addition to `name`, `width` and `height`.
|
|
||||||
|
|
||||||
See also [`drawSprite`](#Lib-drawSprite).
|
|
||||||
|
|
||||||
### `drawRect`
|
### `drawRect`
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
@ -367,45 +335,6 @@ lib.startGameLoop(function () {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### `drawLine`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.drawLine(x0: number, y0: number, x1: number, y1: number, thickness: number, color: string) -> void
|
|
||||||
```
|
|
||||||
|
|
||||||
Draws a line.
|
|
||||||
|
|
||||||
### `drawPath`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.drawPath(path: [number, number][], color: string) -> void
|
|
||||||
```
|
|
||||||
|
|
||||||
Fills an arbitrary polygon with [`Color`](#Models-Color).
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.drawPath([
|
|
||||||
[0, 0],
|
|
||||||
[10, 0],
|
|
||||||
[10, 10],
|
|
||||||
[0, 10],
|
|
||||||
], "blue");
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: The `path` array must contain at minimum 1 element.
|
|
||||||
|
|
||||||
### `drawPathLine`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.drawPathLine(path: [number, number][], thickness: number, color: string) -> void
|
|
||||||
```
|
|
||||||
|
|
||||||
Draws the outline of an arbitrary polygon.
|
|
||||||
|
|
||||||
See also [`drawPath`](#Lib-drawPath).
|
|
||||||
|
|
||||||
### `onMouseMove`
|
### `onMouseMove`
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
|||||||
118
src/gamelib.js
118
src/gamelib.js
@ -106,15 +106,19 @@ export class Gamelib {
|
|||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
#loadSprite(width, height, name) {
|
drawSprite(x, y, width, height, name) {
|
||||||
|
const cx = this.cx;
|
||||||
const spriteId = `${name}_${width}x${height}`;
|
const spriteId = `${name}_${width}x${height}`;
|
||||||
|
|
||||||
if (this.spriteCache.has(spriteId)) {
|
if (this.spriteCache.has(spriteId)) {
|
||||||
return this.spriteCache.get(spriteId);
|
const sprite = this.spriteCache.get(spriteId);
|
||||||
|
cx.drawImage(sprite, x, y);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start by caching an empty canvas
|
// start by caching an empty canvas
|
||||||
const sprite = new OffscreenCanvas(width, height);
|
const canvas = new OffscreenCanvas(width, height);
|
||||||
this.spriteCache.set(spriteId, sprite);
|
this.spriteCache.set(spriteId, canvas);
|
||||||
|
|
||||||
const image = new Image();
|
const image = new Image();
|
||||||
image.src = this.assetProvider.url(name);
|
image.src = this.assetProvider.url(name);
|
||||||
@ -123,60 +127,8 @@ export class Gamelib {
|
|||||||
const spriteCx = sprite.getContext("2d");
|
const spriteCx = sprite.getContext("2d");
|
||||||
spriteCx.drawImage(image, 0, 0);
|
spriteCx.drawImage(image, 0, 0);
|
||||||
|
|
||||||
const invalidatedKeys = this.spriteCache.keys()
|
// does it make sense to draw post fectum?
|
||||||
.filter((key) => key.startsWith(`${spriteId}r`));
|
|
||||||
for (const key of invalidatedKeys) {
|
|
||||||
this.spriteCache.delete(key);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawSprite(x, y, width, height, name) {
|
|
||||||
const cx = this.cx;
|
|
||||||
|
|
||||||
const sprite = this.#loadSprite(width, height, name);
|
|
||||||
cx.drawImage(sprite, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawSpriteRotated(x, y, width, height, name, angle) {
|
|
||||||
const cx = this.cx;
|
|
||||||
|
|
||||||
const angleIncrement = Math.PI * 2 / 360;
|
|
||||||
const angleNormalized = Math.floor((angle % (Math.PI * 2)) / angleIncrement) *
|
|
||||||
angleIncrement;
|
|
||||||
|
|
||||||
const rotatedSpriteId = `${name}_${width}x${height}r${angleNormalized}`;
|
|
||||||
if (this.spriteCache.has(rotatedSpriteId)) {
|
|
||||||
const sprite = this.spriteCache.get(rotatedSpriteId);
|
|
||||||
cx.drawImage(sprite, x, y);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sprite = this.#loadSprite(width, height, name);
|
|
||||||
|
|
||||||
const newSprite = new OffscreenCanvas(sprite.width, sprite.height);
|
|
||||||
const newSpriteCx = newSprite.getContext("2d");
|
|
||||||
|
|
||||||
newSpriteCx.imageSmoothingEnabled = false;
|
|
||||||
newSpriteCx.save();
|
|
||||||
newSpriteCx.translate(sprite.width / 2, sprite.height / 2);
|
|
||||||
newSpriteCx.rotate(angleNormalized);
|
|
||||||
|
|
||||||
newSpriteCx.drawImage(
|
|
||||||
sprite,
|
|
||||||
-sprite.width / 2,
|
|
||||||
-sprite.height / 2,
|
|
||||||
sprite.width,
|
|
||||||
sprite.height,
|
|
||||||
);
|
|
||||||
|
|
||||||
newSpriteCx.restore();
|
|
||||||
|
|
||||||
cx.drawImage(newSprite, x, y);
|
|
||||||
|
|
||||||
this.spriteCache.set(rotatedSpriteId, newSprite);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clear(color) {
|
clear(color) {
|
||||||
@ -193,42 +145,6 @@ export class Gamelib {
|
|||||||
cx.fillRect(x, y, width, height);
|
cx.fillRect(x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawLine(x0, y0, x1, y1, thickness, color) {
|
|
||||||
const cx = this.cx;
|
|
||||||
|
|
||||||
cx.strokeStyle = color;
|
|
||||||
cx.lineWidth = thickness;
|
|
||||||
cx.beginPath();
|
|
||||||
cx.moveTo(x0, y0);
|
|
||||||
cx.lineTo(x1, y1);
|
|
||||||
cx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
drawPath(path, color) {
|
|
||||||
const cx = this.cx;
|
|
||||||
|
|
||||||
cx.fillStyle = color;
|
|
||||||
cx.beginPath();
|
|
||||||
cx.moveTo(path[0][0], path[0][1]);
|
|
||||||
for (const [x, y] of path.slice(1)) {
|
|
||||||
cx.lineTo(x, y);
|
|
||||||
}
|
|
||||||
cx.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
drawPathLine(path, thickness, color) {
|
|
||||||
const cx = this.cx;
|
|
||||||
|
|
||||||
cx.strokeStyle = color;
|
|
||||||
cx.lineWidth = thickness;
|
|
||||||
cx.beginPath();
|
|
||||||
cx.moveTo(path[0][0], path[0][1]);
|
|
||||||
for (const [x, y] of path.slice(1)) {
|
|
||||||
cx.lineTo(x, y);
|
|
||||||
}
|
|
||||||
cx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
drawText(x, y, text, style = {}) {
|
drawText(x, y, text, style = {}) {
|
||||||
const cx = this.cx;
|
const cx = this.cx;
|
||||||
|
|
||||||
@ -323,10 +239,6 @@ export class GamelibAdapter {
|
|||||||
this.gamelib.drawSprite(x, y, width, height, name);
|
this.gamelib.drawSprite(x, y, width, height, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawSpriteRotated(x, y, width, height, name, angle) {
|
|
||||||
this.gamelib.drawSpriteRotated(x, y, width, height, name, angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
rgb(red, green, blue) {
|
rgb(red, green, blue) {
|
||||||
return `rgb(${red}, ${green}, ${blue})`;
|
return `rgb(${red}, ${green}, ${blue})`;
|
||||||
}
|
}
|
||||||
@ -339,18 +251,6 @@ export class GamelibAdapter {
|
|||||||
this.gamelib.drawRect(x, y, width, height, color);
|
this.gamelib.drawRect(x, y, width, height, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawLine(x0, y0, x1, y1, thickness, color) {
|
|
||||||
this.gamelib.drawLine(x0, y0, x1, y1, thickness, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawPath(path, color) {
|
|
||||||
this.gamelib.drawPath(path, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawPathLine(path, thickness, color) {
|
|
||||||
this.gamelib.drawPathLine(path, thickness, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawText(x, y, text, style = {}) {
|
drawText(x, y, text, style = {}) {
|
||||||
this.gamelib.drawText(x, y, text, style);
|
this.gamelib.drawText(x, y, text, style);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user