kippy 0.1.0 → 0.2.1
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.
- package/README.md +50 -22
- package/dist/entity.d.ts +4 -2
- package/dist/entity.js +6 -7
- package/dist/game.d.ts +5 -2
- package/dist/game.js +23 -10
- package/dist/physics.d.ts +26 -0
- package/dist/physics.js +36 -0
- package/dist/sprite.js +2 -2
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,6 +31,9 @@ const game = new Game({
|
|
|
31
31
|
|
|
32
32
|
// Start the game loop
|
|
33
33
|
game.start();
|
|
34
|
+
|
|
35
|
+
// You can also swap canvas if you want
|
|
36
|
+
// game.setCanvas(someOtherCanvas);
|
|
34
37
|
```
|
|
35
38
|
|
|
36
39
|
### Create a scene
|
|
@@ -63,7 +66,8 @@ const entity = new Entity({
|
|
|
63
66
|
sprite, // Entity's sprite to be rendered, type Sprite
|
|
64
67
|
x, // Entity's x position (centered), type number
|
|
65
68
|
y, // Entity's y position (centered), type number
|
|
66
|
-
rotation // Entity's rotation in radians, type number
|
|
69
|
+
rotation, // Entity's rotation in radians, type number
|
|
70
|
+
body, // Entity's physical body, type EntityBody
|
|
67
71
|
});
|
|
68
72
|
|
|
69
73
|
// Add it to a scene
|
|
@@ -81,50 +85,74 @@ entity.rotation; // Initialized from the "rotation" param above, 0 if not specif
|
|
|
81
85
|
|
|
82
86
|
A sprite represents what an entity looks like, the "graphics part", you can create a sprite like this:
|
|
83
87
|
```js
|
|
88
|
+
import { Sprite } from "kippy";
|
|
89
|
+
|
|
84
90
|
const sprite = new Sprite({
|
|
85
|
-
texture, // Sprite's texture
|
|
91
|
+
texture, // Sprite's texture - HTMLImageElement, HTMLCanvasElement, OffscreenCanvas, ImageBitmap
|
|
86
92
|
width, // Sprite's width, type number
|
|
87
93
|
height // Sprite's height, type number
|
|
88
94
|
});
|
|
89
95
|
|
|
90
96
|
// Set sprite for an entity
|
|
91
|
-
entity.
|
|
97
|
+
entity.sprite = sprite;
|
|
92
98
|
```
|
|
93
99
|
|
|
94
100
|
### Add controls
|
|
95
101
|
|
|
96
|
-
Game controls like mouse presses, key presses, and mouse cursor traking (in the game canvas, not the web window) can be done
|
|
102
|
+
Game controls like mouse presses, key presses, and mouse cursor traking (in the game canvas, not the web window) can be done by using the input handler from your `game` instance:
|
|
97
103
|
```js
|
|
98
|
-
const input =
|
|
99
|
-
canvas
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// You can assign it into a game during initialization
|
|
103
|
-
const game = new Game({
|
|
104
|
-
// other stuff
|
|
105
|
-
input
|
|
106
|
-
})
|
|
107
|
-
// or after
|
|
108
|
-
game.setInput(input);
|
|
104
|
+
const input = game.input;
|
|
109
105
|
```
|
|
110
106
|
|
|
111
107
|
Then in a scene's `update` method, you can use these utilities to check for key presses:
|
|
112
108
|
```js
|
|
113
109
|
// Keyboard
|
|
114
|
-
input.isKeyDown(/* Character/key here */); //
|
|
115
|
-
input.isKeyPressed(/* Character/key here */); //
|
|
116
|
-
input.isKeyReleased(/* Character/key here */); //
|
|
110
|
+
input.isKeyDown(/* Character/key here */); // true if key is held, false otherwise
|
|
111
|
+
input.isKeyPressed(/* Character/key here */); // true if key is pressed, false otherwise
|
|
112
|
+
input.isKeyReleased(/* Character/key here */); // true if key is released, false otherwise
|
|
117
113
|
// Mouse
|
|
118
|
-
input.isMouseDown(/* 0 for left, 1 for right */); //
|
|
119
|
-
input.isMousePressed(/* 0 for left, 1 for right */); //
|
|
120
|
-
input.isMouseReleased(/* 0 for left, 1 for right */); //
|
|
114
|
+
input.isMouseDown(/* 0 for left, 1 for right */); // true if mouse is held, false otherwise
|
|
115
|
+
input.isMousePressed(/* 0 for left, 1 for right */); // true if mouse is pressed, false otherwise
|
|
116
|
+
input.isMouseReleased(/* 0 for left, 1 for right */); // true if mouse is released, false otherwise
|
|
121
117
|
input.mouseX; // Current X position of mouse
|
|
122
118
|
input.mouseY; // Current Y position of mouse
|
|
123
119
|
```
|
|
124
120
|
|
|
125
121
|
### Physics
|
|
126
122
|
|
|
127
|
-
|
|
123
|
+
For movements, currently you can create a `RigidBody`:
|
|
124
|
+
```js
|
|
125
|
+
// Create a rigid body
|
|
126
|
+
const rigidBody = new RigidBody({
|
|
127
|
+
velocityX, // X velocity, type number
|
|
128
|
+
velocityY, // Y velocity, type number
|
|
129
|
+
rotationVelocity, // Angular/rotation velocity, type number
|
|
130
|
+
mass, // Entity's mass, type number
|
|
131
|
+
inertia, // Entity's inertia, type number
|
|
132
|
+
forceX, // Entity's force on X axis, type number
|
|
133
|
+
forceY, // Entity's force on Y axis, type number
|
|
134
|
+
torque, // Entity's torque/rotational force, type number
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Attach body to an entity
|
|
138
|
+
entity.body = rigidBody;
|
|
139
|
+
|
|
140
|
+
// And you can mutate these props to update movement every frame
|
|
141
|
+
entity.body.velocityX; // Set with the matching parameter above, default is 0
|
|
142
|
+
entity.body.velocityY; // Set with the matching parameter above, default is 0
|
|
143
|
+
entity.body.rotationVelocity; // Set with the matching parameter above, default is 0
|
|
144
|
+
entity.body.mass; // Set with the matching parameter above, default is 1
|
|
145
|
+
entity.body.inertia; // Set with the matching parameter above, default is 1
|
|
146
|
+
entity.body.forceX; // Set with the matching parameter above, default is 0
|
|
147
|
+
entity.body.forceY; // Set with the matching parameter above, default is 0
|
|
148
|
+
entity.body.torque; // Set with the matching parameter above, default is 0
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Collisions to be added.
|
|
152
|
+
|
|
153
|
+
### Animation
|
|
154
|
+
|
|
155
|
+
To be added, for now mutate `entity.sprite` to swap sprites and create animations manually.
|
|
128
156
|
|
|
129
157
|
### Audio
|
|
130
158
|
|
package/dist/entity.d.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
import { EntityBody } from "./physics.js";
|
|
1
2
|
import { Sprite } from "./sprite.js";
|
|
2
3
|
export interface EntityOptions {
|
|
3
4
|
sprite?: Sprite;
|
|
4
5
|
x?: number;
|
|
5
6
|
y?: number;
|
|
6
7
|
rotation?: number;
|
|
8
|
+
body?: EntityBody;
|
|
7
9
|
}
|
|
8
10
|
export declare class Entity {
|
|
9
11
|
sprite?: Sprite;
|
|
10
12
|
x: number;
|
|
11
13
|
y: number;
|
|
12
14
|
rotation: number;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
body?: EntityBody;
|
|
16
|
+
constructor(options?: EntityOptions);
|
|
15
17
|
render(ctx: CanvasRenderingContext2D): void;
|
|
16
18
|
}
|
package/dist/entity.js
CHANGED
|
@@ -3,14 +3,13 @@ export class Entity {
|
|
|
3
3
|
x;
|
|
4
4
|
y;
|
|
5
5
|
rotation;
|
|
6
|
-
|
|
6
|
+
body;
|
|
7
|
+
constructor(options = {}) {
|
|
7
8
|
this.sprite = options.sprite;
|
|
8
|
-
this.x = options.x
|
|
9
|
-
this.y = options.y
|
|
10
|
-
this.rotation = options.rotation
|
|
11
|
-
|
|
12
|
-
setSprite(sprite) {
|
|
13
|
-
this.sprite = sprite;
|
|
9
|
+
this.x = options.x ?? 0;
|
|
10
|
+
this.y = options.y ?? 0;
|
|
11
|
+
this.rotation = options.rotation ?? 0;
|
|
12
|
+
this.body = options.body;
|
|
14
13
|
}
|
|
15
14
|
render(ctx) {
|
|
16
15
|
if (this.sprite) {
|
package/dist/game.d.ts
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { Input } from "./input.js";
|
|
2
|
+
import { Physics } from "./physics.js";
|
|
2
3
|
import { Scene } from "./scene.js";
|
|
3
4
|
export interface GameOptions {
|
|
4
5
|
canvas: HTMLCanvasElement;
|
|
5
6
|
input?: Input;
|
|
7
|
+
physics?: Physics;
|
|
6
8
|
}
|
|
7
9
|
export declare class Game {
|
|
8
10
|
canvas: HTMLCanvasElement;
|
|
9
11
|
ctx: CanvasRenderingContext2D;
|
|
10
12
|
scene?: Scene;
|
|
11
13
|
lastTime: number;
|
|
12
|
-
input
|
|
14
|
+
input: Input;
|
|
15
|
+
physics: Physics;
|
|
13
16
|
constructor(options: GameOptions);
|
|
17
|
+
setCanvas(canvas: HTMLCanvasElement): void;
|
|
14
18
|
setScene(scene: Scene): void;
|
|
15
|
-
setInput(input: Input): void;
|
|
16
19
|
start(): void;
|
|
17
20
|
loop(timestamp: number): void;
|
|
18
21
|
}
|
package/dist/game.js
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
|
+
import { Input } from "./input.js";
|
|
2
|
+
import { Physics } from "./physics.js";
|
|
1
3
|
export class Game {
|
|
2
4
|
canvas;
|
|
3
5
|
ctx;
|
|
4
6
|
scene;
|
|
5
7
|
lastTime = 0;
|
|
6
8
|
input;
|
|
9
|
+
physics;
|
|
7
10
|
constructor(options) {
|
|
8
11
|
this.canvas = options.canvas;
|
|
9
12
|
this.ctx = this.canvas.getContext("2d");
|
|
10
|
-
this.input = options.input;
|
|
13
|
+
this.input = options.input ?? new Input({ canvas: this.canvas });
|
|
14
|
+
this.physics = options.physics ?? new Physics();
|
|
15
|
+
}
|
|
16
|
+
setCanvas(canvas) {
|
|
17
|
+
this.canvas = canvas;
|
|
18
|
+
this.ctx = this.canvas.getContext("2d");
|
|
11
19
|
}
|
|
12
20
|
setScene(scene) {
|
|
13
21
|
this.scene?.exit();
|
|
14
22
|
this.scene = scene;
|
|
15
23
|
this.scene.init();
|
|
16
24
|
}
|
|
17
|
-
setInput(input) {
|
|
18
|
-
this.input = input;
|
|
19
|
-
}
|
|
20
25
|
start() {
|
|
21
26
|
requestAnimationFrame(this.loop.bind(this));
|
|
22
27
|
}
|
|
@@ -24,12 +29,20 @@ export class Game {
|
|
|
24
29
|
loop(timestamp) {
|
|
25
30
|
const dt = (timestamp - this.lastTime) / 1000;
|
|
26
31
|
this.lastTime = timestamp;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
if (this.scene) {
|
|
33
|
+
// Update input info
|
|
34
|
+
this.input.update();
|
|
35
|
+
// Update game logic
|
|
36
|
+
this.scene.update(dt);
|
|
37
|
+
// Update physics info
|
|
38
|
+
this.physics.update(this.scene.entities);
|
|
39
|
+
// Render
|
|
40
|
+
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
|
|
41
|
+
this.scene.render(this.ctx);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
throw new Error("Can not run game loop without a scene");
|
|
45
|
+
}
|
|
33
46
|
requestAnimationFrame(this.loop.bind(this));
|
|
34
47
|
}
|
|
35
48
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Entity } from "./entity";
|
|
2
|
+
export interface RigidBodyOptions {
|
|
3
|
+
velocityX?: number;
|
|
4
|
+
velocityY?: number;
|
|
5
|
+
rotationVelocity?: number;
|
|
6
|
+
mass?: number;
|
|
7
|
+
inertia?: number;
|
|
8
|
+
forceX?: number;
|
|
9
|
+
forceY?: number;
|
|
10
|
+
torque?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class RigidBody {
|
|
13
|
+
velocityX: number;
|
|
14
|
+
velocityY: number;
|
|
15
|
+
rotationVelocity: number;
|
|
16
|
+
mass: number;
|
|
17
|
+
inertia: number;
|
|
18
|
+
forceX: number;
|
|
19
|
+
forceY: number;
|
|
20
|
+
torque: number;
|
|
21
|
+
constructor(options?: RigidBodyOptions);
|
|
22
|
+
}
|
|
23
|
+
export type EntityBody = RigidBody;
|
|
24
|
+
export declare class Physics {
|
|
25
|
+
update(entities: Entity[]): void;
|
|
26
|
+
}
|
package/dist/physics.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export class RigidBody {
|
|
2
|
+
velocityX;
|
|
3
|
+
velocityY;
|
|
4
|
+
rotationVelocity;
|
|
5
|
+
mass;
|
|
6
|
+
inertia;
|
|
7
|
+
forceX;
|
|
8
|
+
forceY;
|
|
9
|
+
torque;
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
this.velocityX = options.velocityX ?? 0;
|
|
12
|
+
this.velocityY = options.velocityY ?? 0;
|
|
13
|
+
this.rotationVelocity = options.rotationVelocity ?? 0;
|
|
14
|
+
this.mass = options.mass ?? 1;
|
|
15
|
+
this.inertia = options.inertia ?? 1;
|
|
16
|
+
this.forceX = options.forceX ?? 0;
|
|
17
|
+
this.forceY = options.forceY ?? 0;
|
|
18
|
+
this.torque = options.torque ?? 0;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class Physics {
|
|
22
|
+
update(entities) {
|
|
23
|
+
for (const entity of entities) {
|
|
24
|
+
if (entity.body instanceof RigidBody) {
|
|
25
|
+
// Acceleration/apply force
|
|
26
|
+
entity.body.velocityX += entity.body.forceX / entity.body.mass;
|
|
27
|
+
entity.body.velocityY += entity.body.forceY / entity.body.mass;
|
|
28
|
+
entity.body.rotationVelocity += entity.body.torque / entity.body.inertia;
|
|
29
|
+
// Positional update
|
|
30
|
+
entity.x += entity.body.velocityX;
|
|
31
|
+
entity.y += entity.body.velocityY;
|
|
32
|
+
entity.rotation += entity.body.rotationVelocity;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
package/dist/sprite.js
CHANGED
|
@@ -4,7 +4,7 @@ export class Sprite {
|
|
|
4
4
|
height;
|
|
5
5
|
constructor(options) {
|
|
6
6
|
this.texture = options.texture;
|
|
7
|
-
this.width = options.width
|
|
8
|
-
this.height = options.height
|
|
7
|
+
this.width = options.width ?? this.texture.width;
|
|
8
|
+
this.height = options.height ?? this.texture.height;
|
|
9
9
|
}
|
|
10
10
|
}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED