- Game
See here for a live demo of the project.
You must have npm
and node
installed.
- Windows: Node.js You can also use the Windows package manager called
winget
:- Open a terminal and run
winget install nodejs
- Open a terminal and run
- macOS: Node.js
- Linux: Node.js
Start by creating a new vite
project.
npm create vite
You might need to install the create-vite
package. You'll see a prompt something like this if you do:
Need to install the following packages:
create-vite@5.2.3
Ok to proceed? (y)
Just press return and the package will install.
You'll be prompted to name your project and select a project type. Name your project and then select Vanilla
as the project type. Choose TypeScript
as your project language.
You might need to update your NPM to the latest version. You might see a message similar to the following:
npm notice
npm notice New minor version of npm available! 10.1.0 -> 10.5.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.5.0
npm notice Run npm install -g npm@10.5.0 to update!
npm notice
You can either ignore it for now or update it to the latest version.
Starting the project by following the instructions you're presented with:
cd vite-project
npm install
npm run dev
where vite-project
is whatever you named your project.
The npm run dev
command starts the project. If you press o
and then enter
, your browser will open to your project, hosted locally on your machine. If you press q
and then enter
, the project will close it.
You can edit your source while the project is running. Occasionally, you will need to either refresh your browser or restart the server. But for the most part, you can start the server and see your changes update instantly in the browser each time you save the file.
Now that you have your project up and running, you can remove the boilerplate code from the project.
First, be sure your server is stopped by using either Ctrl + C
or q
to quit.
Remove all the files in the public
and src
folders.
rm -rf public/*
rm -rf src/*
Next, you need to install the BabylonJS library. We'll also want the inspector for debugging the project.
npm install --save-dev @babylonjs/core
npm install --save-dev @babylonjs/inspector
NOTE: You can shorten the above commands with:
npm i -D @babylonjs/core @babylonjs/inspector
We need to add a <style>
tag to the index.html
file. Change your html file to look like the following:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Game</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
width: 100%;
height: 100%;
}
</style>
</html>
Here we've added a <style>
tag to the index.html
file and also removed the <link>
tag and changed the <title>
tag.
Change your tsconfig.json
file to look like the following:
{
"compilerOptions": {
"target": "ES6",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES6", "DOM"],
"skipLibCheck": true,
"removeComments": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
Here we've changed the target
to ES6
, the lib
to ES6
and DOM
, and added the removeComments
option.
Now that we have a basic project set up, we can start adding code to it. Create a new file called main.ts
and add the following code to it:
import { Scene, Engine, FreeCamera, HemisphericLight, MeshBuilder, Vector3 } from "@babylonjs/core";
class Main {
constructor() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
let engine = new Engine(canvas, true);
let scene = this.createScene(engine, canvas);
engine.runRenderLoop(function () {
scene.render();
})
}
public createScene(engine: Engine, canvas: HTMLCanvasElement): Scene {
// This creates a basic Babylon Scene object (non-mesh)
let scene = new Scene(engine);
// This creates and positions a free camera (non-mesh)
let camera = new FreeCamera("camera1", new Vector3(0, 5, -10), scene);
// This targets the camera to scene origin
camera.setTarget(Vector3.Zero());
// This attaches the camera to the canvas
camera.attachControl(canvas, true);
// This creates a light, aiming 0,1,0 - to the sky (non-mesh)
let light = new HemisphericLight("light1", new Vector3(0, 1, 0), scene);
// Default intensity is 1. Let's dim the light a small amount
light.intensity = 0.7;
// Our built-in 'sphere' shape. Params: name, options, scene
let sphere = MeshBuilder.CreateSphere("sphere", {diameter: 2, segments: 32}, scene);
// Move the sphere upward 1/2 its height
sphere.position.y = 1;
// Our built-in 'ground' shape. Params: name, options, scene
let ground = MeshBuilder.CreateGround("ground", {width: 6, height: 6}, scene);
return scene;
}
}
new Main();
Edit the main.ts
file to add the following code:
constructor() {
let canvas = document.createElement("canvas");
> canvas.style.width = '100%';
> canvas.style.height = '100%';
document.body.appendChild(canvas);
let engine = new Engine(canvas, true);
let scene = this.createScene(engine, canvas);
This will allow the canvas to fill the entire browser window.
To handle the browser changing sizes, add the following code:
constructor() {
let canvas = document.createElement("canvas");
canvas.style.width = '100%';
canvas.style.height = '100%';
document.body.appendChild(canvas);
let engine = new Engine(canvas, true);
let scene = this.createScene(engine, canvas);
> window.addEventListener("resize", function () {
> engine.resize();
> });
Add the following code to toggle fullscreen mode with Shift-Ctrl-Alt-F.
let engine = new Engine(canvas, true);
let scene = this.createScene(engine, canvas);
window.addEventListener("resize", function () {
engine.resize();
});
> window.addEventListener("keydown", (ev) => {
> // Shift+Ctrl+Alt+F
> if (ev.shiftKey && ev.ctrlKey && ev.altKey && ev.code === "KeyF") {
> engine.switchFullscreen(false);
> }
> });
Edit the main.ts
file to add another import to the top of the file:
import "@babylonjs/inspector";
Update the main.ts
file to add the following code to toggle the inspector with Shift-Ctrl-I.
window.addEventListener("keydown", (ev) => {
// Shift+Ctrl+Alt+F
if (ev.shiftKey && ev.ctrlKey && ev.altKey && ev.code === "KeyF") {
engine.switchFullscreen(false);
}
> // Shift+Ctrl+Alt+I
> if (ev.shiftKey && ev.ctrlKey && ev.altKey && ev.code === "KeyI") {
> if (scene.debugLayer.isVisible()) {
> scene.debugLayer.hide();
> } else {
> scene.debugLayer.show();
> }
> }
});
Deploy your project to GitHub Pages by following the instructions in the following sections.
Under settings, select Pages
. Set it to use GitHub Actions.
Edit the vite.config.js
file to add the following code. Your base should be your repository name.
import { defineConfig } from 'vite'
// https://vitejs.dev/config/
export default defineConfig({
base: '/vite-project/'
})
Create the subdirectory .github/workflows
and add the following code to a file named deploy.yml
:
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages
on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets the GITHUB_TOKEN permissions to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
# Upload dist folder
path: "./dist"
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Push your changes up to github. You should see the deployment of the project in the GitHub Actions tab. If it is successful, you should be able to browse to https://<your-github-username>.github.io/<your-repository-name>/
.
Create a launch.json
file within your .vscode folder and add the following code to it:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome",
"request": "launch",
"type": "chrome",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}"
}
]
}