Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Application state management - launch #39

Merged
merged 25 commits into from
Apr 21, 2021
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5e81ebc
add application state enum
jelster Feb 7, 2021
ff58788
update eslint, webpack to latest
jelster Feb 9, 2021
c9bfffb
use webpack 5.x asset type to replace urlloader
jelster Feb 9, 2021
8b98937
Add loading screen, display on button click
jelster Feb 9, 2021
98df437
Add loading text to screen as GUI Layer text block
jelster Feb 9, 2021
a88616f
Clean up format, add no-select class
jelster Feb 10, 2021
aa8f497
Enter full screen on launch, listen for resize events
jelster Feb 10, 2021
7ca43bd
convert let to const, disable controls
jelster Feb 10, 2021
15a2687
"fix up merge issues"
jelster Feb 13, 2021
9821811
Design refactorings to extract planet construction, improve readability
jelster Feb 13, 2021
85c12bd
Add Application and initialization state mgmt
jelster Feb 13, 2021
6e1916b
Add logger proxy
jelster Feb 13, 2021
523082b
Update loading screen text with progress if available
jelster Feb 13, 2021
9b88a2e
Add iterator state machine for application
jelster Feb 13, 2021
0ecb3aa
Refactor state machine, add main menu stubs
jelster Feb 14, 2021
370b71b
Add title theme song #32
jelster Feb 14, 2021
4f170ef
Add 5s fake loading time, show loading UI during init
jelster Feb 14, 2021
2eeb410
Fix duplicated loadingUI calls and button evt handler
jelster Feb 17, 2021
beb16ec
Add title and play button to menu. Swap bg img styles FPO
jelster Feb 17, 2021
83d23d4
change background image to gradient
jelster Feb 20, 2021
70c1d9c
Added truck selection icon
jelster Feb 21, 2021
7a16085
make icon transparent (doh!)
jelster Feb 21, 2021
9a3a018
Incorporate main menu #33. snippet #16XY6Z#5
jelster Mar 11, 2021
b2488e4
add onMenuEnter/Leave transitions
jelster Mar 14, 2021
9523c3b
Add logger, title music
jelster Mar 14, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
// 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": [
{
"type": "edge",
"request": "launch",
"name": "Launch Edge against localhost",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
}
]
}
Binary file added assets/menuBackground.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/sounds/space-trucker-title-theme.m4a
Binary file not shown.
Binary file added assets/ui-selection-icon.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
212 changes: 87 additions & 125 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@
"@babylonjs/procedural-textures": "^5.0.0-alpha.9 <= 5.0.0",
"@babylonjs/serializers": "^5.0.0-alpha.9 <= 5.0.0",
"clean-webpack-plugin": "^3.0.0",
"eslint": "^7.18.0",
"eslint": "^7.19.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^4.5.1",
"source-map-loader": "^2.0.0",
"url-loader": "^4.1.1",
"webpack": "^5.17.0",
"webpack-cli": "^4.4.0",
"webpack": "^5.21.2",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.7.3"
}
Expand Down
27 changes: 20 additions & 7 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* {
font-family: sans-serif;
}

html,
body {
overflow: hidden;
Expand All @@ -23,9 +24,9 @@
touch-action: none;
}

#pageContainer {
position: relative;
background-color: transparent;
#pageContainer {
position: relative;
background-color: black;
margin: 10px;
padding: 17px;
border: solid white;
Expand All @@ -35,7 +36,7 @@

}

#landingPageContainer {
#landingPageContainer {
width: 100%;
height: 100%;
}
Expand All @@ -50,7 +51,7 @@
#ctaRow,
#footer {
margin-top: 10px;
padding-bottom:7px;
padding-bottom: 7px;
}

#ctaRow button {
Expand All @@ -69,17 +70,29 @@
left: auto;
z-index: -10;
}

.disable-selection {
-moz-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-webkit-touch-callout: none;
user-select: none;
outline: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
/* mobile webkit */
}
</style>
</head>

<body>
<body class="disable-selection">
<div id="pageContainer">
<h1>Space-Truckers: The Video Game</h1>
<div id="landingPageContainer">
<div id="hero">
</div>
<div id="ctaRow">
<button>Launch</button>
<button id="btnLaunch">Launch</button>
</div>
<div id="footer">
Copyright Notice: See <a href="//github.com/jelster/space-truckers/LICENSE">here</a> for license and copyright
Expand Down
8 changes: 8 additions & 0 deletions src/appstates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default Object.freeze({
CREATED: 0,
INITIALIZING: 2,
CUTSCENE: 3,
MENU: 4,
RUNNING: 5,
EXITING: 6
});
81 changes: 81 additions & 0 deletions src/astroFactory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { SphereBuilder } from "@babylonjs/core/Meshes/Builders/sphereBuilder"
import { Texture } from "@babylonjs/core/Materials/Textures/texture"
import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"
import { Scalar } from "@babylonjs/core/Maths/math.scalar"
import { Animation } from "@babylonjs/core/Animations/animation"

