UNPKG

ridder

Version:

A straightforward game engine for simple data-driven games in JavaScript

211 lines (210 loc) 6.53 kB
import { getCameraPosition, getCameraShake, getCameraZoom } from "./camera.js"; import { canvas, ctx, scale } from "./canvas.js"; import { getFont } from "./fonts.js"; import { getSprite } from "./sprites.js"; import { getTexture } from "./textures.js"; import { toRadians } from "./utils.js"; const DEFAULT_LINE_SEGMENTS = []; let background = "black"; let font = "16px sans-serif"; /** * Clear the background using the set `background` color. * * @see {@link setBackgroundColor} */ export function clearBackground() { ctx.resetTransform(); ctx.fillStyle = background; ctx.fillRect(0, 0, canvas.width, canvas.height); } /** * Reset the transformation matrix, also known as the identity matrix. */ export function resetTransform() { ctx.setTransform(scale.x, 0, 0, scale.y, 0, 0); } /** * Move the origin of the transformation matrix by the given x and y values. */ export function translateTransform(x, y) { ctx.translate(x, y); } /** * Additionally scale the transformation matrix by the given x and y values. */ export function scaleTransform(x, y) { ctx.scale(x, y); } /** * Rotate the transformation matrix by the given degrees. */ export function rotateTransform(degrees) { ctx.rotate(toRadians(degrees)); } /** * Add the camera transform (position, shake) to the current transformation matrix. * @param scrollX - The scrolling factor for the x-axis, you can add a parallax effect by setting this to a value between 0 and 1. * @param scrollY - The scrolling factor for the y-axis, you can add a parallax effect by setting this to a value between 0 and 1. */ export function applyCameraTransform(scrollX = 1, scrollY = 1) { const camera = getCameraPosition(); const shake = getCameraShake(); const zoom = getCameraZoom(); const x = camera.x + shake.x / zoom; const y = camera.y + shake.y / zoom; ctx.scale(zoom, zoom); ctx.translate(-x * scrollX, -y * scrollY); } /** * Draw a texture from the cache onto the canvas. */ export function drawTexture(id, x, y) { ctx.drawImage(getTexture(id), x, y); } /** * Draw a sprite (a region within a texture) from the cache onto the canvas. */ export function drawSprite(id, x, y) { const sprite = getSprite(id); const texture = getTexture(sprite.textureId); ctx.drawImage(texture, sprite.x, sprite.y, sprite.w, sprite.h, x, y, sprite.w, sprite.h); } /** * Draw text onto the canvas. * @param color - A color value, e.g. `white` or `#ffffff` * @param align - The horizontal alignment of the text * @param baseline - The vertical alignment of the text */ export function drawText(text, x, y, color = "white", align = "left", baseline = "top") { ctx.font = font; ctx.textAlign = align; ctx.textBaseline = baseline; ctx.fillStyle = color; ctx.fillText(text, x, y); } /** * Draw outlined text onto the canvas. * @param color - A color value, e.g. `white` or `#ffffff` * @param outlineColor - A color value, e.g. `white` or `#ffffff` * @param outlineMode - The mode of the outline. Either "circle" or "square". * @param align - The horizontal alignment of the text * @param baseline - The vertical alignment of the text */ export function drawTextOutlined(text, x, y, color = "white", outlineColor = "black", outlineMode = "circle", align = "left", baseline = "top") { drawText(text, x, y - 1, outlineColor, align, baseline); drawText(text, x + 1, y, outlineColor, align, baseline); drawText(text, x, y + 1, outlineColor, align, baseline); drawText(text, x - 1, y, outlineColor, align, baseline); if (outlineMode === "square") { drawText(text, x - 1, y - 1, outlineColor, align, baseline); drawText(text, x + 1, y - 1, outlineColor, align, baseline); drawText(text, x + 1, y + 1, outlineColor, align, baseline); drawText(text, x - 1, y + 1, outlineColor, align, baseline); } drawText(text, x, y, color, align, baseline); } /** * Draw a rectangle onto the canvas. */ export function drawRect(x, y, w, h, color = "white", fill = false) { if (fill) { ctx.fillStyle = color; ctx.fillRect(x, y, w, h); } else { ctx.strokeStyle = color; ctx.strokeRect(x, y, w, h); } } /** * Draw a rectangle onto the canvas. */ export function drawRectInstance(r, color = "white", fill = false) { drawRect(r.x, r.y, r.w, r.h, color, fill); } /** * Draw a circle onto the canvas. */ export function drawCircle(x, y, r, color = "white", fill = false) { ctx.beginPath(); ctx.arc(x, y, r, 0, 2 * Math.PI); ctx.closePath(); if (fill) { ctx.fillStyle = color; ctx.fill(); } else { ctx.strokeStyle = color; ctx.stroke(); } } /** * Draw a circle onto the canvas. */ export function drawCircleInstance(c, color = "white", fill = false) { drawCircle(c.x, c.y, c.r, color, fill); } /** * Draw a polygon onto the canvas. */ export function drawPolygon(x, y, points, color = "white", fill = false) { if (points.length < 3) return; ctx.beginPath(); ctx.moveTo(x + points[0].x, y + points[0].y); for (let i = 1; i < points.length; i++) { ctx.lineTo(x + points[i].x, y + points[i].y); } ctx.closePath(); if (fill) { ctx.fillStyle = color; ctx.fill(); } else { ctx.strokeStyle = color; ctx.stroke(); } } /** * Draw a polygon onto the canvas. */ export function drawPolygonInstance(p, color = "white", fill = false) { drawPolygon(p.x, p.y, p.calcPoints, color, fill); } /** * Draw a line onto the canvas. */ export function drawLine(x1, y1, x2, y2, color = "white", segments = DEFAULT_LINE_SEGMENTS) { ctx.beginPath(); ctx.setLineDash(segments); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.strokeStyle = color; ctx.stroke(); } /** * Set the background color of the canvas. */ export function setBackgroundColor(color) { background = color; } /** * Use a font from the cache for the upcoming text rendering. */ export function setFont(id) { font = getFont(id); } /** * Set the alpha for the upcoming drawings. */ export function setAlpha(alpha) { ctx.globalAlpha = alpha; } /** * Set the blend mode for the upcoming drawings. * * For an overview of blend modes, see the bottom of [this](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) MDN page. */ export function setBlendMode(mode) { ctx.globalCompositeOperation = mode; }