forked from Orillusion/orillusion
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sample): add EatTheBox sample,add ShootTheBox sample (Orillusion…
- Loading branch information
1 parent
d447cd1
commit e925d1f
Showing
2 changed files
with
418 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
import { BoxGeometry, Camera3D, Engine3D, LitMaterial, MeshRenderer, Object3D, Scene3D, View3D, Object3DUtil, Vector3, AtmosphericComponent, ColliderComponent, BoxColliderShape, KeyEvent, SphereColliderShape, DirectLight, SphereGeometry, ComponentBase, KeyCode, KelvinUtil, Time } from "@orillusion/core"; | ||
import { Stats } from "@orillusion/stats"; | ||
import { Ammo, Physics, Rigidbody } from "@orillusion/physics"; | ||
import dat from "dat.gui"; | ||
|
||
class Sample_EatTheBox { | ||
view: View3D; | ||
ammoWorld: Ammo.btDiscreteDynamicsWorld; | ||
foods: Object3D[] = []; | ||
dispatcher: Ammo.btDispatcher; | ||
numManifolds: number; | ||
Manifold: Ammo.btPersistentManifold; | ||
objIndex: number; | ||
tempObj: Object3D; | ||
score: number = 0; | ||
moveScript: MoveScript; | ||
async run() { | ||
//init physics and engine | ||
await Physics.init(); | ||
await Engine3D.init({ | ||
renderLoop: () => this.loop() | ||
}); | ||
|
||
//set shadow | ||
Engine3D.setting.shadow.updateFrameRate = 1; | ||
Engine3D.setting.shadow.shadowSize = 2048; | ||
Engine3D.setting.shadow.shadowBound = 64; | ||
//get original ammo world for processing more custom function | ||
this.ammoWorld = Physics.world; | ||
|
||
//create scene,add sky and FPS | ||
let scene = new Scene3D(); | ||
let sky = scene.addComponent(AtmosphericComponent); | ||
scene.addComponent(Stats); | ||
|
||
//create camera | ||
let cameraObj = new Object3D(); | ||
let camera = cameraObj.addComponent(Camera3D); | ||
// camera.enableCSM = true; | ||
camera.perspective(60, Engine3D.aspect, 1, 5000); | ||
camera.lookAt(new Vector3(0, 40, 35), new Vector3()); | ||
scene.addChild(cameraObj); | ||
|
||
//add DirectLight | ||
let lightObj = new Object3D(); | ||
let light = lightObj.addComponent(DirectLight); | ||
light.intensity = 50; | ||
light.castShadow = true; | ||
lightObj.rotationX = 60; | ||
lightObj.rotationY = 80; | ||
sky.relativeTransform = light.transform; | ||
light.lightColor = KelvinUtil.color_temperature_to_rgb(5355); | ||
scene.addChild(lightObj); | ||
|
||
//create view | ||
this.view = new View3D(); | ||
this.view.scene = scene; | ||
this.view.camera = camera; | ||
|
||
//create floor and wall | ||
this.createFloor(); | ||
//create foods(box) | ||
this.createFoods(); | ||
//create player(ball) | ||
this.createBall(); | ||
//start render | ||
Engine3D.startRenderView(this.view); | ||
|
||
//add debug UI | ||
const gui = new dat.GUI(); | ||
let tip = gui.addFolder("Orillusion"); | ||
tip.add({ tip1: "press wasd to move" }, "tip1"); | ||
tip.add({ tip2: "eat box to get score" }, "tip2"); | ||
tip.add(this, "score").listen(); | ||
tip.add(this.moveScript, "moveSpeed", 10, 50, 1); | ||
tip.open(); | ||
} | ||
private createFloor() { | ||
//create floor and wall | ||
let floor = Object3DUtil.GetSingleCube(50, 1, 50, 0.3, 0.3, 0.6); | ||
let border1 = Object3DUtil.GetSingleCube(50, 5, 1, 0.3, 0.3, 0.6); | ||
let border2 = Object3DUtil.GetSingleCube(50, 5, 1, 0.3, 0.3, 0.6); | ||
let border3 = Object3DUtil.GetSingleCube(50, 5, 1, 0.3, 0.3, 0.6); | ||
let border4 = Object3DUtil.GetSingleCube(50, 5, 1, 0.3, 0.3, 0.6); | ||
//set their mass to 0,because they are static | ||
let rigidbody = floor.addComponent(Rigidbody); | ||
let rigidbody1 = border1.addComponent(Rigidbody); | ||
let rigidbody2 = border2.addComponent(Rigidbody); | ||
let rigidbody3 = border3.addComponent(Rigidbody); | ||
let rigidbody4 = border4.addComponent(Rigidbody); | ||
rigidbody.mass = rigidbody1.mass = rigidbody2.mass = rigidbody3.mass = rigidbody4.mass = 0; | ||
//add collider component ,collider shape and size is same as their geometry | ||
let collider = floor.addComponent(ColliderComponent); | ||
collider.shape = new BoxColliderShape(); | ||
collider.shape.size = new Vector3(50, 1, 50); | ||
let colshape = new BoxColliderShape(); | ||
colshape.size = new Vector3(50, 5, 1); | ||
let collider1 = border1.addComponent(ColliderComponent); | ||
let collider2 = border2.addComponent(ColliderComponent); | ||
let collider3 = border3.addComponent(ColliderComponent); | ||
let collider4 = border4.addComponent(ColliderComponent); | ||
collider1.shape = collider2.shape = collider3.shape = collider4.shape = colshape; | ||
//place the floor and walls | ||
border1.y = 3; | ||
border1.z = 24.5; | ||
border2.y = 3; | ||
border2.z = -24.5; | ||
border3.y = 3; | ||
border3.x = 24.5; | ||
border3.rotationY = 90; | ||
border4.y = 3; | ||
border4.x = -24.5; | ||
border4.rotationY = 90; | ||
//set friction and restitution | ||
rigidbody.rollingFriction = 10; | ||
rigidbody1.restitution = rigidbody2.restitution = rigidbody3.restitution = rigidbody4.restitution = 0.3; | ||
//set their index to -1 | ||
rigidbody.addInitedFunction(() => { | ||
rigidbody.btRigidbody.setUserIndex(-1); | ||
}, this); | ||
rigidbody1.addInitedFunction(() => { | ||
rigidbody1.btRigidbody.setUserIndex(-1); | ||
}, this); | ||
rigidbody2.addInitedFunction(() => { | ||
rigidbody2.btRigidbody.setUserIndex(-1); | ||
}, this); | ||
rigidbody3.addInitedFunction(() => { | ||
rigidbody3.btRigidbody.setUserIndex(-1); | ||
}, this); | ||
rigidbody4.addInitedFunction(() => { | ||
rigidbody4.btRigidbody.setUserIndex(-1); | ||
}, this); | ||
this.view.scene.addChild(floor); | ||
this.view.scene.addChild(border1); | ||
this.view.scene.addChild(border2); | ||
this.view.scene.addChild(border3); | ||
this.view.scene.addChild(border4); | ||
} | ||
private createFoods() { | ||
//create the sample food | ||
let boxobj = new Object3D(); | ||
let mr = boxobj.addComponent(MeshRenderer); | ||
mr.geometry = new BoxGeometry(2, 2, 2); | ||
mr.material = new LitMaterial(); | ||
let boxColliderShape = new BoxColliderShape(); | ||
boxColliderShape.size = new Vector3(2, 2, 2); | ||
//create 10 food box | ||
for (let index = 0; index < 10; index++) { | ||
let boxObj = boxobj.clone(); | ||
boxObj.y = 2; | ||
//random position | ||
boxObj.x = Math.random() * 40 - 20; | ||
boxObj.z = Math.random() * 40 - 20; | ||
let rig = boxObj.addComponent(Rigidbody); | ||
rig.mass = 0; | ||
let col = boxObj.addComponent(ColliderComponent); | ||
col.shape = boxColliderShape; | ||
rig.addInitedFunction(() => { | ||
//get original rigidbody to get/set more property | ||
let btrig = rig.btRigidbody; | ||
//set this colider as trigger,trigger will not respond to collision | ||
btrig.setCollisionFlags(4); | ||
//set index to 0~9 | ||
btrig.setUserIndex(index); | ||
this.foods[index] = boxObj; | ||
}, this); | ||
boxObj.addComponent(RotateScript); | ||
this.view.scene.addChild(boxObj); | ||
} | ||
} | ||
private createBall() { | ||
//add player(ball) | ||
let sphereObj = new Object3D(); | ||
let mr = sphereObj.addComponent(MeshRenderer); | ||
mr.geometry = new SphereGeometry(1, 20, 20); | ||
let mat = new LitMaterial(); | ||
mr.material = mat; | ||
mat.baseColor = KelvinUtil.color_temperature_to_rgb(1325); | ||
sphereObj.y = 5; | ||
//add movescript | ||
this.moveScript = sphereObj.addComponent(MoveScript); | ||
this.moveScript.rigidbody = sphereObj.addComponent(Rigidbody); | ||
this.moveScript.rigidbody.addInitedFunction(() => { | ||
this.moveScript.rigidbody.btRigidbody.setUserIndex(-1); | ||
}, this); | ||
this.moveScript.rigidbody.mass = 10; | ||
let collider = sphereObj.addComponent(ColliderComponent); | ||
collider.shape = new SphereColliderShape(1); | ||
this.view.scene.addChild(sphereObj); | ||
} | ||
private loop() { | ||
if (Physics.isInited) { | ||
//get ammo world collision info | ||
this.dispatcher = this.ammoWorld.getDispatcher(); | ||
//get count of collision info | ||
this.numManifolds = this.dispatcher.getNumManifolds(); | ||
if (this.numManifolds > 0) { | ||
//iterate all collision info | ||
for (let index = 0; index < this.numManifolds; index++) { | ||
this.Manifold = this.dispatcher.getManifoldByIndexInternal(index); | ||
//detect ammo rigidbody's userindex,if greater than -1,the box(food) is colliding | ||
if (this.Manifold.getBody0().getUserIndex() > -1 || this.Manifold.getBody1().getUserIndex() > -1) { | ||
this.objIndex = Math.max(this.Manifold.getBody0().getUserIndex(), this.Manifold.getBody1().getUserIndex()); | ||
//destroy this box | ||
this.tempObj = this.foods[this.objIndex]; | ||
if (this.tempObj) { | ||
this.foods[this.objIndex] = undefined; | ||
this.score++; | ||
this.tempObj.destroy(); | ||
} | ||
} | ||
} | ||
} | ||
Physics.update(); | ||
} | ||
} | ||
} | ||
|
||
class MoveScript extends ComponentBase { | ||
forward: boolean = false; | ||
back: boolean = false; | ||
left: boolean = false; | ||
right: boolean = false; | ||
moveSpeed: number = 30; | ||
rigidbody: Rigidbody; | ||
x: number = 0; | ||
y: number = 0; | ||
direction: Vector3 = new Vector3(); | ||
init(): void { | ||
Engine3D.inputSystem.addEventListener(KeyEvent.KEY_DOWN, this.keyDown, this); | ||
Engine3D.inputSystem.addEventListener(KeyEvent.KEY_UP, this.keyUp, this); | ||
} | ||
private keyDown(e: KeyEvent) { | ||
if (e.keyCode == KeyCode.Key_A) { | ||
this.left = true; | ||
} else if (e.keyCode == KeyCode.Key_D) { | ||
this.right = true; | ||
} else if (e.keyCode == KeyCode.Key_W) { | ||
this.forward = true; | ||
} else if (e.keyCode == KeyCode.Key_S) { | ||
this.back = true; | ||
} | ||
} | ||
private keyUp(e: KeyEvent) { | ||
if (e.keyCode == KeyCode.Key_A) { | ||
this.left = false; | ||
} else if (e.keyCode == KeyCode.Key_D) { | ||
this.right = false; | ||
} else if (e.keyCode == KeyCode.Key_W) { | ||
this.forward = false; | ||
} else if (e.keyCode == KeyCode.Key_S) { | ||
this.back = false; | ||
} | ||
} | ||
|
||
onUpdate() { | ||
//if w or a or s or d was pressed | ||
if (this.forward || this.back || this.left || this.right) { | ||
//activate ammo btrigidbody if its state is inactive | ||
if (!this.rigidbody.btRigidbody.isActive()) { | ||
this.rigidbody.btRigidbody.activate(); | ||
} | ||
//force the ball to move | ||
this.x = -1 * Number(this.left) + Number(this.right); | ||
this.y = -1 * Number(this.forward) + Number(this.back); | ||
this.direction.set(this.x * this.moveSpeed * Time.delta, 0, this.y * this.moveSpeed * Time.delta); | ||
this.rigidbody.velocity = this.direction; | ||
} | ||
} | ||
} | ||
//rotate script | ||
class RotateScript extends ComponentBase { | ||
onUpdate() { | ||
this.object3D.rotationY += (90 * Time.delta) / 1000; | ||
} | ||
} | ||
|
||
new Sample_EatTheBox().run(); |
Oops, something went wrong.