animation basics
This commit is contained in:
parent
627ce43e4f
commit
ff593dcd92
@ -26,6 +26,9 @@ export class Drawable {
|
||||
throw new Error("draw() must be implemented on child class");
|
||||
}
|
||||
|
||||
// do nothing by default
|
||||
update() {}
|
||||
|
||||
// setters
|
||||
|
||||
fill(color) {
|
||||
|
34
artworld/timer.js
Normal file
34
artworld/timer.js
Normal file
@ -0,0 +1,34 @@
|
||||
export class Timer {
|
||||
constructor() {
|
||||
this._pausedAt = null;
|
||||
this._elapsed = 0;
|
||||
this._lastStarted = performance.now();
|
||||
}
|
||||
|
||||
pause() {
|
||||
if (!this.isPaused) {
|
||||
this._pausedAt = performance.now();
|
||||
// store time since last pause
|
||||
this._elapsed += this._pausedAt - this._lastStarted;
|
||||
}
|
||||
}
|
||||
|
||||
unpause() {
|
||||
if (this.isPaused) {
|
||||
this.lastStarted = performance.now();
|
||||
this._pausedAt = null;
|
||||
}
|
||||
}
|
||||
|
||||
get isPaused() {
|
||||
return this._pausedAt !== null;
|
||||
}
|
||||
|
||||
time() {
|
||||
if (this.isPaused) {
|
||||
return this._elapsed;
|
||||
} else {
|
||||
return this._elapsed + (performance.now() - this._lastStarted);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,14 @@
|
||||
import { Timer } from "./timer.js";
|
||||
|
||||
export class World {
|
||||
constructor() {
|
||||
this.drawables = [];
|
||||
this.ctx = null;
|
||||
this.drawables = [];
|
||||
this.backgroundColor = "white";
|
||||
this.timer = new Timer();
|
||||
this.targetFrameRate = 60;
|
||||
this.stepSize = 1000 / this.targetFrameRate;
|
||||
this.lastTick = this.timer.time();
|
||||
}
|
||||
|
||||
bindCanvas(id) {
|
||||
@ -16,16 +23,39 @@ export class World {
|
||||
return this.ctx.canvas.height;
|
||||
}
|
||||
|
||||
// TODO rename
|
||||
register(drawable) {
|
||||
this.drawables.push(drawable);
|
||||
}
|
||||
|
||||
draw() {
|
||||
this.ctx.fillStyle = "white";
|
||||
this.ctx.beginPath();
|
||||
this.ctx.fillRect(0, 0, this.width, this.height);
|
||||
this.ctx.fill();
|
||||
for (let d of this.drawables.sort((a, b) => a._z_index - b._z_index)) {
|
||||
d.draw();
|
||||
}
|
||||
}
|
||||
|
||||
tick() {
|
||||
for (let d of this.drawables) {
|
||||
d.update();
|
||||
}
|
||||
}
|
||||
|
||||
loopStep() {
|
||||
window.requestAnimationFrame(() => this.loopStep());
|
||||
|
||||
let curTime = this.timer.time();
|
||||
// tick appropriate number of times
|
||||
while (curTime - this.lastTick > this.stepSize) {
|
||||
this.lastTick += this.stepSize;
|
||||
this.tick();
|
||||
}
|
||||
this.draw();
|
||||
}
|
||||
|
||||
// Canvas 2D /////////////////
|
||||
|
||||
prepareDraw(drawable) {
|
||||
|
63
examples/balls.html
Normal file
63
examples/balls.html
Normal file
@ -0,0 +1,63 @@
|
||||
<html>
|
||||
<head> </head>
|
||||
<body>
|
||||
<canvas id="mainCanvas" width="500" height="500"></canvas>
|
||||
<script type="module">
|
||||
import {
|
||||
artworld,
|
||||
Color,
|
||||
Pico8,
|
||||
Group,
|
||||
Circle,
|
||||
Random,
|
||||
Vector2,
|
||||
degToRad,
|
||||
} from "../artworld/index.js";
|
||||
artworld.bindCanvas("mainCanvas");
|
||||
window.artworld = artworld;
|
||||
|
||||
class Ball extends Circle {
|
||||
constructor() {
|
||||
super();
|
||||
this.speed = new Vector2(0, Random.between(9, 15));
|
||||
}
|
||||
|
||||
update() {
|
||||
this.move(this.speed);
|
||||
if (this.worldPos.y > artworld.height + 20) {
|
||||
this.y(-20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GravityBall extends Circle {
|
||||
constructor() {
|
||||
super();
|
||||
this.accel = new Vector2(0, 0.5);
|
||||
this.speed = Vector2.random(0, 5);
|
||||
}
|
||||
|
||||
update() {
|
||||
this.speed = this.speed.add(this.accel);
|
||||
this.move(this.speed);
|
||||
if (this.worldPos.y > artworld.height - 10) {
|
||||
this.speed = this.speed.scale(-0.98); // bounce w/ dampening
|
||||
this.y(artworld.height - 10.01);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < 21; i++) {
|
||||
new Ball()
|
||||
.pos(new Vector2(40 * i, 0))
|
||||
.radius(10)
|
||||
.fill(Pico8.BLUE);
|
||||
new GravityBall()
|
||||
.pos(new Vector2(20 + 40 * i, 0))
|
||||
.radius(10)
|
||||
.fill(Pico8.PURPLE);
|
||||
}
|
||||
artworld.loopStep();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user