216 lines
5.9 KiB
JavaScript
216 lines
5.9 KiB
JavaScript
export class Gamelib {
|
|
constructor(console, assetProvider, canvasElement) {
|
|
this.console = console;
|
|
this.assetProvider = assetProvider;
|
|
|
|
this.canvas = canvasElement;
|
|
this.width = 480;
|
|
this.height = 360;
|
|
this.canvas.width = this.width;
|
|
this.canvas.height = this.height;
|
|
this.cx = this.canvas.getContext("2d");
|
|
this.cx.imageSmootingEnabled = false;
|
|
this.loopInterval = null;
|
|
|
|
this.keysPressed = new Set();
|
|
this.keyPressHandlers = new Map();
|
|
this.keyReleaseHandlers = new Map();
|
|
this.mouseMoveHandler = null;
|
|
this.mouseButtonsPressed = new Set();
|
|
this.mouseDownHandlers = new Map();
|
|
this.mouseUpHandlers = new Map();
|
|
this.mouseX = null;
|
|
this.mouseY = null;
|
|
}
|
|
|
|
init() {
|
|
document.body.addEventListener("keydown", this.keydownListener.bind(this));
|
|
document.body.addEventListener("keyup", this.keyupListener.bind(this));
|
|
|
|
this.canvas.addEventListener("mousemove", this.mousemoveListener.bind(this));
|
|
this.canvas.addEventListener("mousedown", this.mousedownListener.bind(this));
|
|
this.canvas.addEventListener("mouseup", this.mouseupListener.bind(this));
|
|
this.canvas.addEventListener("contextmenu", this.contextMenuListener.bind(this));
|
|
}
|
|
|
|
destroy() {
|
|
document.body.removeEventListener("keydown", this.keydownListener);
|
|
document.body.removeEventListener("keyup", this.keyupListener);
|
|
|
|
this.canvas.removeEventListener("mousemove", this.mousemoveListener);
|
|
this.canvas.removeEventListener("mousedown", this.mousedownListener);
|
|
this.canvas.removeEventListener("mouseup", this.mouseupListener);
|
|
this.canvas.removeEventListener("contextmenu", this.contextMenuListener);
|
|
|
|
clearInterval(this.loopInterval);
|
|
}
|
|
|
|
startGameLoop(loopFunction) {
|
|
let before = Date.now();
|
|
|
|
this.loopInterval = setInterval(() => {
|
|
const now = Date.now();
|
|
const deltaT = (now - before) / 1000;
|
|
before = now;
|
|
try {
|
|
loopFunction(deltaT);
|
|
} catch (error) {
|
|
this.console.error(error);
|
|
}
|
|
}, 16);
|
|
}
|
|
|
|
keydownListener(ev) {
|
|
this.keysPressed.add(ev.key);
|
|
this.keyPressHandlers.get(ev.key)?.();
|
|
}
|
|
|
|
keyupListener(ev) {
|
|
this.keysPressed.delete(ev.key);
|
|
this.keyReleaseHandlers.get(ev.key)?.();
|
|
}
|
|
|
|
mousemoveListener(ev) {
|
|
const ratioX = this.canvas.width / this.canvas.clientWidth;
|
|
const ratioY = this.canvas.height / this.canvas.clientHeight;
|
|
|
|
this.mouseX = ev.offsetX * ratioX;
|
|
this.mouseY = ev.offsetY * ratioY;
|
|
|
|
this.mouseMoveHandler?.(
|
|
ev.offsetX * ratioX,
|
|
ev.offsetY * ratioY,
|
|
ev.movementX * ratioX,
|
|
ev.movementY * ratioY,
|
|
);
|
|
}
|
|
|
|
mousedownListener(ev) {
|
|
const ratioX = this.canvas.width / this.canvas.clientWidth;
|
|
const ratioY = this.canvas.height / this.canvas.clientHeight;
|
|
|
|
this.mouseButtonsPressed.add(ev.button);
|
|
this.mouseDownHandlers.get(ev.button)?.(ev.offsetX * ratioX, ev.offsetY * ratioY);
|
|
}
|
|
|
|
mouseupListener(ev) {
|
|
const ratioX = this.canvas.width / this.canvas.clientWidth;
|
|
const ratioY = this.canvas.height / this.canvas.clientHeight;
|
|
|
|
this.mouseButtonsPressed.delete(ev.button);
|
|
this.mouseUpHandlers.get(ev.button)?.(ev.offsetX * ratioX, ev.offsetY * ratioY);
|
|
}
|
|
|
|
contextMenuListener(ev) {
|
|
ev.preventDefault();
|
|
}
|
|
|
|
drawSprite(x, y, width, height, name) {
|
|
const cx = this.cx;
|
|
|
|
const image = new Image();
|
|
image.src = this.assetProvider.url(name);
|
|
image.onload = () => {
|
|
cx.drawImage(image, x, y, width, height);
|
|
};
|
|
}
|
|
|
|
clear(color) {
|
|
const cx = this.cx;
|
|
|
|
cx.fillStyle = color;
|
|
cx.fillRect(0, 0, this.width, this.height);
|
|
}
|
|
|
|
drawRect(x, y, width, height, color) {
|
|
const cx = this.cx;
|
|
|
|
cx.fillStyle = color;
|
|
cx.fillRect(x, y, width, height);
|
|
}
|
|
|
|
getAdapter() {
|
|
return new GamelibAdapter(this);
|
|
}
|
|
}
|
|
|
|
export class GamelibAdapter {
|
|
MouseButton = {
|
|
Left: 0,
|
|
Right: 1,
|
|
Middle: 2,
|
|
};
|
|
|
|
constructor(gamelib) {
|
|
this.gamelib = gamelib;
|
|
}
|
|
|
|
get width() {
|
|
return this.gamelib.width;
|
|
}
|
|
|
|
get height() {
|
|
return this.gamelib.height;
|
|
}
|
|
|
|
get mouseX() {
|
|
return this.gamelib.mouseX;
|
|
}
|
|
|
|
get mouseY() {
|
|
return this.gamelib.mouseY;
|
|
}
|
|
|
|
println(msg) {
|
|
this.gamelib.console.log(msg);
|
|
}
|
|
|
|
startGameLoop(loopFunction) {
|
|
this.gamelib.startGameLoop(loopFunction);
|
|
}
|
|
|
|
isPressed(key) {
|
|
return this.gamelib.keysPressed.has(key);
|
|
}
|
|
|
|
onPress(key, handlerFunction) {
|
|
this.gamelib.keyPressHandlers.set(key, handlerFunction);
|
|
}
|
|
|
|
onRelease(key, handlerFunction) {
|
|
this.gamelib.keyReleaseHandlers.set(key, handlerFunction);
|
|
}
|
|
|
|
onMouseMove(handlerFunction) {
|
|
this.gamelib.mouseMoveHandler = handlerFunction;
|
|
}
|
|
|
|
isClicking(button = this.MouseButton.Left) {
|
|
return this.gamelib.mouseButtonsPressed.has(button);
|
|
}
|
|
|
|
onClick(handlerFunction, button = this.MouseButton.Left) {
|
|
this.gamelib.mouseDownHandlers.set(button, handlerFunction);
|
|
}
|
|
|
|
onClickRelease(handlerFunction, button = this.MouseButton.Left) {
|
|
this.gamelib.mouseUpHandlers.set(button, handlerFunction);
|
|
}
|
|
|
|
drawSprite(x, y, width, height, name) {
|
|
this.gamelib.drawSprite(x, y, width, height, name);
|
|
}
|
|
|
|
rgb(red, green, blue) {
|
|
return `rgb(${red}, ${green}, ${blue})`;
|
|
}
|
|
|
|
clear(color) {
|
|
this.gamelib.clear(color);
|
|
}
|
|
|
|
drawRect(x, y, width, height, color) {
|
|
this.gamelib.drawRect(x, y, width, height, color);
|
|
}
|
|
}
|