blockly3d/src/state/world.ts

146 lines
3.8 KiB
TypeScript

import { makeAutoObservable } from "mobx";
import { WorldFactory } from "../model/worldFactory";
import type { ObjectType, RunningGameState, Scene, World } from "../types";
import { CharacterState } from "./character";
import type { Pos3, V3 } from "../types/3d";
import { clone, randomId } from "../utils";
import type { VoxelType } from "../types/voxel";
import { state } from "./root";
export class WorldState {
public data: World = WorldFactory.create();
public character = new CharacterState(this);
constructor() {
this.load();
makeAutoObservable(this);
}
public reset() {
this.data = WorldFactory.create();
}
public loadMock() {
this.data = {
objectTypes: [
{
id: 'test1',
name: 'Test Object',
voxels: [
{
typeId: 'red',
position: [0, 0, 0],
color: 'red',
opacity: 1,
},
],
},
],
voxelTypes: [
{
id: 'red',
collidable: true,
name: 'Red',
opacity: 1,
color: 'red',
}
],
editorCamera: {
position: [0, 2, 10],
look: [0, 0, 0],
},
intialScene: {
character: {
position: [0, 0, 0],
look: [0, 0, 0],
},
objects: [
{
id: randomId(),
typeId: 'test1',
position: [0, 0, 0],
rotation: [0, 0, 0],
},
],
},
gameRules: {
gravity: true,
},
state: {
playing: false,
},
};
}
public load() {
this.data = WorldFactory.load() ?? WorldFactory.create();
}
public save(): void {
WorldFactory.save(this.data);
}
public get isPlaying(): boolean {
return this.data.state.playing;
}
public get currentScene(): Scene {
return this.isPlaying
? (this.data.state as RunningGameState).scene
: this.data.intialScene;
}
public get currentCamera(): Pos3 {
return this.isPlaying
? (this.data.state as RunningGameState).scene.character
: this.data.editorCamera;
}
public tick(_delta: number) {
if (!this.isPlaying)
return;
//TODO
}
public play(): void {
if (this.isPlaying) {
const state = clone(this.data.state) as RunningGameState;
state.paused = false;
this.data.state = state;
}
else {
this.data.state = {
playing: true,
paused: false,
time: 0,
scene: clone(this.data.intialScene),
}
}
state.worldEditor.setSelectedObjectId(undefined);
}
public pause(): void {
if (!this.isPlaying)
return;
const state = clone(this.data.state) as RunningGameState;
state.paused = true;
this.data.state = state;
}
public stop(): void {
if (!this.isPlaying)
return;
this.data.state = { playing: false };
}
public getObjectTypeById(id: string): ObjectType | undefined {
return this.data.objectTypes.find((obj) => obj.id === id);
}
public getVoxelTypeById(id: string): VoxelType | undefined {
return this.data.voxelTypes.find((obj) => obj.id === id);
}
}