diff --git a/hampsterengine b/hampsterengine index 807fd4a5128f8b010e92648b14dcc20f2ffce128..fbfeacd075bf597acf3de2b5f803cd46ca6583df 160000 --- a/hampsterengine +++ b/hampsterengine @@ -1 +1 @@ -Subproject commit 807fd4a5128f8b010e92648b14dcc20f2ffce128 +Subproject commit fbfeacd075bf597acf3de2b5f803cd46ca6583df diff --git a/package-lock.json b/package-lock.json index 3f397157df3a78f99af60d6f87aec1f57e3ff5cc..c223d6a0694775bd37dcff5b4bd9851d1cb85a56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,8 @@ "packages": { "": { "dependencies": { - "jsfxr": "^1.2.2" + "jsfxr": "^1.2.2", + "stats.js": "^0.17.0" }, "devDependencies": { "advzip-bin": "^2.0.0", @@ -5943,6 +5944,12 @@ "node": ">=0.8.0" } }, + "node_modules/stats.js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==", + "license": "MIT" + }, "node_modules/statuses": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", diff --git a/package.json b/package.json index 7456c322efa58545d8d6b0a99e042f8f3d6d6726..e1117a399e14de065e451936cadcfe38d7d5ecba 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "terser": "^5.31.6" }, "dependencies": { - "jsfxr": "^1.2.2" + "jsfxr": "^1.2.2", + "stats.js": "^0.17.0" } } diff --git a/src/js/extras.js b/src/js/extras.js index d1c119a0d88540130cc8d2ec7b15ce11ea9cd780..51f186c805311f86e920f7ad8b48358647f27523 100644 --- a/src/js/extras.js +++ b/src/js/extras.js @@ -3,3 +3,5 @@ export function drawLineThroughPoint(x, y) { // draws a line across the whole canvas through a point canvas.drawLine(); } + +export const GRAVITY = 100; diff --git a/src/js/main.js b/src/js/main.js index 5d4df43d87274e643f2fb500b9c8f8266a0453bb..585c46e95f5ad73731a0916b24b92590ee2d142a 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -5,6 +5,9 @@ import Engine from "../../hampsterengine/src/engine.js"; import SoundBox from "./sb-player-small"; // import {mus_DEMOSONG} from "./songs/DEMOSONGDONOTCOMMIT"; +// dependencies used for debugging. comment out code that uses this and they won't be included +import Stats from "stats.js"; + // Rooms import {rm_mainMenu} from "./rooms/mainMenu"; import {rm_game} from "./rooms/game"; @@ -14,64 +17,100 @@ import {rm_DEBUG_music} from "./rooms/debug_music"; import {rm_DEBUG_INCURSION} from "./rooms/debug_incursion"; // Music +// There is none +// Init the engine and canvas const canvas = new Canvas('canvas'); const engine = new Engine(canvas); const assets = engine.assetStore; -// assets.addSoundBoxAudio('mus_DEMO', mus_DEMOSONG, new SoundBox()); - canvas.width = 640; canvas.height = 480; canvas.pixelRatio = 2; canvas.ctx.setTransform(canvas.pixelRatio, 0, 0, canvas.pixelRatio, 0, 0); canvas.ctx.imageSmoothingEnabled = false; -let lastClickPos = { - x: 0, y: 0 -} +engine.running = false; // Game uses this as a pause state actually -window.lastClickPos = lastClickPos; +// Parse query parameters +const query = new URLSearchParams(window.location.search) engine.registerRoom(rm_mainMenu, 'mainMenu'); engine.registerRoom(rm_game, 'game'); -//Debug rooms. Comment out to not include in build (esbuild will not import them if they arent used) engine.registerRoom(rm_DEBUG_button, 'debug_button'); engine.registerRoom(rm_DEBUG_mouse, 'debug_mouse'); -engine.registerRoom(rm_DEBUG_music, 'debug_music'); -engine.registerRoom(rm_DEBUG_INCURSION, 'debug_incursion') +// engine.registerRoom(rm_DEBUG_music, 'debug_music'); +engine.registerRoom(rm_DEBUG_INCURSION, 'debug_incursion'); + +// Init stats.js +const stats = new Stats(); +stats.showPanel(0); +document.body.appendChild( stats.dom ); function main() { - requestAnimationFrame(main); - engine.frames++; - canvas.fill(engine.room.bgColor ?? 'black'); + try { + stats.begin(); + engine.frames++; + canvas.fill(engine.room.bgColor ?? 'black'); + + engine.step(); + engine.draw(); + engine.drawGui(); + + // engine.drawCursor(); + + stats.end(); - engine.step(); - engine.draw(); - engine.drawGui(); + // Ask to run at the next frame + requestAnimationFrame(main); + } catch (e) { + engine.running = false; - engine.drawCursor(); + canvas.pixelRatio = 2; + canvas.ctx.setTransform(canvas.pixelRatio, 0, 0, canvas.pixelRatio, 0, 0); + canvas.fill('#a05555d0'); + + const logo = assets.get('splash') + canvas.drawImage(logo, 10, 10, logo.width, logo.height) + + canvas.setFillColor('black'); + canvas.drawText(e, 10, canvas.height-10, { + maxWidth: canvas.width-20, + textBaseline: 'bottom' + }); + } +} + +function physicsTick() { + if (!engine.running) return; // Paused + // Tell every object to process physics + for (let thing of engine.room.entities) { + thing.physicsTick(); + } } console.debug(engine.rooms); -if (document.location.hash) { - console.log('Requesting room', document.location.hash.substring(1)); +if (query.get('room')) { + console.log('Requesting room', query.get('room')); engine.loadDelay = 0; - engine.room = engine.getRoomIndex(document.location.hash.substring(1)); + engine.room = engine.getRoomIndex(query.get('room')); } else { engine.room = engine.getRoomIndex('mainMenu'); } // Ensure assets are loaded. function load() { + stats.begin(); if (engine.loading) { engine.loadLoop(); setTimeout(load, 1000/60); } else { main(); + setInterval(physicsTick, 1000/60); // Update physics 60 times a second } + stats.end(); } load(); diff --git a/src/js/objects.js b/src/js/objects.js index 6054b517c3aa0621eaef01a134956032a2e6282d..f9dbd59ed57dfc4e0b2f4eae304f3f20e17b7cac 100644 --- a/src/js/objects.js +++ b/src/js/objects.js @@ -1,4 +1,4 @@ -import {Thing} from "../../hampsterengine/src/things"; +import {Entity} from "../../hampsterengine/src/things"; import ButtonBorder from "../img/button.webp"; // Private @@ -24,7 +24,7 @@ function drawButton(x, y, width, height, sprite, clicked, depressedColour) { // Public -export class Button extends Thing { +export class Button extends Entity { constructor(props) { super(props); this.sprite = ButtonBorder; @@ -99,7 +99,7 @@ export class MainMenuButton extends Button { } } -export class Logo extends Thing { +export class Logo extends Entity { constructor(props) { super(props); this.spriteImage = null; @@ -117,16 +117,35 @@ export class Logo extends Thing { case 3: return 'right'; } }) - canvas.drawText('Committee of', this.x, this.y, { + canvas.drawText('Untitled', this.x, this.y, { textAlign: align, textBaseline: 'bottom', font: `12px ${font}` }) - canvas.drawText('THIRTEEN', this.x, this.y, { - textAlign: align, - textBaseline: 'top', - font: `24px ${font}` - }); } } + +// ENTITIES + +export class Player extends Entity { + constructor() { + super(); + this.height=16; + this.width=10; + this.velocity = { + x:0, y:0 + }; + } + + draw() { + canvas.setFillColor('red'); + canvas.fillRect(this.x,this.y,this.width,this.height); + } + + physicsTick() { + // Physics update 60 times a second + this.y += this.velocity.y/60; + this.x += this.velocity.x/60; + } +} diff --git a/src/js/rooms/debug_button.js b/src/js/rooms/debug_button.js index dd17d0314ec524ff65e655734472c725158539ca..e4b8c953261c14152e734b1e2467cf149accfcef 100644 --- a/src/js/rooms/debug_button.js +++ b/src/js/rooms/debug_button.js @@ -1,9 +1,9 @@ -import {Room, Thing} from "../../../hampsterengine/src/things"; +import {Room, Entity} from "../../../hampsterengine/src/things"; import {Button} from "../objects"; export const rm_DEBUG_button = new Room(); rm_DEBUG_button.bgColor = 'gray'; const demoButton = new Button(); -rm_DEBUG_button.things.push(demoButton); +rm_DEBUG_button.entities.push(demoButton); diff --git a/src/js/rooms/game.js b/src/js/rooms/game.js index 3d22f136793b627125dff0f4c744821e298ec5df..02ded7a3a0b49976625cdf3a960c0c24ac1f07a0 100644 --- a/src/js/rooms/game.js +++ b/src/js/rooms/game.js @@ -1,5 +1,26 @@ import {Room} from "../../../hampsterengine/src/things"; +import {Player} from "../objects"; +import {GRAVITY} from "../extras"; export const rm_game = new Room(); +rm_game.start = _=>{ + canvas.pixelRatio = 3; + canvas.ctx.setTransform(canvas.pixelRatio, 0, 0, canvas.pixelRatio, 0, 0); + canvas.canvas.style.cursor = 'none'; + engine.running = true; +} +rm_game.stop = _=>{ + canvas.canvas.style.cursor = 'auto'; + engine.running = false; +} +rm_game.step = _=>{ + +} + +const player = new Player(); +player.velocity.x = 0; +player.velocity.y = 0; +player.direction = 0;// Radians +rm_game.entities.push(player); diff --git a/src/js/rooms/mainMenu.js b/src/js/rooms/mainMenu.js index cefe8ac2889e93d3387964c6888ba107f114d016..3b4782bb515ff26e957e8502cd9a4d128125bfa1 100644 --- a/src/js/rooms/mainMenu.js +++ b/src/js/rooms/mainMenu.js @@ -8,14 +8,14 @@ const logo = new Logo(); logo.x = 30; logo.y = 45; logo.align = 2 -rm_mainMenu.things.push(logo); +rm_mainMenu.entities.push(logo); const newGameButton = new MainMenuButton('New Game', _=>{ engine.room = engine.getRoomIndex('game'); }); newGameButton.x = 30; newGameButton.y = 70; -rm_mainMenu.things.push(newGameButton); +rm_mainMenu.entities.push(newGameButton); rm_mainMenu.drawGui = _ => { canvas.setFillColor('#0f0f0f');