Skip to content

Commit

Permalink
Adds Camera config option to new Game()
Browse files Browse the repository at this point in the history
Updates PhysX path, add additional ready guard
Removes un-used debug GUI from CSSGraphics
Switches default scriptRoot to yantra.gg CDN
Updates ReadMe
  • Loading branch information
Marak committed Nov 7, 2023
1 parent b05c796 commit f380825
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 89 deletions.
9 changes: 4 additions & 5 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Mantra's default 3D graphics are rendered using WebGPU and Babylon.js. Mantra's

### Matter.js + Phaser 3

For 2D, Mantra has built-in support for Phaser 3 and Matter.js. It's possible to mix and match configuration options and easily add new Graphics plugins. You can even render the same Game through [multiple graphics pipelines](https://yantra.gg/mantra/examples/solo/split-render/pong.html) at once if you need to.
For 2D, Mantra has built-in support for Phaser 3 and Matter.js. It's possible to mix and match configuration options and easily add new Graphics plugins. You can render Mantra games [entirely in CSS](https://codepen.io/Marak-Squires/pen/abXpEve). You can even render the same Game through [multiple graphics pipelines](https://yantra.gg/mantra/examples/solo/split-render/pong.html) at once if you need to.

**How is this even possible?**

Expand All @@ -57,9 +57,7 @@ Mantra is designed to start a full-featured local game instance immediately with

## Serverless Physics