import logger from "./logger";

import distortTexture from "../assets/textures/distortion.png";
import rockTextureN from "../assets/textures/rockn.png";
import rockTexture from "../assets/textures/rock.png";

class AstroFactory {
static createPlanet(opts, scene) {
jelster marked this conversation as resolved.
Show resolved Hide resolved
let planet = SphereBuilder.CreateSphere(opts.name, { diameter: 1 }, scene);
let mat = new StandardMaterial(planet.name + "-mat", scene);
mat.diffuseColor = mat.specularColor = mat.emissiveColor = opts.color;
jelster marked this conversation as resolved.
Show resolved Hide resolved
mat.specularPower = 0;
if (opts.rocky === true) {
mat.bumpTexture = new Texture(rockTextureN, scene);
mat.diffuseTexture = new Texture(rockTexture, scene);
}
else {
mat.diffuseTexture = new Texture(distortTexture, scene);
}

planet.material = mat;
planet.scaling.setAll(opts.scale);
planet.position.x = opts.posRadius * Math.sin(opts.posRadians);
planet.position.z = opts.posRadius * Math.cos(opts.posRadians);
planet.orbitOptions = opts;

logger.logInfo("Created planet " + opts.name);
return planet;
}

static createAndStartOrbitAnimation(planet, scene) {
const Gm = 6672.59 * 0.07;
const opts = planet.orbitOptions;
const rCubed = Math.pow(opts.posRadius, 3);
const period = Scalar.TwoPi * Math.sqrt(rCubed / Gm);
const v = Math.sqrt(Gm / opts.posRadius);
const w = v / period;

let angPos = opts.posRadians;

planet.orbitOptions.period = period;
planet.orbitOptions.orbitalVel = v;
planet.orbitOptions.angularVel = w;
planet.orbitOptions.orbitalCircum = Math.pow(Math.PI * opts.posRadius, 2);
planet.preRenderObsv = scene.onBeforeRenderObservable.add(() => {
planet.position.x = opts.posRadius * Math.sin(angPos);
planet.position.z = opts.posRadius * Math.cos(angPos);
angPos = Scalar.Repeat(angPos + w, Scalar.TwoPi);
});
logger.logInfo("Calculated and started orbital animation for " + planet.name);

return planet;
}

static createSpinAnimation() {
let orbitAnim = new Animation("spin-y", "rotation.y", 30, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE);
const keyFrames = [];
keyFrames.push({
frame: 0,
value: 0
});

keyFrames.push({
frame: 60,
value: Scalar.TwoPi
});

orbitAnim.setKeys(keyFrames);
return orbitAnim;
}


}

export default AstroFactory
35 changes: 26 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
import { Engine } from "@babylonjs/core/Engines/engine";
import createStartScene from "./startscene";
import SpaceTruckerApplication from "./spaceTruckerApplication";
import SpaceTruckerLoadingScreen from "./spaceTruckerLoadingScreen";
import logger from "./logger";

const CanvasName = "index-canvas";
const launchButton = document.getElementById("btnLaunch");
const pageLandingContent = document.getElementById("pageContainer");

let canvas = document.createElement("canvas");
const canvas = document.createElement("canvas");
canvas.id = CanvasName;

canvas.classList.add("background-canvas");
document.body.appendChild(canvas);

let eng = new Engine(canvas, true, null, true);
let startScene = createStartScene(eng);
eng.runRenderLoop(() => {
startScene.scene.render();
});
const eng = new Engine(canvas, true, null, true);
logger.logInfo("Created BJS engine");

eng.loadingScreen = new SpaceTruckerLoadingScreen(eng);

const theApp = new SpaceTruckerApplication(eng);

const btnClickEvtHandle = () => {
logger.logInfo("Launch button clicked. Initializing application.");
canvas.classList.remove("background-canvas");
pageLandingContent.style.display = "none";
launchButton.removeEventListener("click", btnClickEvtHandle);

theApp.run();
};
launchButton.addEventListener("click", btnClickEvtHandle);

//canvas.classList.remove("background-canvas");
window.addEventListener('resize', () => {
eng.resize();
});
51 changes: 51 additions & 0 deletions src/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

