add license, more objects
This commit is contained in:
parent
3fcd1b0385
commit
8e073effa8
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (c) 2023 Evert Prants <evert@lunasqu.ee>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Freeblox monorepo
|
||||||
|
|
||||||
|
Simple game platform front-end powered by THREE.js and Vue.
|
||||||
|
|
||||||
|
## Develop
|
||||||
|
|
||||||
|
1. Install PNPM `npm i -g pnpm`.
|
||||||
|
2. Install dependencies `pnpm install`.
|
||||||
|
3. Watch engine changes `pnpm --filter engine dev`
|
||||||
|
4. Watch editor changes `pnpm --filter editor dev`
|
||||||
|
5. Watch client changes `pnpm --filter client dev`
|
|
@ -15,6 +15,6 @@
|
||||||
"pnpm": ">=6"
|
"pnpm": ">=6"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "Evert Prants <evert@lunasqu.ee>",
|
||||||
"license": "ISC"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
"require": "./dist/client.umd.cjs"
|
"require": "./dist/client.umd.cjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"author": "Evert Prants <evert@lunasqu.ee>",
|
||||||
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vue-tsc && vite build",
|
"build": "vue-tsc && vite build",
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
"require": "./dist/editor.umd.cjs"
|
"require": "./dist/editor.umd.cjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"author": "Evert Prants <evert@lunasqu.ee>",
|
||||||
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vue-tsc && vite build",
|
"build": "vue-tsc && vite build",
|
||||||
|
|
|
@ -62,5 +62,6 @@ export class Editor extends GameRunner {
|
||||||
this.viewport.cleanUp();
|
this.viewport.cleanUp();
|
||||||
this.workspace.cleanUp();
|
this.workspace.cleanUp();
|
||||||
this.mouse.cleanUp();
|
this.mouse.cleanUp();
|
||||||
|
this.render.cleanUp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,9 @@ import {
|
||||||
MouseButtonEvent,
|
MouseButtonEvent,
|
||||||
Renderer,
|
Renderer,
|
||||||
Sphere,
|
Sphere,
|
||||||
|
Wedge,
|
||||||
|
WedgeCorner,
|
||||||
|
WedgeInnerCorner,
|
||||||
} from '@freeblox/engine';
|
} from '@freeblox/engine';
|
||||||
import {
|
import {
|
||||||
AxesHelper,
|
AxesHelper,
|
||||||
|
@ -70,12 +73,18 @@ export class WorkspaceComponent extends EngineComponent {
|
||||||
scene.add(this.background, this.world, this.helpers);
|
scene.add(this.background, this.world, this.helpers);
|
||||||
|
|
||||||
const test = new Brick();
|
const test = new Brick();
|
||||||
test.position.set(2, 2, 2);
|
test.position.set(2, 0, 2);
|
||||||
const test2 = new Cylinder();
|
const test2 = new Cylinder();
|
||||||
test2.position.set(0, 2, 2);
|
test2.position.set(0, 0, 2);
|
||||||
const test3 = new Sphere();
|
const test3 = new Sphere();
|
||||||
test3.position.set(0, 2, 0);
|
test3.position.set(0, 0, 0);
|
||||||
this.world.add(test, test2, test3);
|
const test4 = new Wedge();
|
||||||
|
test4.position.set(2, 0, 0);
|
||||||
|
const test5 = new WedgeCorner();
|
||||||
|
test5.position.set(4, 0, 0);
|
||||||
|
const test6 = new WedgeInnerCorner();
|
||||||
|
test6.position.set(4, 0, 2);
|
||||||
|
this.world.add(test, test2, test3, test4, test5, test6);
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeFromScene(scene: Object3D) {
|
private removeFromScene(scene: Object3D) {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"engine",
|
"engine",
|
||||||
"three"
|
"three"
|
||||||
],
|
],
|
||||||
"author": "Evert",
|
"author": "Evert Prants <evert@lunasqu.ee>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/three": "^0.152.1",
|
"@types/three": "^0.152.1",
|
||||||
|
|
|
@ -25,12 +25,11 @@ export class EnvironmentComponent extends EngineComponent {
|
||||||
|
|
||||||
this.renderer.scene.add(this.ambient);
|
this.renderer.scene.add(this.ambient);
|
||||||
this.renderer.scene.add(this.directional);
|
this.renderer.scene.add(this.directional);
|
||||||
}
|
|
||||||
|
|
||||||
update(delta: number): void {
|
|
||||||
this.handlerCleanUp = this.initializeEvents();
|
this.handlerCleanUp = this.initializeEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update(delta: number): void {}
|
||||||
|
|
||||||
cleanUp(): void {
|
cleanUp(): void {
|
||||||
this.renderer.scene.remove(this.ambient);
|
this.renderer.scene.remove(this.ambient);
|
||||||
this.renderer.scene.remove(this.directional);
|
this.renderer.scene.remove(this.directional);
|
||||||
|
|
|
@ -28,4 +28,8 @@ export class Renderer {
|
||||||
render() {
|
render() {
|
||||||
this.renderer.render(this.scene, this.camera);
|
this.renderer.render(this.scene, this.camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanUp() {
|
||||||
|
this.renderer.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,26 +6,30 @@ import {
|
||||||
Mesh,
|
Mesh,
|
||||||
MeshPhongMaterial,
|
MeshPhongMaterial,
|
||||||
} from 'three';
|
} from 'three';
|
||||||
import { GameObject3D } from '../types/game-object';
|
import {
|
||||||
|
EditorProperties,
|
||||||
|
GameObject3D,
|
||||||
|
gameObject3DEditorProperties,
|
||||||
|
} from '../types/game-object';
|
||||||
import { Property } from '../types/property';
|
import { Property } from '../types/property';
|
||||||
import { gameObjectFactory } from './factory';
|
import { gameObjectFactory } from './factory';
|
||||||
|
|
||||||
|
export const brickEditorProperties: EditorProperties = {
|
||||||
|
...gameObject3DEditorProperties,
|
||||||
|
color: new Property('color', Color, true, []),
|
||||||
|
transparency: new Property('transparency', Number, true, []),
|
||||||
|
};
|
||||||
|
|
||||||
export class Brick extends GameObject3D {
|
export class Brick extends GameObject3D {
|
||||||
public objectType = Brick.name;
|
public objectType = Brick.name;
|
||||||
protected material = new MeshPhongMaterial();
|
protected material = new MeshPhongMaterial();
|
||||||
protected mesh: Mesh = new Mesh(this.geometry, this.material);
|
protected mesh: Mesh = new Mesh(this.geometry, this.material);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected geometry: BufferGeometry = gameObjectFactory.boxGeometry
|
protected geometry: BufferGeometry = gameObjectFactory.boxGeometry,
|
||||||
|
public editorProperties: EditorProperties = brickEditorProperties
|
||||||
) {
|
) {
|
||||||
super();
|
super(editorProperties);
|
||||||
this.editorProperties.color = new Property('color', Color, true, []);
|
|
||||||
this.editorProperties.transparency = new Property(
|
|
||||||
'transparency',
|
|
||||||
Number,
|
|
||||||
true,
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
this.add(this.mesh);
|
this.add(this.mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,47 @@ class GameObjectFactory {
|
||||||
public boxGeometry = new BoxGeometry();
|
public boxGeometry = new BoxGeometry();
|
||||||
public sphereGeometry = new SphereGeometry(0.5);
|
public sphereGeometry = new SphereGeometry(0.5);
|
||||||
public cylinderGeometry = new CylinderGeometry(0.5, 0.5);
|
public cylinderGeometry = new CylinderGeometry(0.5, 0.5);
|
||||||
|
public wedgeGeometry = new BoxGeometry();
|
||||||
|
public wedgeCornerGeometry = new BoxGeometry();
|
||||||
|
public wedgeInnerCornerGeometry = new BoxGeometry();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.makeProceduralShapes();
|
||||||
|
this.finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private makeProceduralShapes() {
|
||||||
|
const pos = this.wedgeGeometry.attributes.position;
|
||||||
|
for (let i = 0; i < pos.count; i++) {
|
||||||
|
if (pos.getX(i) < 0 && pos.getY(i) > 0) pos.setY(i, -0.5);
|
||||||
|
}
|
||||||
|
this.wedgeGeometry.computeVertexNormals();
|
||||||
|
|
||||||
|
const pos2 = this.wedgeCornerGeometry.attributes.position;
|
||||||
|
for (let i = 0; i < pos2.count; i++) {
|
||||||
|
if (pos2.getY(i) > 0 && (pos2.getX(i) !== 0.5 || pos2.getZ(i) !== -0.5)) {
|
||||||
|
pos2.setY(i, -0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.wedgeCornerGeometry.computeVertexNormals();
|
||||||
|
|
||||||
|
const pos3 = this.wedgeInnerCornerGeometry.attributes.position;
|
||||||
|
for (let i = 0; i < pos3.count; i++) {
|
||||||
|
if (pos3.getY(i) > 0 && pos3.getX(i) === 0.5 && pos3.getZ(i) === 0.5) {
|
||||||
|
pos3.setY(i, -0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.wedgeInnerCornerGeometry.computeVertexNormals();
|
||||||
|
}
|
||||||
|
|
||||||
|
private finalize() {
|
||||||
|
this.boxGeometry.computeBoundingBox();
|
||||||
|
this.sphereGeometry.computeBoundingBox();
|
||||||
|
this.cylinderGeometry.computeBoundingBox();
|
||||||
|
this.wedgeGeometry.computeBoundingBox();
|
||||||
|
this.wedgeCornerGeometry.computeBoundingBox();
|
||||||
|
this.wedgeInnerCornerGeometry.computeBoundingBox();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const gameObjectFactory = new GameObjectFactory();
|
export const gameObjectFactory = new GameObjectFactory();
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
export * from './brick.object';
|
export * from './brick.object';
|
||||||
export * from './cylinder.object';
|
export * from './cylinder.object';
|
||||||
export * from './sphere.object';
|
export * from './sphere.object';
|
||||||
|
export * from './wedge.object';
|
||||||
|
export * from './wedge-corner.object';
|
||||||
|
export * from './wedge-inner-corner.object';
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { Mesh, Color } from 'three';
|
||||||
|
import { Property } from '../types/property';
|
||||||
|
import { Brick } from './brick.object';
|
||||||
|
import { gameObjectFactory } from './factory';
|
||||||
|
|
||||||
|
export class WedgeCorner extends Brick {
|
||||||
|
public objectType = WedgeCorner.name;
|
||||||
|
protected mesh = new Mesh(this.geometry, this.material);
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(gameObjectFactory.wedgeCornerGeometry);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { Mesh, Color } from 'three';
|
||||||
|
import { Property } from '../types/property';
|
||||||
|
import { Brick } from './brick.object';
|
||||||
|
import { gameObjectFactory } from './factory';
|
||||||
|
|
||||||
|
export class WedgeInnerCorner extends Brick {
|
||||||
|
public objectType = WedgeInnerCorner.name;
|
||||||
|
protected mesh = new Mesh(this.geometry, this.material);
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(gameObjectFactory.wedgeInnerCornerGeometry);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { Mesh, Color } from 'three';
|
||||||
|
import { Property } from '../types/property';
|
||||||
|
import { Brick } from './brick.object';
|
||||||
|
import { gameObjectFactory } from './factory';
|
||||||
|
|
||||||
|
export class Wedge extends Brick {
|
||||||
|
public objectType = Wedge.name;
|
||||||
|
protected mesh = new Mesh(this.geometry, this.material);
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(gameObjectFactory.wedgeGeometry);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,68 @@
|
||||||
import { Euler, Object3D, Vector3 } from 'three';
|
import { Euler, Object3D, Vector3 } from 'three';
|
||||||
import { Property } from './property';
|
import { Property } from './property';
|
||||||
|
|
||||||
|
export type EditorProperties = { [x: string]: Property };
|
||||||
|
export const gameObjectEditorProperties: EditorProperties = {
|
||||||
|
name: new Property('name', String, true, []),
|
||||||
|
visible: new Property('visible', Boolean, true, []),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const gameObject3DEditorProperties: EditorProperties = {
|
||||||
|
...gameObjectEditorProperties,
|
||||||
|
position: new Property('position', Vector3, true, []),
|
||||||
|
scale: new Property('scale', Vector3, true, []),
|
||||||
|
rotation: new Property('rotation', Euler, true, []),
|
||||||
|
};
|
||||||
|
|
||||||
export class GameObject extends Object3D {
|
export class GameObject extends Object3D {
|
||||||
public objectType = 'GameObject';
|
public objectType = 'GameObject';
|
||||||
public editorProperties: { [x: string]: Property } = {
|
constructor(
|
||||||
name: new Property('name', String, true, []),
|
public editorProperties: EditorProperties = gameObjectEditorProperties
|
||||||
};
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize GameObject for exporting
|
||||||
|
*/
|
||||||
|
serialize() {
|
||||||
|
const object: SerializedObject = {
|
||||||
|
name: this.name,
|
||||||
|
objectType: this.objectType,
|
||||||
|
children: this.children
|
||||||
|
.filter((entry) => entry instanceof GameObject)
|
||||||
|
.map((entry) => (entry as GameObject).serialize()),
|
||||||
|
visible: this.visible,
|
||||||
|
};
|
||||||
|
|
||||||
|
const keys = Object.keys(this.editorProperties);
|
||||||
|
|
||||||
|
Object.assign(
|
||||||
|
object,
|
||||||
|
keys.reduce<{ [x: string]: unknown }>(
|
||||||
|
(obj, key) => ({
|
||||||
|
...obj,
|
||||||
|
[key]: (this as Record<string, unknown>)[key],
|
||||||
|
}),
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GameObject3D extends GameObject {
|
export class GameObject3D extends GameObject {
|
||||||
public objectType = 'GameObject3D';
|
public objectType = 'GameObject3D';
|
||||||
public editorProperties: { [x: string]: Property } = {
|
constructor(public editorProperties = gameObject3DEditorProperties) {
|
||||||
name: new Property('name', String, true, []),
|
super(editorProperties);
|
||||||
position: new Property('position', Vector3, true, []),
|
}
|
||||||
scale: new Property('scale', Vector3, true, []),
|
}
|
||||||
rotation: new Property('rotation', Euler, true, []),
|
|
||||||
};
|
export interface SerializedObject {
|
||||||
|
[x: string]: unknown;
|
||||||
|
name: string;
|
||||||
|
objectType: string;
|
||||||
|
children: SerializedObject[];
|
||||||
|
visible: boolean;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue