Skip to content

Instantly share code, notes, and snippets.

@Trivoz
Created January 3, 2023 06:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Trivoz/92a37a6a890f883c935beb43c490200a to your computer and use it in GitHub Desktop.
Save Trivoz/92a37a6a890f883c935beb43c490200a to your computer and use it in GitHub Desktop.
Javascript canvas template
function randint(a=0, b) {
/* Return random whole number between a and b */
return Math.floor(Math.random() * (b - a + 1)) + a;
}
function choice(list) {
/* Return positive integer to index list */
index = Math.abs(Math.floor(Math.random() * (list.length - 0 + 1)) - 1);
return list[index];
}
class Player {
/* Moveable entity with physics properties */
constructor(canvas, ctx, px, py) {
/* px: position x
* py: position y
*/
if (px === undefined) {
this.x = 0;
} if (px === undefined) {
this.y = 0;
} else {
this.x = px;
this.y = py;
}
// Define size of player
this.width = 10;
this.height = 10;
// gravity contant TODO seperate non-player consts
this.gravity = 2; // pixels / second^2
// player velocity (relative to bidimensional axis)
this.vx = 0;
this.vy = 0;
// define constructor args
this.canvas = canvas;
this.ctx = ctx;
// define player color
this.color = "blue";
}
update() {
// Push current ctx state to stack
// ctx.save();
if (this.ctx.getTime() > 1000) {
// NOTE si = speed increment
let si = this.gravity * this.ctx.frame.timeInterval / 1000;
// increment velocity regulated by frametime
this.vy += si;
// set y position of player
this.y += this.vy * this.ctx.frame.timeInterval;
// Collission / border detection
if (this.y > this.canvas.height - this.height) {
this.y = this.canvas.height - this.height;
ctx.stop();
}
}
// Refresh display
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
draw() {
/* draw playre to canvas */
this.ctx.beginPath();
this.ctx.fillStyle = this.color;
// blit rect to this.canvas
this.ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
class Cursor {
/* Mouse cursor position */
constructor(canvas) {
// Cursor x and y position
this.x = 0;
this.y = 0;
// Primary display surface
this.canvas = canvas;
// Collision and rounding rect
this.rect = canvas.getBoundingClientRect();
}
get mousePosition() {
// Returns rounded mouse pos (over rect)
return (this.x, this.y);
}
}
class Grid {
/* Grid manages object position definitions */
constructor(canvas, ctx) {
this.canvas = canvas;
this.ctx = ctx;
this.width = this.canvas.width;
this.height = this.canvas.height;
}
draw() {
/* Draws black square grid onto this.canvas */
for (let w=0; w<=this.width; w+=50) {
for (let h=0; h<=this.height; h+=50) {
this.drawLine(w-50, h-50, w, h);
}
}
}
drawLine(sx, sy, ex, ey) {
/* Makes drawing lines more comprehensible (for me)
* sx: starting x position
* sy: starting y position
* ex: ending x position
* ey: ending y position
*/
this.ctx.moveTo(sx, sy);
this.ctx.lineTo(ex, ey);
// Fill line with ctx.fillStyle (default=black)
this.ctx.stroke();
}
}
class Window {
/* Event and display manager class */
constructor(canvasId) {
// entry & exit flag
this.active = true;
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext("2d");
// Storing width and height prevents having to query
// canvas size every time it's requested as it's constant.
this.width = this.canvas.width;
this.height = this.canvas.height;
// Font is changeable and inits here.
this.font = "30px Arial";
this.ctx.font = this.font;
// Instantiate cursor
this.cursor = new Cursor(this.canvas);
this.grid = new Grid(this.canvas, this.ctx);
// define fps and frame properties
this.frame = {
t: 0, // time
timeInterval: 0, // Interval between frames
st: 0, // start time
lt: 0, // last time
Frame: 0, // current frame
animating: false, // entry / exit flag
fps: 60 // frame allowance per 1000 ms
};
// create player object at 250x250 (x,y)
this.player = new Player(this.canvas, this.ctx, 250, 250);
// request animation frame
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || function(callback) {
window.setTimeout(callback, 1000 / this.frame.fps);
};
})();
// Send any mouse movement to cursor as x & y.
// this.canvas.addEventListener(
// "mousemove",
// event => {
// this.cursor.x = Math.round(event.clientX - this.cursor.rect.left);
// this.cursor.y = Math.round(event.clientY - this.cursor.rect.top);
// });
}
onLoad() {
// Toggle entry and exit flag
this.frame.animating = true;
// Create date for delatime
let date = new Date();
// Get date (time specific)
let thisTime = date.getTime();
// toggle entry flag
this.tick();
}
tick() {
// Animate frames
if (this.frame.animating) {
// call update function
requestAnimationFrame(this.update);
};
};
update() {
console.debug(this.frame.Frame);
// Increment frame by 1 value
this.frame.Frame++;
// Create date for delatime
let date = new Date();
// Get date (time specific)
let thisTime = date.getTime();
// increment t with timeinterval
this.frame.t += this.frame.timeInterval;
// append deltatime
this.frame.lt = thisTime;
};
};
// on window load instantiate Window class
window.onload = function() {
const display = new Window("this_canvas"); // NOTE *args are relative to the canvas id.
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment