Soccer Components.
This commit is contained in:
parent
5510ef5a09
commit
0e6e0bdd1f
71
src/soccer/ball.ts
Normal file
71
src/soccer/ball.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import {
|
||||
AbstractMesh,
|
||||
MeshBuilder,
|
||||
PhysicsAggregate,
|
||||
PhysicsShapeType,
|
||||
Scene,
|
||||
SceneLoader,
|
||||
TransformNode,
|
||||
Vector3
|
||||
} from "@babylonjs/core";
|
||||
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
||||
|
||||
export class Ball {
|
||||
private readonly scene: Scene;
|
||||
private transformNode: TransformNode;
|
||||
private mesh: AbstractMesh;
|
||||
private position: Vector3 = new Vector3(0, .5, 0);
|
||||
private parent: AbstractMesh;
|
||||
private controllers: Controllers;
|
||||
private physicsAggregate: PhysicsAggregate;
|
||||
|
||||
constructor(scene: Scene) {
|
||||
this.scene = scene;
|
||||
this.buildBall();
|
||||
}
|
||||
|
||||
public setControllers(controllers: Controllers) {
|
||||
this.controllers = controllers;
|
||||
this.controllers.controllerObserver.add((event) => {
|
||||
if (event.type == ControllerEventType.MOTION) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public kick(direction: Vector3, force: number) {
|
||||
this.physicsAggregate.body.applyImpulse(direction.scale(force), Vector3.Zero());
|
||||
}
|
||||
|
||||
private buildBall() {
|
||||
SceneLoader.ImportMesh(null, "/assets/models/", "ball.gltf", this.scene,
|
||||
(meshes, particleSystems, skeletons, animationGroups) => {
|
||||
console.log('ball loaded');
|
||||
this.mesh = meshes[0];
|
||||
this.parent = MeshBuilder.CreateSphere("ballParent", {diameter: .17}, this.scene);
|
||||
|
||||
this.parent.isVisible = false;
|
||||
this.parent.position = this.position;
|
||||
|
||||
this.scene.onBeforeRenderObservable.add(() => {
|
||||
if (!this.physicsAggregate &&
|
||||
this.scene?.getPhysicsEngine()?.getPhysicsPlugin()) {
|
||||
console.log("creating physics aggregate");
|
||||
this.physicsAggregate = new PhysicsAggregate(this.parent,
|
||||
PhysicsShapeType.SPHERE, {mass: 1, restitution: .5, friction: .6}, this.scene);
|
||||
this.physicsAggregate.body.setLinearDamping(.2);
|
||||
this.mesh.setParent(this.physicsAggregate.transformNode);
|
||||
this.mesh.position.y = 0;
|
||||
return;
|
||||
}
|
||||
}, -1, false, this, false);
|
||||
|
||||
//animationGroups[0].stop();
|
||||
|
||||
//this.animationGroup = animationGroups[6];
|
||||
//this.animationGroup.start(false, 1, 266, 266);
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
129
src/soccer/field.ts
Normal file
129
src/soccer/field.ts
Normal file
@ -0,0 +1,129 @@
|
||||
import {InstancedMesh, Mesh, MeshBuilder, Scene, StandardMaterial, Vector2, Vector3} from "@babylonjs/core";
|
||||
import {Ball} from "./ball";
|
||||
import {Rigplatform} from "../controllers/rigplatform";
|
||||
|
||||
export class Field {
|
||||
private readonly scene: Scene;
|
||||
private ball: Ball;
|
||||
private rig: Rigplatform;
|
||||
private goalMesh: Mesh;
|
||||
private material: StandardMaterial;
|
||||
|
||||
constructor(scene: Scene) {
|
||||
this.scene = scene;
|
||||
this.goalMesh = MeshBuilder.CreateCylinder("goalPost", {diameter: .1, height: 1}, this.scene);
|
||||
this.material = new StandardMaterial("material", this.scene);
|
||||
this.material.diffuseColor.set(1, 1, 1);
|
||||
this.material.alpha = .5;
|
||||
this.goalMesh.material = this.getMaterial();
|
||||
this.goalMesh.setEnabled(false);
|
||||
this.buildField();
|
||||
}
|
||||
|
||||
public addBall(ball: Ball) {
|
||||
this.ball = ball;
|
||||
}
|
||||
|
||||
public addRig(rig: Rigplatform) {
|
||||
this.rig = rig;
|
||||
|
||||
}
|
||||
|
||||
private buildField() {
|
||||
const width = .08;
|
||||
this.buildLine(new Vector2(35, 0), new Vector2(width, 100));
|
||||
this.buildLine(new Vector2(-35, 0), new Vector2(width, 100));
|
||||
this.buildLine(new Vector2(-9.16, 50 - 2.75), new Vector2(width, 5.5 - width));
|
||||
this.buildLine(new Vector2(9.16, 50 - 2.75), new Vector2(width, 5.5 - width));
|
||||
this.buildLine(new Vector2(-9.16, -50 + 2.75), new Vector2(width, 5.5 - width));
|
||||
this.buildLine(new Vector2(9.16, -50 + 2.75), new Vector2(width, 5.5 - width));
|
||||
|
||||
this.buildLine(new Vector2(-18.33, 50 - 8.25), new Vector2(width, 16.5 - width));
|
||||
this.buildLine(new Vector2(18.33, 50 - 8.25), new Vector2(width, 16.5 - width));
|
||||
this.buildLine(new Vector2(-18.33, -50 + 8.25), new Vector2(width, 16.5 - width));
|
||||
this.buildLine(new Vector2(18.33, -50 + 8.25), new Vector2(width, 16.5 - width));
|
||||
|
||||
|
||||
this.buildLine(new Vector2(0, -50), new Vector2(70 - width, width));
|
||||
this.buildLine(new Vector2(0, 50), new Vector2(70 - width, width));
|
||||
|
||||
this.buildLine(new Vector2(0, -44.5), new Vector2(18.32 + width, width));
|
||||
this.buildLine(new Vector2(0, 44.5), new Vector2(18.32 + width, width));
|
||||
|
||||
this.buildLine(new Vector2(0, -33.5), new Vector2(36.66 + width, width));
|
||||
this.buildLine(new Vector2(0, 33.5), new Vector2(36.66 + width, width));
|
||||
|
||||
this.buildCircle(new Vector2(0, 50 - 11));
|
||||
this.buildCircle(new Vector2(0, -50 + 11));
|
||||
|
||||
|
||||
this.buildLine(new Vector2(0, 0), new Vector2(70 - width, width));
|
||||
this.buildArc(new Vector2(0, 0));
|
||||
this.buildArc(new Vector2(0, 50 - 11), Math.PI / 11, Math.PI / 1.275);
|
||||
this.buildArc(new Vector2(0, -50 + 11), Math.PI / 11, (Math.PI / 1.275) - Math.PI);
|
||||
this.buildGoalPost(new Vector2(3.66, -50));
|
||||
this.buildGoalPost(new Vector2(-3.66, -50));
|
||||
this.buildGoalPost(new Vector2(3.66, 50));
|
||||
this.buildGoalPost(new Vector2(-3.66, 50));
|
||||
this.buildGoalPost(new Vector2(0, 50), false, 7.32, 2.44);
|
||||
this.buildGoalPost(new Vector2(0, -50), false, 7.32, 2.44);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private buildGoalPost(position: Vector2, vertical: boolean = true, length: number = 2.44, y: number = 0) {
|
||||
const goalPost = new InstancedMesh("goalPost", this.goalMesh);
|
||||
goalPost.position.x = position.x;
|
||||
goalPost.position.z = position.y;
|
||||
if (!vertical) {
|
||||
goalPost.rotation.z = Math.PI / 2;
|
||||
goalPost.position.y = y;
|
||||
} else {
|
||||
goalPost.position.y = length / 2;
|
||||
}
|
||||
goalPost.scaling.y = length;
|
||||
goalPost.visibility = 1;
|
||||
}
|
||||
|
||||
private buildCircle(position: Vector2) {
|
||||
const circle = MeshBuilder.CreateDisc("disc", {radius: .25, tessellation: 180}, this.scene);
|
||||
circle.position.x = position.x;
|
||||
circle.position.z = position.y;
|
||||
circle.position.y = .01;
|
||||
circle.rotation.x = Math.PI / 2;
|
||||
circle.material = this.getMaterial();
|
||||
}
|
||||
|
||||
private buildArc(position: Vector2, arc: number = Math.PI, rotation: number = 0) {
|
||||
const myShape = [
|
||||
new Vector3(1, 0, 0),
|
||||
new Vector3(1, 0, 1.012),
|
||||
new Vector3(.975, 0, 1.012)
|
||||
];
|
||||
const circle = MeshBuilder.CreateLathe("lathe", {
|
||||
arc: arc,
|
||||
shape: myShape, radius: 9.15, tessellation: 180
|
||||
}, this.scene);
|
||||
circle.material = this.getMaterial();
|
||||
circle.position.y = 0.01;
|
||||
circle.position.x = position.x;
|
||||
circle.position.z = position.y;
|
||||
circle.rotation = new Vector3(0, rotation, 0);
|
||||
}
|
||||
|
||||
private getMaterial(): StandardMaterial {
|
||||
const material = new StandardMaterial("material", this.scene);
|
||||
material.diffuseColor.set(1, 1, 1);
|
||||
material.alpha = .5;
|
||||
return material;
|
||||
}
|
||||
|
||||
private buildLine(position: Vector2, shape: Vector2) {
|
||||
const line = MeshBuilder.CreatePlane("line", {width: shape.x, height: shape.y}, this.scene);
|
||||
line.material = this.getMaterial();
|
||||
line.rotation.x = Math.PI / 2;
|
||||
line.position.y = .01;
|
||||
line.position.x = position.x;
|
||||
line.position.z = position.y;
|
||||
}
|
||||
}
|
||||
60
src/soccer/player.ts
Normal file
60
src/soccer/player.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import {
|
||||
AbstractMesh,
|
||||
AnimationGroup,
|
||||
MeshBuilder,
|
||||
Observable,
|
||||
PhysicsAggregate,
|
||||
PhysicsShapeType,
|
||||
Scene,
|
||||
SceneLoader,
|
||||
TransformNode,
|
||||
Vector2,
|
||||
Vector3
|
||||
} from "@babylonjs/core";
|
||||
|
||||
export class Player {
|
||||
public readonly onReadyObservable: Observable<any> = new Observable();
|
||||
private readonly scene: Scene;
|
||||
private readonly position: Vector3;
|
||||
private mesh: TransformNode;
|
||||
private parent: AbstractMesh;
|
||||
private animationGroup: AnimationGroup;
|
||||
private physicsAggregate: PhysicsAggregate;
|
||||
|
||||
constructor(scene: Scene, position: Vector3) {
|
||||
this.scene = scene;
|
||||
this.position = position;
|
||||
this.buildPlayer();
|
||||
}
|
||||
|
||||
buildPlayer() {
|
||||
SceneLoader.ImportMesh(null, "/assets/models/", "player2.glb", this.scene,
|
||||
(meshes, particleSystems, skeletons, animationGroups) => {
|
||||
this.mesh = meshes[0];
|
||||
this.parent = MeshBuilder.CreateCylinder("playerParent", {diameter: .5, height: 1.6}, this.scene);
|
||||
this.parent.position = this.position;
|
||||
this.parent.isVisible = false;
|
||||
this.physicsAggregate = new PhysicsAggregate(this.parent,
|
||||
PhysicsShapeType.CYLINDER, {mass: 50, restitution: .02, friction: 0}, this.scene);
|
||||
animationGroups[0].stop();
|
||||
|
||||
this.animationGroup = animationGroups[6];
|
||||
this.animationGroup.start(false, 1, 266, 266);
|
||||
this.mesh.setParent(this.physicsAggregate.transformNode);
|
||||
this.mesh.position.x = 3;
|
||||
this.mesh.position.y = -.84;
|
||||
this.onReadyObservable.notifyObservers(this);
|
||||
});
|
||||
}
|
||||
|
||||
public runTo(location: Vector2) {
|
||||
this.animationGroup.stop();
|
||||
this.animationGroup.start(true, 1.5, 0, 250);
|
||||
this.physicsAggregate.body.transformNode.lookAt(new Vector3(location.x, 2, location.y));
|
||||
const speed = location.normalize().scale(2);
|
||||
this.physicsAggregate.body.setLinearVelocity(new Vector3(0, 0, 3));
|
||||
//this.physicsAggregate.body.setAngularVelocity(new Vector3(0, .1, 0));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
0
src/soccer/team.ts
Normal file
0
src/soccer/team.ts
Normal file
Loading…
Reference in New Issue
Block a user