class ConsoleProxy {

constructor(console) {
this._console = console;
this._consoleIsPresent = this._console;
this._messageBuffer = [];
}

logInfo(message) {
const logObj = { type: "INFO", message: message};
if (this._consoleIsPresent) {
this._console.log(logObj);
return;
}
this._messageBuffer.push();
}

logWarning(message) {
const logObj = { type: "WARN", message: message};
if (this._consoleIsPresent) {
this._console.log(logObj);
return;
}
this._messageBuffer.push();
}

logError(message) {
const logObj = { type: "ERROR", message: message};
if (this._consoleIsPresent) {
this._console.log(logObj);
return;
}
this._messageBuffer.push();
}

logFatal(message) {
const logObj = { type: "FATAL", message: message};
if (this._consoleIsPresent) {
this._console.log(logObj);
return;
}
this._messageBuffer.push();
}

flushBuffer() {
this._messageBuffer.splice(0, this._messageBuffer.length);
}
}
const theProxy = new ConsoleProxy(console);
export default theProxy;
87 changes: 87 additions & 0 deletions src/mainMenuScene.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { CylinderBuilder } from "@babylonjs/core/Meshes/Builders/cylinderBuilder";
import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera";
import { Color4 } from "@babylonjs/core/Maths/math";
import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial";
import { Texture } from "@babylonjs/core/Materials/Textures/texture"
import { Scene, Vector3, Sound, HemisphericLight } from "@babylonjs/core";
import { AdvancedDynamicTexture, Rectangle, Image, Button, StackPanel, Control, TextBlock } from "@babylonjs/gui";
import { StarfieldProceduralTexture } from "@babylonjs/procedural-textures/starfield/starfieldProceduralTexture";
import menuBackground from "../assets/menuBackground.png";
import titleMusic from "../assets/sounds/space-trucker-title-theme.m4a";

class MainMenuScene {

get scene() {
return this._scene;
}
constructor(engine) {
this._engine = engine;
let scene = this._scene = new Scene(engine);
// TODO: Use asset manager instead of directly instantiating
this._music = new Sound("titleMusic", titleMusic, scene, null, { autoplay: true, loop: true, volume: 0.4 });
scene.clearColor = new Color4(0, 0, 0, 1);

const camera = new ArcRotateCamera("menuCam", 0, 0, -30, Vector3.Zero(), scene, true);
this._setupBackgroundEnvironment();
const guiMenu = AdvancedDynamicTexture.CreateFullscreenUI("UI");
guiMenu.idealHeight = 720;

const menuContainer = new Rectangle("menuContainer");
menuContainer.width = 0.8;
menuContainer.thickness = 0;
guiMenu.addControl(menuContainer);

// TODO: find/make a better background image!
const menuBg = new Image("menuBg", menuBackground);
menuContainer.addControl(menuBg);

const menuPanel = new StackPanel("menuPanel");
// menuPanel.background = "rgba(150, 150, 150, 0.67)";
menuPanel.height = 0.9;
menuPanel.top = 0.05;
menuPanel.bottom = 0.05;
menuContainer.addControl(menuPanel);

const titleText = new TextBlock("title", "Space-Truckers: The Video Game!");
titleText.resizeToFit = true;
titleText.fontSize = "56pt";
titleText.color = "white";

titleText.width = 0.8;
titleText.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
titleText.paddingBottom = "28px";
menuPanel.addControl(titleText);
// buttonStyle.fontFamily = "Comic Sans Serif";


// TODO: extract this into a menu item factory method
const playButton = Button.CreateSimpleButton("btPlay", "Play");
playButton.fontSize = "36pt";
playButton.color = "white";
playButton.background = "red";
playButton.height = "80px";
playButton.width = "160px"
playButton.thickness = 4;
playButton.cornerRadius = 105;

playButton.verticalAlignment = Control.VERTICAL_ALIGNMENT_BOTTOM;
menuPanel.addControl(playButton);
}

_setupBackgroundEnvironment() {
const light = new HemisphericLight("light", new Vector3(0,0.5, 0), this._scene);
const starfieldPT = new StarfieldProceduralTexture("starfieldPT", 512, this._scene);
const starfieldMat = new StandardMaterial("starfield", this._scene);
const space = CylinderBuilder.CreateCylinder("space", { height: 100, diameterTop: 0, diameterBottom: 60 }, this._scene);
starfieldMat.diffuseTexture = starfieldPT;
starfieldMat.diffuseTexture.coordinatesMode = Texture.SKYBOX_MODE;
starfieldMat.backFaceCulling = false;
starfieldPT.beta = 0.1;

space.material = starfieldMat;

this._starfieldAnimationHandle = this._scene.registerBeforeRender(() => starfieldPT.time += this._scene.getEngine().getDeltaTime() / 1000);

}
}
export default MainMenuScene;
Loading