Improve gameplay
This commit is contained in:
parent
7412bc8af5
commit
793d9a81e8
1 changed files with 275 additions and 226 deletions
|
|
@ -1,125 +0,0 @@
|
|||
import { mat2d, vec2 } from 'gl-matrix';
|
||||
import { Drawable, DrawableDescriptor } from 'sdf-2d';
|
||||
import { Circle } from 'shared';
|
||||
|
||||
export class BlobShape extends Drawable {
|
||||
public static descriptor: DrawableDescriptor = {
|
||||
sdf: {
|
||||
shader: `
|
||||
uniform vec2 headCenters[BLOB_COUNT];
|
||||
uniform vec2 leftFootCenters[BLOB_COUNT];
|
||||
uniform vec2 rightFootCenters[BLOB_COUNT];
|
||||
uniform float headRadii[BLOB_COUNT];
|
||||
uniform float footRadii[BLOB_COUNT];
|
||||
uniform int blobColors[BLOB_COUNT];
|
||||
|
||||
float blobSmoothMin(float a, float b)
|
||||
{
|
||||
const highp float k = 300.0;
|
||||
highp float res = exp2(-k * a) + exp2(-k * b);
|
||||
return -log2(res) / k;
|
||||
}
|
||||
|
||||
float circleDistance(vec2 circleCenter, float radius, vec2 target) {
|
||||
return distance(target, circleCenter) - radius;
|
||||
}
|
||||
|
||||
float blobMinDistance(vec2 target, out vec4 color) {
|
||||
float minDistance = 1000.0;
|
||||
|
||||
for (int i = 0; i < BLOB_COUNT; i++) {
|
||||
float headDistance = circleDistance(headCenters[i], headRadii[i], target);
|
||||
float leftFootDistance = circleDistance(leftFootCenters[i], footRadii[i], target);
|
||||
float rightFootDistance = circleDistance(rightFootCenters[i], footRadii[i], target);
|
||||
|
||||
float res = min(
|
||||
blobSmoothMin(headDistance, leftFootDistance),
|
||||
blobSmoothMin(headDistance, rightFootDistance)
|
||||
);
|
||||
|
||||
vec2 leftEyeOffset = vec2(-headRadii[i] * 0.35, headRadii[i] * 0.2);
|
||||
vec2 rightEyeOffset = vec2(headRadii[i] * 0.35, headRadii[i] * 0.2);
|
||||
|
||||
float eyeDistance = min(
|
||||
circleDistance(headCenters[i] + rightEyeOffset, headRadii[i] * 0.25, target),
|
||||
circleDistance(headCenters[i] + leftEyeOffset, headRadii[i] * 0.25, target)
|
||||
);
|
||||
|
||||
eyeDistance = max(
|
||||
eyeDistance,
|
||||
-circleDistance(headCenters[i] + leftEyeOffset + vec2(0, -headRadii[i] * 0.175), headRadii[i] * 0.2, target)
|
||||
);
|
||||
|
||||
eyeDistance = max(
|
||||
eyeDistance,
|
||||
-circleDistance(headCenters[i] + rightEyeOffset + vec2(0, -headRadii[i] * 0.175), headRadii[i] * 0.2, target)
|
||||
);
|
||||
|
||||
if (res < minDistance) {
|
||||
minDistance = res;
|
||||
color = eyeDistance < 0.0 ? vec4(1.0) : readFromPalette(blobColors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return minDistance;
|
||||
}
|
||||
`,
|
||||
distanceFunctionName: 'blobMinDistance',
|
||||
},
|
||||
propertyUniformMapping: {
|
||||
footRadius: 'footRadii',
|
||||
headRadius: 'headRadii',
|
||||
rightFootCenter: 'rightFootCenters',
|
||||
leftFootCenter: 'leftFootCenters',
|
||||
headCenter: 'headCenters',
|
||||
color: 'blobColors',
|
||||
},
|
||||
uniformCountMacroName: 'BLOB_COUNT',
|
||||
shaderCombinationSteps: [0, 1, 2, 8],
|
||||
empty: new BlobShape(0),
|
||||
};
|
||||
|
||||
protected head!: Circle;
|
||||
protected leftFoot!: Circle;
|
||||
protected rightFoot!: Circle;
|
||||
|
||||
public constructor(private readonly color: number) {
|
||||
super();
|
||||
|
||||
const circle = new Circle(vec2.create(), 200);
|
||||
this.setCircles([circle, circle, circle]);
|
||||
}
|
||||
|
||||
public setCircles([head, leftFoot, rightFoot]: [Circle, Circle, Circle]) {
|
||||
this.head = head;
|
||||
this.leftFoot = leftFoot;
|
||||
this.rightFoot = rightFoot;
|
||||
}
|
||||
|
||||
public minDistance(target: vec2): number {
|
||||
return Math.min(
|
||||
this.head.distance(target),
|
||||
this.leftFoot.distance(target),
|
||||
this.rightFoot.distance(target),
|
||||
);
|
||||
}
|
||||
|
||||
protected getObjectToSerialize(transform2d: mat2d, transform1d: number): any {
|
||||
return {
|
||||
headCenter: vec2.transformMat2d(vec2.create(), this.head.center, transform2d),
|
||||
leftFootCenter: vec2.transformMat2d(
|
||||
vec2.create(),
|
||||
this.leftFoot.center,
|
||||
transform2d,
|
||||
),
|
||||
rightFootCenter: vec2.transformMat2d(
|
||||
vec2.create(),
|
||||
this.rightFoot.center,
|
||||
transform2d,
|
||||
),
|
||||
headRadius: this.head.radius * transform1d,
|
||||
footRadius: this.leftFoot.radius * transform1d,
|
||||
color: this.color,
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue