この記事は最終更新日から1年以上が経過しています。
@programming
投稿日 2020/2/20
更新日 2020/2/21 ✏
PixiJSでブラウザゲーム 03エフェクト
PixiJSでブラウザゲーム 02シーン切替ではゲームシーンの切替処理を実装してみました。 今回は、キャラアイコンにエフェクトをかけてみます。 サンプルでは、キャラアイコンの「フェードイン」、「フェードアウト」、「バイブレーション」、「点滅」、「回転」を実現しています。
目次:
前提
- PixiJS v5.2.1
サンプルコード
03-character-effect.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>キャラアイコンのエフェクト</title>
</head>
<body>
キャラアイコンのエフェクト
<div>
<button onclick="effectFadeOut(event)">フェードアウト</button>
<button onclick="effectFadeIn(event)">フェードイン</button>
<button onclick="effectVibe(event)">バイブレーション</button>
<button onclick="effectFlash(event)">点滅</button>
<button onclick="effectRotate(event)">回転</button>
</div>
<div id="game"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
<script>
// Create a Pixi Application
const app = new PIXI.Application({
width: 512,
height: 512,
antialiasing: true,
transparent: false,
resolution: 1
});
let anim1; // キャラアイコンインスタンス
// #game要素にpixiApp.view追加
document.querySelector("#game").appendChild(app.view);
//load an image and run the `setup` function when it's done
PIXI.Loader.shared
// リソースを登録
// 第一引数は任意のキー、第二引数は実体パス
.add("chara-1", "https://i.imgur.com/JNGbC6F.png")
.add("chara-2", "https://i.imgur.com/H9smyaD.png")
.add("chara-3", "https://i.imgur.com/xT6FStW.png")
.add("explorer", "https://i.imgur.com/rWus6RK.png")
.add("cat", "https://i.imgur.com/Fk2JkI5.png")
.add("dungeon", "https://i.imgur.com/EzpxVBZ.png")
.load(setup);
//This `setup` function will run when the image has loaded
function setup(loader, res) {
//
// ゲームシーンを作成
//
const gameScene = new PIXI.Container();
app.stage.addChild(gameScene);
// ダンジョン作成(ここで画面の大枠サイズを確定)
const dungeon = new PIXI.Sprite(PIXI.utils.TextureCache["dungeon"]);
gameScene.addChild(dungeon);
// アニメーションを作成してシーンに追加
anim1 = createAnim(["chara-1", "chara-2", "chara-3", ]);
anim1.x = 30;
anim1.y = (gameScene.height / 2) - (anim1.height / 2);
anim1.vx = 0;
anim1.vy = 0;
anim1.play();
gameScene.addChild(anim1);
}
/**
* アニメーションスプライトオブジェクトを作成
* @param {Array<String>} imgs - imageパスの配列
* @param {Object} opts - [OPTIONAL] オプション @see PIXI.AnimatedSprite
* @return {AnimatedSprite}
*/
function createAnim(imgs, opts) {
const textureArray = [];
for (let i = 0; i < imgs.length; i++) {
let texture = PIXI.Texture.from(imgs[i]);
textureArray.push(texture);
};
const animatedSprite = new PIXI.AnimatedSprite(textureArray);
animatedSprite.animationSpeed = (opts && opts.animationSpeed) ? opts.animationSpeed : 0.1;
return animatedSprite;
}
/**
* キャラのフェードアウト
*/
function effectFadeOut(e) {
const item = anim1;
_effect(item.alpha - 0.1, () => {
console.log("effectFadeOut end.")
});
function _effect(alpha, cb) {
item.alpha = alpha;
if (alpha <= 0) return cb && cb(null);
setTimeout(() => {
_effect(alpha - 0.1, cb);
}, 100);
}
}
/**
* キャラのフェードイン
*/
function effectFadeIn(e) {
const item = anim1;
_effect(item.alpha + 0.1, () => {
console.log("effectFadeIn end.")
});
function _effect(alpha, cb) {
item.alpha = alpha;
if (alpha >= 1) return cb && cb(null);
setTimeout(() => {
_effect(alpha + 0.1, cb);
}, 100);
}
}
/**
* キャラの回転
*/
function effectRotate(e) {
const item = anim1;
let rotation = 0; // 現在の回転度数
const maxCount = 3; // 上限回転数
const maxTick = 57 * maxCount; // 57 = 1 radians.
const rotationPerTick = 10; // 1tickのrotation
const defaultX = item.x;
const defaultY = item.y;
// アイコンの中心位置を取得しセット
const offsetX = item.width / 2;
const offsetY = item.height / 2;
item.x += offsetX;
item.y += offsetY;
item.anchor.set(0.5, 0.5);
// item.pivot.set(item.width/2, item.height/2);
_effect(() => {
console.log("effectRotate end");
// アイコンの中心位置を戻す
item.x -= offsetX;
item.y -= offsetY;
item.anchor.set(0, 0);
item.rotation = 0;
});
function _effect(cb) {
item.rotation += rotationPerTick;
rotation += rotationPerTick;
if (rotation >= maxTick) return cb && cb(null);
setTimeout(() => {
_effect(cb);
}, 100);
}
}
/**
* キャラのバイブ
*/
function effectVibe(e) {
const item = anim1;
let count = 0; // 現在の回数
const maxCount = 10; // 上限回転数
const maxRotation = 57 * maxCount; // 57 = 1 radians.
const rotationPerTick = 0.3; // 1tickのrotation
const defaultX = item.x;
const defaultY = item.y;
const offsetX = item.width / 2;
const offsetY = item.height / 2;
item.x += offsetX;
item.y += offsetY;
item.anchor.set(0.5, 0.5);
// item.pivot.set(item.width/2, item.height/2);
_effect(true, () => {
console.log("effectVibe end");
// 位置を戻す
item.x -= offsetX;
item.y -= offsetY;
item.anchor.set(0, 0);
item.rotation = 0;
});
function _effect(leanRight, cb) {
item.rotation = (leanRight) ? rotationPerTick : -rotationPerTick;
count += 1;
if (count > maxCount) return cb && cb(null);
setTimeout(() => {
_effect(!leanRight, cb);
}, 100);
}
}
/**
* キャラの点滅
*/
function effectFlash(e) {
const item = anim1;
let count = 0;
const flashCount = 3; // 点滅回数
const maxCount = flashCount * 2;
_effect(false, () => {
console.log("effectFlash end");
item.alpha = 1;
});
function _effect(appear, cb) {
item.alpha = (appear) ? 1 : 0;
count += 1;
if (count > maxCount) return cb && cb(null);
setTimeout(() => {
_effect(!appear, cb);
}, 100);
}
}
</script>
</body>
</html>
実行
ひとこと
キャラアイコンのエフェクトが実現できました。 次回はクリック(&タップ)イベントのハンドリングを実現してみたいと思います。
宣伝: PixiJSを使ったブラウザゲーム開発なら田中ソフトウェアラボにご相談ください!