diff --git a/remotion/src/baukasten/natur.tsx b/remotion/src/baukasten/natur.tsx
index 3f83532..ef6c7c1 100644
--- a/remotion/src/baukasten/natur.tsx
+++ b/remotion/src/baukasten/natur.tsx
@@ -308,25 +308,45 @@ export const Blume: React.FC<{x: number; y: number; s?: number; r?: number}> = (
);
-// Folge 1: Laubhaufen (Fuß bei x, y; ca. 340 × 140 px bei s = 1).
+// Ahornblatt (Spitze oben, ca. 90 px hoch bei s = 1) und schmales Buchenblatt, für den Laubhaufen
+const AHORN = 'M0,40 L4,18 L22,27 L18,12 L40,5 L30,-2 L37,-21 L18,-14 L16,-31 L6,-22 L0,-46 L-6,-22 L-16,-31 L-18,-14 L-37,-21 L-30,-2 L-40,5 L-18,12 L-22,27 L-4,18 Z';
+const AHORN_ADERN = 'M0,52 L0,-38 M0,10 L30,-14 M0,10 L-30,-14 M0,18 L18,24 M0,18 L-18,24';
+const BUCHE = 'M0,-44 C 22,-30 24,0 0,30 C -24,0 -22,-30 0,-44 Z';
+const BUCHE_ADERN = 'M0,40 L0,-36 M0,-14 L12,-24 M0,-2 L14,-12 M0,-8 L-12,-18 M0,4 L-13,-6';
+const HAUFEN_HELL = ['#e07a2e', '#d4522a', '#e9a83a', '#c2412a', '#f0c048', '#d98a3a', '#b8662a'];
+const HAUFEN_DUNKEL = ['#9e4a26', '#8a3a22', '#a8682e', '#7a3a24'];
+
+// Folge 1: Laubhaufen aus großen Herbstblättern (Fuß bei x, y; ca. 400 × 190 px bei s = 1).
+// Reicht unten 45 px unter den Fußpunkt, damit Füße darin verschwinden.
// `wackeln` 0 … 1 lässt ihn zittern, `flach` 0 … 1 drückt ihn zusammen (Noa springt hinein).
export const Laubhaufen: React.FC<{x: number; y: number; s?: number; wackeln?: number; flach?: number}> = ({x, y, s = 1, wackeln = 0, flach = 0}) => {
const frame = useCurrentFrame();
const zitter = wackeln * Math.sin(frame * 1.3) * 3;
+ // hinten/oben zuerst zeichnen, vorne/unten zuletzt
+ const blaetter = new Array(120).fill(0).map((_, i) => {
+ const r = (k: string) => random(`lh${k}${i}`);
+ const u = r('u') * 2.2 - 1.1;
+ const kuppe = Math.pow(Math.max(0, 1 - u * u), 0.6) * 150;
+ const ly = 40 - r('y') * (kuppe + 40);
+ return {i, u, lx: u * 180, ly, ahorn: r('a') < 0.62, s: 0.85 + r('s') * 0.65, w: r('w') * 360, dunkel: ly < -kuppe * 0.55 ? false : r('d') < 0.3, farbe: r('f')};
+ });
+ blaetter.sort((a, b) => a.ly - b.ly);
return (
);
diff --git a/remotion/src/folge01/szene2.tsx b/remotion/src/folge01/szene2.tsx
index 2709271..d9c1280 100644
--- a/remotion/src/folge01/szene2.tsx
+++ b/remotion/src/folge01/szene2.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import {useCurrentFrame} from 'remotion';
import {kurve} from '../bewegung';
-import {Figur, Geher, Kamera} from '../baukasten/figur';
+import {ClipFigur, Figur, Geher, Kamera, NOA_HOCKE_FRAMES, NoaHocke} from '../baukasten/figur';
import {Blende, Vignette, atmen, hopfStauch, huepfer, kamFahrt, ruck} from '../baukasten/helfer';
import {Apfel, Blaetterregen, Blaetterwind, Blume, Laubhaufen} from '../baukasten/natur';
import {BODEN, Ort} from '../baukasten/orte';
@@ -16,7 +16,7 @@ export const APFEL = {x: 560, y: 205}; // der letzte Apfel, ganz oben im Baum
export const BLUME_X = 1560; // blaue Blume am Zaun
export const BLUME_Y = 805;
export const NOA_X = 960; // Noa neben dem Haufen
-export const PINO_HAUFEN_Y = BODEN - 92; // Pino sitzt oben im Haufen
+export const PINO_HAUFEN_Y = BODEN - 128; // Pino steckt oben im Haufen (als Kugel)
export const S2 = plane('s2', [
{id: 'bild0', dauer: 2.2},
@@ -71,16 +71,18 @@ export const Szene2: React.FC = () => {
[schreck, 'noa_B2_erschrocken'],
[z.n2.start + 6, 'noa_A4_staunen'],
[z.e6.start, 'noa_A6_blick-rechts'],
- [hocke, 'noa_B_hocken'],
[aufstehen, 'noa_A3_lachen'],
[z.p2.start + 10, 'noa_A6_blick-rechts'],
];
+ // Hocke: Clip „hinsetzen“ bis zur Hocke, zum Aufstehen rückwärts
+ const inHocke = f >= hocke && f < aufstehen + NOA_HOCKE_FRAMES;
+ const hockeStart = f < aufstehen ? hocke : aufstehen;
const noaY =
BODEN +
sprungY +
huepfer(f, raus, 60, 16) +
ruck(f, schreck, 3) +
- huepfer(f, z.n4.start + 20, 14, 10);
+ huepfer(f, aufstehen + NOA_HOCKE_FRAMES + 4, 14, 10);
// Laubhaufen: wird bei der Landung gestaucht, später raschelt er
const flach = kurve(f, [
@@ -96,24 +98,28 @@ export const Szene2: React.FC = () => {
]);
// Pino: als Stachelkugel im Haufen, kommt hoch, öffnet sich bei bild4
+ const auf = z.bild4.start; // Einroll-Clip rückwärts
+ const AUF_FRAMES = 75; // 121 Clip-Bilder (24 fps) bei Tempo 2
+ const oeffnet = f >= auf && f < auf + AUF_FRAMES;
+ const zuNoa = f >= auf; // die Bilder schauen nach rechts, Noa sitzt links
const pinoY = kurve(f, [
- [schreck - 10, PINO_HAUFEN_Y + 110],
+ [schreck - 10, PINO_HAUFEN_Y + 140],
[schreck + 6, PINO_HAUFEN_Y],
- [z.bild4.start + 14, PINO_HAUFEN_Y],
- [z.bild4.start + 40, PINO_HAUFEN_Y - 42],
+ [auf + 20, PINO_HAUFEN_Y],
+ [auf + AUF_FRAMES, PINO_HAUFEN_Y - 40],
]);
const pinoDa = f >= schreck - 10;
const pinoPose: [number, string][] = [
[0, 'pino_A_kugel'],
- [z.bild4.start + 20, 'pino_ref_sitzend'],
+ [auf + AUF_FRAMES, 'pino_ref_sitzend'],
[z.p1.start, 'pino_B_blick-nach-oben'],
[z.p1.start + 40, 'pino_A4_staunen'],
[z.p2.start, 'pino_B_blick-nach-oben'],
[z.p2.ende - 10, 'pino_A3_lachen'],
];
// Stacheln zittern vor Angst, solange er eine Kugel ist
- const angst = f < z.bild4.start + 20 ? Math.sin(f * 1.7) * 1.5 : 0;
- const pinoStauch = atmen(f, 1, 0.01) * hopfStauch(f, schreck) * (f >= z.bild4.start && f < z.bild4.start + 24 ? kurve(f, [[z.bild4.start, 0.9], [z.bild4.start + 24, 1]]) : 1);
+ const angst = f < auf ? Math.sin(f * 1.7) * 1.5 : 0;
+ const pinoStauch = atmen(f, 1, 0.01) * hopfStauch(f, schreck);
const kam = kamFahrt(f, [
[0, 960, 540, 1.0],
@@ -135,11 +141,22 @@ export const Szene2: React.FC = () => {
- {pinoDa && }
+ {pinoDa &&
+ (oeffnet ? (
+
+ ) : (
+
+ ))}
{/* Im Haufen steht Noa hinter den vorderen Blättern */}
{imHaufen && }
-
- {imHaufen ? null : noaGeht ? : }
+
+ {imHaufen ? null : noaGeht ? (
+
+ ) : inHocke ? (
+ = aufstehen} x={noaX} y={BODEN} />
+ ) : (
+
+ )}