From b9573cee19957d7d730a4a03fd42a124ec617693 Mon Sep 17 00:00:00 2001 From: umfy <39531680+umfy@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:56:04 +0200 Subject: [PATCH] Fix: update fish-pond tutorial --- .../fishPond/step2/addBackground-completed.js | 8 +++---- .../v8.0.0/fishPond/step2/step2-content.md | 5 +++-- .../fishPond/step3/addFishes-completed.js | 22 +++++++++++-------- .../v8.0.0/fishPond/step3/addFishes.js | 2 +- .../v8.0.0/fishPond/step3/step3-code.js | 6 ++--- .../v8.0.0/fishPond/step3/step3-content.md | 18 +++++++++------ .../step4/addWaterOverlay-completed.js | 10 ++++----- .../v8.0.0/fishPond/step4/addWaterOverlay.js | 5 +---- .../v8.0.0/fishPond/step4/step4-code.js | 10 ++++----- .../v8.0.0/fishPond/step4/step4-content.md | 14 +++++++----- .../v8.0.0/fishPond/step5/step5-code.js | 11 +++++----- .../v8.0.0/fishPond/step6/step6-code.js | 11 +++++----- 12 files changed, 62 insertions(+), 60 deletions(-) diff --git a/src/tutorials/v8.0.0/fishPond/step2/addBackground-completed.js b/src/tutorials/v8.0.0/fishPond/step2/addBackground-completed.js index c8a947443..456994847 100644 --- a/src/tutorials/v8.0.0/fishPond/step2/addBackground-completed.js +++ b/src/tutorials/v8.0.0/fishPond/step2/addBackground-completed.js @@ -5,8 +5,8 @@ export function addBackground(app) // Create a background sprite. const background = Sprite.from('background'); - // Center background sprite anchor. - background.anchor.set(0.5); + // Add the background to the stage. + app.stage.addChild(background); /** * If the preview is landscape, fill the width of the screen @@ -28,9 +28,7 @@ export function addBackground(app) } // Position the background sprite in the center of the stage. + background.anchor.set(0.5); background.x = app.screen.width / 2; background.y = app.screen.height / 2; - - // Add the background to the stage. - app.stage.addChild(background); } diff --git a/src/tutorials/v8.0.0/fishPond/step2/step2-content.md b/src/tutorials/v8.0.0/fishPond/step2/step2-content.md index db5eff33d..c7bd5137c 100644 --- a/src/tutorials/v8.0.0/fishPond/step2/step2-content.md +++ b/src/tutorials/v8.0.0/fishPond/step2/step2-content.md @@ -4,12 +4,12 @@ Now lets fill the pond with some rocks and pebbles, shall we? Let's work inside ## Create and Setup Background Sprite -We already preloaded the pond background asset as the alias 'background' so we can just simply create a sprite +We already preloaded the pond background asset as the alias 'background' so we can just simply create a sprite and add it to the stage. ```javascript const background = Sprite.from('background'); -background.anchor.set(0.5); +app.stage.addChild(background); ``` ## Fit and Position Sprite @@ -36,6 +36,7 @@ When we manually set the width or height on a sprite, it will apply a scale on t Then we simply position it at the center of the preview. ```javascript +background.anchor.set(0.5); background.x = app.screen.width / 2; background.y = app.screen.height / 2; ``` diff --git a/src/tutorials/v8.0.0/fishPond/step3/addFishes-completed.js b/src/tutorials/v8.0.0/fishPond/step3/addFishes-completed.js index 9f38dea0e..340e8da58 100644 --- a/src/tutorials/v8.0.0/fishPond/step3/addFishes-completed.js +++ b/src/tutorials/v8.0.0/fishPond/step3/addFishes-completed.js @@ -1,6 +1,6 @@ import { Container, Sprite } from 'pixi.js'; -export function addFishes(app, fishes) +export function addFishes(app) { // Create a container to hold all the fish sprites. const fishContainer = new Container(); @@ -10,9 +10,10 @@ export function addFishes(app, fishes) const fishCount = 20; const fishAssets = ['fish1', 'fish2', 'fish3', 'fish4', 'fish5']; + const fishes = []; // Create a fish sprite for each fish. - for (let i = 0; i < fishCount; i++) + for (let i = 0; i < fishCount; i++) { // Cycle through the fish assets for each sprite. const fishAsset = fishAssets[i % fishAssets.length]; @@ -41,6 +42,9 @@ export function addFishes(app, fishes) // Add the fish sprite to the fish array. fishes.push(fish); } + + // Return the fish array. + return fishes; } export function animateFishes(app, fishes, time) @@ -57,29 +61,29 @@ export function animateFishes(app, fishes, time) fishes.forEach((fish) => { // Animate the fish movement direction according to the turn speed. - fish.direction += fish.turnSpeed * 0.01; + fish.direction += fish.turnSpeed * 0.01 * delta; // Animate the fish position according to the direction and speed. - fish.x += Math.sin(fish.direction) * fish.speed; - fish.y += Math.cos(fish.direction) * fish.speed; + fish.x += Math.sin(fish.direction) * fish.speed * delta; + fish.y += Math.cos(fish.direction) * fish.speed * delta; // Apply the fish rotation according to the direction. fish.rotation = -fish.direction - Math.PI / 2; // Wrap the fish position when it goes out of bounds. - if (fish.x < -stagePadding) + if (fish.x < -stagePadding) { fish.x += boundWidth; } - if (fish.x > app.screen.width + stagePadding) + if (fish.x > app.screen.width + stagePadding) { fish.x -= boundWidth; } - if (fish.y < -stagePadding) + if (fish.y < -stagePadding) { fish.y += boundHeight; } - if (fish.y > app.screen.height + stagePadding) + if (fish.y > app.screen.height + stagePadding) { fish.y -= boundHeight; } diff --git a/src/tutorials/v8.0.0/fishPond/step3/addFishes.js b/src/tutorials/v8.0.0/fishPond/step3/addFishes.js index f6813a7ae..f75addf4a 100644 --- a/src/tutorials/v8.0.0/fishPond/step3/addFishes.js +++ b/src/tutorials/v8.0.0/fishPond/step3/addFishes.js @@ -1,6 +1,6 @@ import { Container, Sprite } from 'pixi.js'; -export function addFishes(app, fishes) +export function addFishes(app) { /** -- INSERT CODE HERE -- */ } diff --git a/src/tutorials/v8.0.0/fishPond/step3/step3-code.js b/src/tutorials/v8.0.0/fishPond/step3/step3-code.js index fd5c04901..624945482 100644 --- a/src/tutorials/v8.0.0/fishPond/step3/step3-code.js +++ b/src/tutorials/v8.0.0/fishPond/step3/step3-code.js @@ -5,9 +5,6 @@ import { addFishes, animateFishes } from './addFishes'; // Create a PixiJS application. const app = new Application(); -// Store an array of fish sprites for animation. -const fishes = []; - async function setup() { // Intialize the application. @@ -42,7 +39,8 @@ async function preload() await preload(); addBackground(app); - addFishes(app, fishes); + + const fishes = addFishes(app); // Add the fish animation callback to the application's ticker. app.ticker.add((time) => animateFishes(app, fishes, time)); diff --git a/src/tutorials/v8.0.0/fishPond/step3/step3-content.md b/src/tutorials/v8.0.0/fishPond/step3/step3-content.md index fc09e0945..a0324060a 100644 --- a/src/tutorials/v8.0.0/fishPond/step3/step3-content.md +++ b/src/tutorials/v8.0.0/fishPond/step3/step3-content.md @@ -12,16 +12,18 @@ const fishContainer = new Container(); app.stage.addChild(fishContainer); ``` -Then we declare some reference variables like how many fishes should there be in the pond and what are the fish types available. For the types, we refer to the 5 different fish assets we have preloaded earlier and made them into an array of aliases. +Then we declare some reference variables like how many fishes should be there in the pond and what are the fish types available. For the types, we refer to the 5 different fish assets we have preloaded earlier and made them into an array of aliases. ```javascript const fishCount = 20; const fishAssets = ['fish1', 'fish2', 'fish3', 'fish4', 'fish5']; ``` -Instead of creating each of the fish individually, which will be super tedious, we will use a simple `for` loop to create each of the fish until it reaches our desire count, also cycling through the fish asset aliases array. In addition to the basic setup and applying initial transforms, we also assign them with custom properties like `direction`, `speed` and `turnSpeed` which will be used during the animation. We will store the fishes in a reference array defined outside of the IIFE. +Instead of creating every fish individually, which would be super tedious, we will use a simple `for` loop to create each of the fishes and store them in an array until it reaches our desired count. In addition to the basic setup and applying initial transforms, we also assign them with custom properties like `direction`, `speed` and `turnSpeed` which will be used during the animation. ```javascript +const fishes = []; + for (let i = 0; i < fishCount; i++) { const fishAsset = fishAssets[i % fishAssets.length]; @@ -40,13 +42,15 @@ for (let i = 0; i < fishCount; i++) fishContainer.addChild(fish); fishes.push(fish); } + +return fishes; ``` ## Animate Fishes -It's time to give the fishes some movements! Another function `animateFishes` has been prepared and connected to the application's ticker which will be continuously called. It is supplied with a Ticker object which we can use to infer the amount of time passed between the calls. +It's time to give the fishes some movements! Another function `animateFishes` has been prepared and connected to the application's ticker which will be continuously called. -We will declare a few variables to help us with the animation. We extract `deltaTime` from the Ticker object which tells us the amount of time passed since last call, in seconds. We also define an imaginary bound that is larger than the stage itself to wrap the position of the fishes when they go off the screen. We use this bound instead of the actual screen size to avoid having the fishes disappear before they actually go off the edges, since the fish sprites' anchor is in the center so, eg. when a `fish.x = 0`, half of the fish's width is still apparent on the screen. +We will declare a few variables to help us with the animation. We extract `deltaTime` from the Ticker object which tells us the amount of time passed since last call. Using it guarantees consistent movement, regardless of the frame rate. We also define an imaginary bound that is larger than the stage itself to wrap the position of the fishes when they go off the screen. We use this bound instead of the actual screen size to avoid having the fishes disappear before they actually go off the edges, since the fish sprites' anchor is in the center so, eg. when a `fish.x = 0`, half of the fish's width is still apparent on the screen. ```javascript const delta = time.deltaTime; @@ -61,9 +65,9 @@ We can then simply loop through individual fishes array and update them one by o ```javascript fishes.forEach((fish) => { - fish.direction += fish.turnSpeed * 0.01; - fish.x += Math.sin(fish.direction) * fish.speed; - fish.y += Math.cos(fish.direction) * fish.speed; + fish.direction += fish.turnSpeed * 0.01 * delta; + fish.x += Math.sin(fish.direction) * fish.speed * delta; + fish.y += Math.cos(fish.direction) * fish.speed * delta; fish.rotation = -fish.direction - Math.PI / 2; if (fish.x < -stagePadding) diff --git a/src/tutorials/v8.0.0/fishPond/step4/addWaterOverlay-completed.js b/src/tutorials/v8.0.0/fishPond/step4/addWaterOverlay-completed.js index d7d0a4d28..a95c2d7ce 100644 --- a/src/tutorials/v8.0.0/fishPond/step4/addWaterOverlay-completed.js +++ b/src/tutorials/v8.0.0/fishPond/step4/addWaterOverlay-completed.js @@ -1,15 +1,12 @@ import { Texture, TilingSprite } from 'pixi.js'; -// Reference to the water overlay. -let overlay; - export function addWaterOverlay(app) { // Create a water texture object. const texture = Texture.from('overlay'); // Create a tiling sprite with the water texture and specify the dimensions. - overlay = new TilingSprite({ + const overlay = new TilingSprite({ texture, width: app.screen.width, height: app.screen.height, @@ -17,9 +14,12 @@ export function addWaterOverlay(app) // Add the overlay to the stage. app.stage.addChild(overlay); + + // Return the water overlay. + return overlay; } -export function animateWaterOverlay(app, time) +export function animateWaterOverlay(overlay, time) { // Extract the delta time from the Ticker object. const delta = time.deltaTime; diff --git a/src/tutorials/v8.0.0/fishPond/step4/addWaterOverlay.js b/src/tutorials/v8.0.0/fishPond/step4/addWaterOverlay.js index fe2bbbd0f..34f1c1f07 100644 --- a/src/tutorials/v8.0.0/fishPond/step4/addWaterOverlay.js +++ b/src/tutorials/v8.0.0/fishPond/step4/addWaterOverlay.js @@ -1,14 +1,11 @@ import { Texture, TilingSprite } from 'pixi.js'; -// Reference to the water overlay. -let overlay; - export function addWaterOverlay(app) { /** -- INSERT CODE HERE -- */ } -export function animateWaterOverlay(app, time) +export function animateWaterOverlay(overlay, time) { /** -- INSERT CODE HERE -- */ } diff --git a/src/tutorials/v8.0.0/fishPond/step4/step4-code.js b/src/tutorials/v8.0.0/fishPond/step4/step4-code.js index 903c64188..d565fc14d 100644 --- a/src/tutorials/v8.0.0/fishPond/step4/step4-code.js +++ b/src/tutorials/v8.0.0/fishPond/step4/step4-code.js @@ -6,9 +6,6 @@ import { addWaterOverlay, animateWaterOverlay } from './addWaterOverlay'; // Create a PixiJS application. const app = new Application(); -// Store an array of fish sprites for animation. -const fishes = []; - async function setup() { // Intialize the application. @@ -43,13 +40,14 @@ async function preload() await preload(); addBackground(app); - addFishes(app, fishes); - addWaterOverlay(app); + + const fishes = addFishes(app); + const overlay = addWaterOverlay(app); // Add the animation callbacks to the application's ticker. app.ticker.add((time) => { animateFishes(app, fishes, time); - animateWaterOverlay(app, time); + animateWaterOverlay(overlay, time); }); })(); diff --git a/src/tutorials/v8.0.0/fishPond/step4/step4-content.md b/src/tutorials/v8.0.0/fishPond/step4/step4-content.md index 99b9915fa..fdf380457 100644 --- a/src/tutorials/v8.0.0/fishPond/step4/step4-content.md +++ b/src/tutorials/v8.0.0/fishPond/step4/step4-content.md @@ -9,22 +9,26 @@ Here we create a tiling sprite, supplying a texture and dimensions as an option ```javascript const texture = Texture.from('overlay'); -overlay = new TilingSprite({ +const overlay = new TilingSprite({ texture, width: app.screen.width, height: app.screen.height, }); + app.stage.addChild(overlay); + +return overlay; ``` ## Animate Overlay -Similar to the previous step, we will now animate the water overlay using the application's ticker. The code has been modify to call both animation functions for the fish and this overlay so we only need to add the animation logic inside the `animateWaterOverlay` function. +Similar to the previous step, we will now animate the water overlay using the application's ticker. The code has been modified to call both animation functions for the fish and overlay, so now we only need to add the animation logic inside the `animateWaterOverlay` function. ```javascript -elapsed += time.deltaTime; -overlay.tilePosition.x = elapsed * -1; -overlay.tilePosition.y = elapsed * -1; +const delta = time.deltaTime; + +overlay.tilePosition.x -= delta; +overlay.tilePosition.y -= delta; ``` Congratulations, we have now completed a beautiful pond! But we can take it a step further. Let's proceed to the final touch! \ No newline at end of file diff --git a/src/tutorials/v8.0.0/fishPond/step5/step5-code.js b/src/tutorials/v8.0.0/fishPond/step5/step5-code.js index f7e858e97..4620cc7e9 100644 --- a/src/tutorials/v8.0.0/fishPond/step5/step5-code.js +++ b/src/tutorials/v8.0.0/fishPond/step5/step5-code.js @@ -7,9 +7,6 @@ import { addDisplacementEffect } from './addDisplacementEffect'; // Create a PixiJS application. const app = new Application(); -// Store an array of fish sprites for animation. -const fishes = []; - async function setup() { // Intialize the application. @@ -44,14 +41,16 @@ async function preload() await preload(); addBackground(app); - addFishes(app, fishes); - addWaterOverlay(app); + + const fishes = addFishes(app); + const overlay = addWaterOverlay(app); + addDisplacementEffect(app); // Add the animation callbacks to the application's ticker. app.ticker.add((time) => { animateFishes(app, fishes, time); - animateWaterOverlay(app, time); + animateWaterOverlay(overlay, time); }); })(); diff --git a/src/tutorials/v8.0.0/fishPond/step6/step6-code.js b/src/tutorials/v8.0.0/fishPond/step6/step6-code.js index f7e858e97..4620cc7e9 100644 --- a/src/tutorials/v8.0.0/fishPond/step6/step6-code.js +++ b/src/tutorials/v8.0.0/fishPond/step6/step6-code.js @@ -7,9 +7,6 @@ import { addDisplacementEffect } from './addDisplacementEffect'; // Create a PixiJS application. const app = new Application(); -// Store an array of fish sprites for animation. -const fishes = []; - async function setup() { // Intialize the application. @@ -44,14 +41,16 @@ async function preload() await preload(); addBackground(app); - addFishes(app, fishes); - addWaterOverlay(app); + + const fishes = addFishes(app); + const overlay = addWaterOverlay(app); + addDisplacementEffect(app); // Add the animation callbacks to the application's ticker. app.ticker.add((time) => { animateFishes(app, fishes, time); - animateWaterOverlay(app, time); + animateWaterOverlay(overlay, time); }); })();