Soccer Components.

This commit is contained in:
Michael Mainguy 2023-09-17 09:16:56 -05:00
parent 5510ef5a09
commit 0e6e0bdd1f
4 changed files with 260 additions and 0 deletions

71
src/soccer/ball.ts Normal file
View 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
View 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
View 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
View File