はじめに
Pixi.jsについて学んだことの備忘録。
シーン切り替え(フェード)について。
ここではPixi.jsのver4を使用しています。
最新版では書き方が全然違うため動かないため注意が必要です。
シーン切り替え:フェード
場面Aから場面Bにシーンを切り替えたい。
スライド式以外のやり方もやってみよう。
画面をタッチすると、シーンAとシーンBが切り替わります。
画面が暗くなり、明るくなった時にはシーンが変わっている!
全然別のシーンでも違和感なく繋げられそうですね。
(前回は連打するとおかしかったので、今回はその対策もしました)
コードは下記のとおり。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>シーン切替(フェードスライド) Pixi.js</title>
<script src="../../pixi.min.js"></script>
</head>
<body style="margin: 0; overflow: hidden;">
<script>
// Pixi.jsのアプリケーションを作成
const app = new PIXI.Application({
width: 360, // 画面の横幅
height: 548, // 画面の縦幅
backgroundColor: 0xcccccc, // 背景色を設定
})
// appをbodyに追加
document.body.appendChild(app.view);
// シーンA
const sceneA = new PIXI.Container();
const backgroundA = new PIXI.Graphics();
backgroundA.beginFill(0xFFD1D1);
backgroundA.drawRect(0, 0, app.screen.width, app.screen.height);
backgroundA.endFill();
sceneA.addChild(backgroundA);
const textA = new PIXI.Text('シーンA', { fontSize: 50, fill: 0x000000 });
textA.anchor.set(0.5);
textA.x = app.screen.width / 2;
textA.y = app.screen.height / 2;
sceneA.addChild(textA);
// シーンB
const sceneB = new PIXI.Container();
const backgroundB = new PIXI.Graphics();
backgroundB.beginFill(0xA8D0E6);
backgroundB.drawRect(0, 0, app.screen.width, app.screen.height);
backgroundB.endFill();
sceneB.addChild(backgroundB);
const textB = new PIXI.Text('シーンB', { fontSize: 50, fill: 0x000000 });
textB.anchor.set(0.5);
textB.x = app.screen.width / 2;
textB.y = app.screen.height / 2;
sceneB.addChild(textB);
// フェードエフェクトのシーン
const blackout = new PIXI.Graphics();
blackout.beginFill(0x000000);
blackout.drawRect(0, 0, app.screen.width, app.screen.height);
blackout.endFill();
blackout.alpha = 0;
app.stage.addChild(sceneA);
app.stage.addChild(blackout);
let currentScene = 'A';
let isTransitioning = false;
// シーン切替(フェード)
function switchScene() {
if (isTransitioning) return;
isTransitioning = true;
blackout.alpha = 0;
app.stage.addChild(blackout);
let fadeIn = true;
let fadeOut = false;
function fadeEffect(delta) {
if (fadeIn) {
blackout.alpha += delta * 0.05;
if (blackout.alpha >= 1) {
blackout.alpha = 1;
fadeIn = false;
fadeOut = true;
if (currentScene === 'A') {
app.stage.removeChild(sceneA);
app.stage.addChild(sceneB);
currentScene = 'B';
} else {
app.stage.removeChild(sceneB);
app.stage.addChild(sceneA);
currentScene = 'A';
}
app.stage.addChild(blackout);
}
} else if (fadeOut) {
blackout.alpha -= delta * 0.05;
if (blackout.alpha <= 0) {
blackout.alpha = 0;
fadeOut = false;
isTransitioning = false;
app.stage.removeChild(blackout);
app.ticker.remove(fadeEffect);
}
}
}
app.ticker.add(fadeEffect);
}
app.view.addEventListener('pointerdown', switchScene);
</script>
</body>
</html>
◆メインの処理を抜粋
// シーン切替(フェード)
function switchScene() {
if (isTransitioning) return;
isTransitioning = true;
blackout.alpha = 0;
app.stage.addChild(blackout);
let fadeIn = true;
let fadeOut = false;
function fadeEffect(delta) {
if (fadeIn) {
blackout.alpha += delta * 0.05;
if (blackout.alpha >= 1) {
blackout.alpha = 1;
fadeIn = false;
fadeOut = true;
if (currentScene === 'A') {
app.stage.removeChild(sceneA);
app.stage.addChild(sceneB);
currentScene = 'B';
} else {
app.stage.removeChild(sceneB);
app.stage.addChild(sceneA);
currentScene = 'A';
}
app.stage.addChild(blackout);
}
} else if (fadeOut) {
blackout.alpha -= delta * 0.05;
if (blackout.alpha <= 0) {
blackout.alpha = 0;
fadeOut = false;
isTransitioning = false;
app.stage.removeChild(blackout);
app.ticker.remove(fadeEffect);
}
}
}
app.ticker.add(fadeEffect);
}
0.連打対策
処理実行時にフラグを立て、フラグが立っていたら何もせずに返しています
if (isTransitioning) return;
isTransitioning = true;
1.フェード用のコンテナを追加
フェード演出用のコンテナを画面に追加(この時点では透明で黒くない状態)
(シーンの切り替えで画面の前後関係が変わるので、毎回必ず追加する)
app.stage.addChild(blackout);
2.フェードイン、画面を徐々に暗くする
おなじみdeltaを使って透明度を徐々に下げ、画面を黒くする。
function fadeEffect(delta) {
if (fadeIn) {
blackout.alpha += delta * 0.05;
3.シーンの切り替え
真っ暗になったら現在のシーンを削除して、新しいシーンを追加する。
if (blackout.alpha >= 1) {
blackout.alpha = 1;
fadeIn = false;
fadeOut = true;
if (currentScene === ‘A’) {
app.stage.removeChild(sceneA);
app.stage.addChild(sceneB);
currentScene = ‘B’;
4.フェードアウト
フェード演出用コンテナの透明度を徐々に上げて、画面を見えるようにする。
} else if (fadeOut) {
blackout.alpha -= delta * 0.05;
if (blackout.alpha <= 0) {
blackout.alpha = 0;
fadeOut = false;
isTransitioning = false;
app.stage.removeChild(blackout);
app.ticker.remove(fadeEffect);
}
こんな感じです。よく見るやつですがちゃんと動くと嬉しい。
おわりに
きっと一番使いやすいシーン切り替え。
真っ暗じゃなくて真っ白のパターンもありますね。
フェード演出用コンテナの背景色を変えれば好きな色でフェードできるはず。
2週連続のシーン切り替え演出でした。
今週はゲームを公開したかったのだけど製作が間に合わず。
やりたいことはたくさんあるけど思うようにはいかないものです!
健康第一で楽しく過ごしましょう。
おわり
コメント