animated sprites

This commit is contained in:
Emmaline Autumn 2023-11-03 23:10:45 -06:00
parent a7e7cd139f
commit 2e039719f6
3 changed files with 127 additions and 52 deletions

45
animation/sprite.ts Normal file
View File

@ -0,0 +1,45 @@
import { Vector } from "../geometry/vector.ts";
export class SpriteAnimation {
image: HTMLImageElement;
origin: Vector;
constructor(
private imageUrl: string,
private cellWidth: number,
private cellHeight: number,
private cellCountX: number,
private cellCountY: number,
private timing = 1,
private scale = 1,
) {
this.image = new Image();
this.image.src = this.imageUrl;
this.origin = new Vector();
}
private _frameCount = 0;
private get frameCount() {
return this._frameCount += this.timing;
}
getCell() {
const time = Math.floor(this.frameCount);
const x = (time % this.cellCountX) * this.cellWidth;
const y = (Math.floor(time / this.cellCountX) % this.cellCountY) *
this.cellHeight;
return { x, y };
}
draw() {
const { x, y } = this.getCell();
doodler.drawSprite(
this.image,
new Vector(x, y),
this.cellWidth,
this.cellHeight,
this.origin,
this.cellWidth * this.scale,
this.cellHeight * this.scale,
);
}
}

View File

@ -259,6 +259,47 @@ class OriginVector extends Vector {
return new OriginVector(origin, v);
}
}
class SpriteAnimation {
imageUrl;
cellWidth;
cellHeight;
cellCountX;
cellCountY;
timing;
scale;
image;
origin;
constructor(imageUrl, cellWidth, cellHeight, cellCountX, cellCountY, timing = 1, scale = 1){
this.imageUrl = imageUrl;
this.cellWidth = cellWidth;
this.cellHeight = cellHeight;
this.cellCountX = cellCountX;
this.cellCountY = cellCountY;
this.timing = timing;
this.scale = scale;
this._frameCount = 0;
this.image = new Image();
this.image.src = this.imageUrl;
this.origin = new Vector();
}
_frameCount;
get frameCount() {
return this._frameCount += this.timing;
}
getCell() {
const time = Math.floor(this.frameCount);
const x = time % this.cellCountX * this.cellWidth;
const y = Math.floor(time / this.cellCountX) % this.cellCountY * this.cellHeight;
return {
x,
y
};
}
draw() {
const { x, y } = this.getCell();
doodler.drawSprite(this.image, new Vector(x, y), this.cellWidth, this.cellHeight, this.origin, this.cellWidth * this.scale, this.cellHeight * this.scale);
}
}
const easeInOut = (x)=>x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
const map = (value, x1, y1, x2, y2)=>(value - x1) * (y2 - x2) / (y1 - x1) + x2;
class Doodler {
@ -844,33 +885,10 @@ const img = new Image();
img.src = "./skeleton.png";
img.hidden;
document.body.append(img);
const p = new Vector(200, 200);
new Vector(200, 200);
const animSprite = new SpriteAnimation("./EngineSprites.png", 100, 20, 1, 5, .02, 5);
doodler.createLayer(()=>{
const [gamepad] = navigator.getGamepads();
if (gamepad) {
const leftX = gamepad.axes[0];
const leftY = gamepad.axes[1];
p.add(Math.min(Math.max(leftX - 0.04, 0), leftX + 0.04), Math.min(Math.max(leftY - 0.04, 0), leftY + 0.04));
const rigthX = gamepad.axes[2];
const rigthY = gamepad.axes[3];
doodler.moveOrigin({
x: -rigthX * 5,
y: -rigthY * 5
});
if (gamepad.buttons[7].value) {
doodler.scaleAt({
x: 200,
y: 200
}, 1 + gamepad.buttons[7].value / 5);
}
if (gamepad.buttons[6].value) {
doodler.scaleAt({
x: 200,
y: 200
}, 1 - gamepad.buttons[6].value / 5);
}
}
doodler.drawImageWithOutline(img, p);
animSprite.draw();
});
document.addEventListener("keyup", (e)=>{
e.preventDefault();

64
main.ts
View File

@ -1,5 +1,6 @@
/// <reference types="./global.d.ts" />
import { SpriteAnimation } from "./animation/sprite.ts";
import { initializeDoodler, Vector } from "./mod.ts";
import { ZoomableDoodler } from "./zoomableCanvas.ts";
@ -25,35 +26,46 @@ document.body.append(img);
const p = new Vector(200, 200);
const animSprite = new SpriteAnimation(
"./EngineSprites.png",
100,
20,
1,
5,
.02,
5,
);
doodler.createLayer(() => {
const [gamepad] = navigator.getGamepads();
const deadzone = 0.04;
if (gamepad) {
const leftX = gamepad.axes[0];
const leftY = gamepad.axes[1];
p.add(
Math.min(Math.max(leftX - deadzone, 0), leftX + deadzone),
Math.min(Math.max(leftY - deadzone, 0), leftY + deadzone),
);
animSprite.draw();
// const [gamepad] = navigator.getGamepads();
// const deadzone = 0.04;
// if (gamepad) {
// const leftX = gamepad.axes[0];
// const leftY = gamepad.axes[1];
// p.add(
// Math.min(Math.max(leftX - deadzone, 0), leftX + deadzone),
// Math.min(Math.max(leftY - deadzone, 0), leftY + deadzone),
// );
const rigthX = gamepad.axes[2];
const rigthY = gamepad.axes[3];
(doodler as ZoomableDoodler).moveOrigin({ x: -rigthX * 5, y: -rigthY * 5 });
// const rigthX = gamepad.axes[2];
// const rigthY = gamepad.axes[3];
// (doodler as ZoomableDoodler).moveOrigin({ x: -rigthX * 5, y: -rigthY * 5 });
if (gamepad.buttons[7].value) {
(doodler as ZoomableDoodler).scaleAt(
{ x: 200, y: 200 },
1 + (gamepad.buttons[7].value / 5),
);
}
if (gamepad.buttons[6].value) {
(doodler as ZoomableDoodler).scaleAt(
{ x: 200, y: 200 },
1 - (gamepad.buttons[6].value / 5),
);
}
}
doodler.drawImageWithOutline(img, p);
// if (gamepad.buttons[7].value) {
// (doodler as ZoomableDoodler).scaleAt(
// { x: 200, y: 200 },
// 1 + (gamepad.buttons[7].value / 5),
// );
// }
// if (gamepad.buttons[6].value) {
// (doodler as ZoomableDoodler).scaleAt(
// { x: 200, y: 200 },
// 1 - (gamepad.buttons[6].value / 5),
// );
// }
// }
// doodler.drawImageWithOutline(img, p);
// doodler.line(new Vector(100, 100), new Vector(200, 200))
// doodler.dot(new Vector(300, 300))
// doodler.fillCircle(movingVector, 6, { color: 'red' });