Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add music, and sound #5

Merged
merged 1 commit into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ coverage
*.un~
*.*~

game
game.zip

.DS_Store

.eslintcache
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ $ npm start # localhost:3000 で実行します。ブラウザで http://local
|[shinonomekazan/akashic-assets](https://github.com/shinonomekazan/akashic-assets)| 2022-11-30 | CC BY 2.1 JP| キャラクター画像 |
|[泥棒バスター](https://github.com/akashic-contents/thiefBuster) | 2022-11-30 | CC BY 2.1 JP | スコア画像・SE |
|[Ricty Diminished](https://rictyfonts.github.io/diminished) | 4.1.1 | SIL Open Font License (OFL) Version 1.1 | ラベル用フォント |
|[爆破音 爆発音](https://commons.nicovideo.jp/material/nc107871) | 2022-12-20 | リンク先「利用条件の詳細」参照 | Sound |
|[夏はsummer!!](https://commons.nicovideo.jp/material/nc133861) | 2022-12-20 | リンク先「利用条件の詳細」参照 | BGM |
|[【日常系BGM】shuffle shuffle](https://commons.nicovideo.jp/material/nc150061) | 2022-12-20 | リンク先「利用条件の詳細」参照 | BGM |

## 利用ツール
以下のツールを利用し素材を作成・加工しています。ありがとうございます。
Expand Down
Binary file added audio/nc107871.aac
Binary file not shown.
Binary file added audio/nc107871.ogg
Binary file not shown.
Binary file added audio/nc133861.aac
Binary file not shown.
Binary file added audio/nc133861.ogg
Binary file not shown.
Binary file added audio/nc150061.aac
Binary file not shown.
Binary file added audio/nc150061.ogg
Binary file not shown.
3 changes: 3 additions & 0 deletions docs/material.csv
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ image,skip.png,CC BY 2.1 JP,"DWANGO Co., Ltd.",ペイントツールで手書き
image,star.png,CC BY 2.1 JP,"DWANGO Co., Ltd.",ペイントツールで手書き
image,tile1.png,CC BY 2.1 JP,"DWANGO Co., Ltd.",[Akashic Engine サンプルデモの素材](https://akashic-games.github.io/asset/material.html) + 改変
image,ui_common.png,CC BY 2.1 JP,"DWANGO Co., Ltd.",[泥棒バスター](https://github.com/akashic-contents/thiefBuster)
audio,nc107871.*,ニコニ・コモンズの作品利用条件参照,"ほしこ",[爆破音 爆発音](https://commons.nicovideo.jp/material/nc107871)
audio,nc133861.*,ニコニ・コモンズの作品利用条件参照,"Keyta",[夏はsummer!!](https://commons.nicovideo.jp/material/nc133861)
audio,nc150061.*,ニコニ・コモンズの作品利用条件参照,"KK",[【日常系BGM】shuffle shuffle](https://commons.nicovideo.jp/material/nc150061)
audio,se_damage.aac,CC BY 2.1 JP,"DWANGO Co., Ltd.",[泥棒バスター](https://github.com/akashic-contents/thiefBuster)
audio,se_damage.ogg,CC BY 2.1 JP,"DWANGO Co., Ltd.",[泥棒バスター](https://github.com/akashic-contents/thiefBuster)
audio,se_item.aac,CC BY 2.1 JP,"DWANGO Co., Ltd.",[泥棒バスター](https://github.com/akashic-contents/thiefBuster)
Expand Down
23 changes: 23 additions & 0 deletions game.json
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,29 @@
"path": "image/bg_result.png",
"width": 640,
"height": 480
},
"nc133861": {
"type": "audio",
"path": "audio/nc133861",
"systemId": "music",
"duration": 198084
},
"nc150061": {
"type": "audio",
"path": "audio/nc150061",
"systemId": "music",
"duration": 129960
},
"MusicPlayer": {
"type": "script",
"path": "script/util/MusicPlayer.js",
"global": true
},
"nc107871": {
"type": "audio",
"path": "audio/nc107871",
"systemId": "sound",
"duration": 2303
}
},
"moduleMainScripts": {
Expand Down
8 changes: 8 additions & 0 deletions src/entities/events/EventEntity.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { FieldEntity } from "../FieldEntity";
import { MusicPlayer } from "../../util/MusicPlayer";

export interface EventEntityParameterObject extends g.EParameterObject {
field: FieldEntity;
musicPlayer: MusicPlayer;
onFinished: (entity: EventEntity) => void;
}

Expand All @@ -10,11 +12,13 @@ export type EventStatus = "started" | "stopped";
export class EventEntity extends g.E {
private _status: EventStatus = "started";
private _field: FieldEntity;
private _musicPlayer: MusicPlayer;
private _onFinished: (entity: EventEntity) => void;

constructor(param: EventEntityParameterObject) {
super(param);
this._field = param.field;
this._musicPlayer = param.musicPlayer;
this._onFinished = param.onFinished;
}

Expand All @@ -26,6 +30,10 @@ export class EventEntity extends g.E {
return this._field;
}

get musicPlayer(): MusicPlayer {
return this._musicPlayer;
}

start(): void {
this._status = "started";
}
Expand Down
3 changes: 3 additions & 0 deletions src/entities/events/FollowerFallingEventEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ export class FollowerFallingEventEntity extends EventEntity {
.con()
.every(() => (this._fallingStarEffect.angle += 45), 1000)
.call(() => {
// 爆発:
this.musicPlayer.play("nc107871");

this._bombEffect = new g.FrameSprite({
scene: this.scene,
src: this.scene.asset.getImageById("effect_fancy"),
Expand Down
10 changes: 10 additions & 0 deletions src/entities/events/OpeningEventEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ export class OpeningEventEntity extends EventEntity {
// のんびりしてる2名:
this._timeline
.create(this._fullFilled)
.call(() => {
this.musicPlayer.play("nc150061");
})
.fadeOut(2000, Easing.easeInOutCubic)
.con()
.wait(1000)
Expand Down Expand Up @@ -364,6 +367,10 @@ export class OpeningEventEntity extends EventEntity {
.create(this._liliea)
.wait(200)
.call(() => {
// 爆発:
this.musicPlayer.play("nc107871");
this.musicPlayer.changeVolume("nc150061", 0.1);

rotationLoop = this._timeline.create(this._liliea, { loop: true }).every((e: number, i: number) => {
this._liliea.angle += 30;
this._liliea.x += 12;
Expand Down Expand Up @@ -496,6 +503,9 @@ export class OpeningEventEntity extends EventEntity {
this.scene.setTimeout(() => {
this.onFinished();

this.musicPlayer.stop("nc150061");
this.musicPlayer.play("nc133861").changeVolume(0.5);

// フィールドのキャラクターを表示:
this.showFieldCharacter();

Expand Down
3 changes: 3 additions & 0 deletions src/entities/events/SimplifyFollowerFallingEventEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ export class SimplifyFollowerFallingEventEntity extends EventEntity {
.con()
.every(() => (this._fallingStarEffect.angle += 45), 1000)
.call(() => {
// 爆発:
this.musicPlayer.play("nc107871");

this._bombEffect = new g.FrameSprite({
scene: this.scene,
src: this.scene.asset.getImageById("effect_fancy"),
Expand Down
21 changes: 14 additions & 7 deletions src/global/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,28 @@ import { MajyoEventEntity } from "../entities/events/MajyoEventEntity";
import { OpeningEventEntity } from "../entities/events/OpeningEventEntity";
import { SimplifyFollowerFallingEventEntity } from "../entities/events/SimplifyFollowerFallingEventEntity";
import { FieldEntity } from "../entities/FieldEntity";
import { MusicPlayer } from "../util/MusicPlayer";

export function createEventEntity(scene: g.Scene, id: string, field: FieldEntity, onFinished: (e: EventEntity) => void): EventEntity {
export function createEventEntity(
scene: g.Scene,
id: string,
field: FieldEntity,
musicPlayer: MusicPlayer,
onFinished: (e: EventEntity) => void
): EventEntity {
switch (id) {
case "opening":
return new OpeningEventEntity({ scene, field, onFinished });
return new OpeningEventEntity({ scene, field, musicPlayer, onFinished });
case "fallingFollower":
return new FollowerFallingEventEntity({ scene, field, onFinished });
return new FollowerFallingEventEntity({ scene, field, musicPlayer, onFinished });
case "simplifyFallingFollower":
return new SimplifyFollowerFallingEventEntity({ scene, field, onFinished });
return new SimplifyFollowerFallingEventEntity({ scene, field, musicPlayer, onFinished });
case "majyo":
return new MajyoEventEntity({ scene, field, onFinished });
return new MajyoEventEntity({ scene, field, musicPlayer, onFinished });
case "dead":
return new DeadEventEntity({ scene, field, onFinished });
return new DeadEventEntity({ scene, field, musicPlayer, onFinished });
case "debug":
return new DebugEventEntity({ scene, field, onFinished });
return new DebugEventEntity({ scene, field, musicPlayer, onFinished });
default:
throw new Error(`${id} is not found.`);
}
Expand Down
19 changes: 17 additions & 2 deletions src/scene/GameFieldScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { characterDataTable, itemDataTable, stageDataTable } from "../global/dat
import { createEventEntity } from "../global/event";
import { createUiSprite } from "../global/sprite";
import { Score } from "../types/Score";
import { MusicPlayer } from "../util/MusicPlayer";
import { SpawnTiming, Stage } from "../types/Stage";

// !! For Debug:
Expand All @@ -26,6 +27,7 @@ export interface GameFieldSceneParameterObject extends g.SceneParameterObject {
}

type SceneStatus = "stopped" | "started";
type KeyToAudioPlayer = { [key: string]: g.AudioPlayer };

// ゲームシーン
export class GameFieldScene extends g.Scene {
Expand All @@ -41,6 +43,7 @@ export class GameFieldScene extends g.Scene {
private _destinationOffset: g.CommonOffset | undefined;
private _statusWindow: StatusWindowEntity;
private _timeEntity: TimeEntity;
private _musicPlayer: MusicPlayer;
private _onFinish: ((score: Score) => void) | undefined;

constructor(param: GameFieldSceneParameterObject) {
Expand Down Expand Up @@ -100,6 +103,12 @@ export class GameFieldScene extends g.Scene {
this._status = "stopped";
}

setupAudio(): void {
this._musicPlayer = new MusicPlayer(this);
g.game.audio.sound.volume = 0.5;
g.game.audio.music.volume = 0.5;
}

private _initialize(param: GameFieldSceneParameterObject): void {
const playerEntity = this.createPlayerEntity(param);

Expand Down Expand Up @@ -175,7 +184,7 @@ export class GameFieldScene extends g.Scene {
this.start();
}
};
const e = createEventEntity(this, id, this._fieldEntity, onFinished);
const e = createEventEntity(this, id, this._fieldEntity, this._musicPlayer, onFinished);
this._eventEntities.push(e);
if (e.shouldGameStopped()) {
// ゲーム進行停止:
Expand Down Expand Up @@ -218,6 +227,7 @@ export class GameFieldScene extends g.Scene {
}
});

// ユーザ操作ハンドラ登録:
this.onPointDownCapture.add(ev => {
console.log(ev);
if (this._status === "started") {
Expand All @@ -234,6 +244,9 @@ export class GameFieldScene extends g.Scene {
this._destinationOffset = undefined;
});
this.onUpdate.add(this._updateHandler, this);

// 音声初期化:
this.setupAudio();
}

private _updateHandler(): void {
Expand All @@ -242,7 +255,7 @@ export class GameFieldScene extends g.Scene {
}

if (this._fieldEntity.isPlayerDied()) {
const e = createEventEntity(this, "dead", this._fieldEntity, () => this.start());
const e = createEventEntity(this, "dead", this._fieldEntity, this._musicPlayer, () => this.start());
this.stop();
// ペナルティ: 戦闘不能演出中もタイマーは止めない
this._timeEntity.start();
Expand All @@ -251,6 +264,8 @@ export class GameFieldScene extends g.Scene {
}

if (this._timeEntity.isTimeout()) {
// 全ての音声再生を止めて次シーン遷移:
this._musicPlayer.stopAll();
this._showResult(createUiSprite(this, "timeUp"));
}

Expand Down
14 changes: 13 additions & 1 deletion src/scene/GameResultScene.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ScoreBoardEntity } from "../entities/ScoreBoardEntity";
import { recreateGameFieldScene } from "../main";
import { Score } from "../types/Score";
import { MusicPlayer } from "../util/MusicPlayer";

export interface GameResultSceneParameterObject extends g.SceneParameterObject {
score: Score;
Expand All @@ -10,15 +11,19 @@ export interface GameResultSceneParameterObject extends g.SceneParameterObject {
// ゲーム結果を表示するシーン
export class GameResultScene extends g.Scene {
private _scoreBoardEntity: ScoreBoardEntity;
private _musicPlayer: MusicPlayer;

constructor(param: GameResultSceneParameterObject) {
super(param);
console.log("score:", param.score);
this.onLoad.add(() => {
this._initialize(param);
});
}

private _initialize(param: GameResultSceneParameterObject): void {
this.setupAudio();
this._musicPlayer.play("nc150061");

this._scoreBoardEntity = new ScoreBoardEntity({
scene: this,
score: param.score,
Expand All @@ -29,8 +34,15 @@ export class GameResultScene extends g.Scene {
g.game.replaceScene(scene);
}
}
this._musicPlayer.stopAll();
}
});
this.append(this._scoreBoardEntity);
}

setupAudio(): void {
this._musicPlayer = new MusicPlayer(this);
g.game.audio.sound.volume = 0.5;
g.game.audio.music.volume = 0.5;
}
}
36 changes: 36 additions & 0 deletions src/util/MusicPlayer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export type KeyToAudioAsset = { [key: string]: g.AudioAsset };
export type KeyToAudioPlayer = { [key: string]: g.AudioPlayer };

export class MusicPlayer {
private _keyToAudioAssets: KeyToAudioAsset = {};
private _keyToAudioPlayer: KeyToAudioPlayer = {};
private _scene: g.Scene;

constructor(scene: g.Scene) {
this._scene = scene;
}

play(assetId: string): g.AudioPlayer {
if (this._keyToAudioAssets[assetId] == null) {
this._keyToAudioAssets[assetId] = this._scene.asset.getAudioById(assetId);
}
this._keyToAudioPlayer[assetId] = this._keyToAudioAssets[assetId].play();
return this._keyToAudioPlayer[assetId];
}

stop(assetId: string): void {
if (this._keyToAudioPlayer[assetId] != null) {
this._keyToAudioPlayer[assetId].stop();
}
}

stopAll(): void {
Object.keys(this._keyToAudioAssets).forEach((id: string) => this.stop(id));
}

changeVolume(assetId: string, volume: number): void {
if (this._keyToAudioPlayer[assetId] != null) {
this._keyToAudioPlayer[assetId].changeVolume(volume);
}
}
}