Add new christmas level
This commit is contained in:
171
src/scenes/scene-christmas-calm.js
Normal file
171
src/scenes/scene-christmas-calm.js
Normal file
@@ -0,0 +1,171 @@
|
||||
(() => {
|
||||
const { Bodies, Body, Vertices } = Matter;
|
||||
const scenes = (window.PhysilinksSceneDefs =
|
||||
window.PhysilinksSceneDefs || []);
|
||||
|
||||
scenes.push({
|
||||
id: "christmas-calm",
|
||||
name: "Christmas calm",
|
||||
config: {
|
||||
gravity: 0.5,
|
||||
spawnIntervalMs: 720,
|
||||
spawnBatchMin: 1,
|
||||
spawnBatchMax: 2,
|
||||
minChain: 3,
|
||||
palette: ["#b91c1c", "#15803d", "#f59e0b", "#7dd3fc", "#fda4af"],
|
||||
ballRadius: 20,
|
||||
ballShape: "gift",
|
||||
giftRibbonColor: "#f8fafc",
|
||||
debugSpawn: true,
|
||||
initialSpawnCount: 10,
|
||||
initialSpawnArea: ({ width, height }) => ({
|
||||
xMin: width * 0.28,
|
||||
xMax: width * 0.72,
|
||||
yMin: height * 0.76,
|
||||
yMax: height * 0.88,
|
||||
}),
|
||||
winCondition: {
|
||||
type: "score",
|
||||
target: 12000,
|
||||
onWin: { shoveBalls: true },
|
||||
},
|
||||
messages: {
|
||||
text: "Cozy winter glow",
|
||||
position: { xPercent: 50, yPercent: 12 },
|
||||
},
|
||||
link: {
|
||||
stiffness: 0.7,
|
||||
lengthScale: 1.05,
|
||||
damping: 0.05,
|
||||
lineWidth: 4,
|
||||
rope: true,
|
||||
renderType: "line",
|
||||
maxLengthMultiplier: 5.4,
|
||||
},
|
||||
backdrop: {
|
||||
colors: ["#0f172a", "#14532d", "#1f2937"],
|
||||
opacity: 0.35,
|
||||
blur: 26,
|
||||
speedSec: 34,
|
||||
},
|
||||
},
|
||||
createBodies: (w, h) => {
|
||||
const wallThickness = Math.max(32, w * 0.045);
|
||||
const wallHeight = h * 1.7;
|
||||
const floorHeight = Math.max(70, h * 0.12);
|
||||
const treeBaseRadius = Math.min(w, h) * 0.22;
|
||||
const treeMidRadius = Math.min(w, h) * 0.16;
|
||||
const treeTopRadius = Math.min(w, h) * 0.11;
|
||||
const trunkWidth = treeBaseRadius * 0.3;
|
||||
const trunkHeight = treeBaseRadius * 0.35;
|
||||
const treeCenterX = w * 0.5;
|
||||
const treeBaseY = h * 0.62;
|
||||
const treeMidY = h * 0.52;
|
||||
const treeTopY = h * 0.43;
|
||||
const treeColor = "#166534";
|
||||
const trunkColor = "#7c2d12";
|
||||
|
||||
const makeTriangle = (x, y, radius) => {
|
||||
const points = [
|
||||
{ x: 0, y: -radius },
|
||||
{ x: radius, y: radius },
|
||||
{ x: -radius, y: radius },
|
||||
];
|
||||
return Bodies.fromVertices(
|
||||
x,
|
||||
y,
|
||||
[points],
|
||||
{
|
||||
isStatic: true,
|
||||
render: { fillStyle: treeColor, strokeStyle: treeColor },
|
||||
},
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
const makeComet = (x, y, size) => {
|
||||
const baseStar = Vertices.fromPath(
|
||||
"50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38",
|
||||
);
|
||||
const scale = (size || 50) / 50;
|
||||
const points = baseStar.map((p) => ({
|
||||
x: (p.x - 50) * scale,
|
||||
y: (p.y - 50) * scale,
|
||||
}));
|
||||
const star = Bodies.fromVertices(
|
||||
x,
|
||||
y,
|
||||
[points],
|
||||
{
|
||||
isStatic: true,
|
||||
render: { fillStyle: "#facc15", strokeStyle: "#facc15" },
|
||||
},
|
||||
true,
|
||||
);
|
||||
const tail = Bodies.rectangle(
|
||||
x + size * 1.1,
|
||||
y + size * 0.2,
|
||||
size * 2.1,
|
||||
size * 0.45,
|
||||
{
|
||||
isStatic: true,
|
||||
angle: 0.35,
|
||||
render: { fillStyle: "#fde68a", strokeStyle: "#fde68a" },
|
||||
},
|
||||
);
|
||||
const starParts =
|
||||
Array.isArray(star.parts) && star.parts.length > 1
|
||||
? star.parts
|
||||
: [star];
|
||||
return Body.create({
|
||||
isStatic: true,
|
||||
parts: [...starParts, tail],
|
||||
render: { fillStyle: "#facc15", strokeStyle: "#facc15" },
|
||||
plugin: { rotSpeed: 0.35 },
|
||||
});
|
||||
};
|
||||
|
||||
return [
|
||||
Bodies.rectangle(
|
||||
w / 2,
|
||||
h + floorHeight / 2,
|
||||
w + wallThickness * 2,
|
||||
floorHeight,
|
||||
{
|
||||
isStatic: true,
|
||||
restitution: 0.7,
|
||||
render: { fillStyle: "#e2e8f0", strokeStyle: "#e2e8f0" },
|
||||
},
|
||||
),
|
||||
Bodies.rectangle(-wallThickness / 2, h / 2, wallThickness, wallHeight, {
|
||||
isStatic: true,
|
||||
render: { fillStyle: "#0f766e", strokeStyle: "#0f766e" },
|
||||
}),
|
||||
Bodies.rectangle(
|
||||
w + wallThickness / 2,
|
||||
h / 2,
|
||||
wallThickness,
|
||||
wallHeight,
|
||||
{
|
||||
isStatic: true,
|
||||
render: { fillStyle: "#0f766e", strokeStyle: "#0f766e" },
|
||||
},
|
||||
),
|
||||
makeTriangle(treeCenterX, treeBaseY, treeBaseRadius),
|
||||
makeTriangle(treeCenterX, treeMidY, treeMidRadius),
|
||||
makeTriangle(treeCenterX, treeTopY, treeTopRadius),
|
||||
Bodies.rectangle(
|
||||
treeCenterX,
|
||||
treeBaseY + treeBaseRadius * 0.65,
|
||||
trunkWidth,
|
||||
trunkHeight,
|
||||
{
|
||||
isStatic: true,
|
||||
render: { fillStyle: trunkColor, strokeStyle: trunkColor },
|
||||
},
|
||||
),
|
||||
makeComet(w * 0.2, h * 0.25, Math.max(18, w * 0.025)),
|
||||
];
|
||||
},
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user