Mantra is architectured from the ground up to work within Serverless environments like CloudFlare Workers or [Hathora](https://hathora.dev).

This unique architecture places Mantra at the forefront of Serverless Physics game engines.
Mantra is architectured from the ground up to work within Serverless environments like [CloudFlare Workers](https://github.com/yantra-core/mantra/tree/master/mantra-edge) or [Hathora](https://hathora.dev). This unique architecture places Mantra at the forefront of Serverless Physics game engines.

Are you still learning about [Serverless Physics](https://yantra.gg)? No worries! Mantra can also run on any standard hosting environment.

Expand All @@ -80,6 +78,7 @@ Returns a new game instance. `options` defaults to:
{
physics: 'matter', // enum, 'physx', 'matter'
graphics: ['babylon'], // array enum, 'babylon', 'phaser', 'css'
camera: 'center', // enum, 'follow', 'center'
keyboard: true, // boolean or `Keyboard` config object
mouse: true, // boolean or `Mouse` config object
collisions: false, // boolean
Expand Down Expand Up @@ -234,7 +233,7 @@ The following checklist outlines the planned features and their current status:

### Plugin System
- [X] **Everything is a Plugin**
- [ ] **All Plugin methods are event emitters**
- [X] **All Plugin methods are event emitters**
- [ ] **All Plugin events have hooks**

## Mod Support
Expand Down
38 changes: 0 additions & 38 deletions mantra-client/public/mantra.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,6 @@ body {
padding: 0;
}

#gameHolder {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: flex-start;
padding: 0;
margin: 0;
}

/* Combined styles for both canvas and .render-div */
#gameHolder>canvas,
#gameHolder>.render-div {
max-width: calc(50% - 20px);
/* Adjust this value to change the number of items per row */
margin: 10px;
/* Spacing between items */
background-color: #000;
/* Visualize the area for both canvases and divs */
/* You might want to set a min-height or a padding-top to maintain aspect ratio */
min-height: 150px;
/* Example fixed min-height */
}

/* If you have absolutely positioned content inside the canvas */
#gameHolder>canvas>* {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

/* Additional specific styles for .render-div if needed */
#gameHolder>.render-div {
/* Additional styles specific to .render-div here */
}


/* InputLegend.js Plugin */

#controlsView {
Expand Down
14 changes: 10 additions & 4 deletions mantra-game/Game.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Game {
physics = 'matter',
graphics = ['babylon'],
collisions,
camera = 'follow',
keyboard = true,
mouse = true,
isOfflineMode,
Expand All @@ -42,17 +43,20 @@ class Game {
physics,
graphics,
collisions,
camera,
keyboard,
mouse,
isOfflineMode,
options
};
this.config = config;

// Define the scriptRoot variable for loading external scripts
// In most cases you will want to load from the local directory
this.scriptRoot = './';
// To support demos and CDN based Serverless Games, we default scriptRoot to yantra.gg
this.scriptRoot = 'https://yantra.gg/mantra';

// Could be CDN or other remote location, https://yantra.gg/mantra/vendor/
// Could be another CDN or other remote location
// For local development, try this.scriptRoot = './';
if (options.scriptRoot) {
this.scriptRoot = options.scriptRoot;
}
Expand Down Expand Up @@ -194,7 +198,9 @@ class Game {
this.use(new plugins.BabylonGraphics());
}
if (graphics.includes('css')) {
this.use(new plugins.CSSGraphics());
this.use(new plugins.CSSGraphics({
camera: this.config.camera
}));
}
if (graphics.includes('phaser')) {
this.use(new plugins.PhaserGraphics());
Expand Down
58 changes: 19 additions & 39 deletions mantra-game/plugins/graphics-css/CSSGraphics.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
// CSSGraphics.js - Marak Squires 2023
import GraphicsInterface from '../../lib/GraphicsInterface.js';

class CSSGraphics extends GraphicsInterface {
constructor({ debug = true, onlineMode = true, followPlayer = false } = {}) {
constructor({ camera } = {}) {
super();
this.onlineMode = onlineMode;
this.entityStates = {};
this.debug = debug;

// config scope for convenience
let config = {
camera
};
this.config = config;

this.name = 'graphics-css';
this.followPlayer = followPlayer;
this.cameraPosition = { x: 0, y: 0 };
}

Expand All @@ -16,42 +20,17 @@ class CSSGraphics extends GraphicsInterface {
game.graphics.push(this);

this.game = game;
// Only initialize DebugGUI if debug flag is set to true
if (this.debug) {}
// leave always on ( for now )
// this.initDebugUI();

this.game.systemsManager.addSystem('graphics-css', this);

// let the graphics pipeline know the document is ready ( we could add document event listener here )
// Remark: CSSGraphics current requires no async external loading scripts
game.graphicsReady.push(self.name);

// Initialize the CSS render div
this.initCSSRenderDiv();
}

initDebugUI() {
// Create a debug UI container
this.debugUIContainer = document.createElement('div');
this.debugUIContainer.id = 'debugUIContainer';
this.debugUIContainer.style.top = '10px';
this.debugUIContainer.style.right = '10px';
this.debugUIContainer.style.width = '40vw';
this.debugUIContainer.style.height = '50vw';
this.debugUIContainer.style.background = 'rgba(0, 0, 0, 0.5)';
this.debugUIContainer.style.padding = '10px';
this.debugUIContainer.style.color = 'white';
this.debugUIContainer.style.zIndex = '9999';
this.debugUIContainer.style.position = 'absolute';

// Create a table within the debug UI container
this.debugTable = document.createElement('table');
this.debugTable.id = 'debugTable';
this.debugUIContainer.appendChild(this.debugTable);

this.renderDiv.appendChild(this.debugUIContainer);
}

initCSSRenderDiv() {
const gameHolder = document.getElementById('gameHolder');
if (!gameHolder) {
Expand Down Expand Up @@ -101,7 +80,6 @@ class CSSGraphics extends GraphicsInterface {
break;
*/
case 'BULLET':

// For PLAYER entities, create a triangle
entityElement.style.width = '0px';
entityElement.style.height = '0px';
Expand Down Expand Up @@ -129,7 +107,6 @@ class CSSGraphics extends GraphicsInterface {
return entityElement;
}


updateGraphic(entityData) {
const entityElement = document.getElementById(`entity-${entityData.id}`);
if (entityElement) {
Expand Down Expand Up @@ -165,7 +142,6 @@ class CSSGraphics extends GraphicsInterface {
return entityElement;
}


removeGraphic(entityId) {

let entity = this.game.getEntity(entityId);
Expand All @@ -180,7 +156,9 @@ class CSSGraphics extends GraphicsInterface {
}

}

updateEntityElementPosition(entityElement, {position, width, height, rotation = 0}) {

// Adjust the position based on the camera position
const adjustedPosition = {
x: position.x - this.cameraPosition.x + window.innerWidth / 2,
Expand All @@ -200,15 +178,17 @@ class CSSGraphics extends GraphicsInterface {

return entityElement;
}

update () {
const currentPlayer = this.game.getEntity(window.currentPlayerId);
if (this.followPlayer && currentPlayer && currentPlayer.position) {
this.cameraPosition.x = currentPlayer.position.x;
this.cameraPosition.y = currentPlayer.position.y;
if (this.config.camera && this.config.camera === 'follow' && currentPlayer) {
if (currentPlayer.position) {
this.cameraPosition.x = currentPlayer.position.x;
this.cameraPosition.y = currentPlayer.position.y;
}
}
}

render () {}
}

Expand Down
20 changes: 17 additions & 3 deletions mantra-game/plugins/physics-physx/PhysXPhysics.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,25 @@ class PhysXPhysics extends PhysicsInterface {
let self = this;

game.loadScripts([
'physx-js-webidl.js'
'/physx-js-webidl.js'
], () => {
this.physXReady();
})
PhysXObjectAvailable(function(){
self.physXReady();
})
});

// PhysXObjectAvailable may not be necessary, the PhysX() should immediately be available
function PhysXObjectAvailable (callback) {
if (typeof PhysX !== 'undefined') {
callback();
}
// try again in 10ms
else {
setTimeout(function () {
PhysXObjectAvailable(callback);
}, 10);
}
}
}

physXReady () {
Expand Down

0 comments on commit f380825

Please sign in to comment.