From 6bae440f3912f882fea1e3901aad2d18f2b6a3b8 Mon Sep 17 00:00:00 2001
From: FineArchs <133759614+FineArchs@users.noreply.github.com>
Date: Wed, 10 Jan 2024 09:47:47 +0900
Subject: [PATCH 01/10] bump aiscript version to 0.17.0 (#12955)
* bump aiscript version to 0.17.0
* Update CHANGELOG.md
---
CHANGELOG.md | 2 ++
packages/frontend/package.json | 2 +-
pnpm-lock.yaml | 8 ++++----
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6963d45f63..244fd724a9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,8 @@
- Enhance: ハッシュタグ入力時に、本文の末尾の行に何も書かれていない場合は新たにスペースを追加しないように
- Enhance: チャンネルノートのピン留めをノートのメニューからできるように
- Enhance: 管理者の場合はAPI tokenの発行画面で管理機能に関する権限を付与できるように
+- Enhance: AiScriptを0.17.0に更新 [CHANGELOG](https://github.com/aiscript-dev/aiscript/blob/bb89d132b633a622d3cb0eff0d0cc7e476c0cfdd/CHANGELOG.md)
+ - 配列の範囲外・非整数のインデックスへの代入が完全禁止になるので注意
- Fix: ネイティブモードの絵文字がモノクロにならないように
- Fix: v2023.12.0で追加された「モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能」が管理画面上で正しく表示されていない問題を修正
- Fix: AiScriptの`readline`関数が不正な値を返すことがある問題のv2023.12.0時点での修正がPlay以外に適用されていないのを修正
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index 895aa47419..8c3ce30668 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -24,7 +24,7 @@
"@rollup/plugin-json": "6.1.0",
"@rollup/plugin-replace": "5.0.5",
"@rollup/pluginutils": "5.1.0",
- "@syuilo/aiscript": "0.16.0",
+ "@syuilo/aiscript": "0.17.0",
"@tabler/icons-webfont": "2.44.0",
"@twemoji/parser": "15.0.0",
"@vitejs/plugin-vue": "5.0.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9d98224822..400051bce7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -686,8 +686,8 @@ importers:
specifier: 5.1.0
version: 5.1.0(rollup@4.9.1)
'@syuilo/aiscript':
- specifier: 0.16.0
- version: 0.16.0
+ specifier: 0.17.0
+ version: 0.17.0
'@tabler/icons-webfont':
specifier: 2.44.0
version: 2.44.0
@@ -7649,8 +7649,8 @@ packages:
dev: false
optional: true
- /@syuilo/aiscript@0.16.0:
- resolution: {integrity: sha512-CXvoWOq6kmOSUQtKv0IEf7Ebfkk5PO1LxAgLqgRRPgssPvDvINCXu/gFNXKdapkFMkmX+Gj8qjemKR1vnUS4ZA==}
+ /@syuilo/aiscript@0.17.0:
+ resolution: {integrity: sha512-3JtQ1rWJHMxQ3153zLCXMUOwrOgjPPYGBl0dPHhR0ohm4tn7okMQRugxMCT0t3YxByemb9FfiM6TUjd0tEGxdA==}
dependencies:
seedrandom: 3.0.5
stringz: 2.1.0
From 138a248a6ce875af812c8ab126b78817d495b0f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=BE=E3=81=A3=E3=81=A1=E3=82=83=E3=81=A8=E3=83=BC?=
=?UTF-8?q?=E3=81=AB=E3=82=85?=
<17376330+u1-liquid@users.noreply.github.com>
Date: Wed, 10 Jan 2024 10:40:09 +0900
Subject: [PATCH 02/10] =?UTF-8?q?fix(drop-and-fusion):=20=E3=83=90?=
=?UTF-8?q?=E3=83=96=E3=83=AB=E3=82=B2=E3=83=BC=E3=83=A0=E3=81=AE=E3=83=AA?=
=?UTF-8?q?=E3=83=88=E3=83=A9=E3=82=A4=E3=83=9C=E3=82=BF=E3=83=B3=E3=81=A7?=
=?UTF-8?q?=E3=83=AA=E3=83=88=E3=83=A9=E3=82=A4=E3=81=8C=E3=81=A7=E3=81=8D?=
=?UTF-8?q?=E3=81=AA=E3=81=84=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?=
=?UTF-8?q?=20(#12957)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ゲーム中なら諦める、ゲームオーバー画面の表示中はリスタートになるように
---
packages/frontend/src/pages/drop-and-fusion.vue | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/packages/frontend/src/pages/drop-and-fusion.vue b/packages/frontend/src/pages/drop-and-fusion.vue
index 974daf35e4..d041a675f8 100644
--- a/packages/frontend/src/pages/drop-and-fusion.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.vue
@@ -153,7 +153,8 @@ SPDX-License-Identifier: AGPL-3.0-only
- Retry
+ Surrender
+ Retry
@@ -483,15 +484,22 @@ async function surrender() {
game.surrender();
}
+async function retry() {
+ end();
+ await start();
+}
+
function end() {
game.dispose();
isGameOver.value = false;
+ replaying.value = false;
currentPick.value = null;
dropReady.value = true;
stock.value = [];
score.value = 0;
combo.value = 0;
comboPrev.value = 0;
+ maxCombo.value = 0;
bgmNodes?.soundSource.stop();
gameStarted.value = false;
}
From 3d9e42efca8792bcfa1be7bd6125cf732db50fdb Mon Sep 17 00:00:00 2001
From: syuilo
Date: Wed, 10 Jan 2024 11:38:49 +0900
Subject: [PATCH 03/10] =?UTF-8?q?enhance(drop-and-fusion):=20=E3=83=AA?=
=?UTF-8?q?=E3=83=97=E3=83=AC=E3=82=A4=E3=81=AE=E5=80=8D=E9=80=9F=E5=86=8D?=
=?UTF-8?q?=E7=94=9F=E5=AF=BE=E5=BF=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../frontend/src/pages/drop-and-fusion.vue | 12 ++-
.../src/scripts/drop-and-fusion-engine.ts | 79 ++++++++++---------
2 files changed, 52 insertions(+), 39 deletions(-)
diff --git a/packages/frontend/src/pages/drop-and-fusion.vue b/packages/frontend/src/pages/drop-and-fusion.vue
index d041a675f8..f585519459 100644
--- a/packages/frontend/src/pages/drop-and-fusion.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.vue
@@ -103,7 +103,11 @@ SPDX-License-Identifier: AGPL-3.0-only
-
END REPLAY
+
+ END REPLAY
+ x2
+ x4
+
@@ -437,10 +441,15 @@ const gameStarted = ref(false);
const highScore = ref(null);
const showConfig = ref(false);
const replaying = ref(false);
+const replayPlaybackRate = ref(1);
const mute = ref(false);
const bgmVolume = ref(defaultStore.state.dropAndFusion.bgmVolume);
const sfxVolume = ref(defaultStore.state.dropAndFusion.sfxVolume);
+watch(replayPlaybackRate, (newValue) => {
+ game.replayPlaybackRate = newValue;
+});
+
function onClick(ev: MouseEvent) {
if (!containerElRect) return;
if (replaying.value) return;
@@ -493,6 +502,7 @@ function end() {
game.dispose();
isGameOver.value = false;
replaying.value = false;
+ replayPlaybackRate.value = 1;
currentPick.value = null;
dropReady.value = true;
stock.value = [];
diff --git a/packages/frontend/src/scripts/drop-and-fusion-engine.ts b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
index 16fe87d97a..a59eb271ec 100644
--- a/packages/frontend/src/scripts/drop-and-fusion-engine.ts
+++ b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
@@ -44,7 +44,7 @@ export class DropAndFusionGame extends EventEmitter<{
gameOver: () => void;
}> {
private PHYSICS_QUALITY_FACTOR = 16; // 低いほどパフォーマンスが高いがガタガタして安定しなくなる、逆に高すぎても何故か不安定になる
- private COMBO_INTERVAL = 1000;
+ private COMBO_INTERVAL = 60; // frame
public readonly DROP_INTERVAL = 500;
public readonly PLAYAREA_MARGIN = 25;
private STOCK_MAX = 4;
@@ -76,7 +76,7 @@ export class DropAndFusionGame extends EventEmitter<{
private latestDroppedBodyId: Matter.Body['id'] | null = null;
private latestDroppedAt = 0;
- private latestFusionedAt = 0;
+ private latestFusionedAt = 0; // frame
private stock: { id: string; mono: Mono }[] = [];
private holding: { id: string; mono: Mono } | null = null;
@@ -100,6 +100,8 @@ export class DropAndFusionGame extends EventEmitter<{
private comboIntervalId: number | null = null;
+ public replayPlaybackRate = 1;
+
constructor(opts: {
canvas: HTMLCanvasElement;
width: number;
@@ -219,13 +221,12 @@ export class DropAndFusionGame extends EventEmitter<{
}
private fusion(bodyA: Matter.Body, bodyB: Matter.Body) {
- const now = Date.now();
- if (this.latestFusionedAt > now - this.COMBO_INTERVAL) {
+ if (this.latestFusionedAt > this.frame - this.COMBO_INTERVAL) {
this.combo++;
} else {
this.combo = 1;
}
- this.latestFusionedAt = now;
+ this.latestFusionedAt = this.frame;
// TODO: 単に位置だけでなくそれぞれの動きベクトルも融合する?
const newX = (bodyA.position.x + bodyB.position.x) / 2;
@@ -390,44 +391,43 @@ export class DropAndFusionGame extends EventEmitter<{
}
});
- this.comboIntervalId = window.setInterval(() => {
- if (this.latestFusionedAt < Date.now() - this.COMBO_INTERVAL) {
- this.combo = 0;
- }
- }, 500);
-
if (logs) {
const playTick = () => {
- this.frame++;
- const log = logs.find(x => x.frame === this.frame - 1);
- if (log) {
- switch (log.operation) {
- case 'drop': {
- this.drop(log.x);
- break;
- }
- case 'hold': {
- this.hold();
- break;
- }
- case 'surrender': {
- this.surrender();
- break;
- }
- default:
- break;
+ for (let i = 0; i < this.replayPlaybackRate; i++) {
+ this.frame++;
+ if (this.latestFusionedAt < this.frame - this.COMBO_INTERVAL) {
+ this.combo = 0;
}
- }
- this.tickCallbackQueue = this.tickCallbackQueue.filter(x => {
- if (x.frame === this.frame) {
- x.callback();
- return false;
- } else {
- return true;
+ const log = logs.find(x => x.frame === this.frame - 1);
+ if (log) {
+ switch (log.operation) {
+ case 'drop': {
+ this.drop(log.x);
+ break;
+ }
+ case 'hold': {
+ this.hold();
+ break;
+ }
+ case 'surrender': {
+ this.surrender();
+ break;
+ }
+ default:
+ break;
+ }
}
- });
+ this.tickCallbackQueue = this.tickCallbackQueue.filter(x => {
+ if (x.frame === this.frame) {
+ x.callback();
+ return false;
+ } else {
+ return true;
+ }
+ });
- Matter.Engine.update(this.engine, this.TICK_DELTA);
+ Matter.Engine.update(this.engine, this.TICK_DELTA);
+ }
if (!this.isGameOver) {
this.tickRaf = window.requestAnimationFrame(playTick);
@@ -446,6 +446,9 @@ export class DropAndFusionGame extends EventEmitter<{
private tick() {
this.frame++;
+ if (this.latestFusionedAt < this.frame - this.COMBO_INTERVAL) {
+ this.combo = 0;
+ }
this.tickCallbackQueue = this.tickCallbackQueue.filter(x => {
if (x.frame === this.frame) {
x.callback();
From 4bd9f664d7213e9d6d507ae1b8cb67e2b78e766a Mon Sep 17 00:00:00 2001
From: syuilo
Date: Wed, 10 Jan 2024 13:44:00 +0900
Subject: [PATCH 04/10] enhance(drop-and-fusion): some tweaks
---
.../frontend/src/pages/drop-and-fusion.vue | 1 +
.../src/scripts/drop-and-fusion-engine.ts | 29 +++++++++++++------
packages/frontend/src/scripts/sound.ts | 2 --
3 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/packages/frontend/src/pages/drop-and-fusion.vue b/packages/frontend/src/pages/drop-and-fusion.vue
index f585519459..c5ab7a33f5 100644
--- a/packages/frontend/src/pages/drop-and-fusion.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.vue
@@ -1028,6 +1028,7 @@ definePageMetadata({
bottom: 10px;
padding: 6px 8px;
color: #f00;
+ font-weight: bold;
background: #0008;
border-radius: 6px;
pointer-events: none;
diff --git a/packages/frontend/src/scripts/drop-and-fusion-engine.ts b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
index a59eb271ec..342e818905 100644
--- a/packages/frontend/src/scripts/drop-and-fusion-engine.ts
+++ b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
@@ -157,6 +157,7 @@ export class DropAndFusionGame extends EventEmitter<{
//#region walls
const WALL_OPTIONS: Matter.IChamferableBodyDefinition = {
+ label: '_wall_',
isStatic: true,
friction: 0.7,
slop: 1.0,
@@ -254,12 +255,14 @@ export class DropAndFusionGame extends EventEmitter<{
const additionalScore = Math.round(currentMono.score * comboBonus);
this.score += additionalScore;
- // TODO: 効果音再生はコンポーネント側の責務なので移動する
- const pan = ((newX / this.gameWidth) - 0.5) * 2;
+ // TODO: 効果音再生はコンポーネント側の責務なので移動するべき?
+ const panV = newX - this.PLAYAREA_MARGIN;
+ const panW = this.gameWidth - this.PLAYAREA_MARGIN - this.PLAYAREA_MARGIN;
+ const pan = ((panV / panW) - 0.5) * 2;
sound.playUrl('/client-assets/drop-and-fusion/bubble2.mp3', {
volume: this.sfxVolume,
pan,
- playbackRate: nextMono.sfxPitch,
+ playbackRate: nextMono.sfxPitch * this.replayPlaybackRate,
});
this.emit('monoAdded', nextMono);
@@ -293,7 +296,7 @@ export class DropAndFusionGame extends EventEmitter<{
this.tickRaf = null;
this.emit('gameOver');
- // TODO: 効果音再生はコンポーネント側の責務なので移動する
+ // TODO: 効果音再生はコンポーネント側の責務なので移動するべき?
sound.playUrl('/client-assets/drop-and-fusion/gameover.mp3', {
volume: this.sfxVolume,
});
@@ -377,14 +380,19 @@ export class DropAndFusionGame extends EventEmitter<{
} else {
const energy = pairs.collision.depth;
if (energy > minCollisionEnergyForSound) {
- // TODO: 効果音再生はコンポーネント側の責務なので移動する
+ // TODO: 効果音再生はコンポーネント側の責務なので移動するべき?
const vol = ((Math.min(maxCollisionEnergyForSound, energy - minCollisionEnergyForSound) / maxCollisionEnergyForSound) / 4) * this.sfxVolume;
- const pan = ((((bodyA.position.x + bodyB.position.x) / 2) / this.gameWidth) - 0.5) * 2;
+ const panV =
+ pairs.bodyA.label === '_wall_' ? bodyB.position.x - this.PLAYAREA_MARGIN :
+ pairs.bodyB.label === '_wall_' ? bodyA.position.x - this.PLAYAREA_MARGIN :
+ ((bodyA.position.x + bodyB.position.x) / 2) - this.PLAYAREA_MARGIN;
+ const panW = this.gameWidth - this.PLAYAREA_MARGIN - this.PLAYAREA_MARGIN;
+ const pan = ((panV / panW) - 0.5) * 2;
const pitch = soundPitchMin + ((soundPitchMax - soundPitchMin) * (1 - (Math.min(10, energy) / 10)));
sound.playUrl('/client-assets/drop-and-fusion/poi1.mp3', {
volume: vol,
pan,
- playbackRate: pitch,
+ playbackRate: pitch * this.replayPlaybackRate,
});
}
}
@@ -518,11 +526,14 @@ export class DropAndFusionGame extends EventEmitter<{
this.emit('dropped');
this.emit('monoAdded', head.mono);
- // TODO: 効果音再生はコンポーネント側の責務なので移動する
- const pan = ((x / this.gameWidth) - 0.5) * 2;
+ // TODO: 効果音再生はコンポーネント側の責務なので移動するべき?
+ const panV = x - this.PLAYAREA_MARGIN;
+ const panW = this.gameWidth - this.PLAYAREA_MARGIN - this.PLAYAREA_MARGIN;
+ const pan = ((panV / panW) - 0.5) * 2;
sound.playUrl('/client-assets/drop-and-fusion/poi2.mp3', {
volume: this.sfxVolume,
pan,
+ playbackRate: this.replayPlaybackRate,
});
}
diff --git a/packages/frontend/src/scripts/sound.ts b/packages/frontend/src/scripts/sound.ts
index 142ddf87c9..05c8977ecf 100644
--- a/packages/frontend/src/scripts/sound.ts
+++ b/packages/frontend/src/scripts/sound.ts
@@ -99,7 +99,6 @@ export async function loadAudio(url: string, options?: { useCache?: boolean; })
}
if (options?.useCache ?? true) {
if (cache.has(url)) {
- if (_DEV_) console.log('use cache');
return cache.get(url) as AudioBuffer;
}
}
@@ -128,7 +127,6 @@ export async function loadAudio(url: string, options?: { useCache?: boolean; })
*/
export function playMisskeySfx(operationType: OperationType) {
const sound = defaultStore.state[`sound_${operationType}`];
- if (_DEV_) console.log('play', operationType, sound);
if (sound.type == null || !canPlay) return;
canPlay = false;
From c1c363bf08a391400e4b8b1df91962c26f2f3192 Mon Sep 17 00:00:00 2001
From: 1Step621 <86859447+1STEP621@users.noreply.github.com>
Date: Wed, 10 Jan 2024 15:06:04 +0900
Subject: [PATCH 05/10] =?UTF-8?q?Enhance(frontend):=20=E7=B5=B5=E6=96=87?=
=?UTF-8?q?=E5=AD=97=E3=83=94=E3=83=83=E3=82=AB=E3=83=BC/=E3=82=AA?=
=?UTF-8?q?=E3=83=BC=E3=83=88=E3=82=B3=E3=83=B3=E3=83=97=E3=83=AA=E3=83=BC?=
=?UTF-8?q?=E3=83=88=E3=81=A7=E5=AE=8C=E5=85=A8=E4=B8=80=E8=87=B4=E3=81=AE?=
=?UTF-8?q?=E7=B5=B5=E6=96=87=E5=AD=97=E3=82=92=E5=84=AA=E5=85=88=E3=81=99?=
=?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=20(#12928)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 絵文字ピッカー/オートコンプリートで完全一致の絵文字を優先するように
* update CHANGELOG.md
* improve performance
---
CHANGELOG.md | 1 +
.../frontend/src/components/MkAutocomplete.vue | 17 +++++++++++++----
.../frontend/src/components/MkEmojiPicker.vue | 13 +++++++++++++
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 244fd724a9..13ad3a3508 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,7 @@
- Enhance: 管理者の場合はAPI tokenの発行画面で管理機能に関する権限を付与できるように
- Enhance: AiScriptを0.17.0に更新 [CHANGELOG](https://github.com/aiscript-dev/aiscript/blob/bb89d132b633a622d3cb0eff0d0cc7e476c0cfdd/CHANGELOG.md)
- 配列の範囲外・非整数のインデックスへの代入が完全禁止になるので注意
+- Enhance: 絵文字ピッカー・オートコンプリートで、完全一致した絵文字を優先的に表示するように
- Fix: ネイティブモードの絵文字がモノクロにならないように
- Fix: v2023.12.0で追加された「モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能」が管理画面上で正しく表示されていない問題を修正
- Fix: AiScriptの`readline`関数が不正な値を返すことがある問題のv2023.12.0時点での修正がPlay以外に適用されていないのを修正
diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue
index 49884c705f..15eda4499f 100644
--- a/packages/frontend/src/components/MkAutocomplete.vue
+++ b/packages/frontend/src/components/MkAutocomplete.vue
@@ -262,15 +262,24 @@ function emojiAutoComplete(query: string | null, emojiDb: EmojiDef[], max = 30):
}
const matched = new Map();
-
- // 前方一致(エイリアスなし)
+ // 完全一致(エイリアス込み)
emojiDb.some(x => {
- if (x.name.startsWith(query) && !x.aliasOf) {
- matched.set(x.name, { emoji: x, score: query.length + 1 });
+ if (x.name === query && !matched.has(x.aliasOf ?? x.name)) {
+ matched.set(x.aliasOf ?? x.name, { emoji: x, score: query.length + 2 });
}
return matched.size === max;
});
+ // 前方一致(エイリアスなし)
+ if (matched.size < max) {
+ emojiDb.some(x => {
+ if (x.name.startsWith(query) && !x.aliasOf) {
+ matched.set(x.name, { emoji: x, score: query.length + 1 });
+ }
+ return matched.size === max;
+ });
+ }
+
// 前方一致(エイリアス込み)
if (matched.size < max) {
emojiDb.some(x => {
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue
index f36d46506f..84424c58ed 100644
--- a/packages/frontend/src/components/MkEmojiPicker.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.vue
@@ -221,6 +221,19 @@ watch(q, () => {
}
}
} else {
+ if (customEmojisMap.has(newQ)) {
+ matches.add(customEmojisMap.get(newQ)!);
+ }
+ if (matches.size >= max) return matches;
+
+ for (const emoji of emojis) {
+ if (emoji.aliases.some(alias => alias === newQ)) {
+ matches.add(emoji);
+ if (matches.size >= max) break;
+ }
+ }
+ if (matches.size >= max) return matches;
+
for (const emoji of emojis) {
if (emoji.name.startsWith(newQ)) {
matches.add(emoji);
From 5c786cace839147a11fadac6ee46da29db5f2457 Mon Sep 17 00:00:00 2001
From: syuilo
Date: Wed, 10 Jan 2024 17:31:59 +0900
Subject: [PATCH 06/10] enhance(drop-and-fusion): add game description
---
locales/index.d.ts | 8 ++++++++
locales/ja-JP.yml | 7 +++++++
packages/frontend/src/pages/drop-and-fusion.vue | 16 +++++++++++++---
3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/locales/index.d.ts b/locales/index.d.ts
index aa74ba54b0..852cbdd27d 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -1199,6 +1199,14 @@ export interface Locale {
"showReplay": string;
"replay": string;
"replaying": string;
+ "_bubbleGame": {
+ "howToPlay": string;
+ "_howToPlay": {
+ "section1": string;
+ "section2": string;
+ "section3": string;
+ };
+ };
"_announcement": {
"forExistingUsers": string;
"forExistingUsersDescription": string;
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 4863bbe770..f85dc0fcf8 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1197,6 +1197,13 @@ showReplay: "リプレイを見る"
replay: "リプレイ"
replaying: "リプレイ中"
+_bubbleGame:
+ howToPlay: "遊び方"
+ _howToPlay:
+ section1: "位置を調整してハコにモノを落とします。"
+ section2: "同じ種類のモノがくっつくと別のモノに変化して、スコアが得られます。"
+ section3: "モノがハコからあふれるとゲームオーバーです。ハコからあふれないようにしつつモノを融合させてハイスコアを目指そう!"
+
_announcement:
forExistingUsers: "既存ユーザーのみ"
forExistingUsersDescription: "有効にすると、このお知らせ作成時点で存在するユーザーにのみお知らせが表示されます。無効にすると、このお知らせ作成後にアカウントを作成したユーザーにもお知らせが表示されます。"
diff --git a/packages/frontend/src/pages/drop-and-fusion.vue b/packages/frontend/src/pages/drop-and-fusion.vue
index c5ab7a33f5..9fb7ab2e23 100644
--- a/packages/frontend/src/pages/drop-and-fusion.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.vue
@@ -8,13 +8,13 @@ SPDX-License-Identifier: AGPL-3.0-only
-
-
+
+
-
+
@@ -33,6 +33,16 @@ SPDX-License-Identifier: AGPL-3.0-only
+
+
+
{{ i18n.ts._bubbleGame.howToPlay }}
+
+ - {{ i18n.ts._bubbleGame._howToPlay.section1 }}
+ - {{ i18n.ts._bubbleGame._howToPlay.section2 }}
+ - {{ i18n.ts._bubbleGame._howToPlay.section3 }}
+
+
+
From 36fd7d17cf1c71fa59eae445d05498a7bf5ab173 Mon Sep 17 00:00:00 2001
From: syuilo
Date: Wed, 10 Jan 2024 19:54:59 +0900
Subject: [PATCH 07/10] enhance(drop-and-fusion): some tweaks
---
.../src/pages/drop-and-fusion.game.vue | 1052 +++++++++++++++++
.../frontend/src/pages/drop-and-fusion.vue | 982 +--------------
.../src/scripts/drop-and-fusion-engine.ts | 2 +-
3 files changed, 1088 insertions(+), 948 deletions(-)
create mode 100644 packages/frontend/src/pages/drop-and-fusion.game.vue
diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue
new file mode 100644
index 0000000000..acaebbadf7
--- /dev/null
+++ b/packages/frontend/src/pages/drop-and-fusion.game.vue
@@ -0,0 +1,1052 @@
+
+
+
+
+
+ Loading...
+
+
+
+
+
+
+
BUBBLE GAME
+
- {{ gameMode }} -
+
+
+
+
+
HOLD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ comboPrev }} Chain!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SCORE:
+
MAX CHAIN:
+
+
+
{{ i18n.ts.replaying }}
+
+
+
+
+
+ END REPLAY
+ x2
+ x4
+
+
+
+
+
+
+
+ {{ i18n.ts.done }}
+ {{ i18n.ts.showReplay }}
+ {{ i18n.ts.share }}
+ Copy replay data
+
+
+
+
+
+
+
SCORE: (MAX CHAIN: )
+
HIGH SCORE: -
+
+
+
+
+
+
+
+ updateSettings('bgmVolume', v)">
+ BGM {{ i18n.ts.volume }}
+
+ updateSettings('sfxVolume', v)">
+ {{ i18n.ts.sfx }} {{ i18n.ts.volume }}
+
+
+
+
+
+
+ Surrender
+ Retry
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/pages/drop-and-fusion.vue b/packages/frontend/src/pages/drop-and-fusion.vue
index 9fb7ab2e23..7bd0eef000 100644
--- a/packages/frontend/src/pages/drop-and-fusion.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.vue
@@ -4,10 +4,16 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
-
-
-
-
+
+
+
@@ -34,8 +40,8 @@ SPDX-License-Identifier: AGPL-3.0-only
-
-
{{ i18n.ts._bubbleGame.howToPlay }}
+
+
{{ i18n.ts._bubbleGame.howToPlay }}
- {{ i18n.ts._bubbleGame._howToPlay.section1 }}
- {{ i18n.ts._bubbleGame._howToPlay.section2 }}
@@ -43,765 +49,47 @@ SPDX-License-Identifier: AGPL-3.0-only
-
-
-
-
-
+
-
BUBBLE GAME
-
- {{ gameMode }} -
-
-
-
-
-
HOLD
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ comboPrev }} Chain!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
SCORE:
-
MAX CHAIN:
-
-
-
{{ i18n.ts.replaying }}
-
-
-
-
-
-
- {{ i18n.ts.done }}
- {{ i18n.ts.showReplay }}
- {{ i18n.ts.share }}
- Copy replay data
-
-
-
-
-
-
-
SCORE: (MAX CHAIN: )
-
HIGH SCORE: -
-
-
-
-
-
-
-
- updateSettings('bgmVolume', v)">
- BGM {{ i18n.ts.volume }}
-
- updateSettings('sfxVolume', v)">
- {{ i18n.ts.sfx }} {{ i18n.ts.volume }}
-
-
-
-
-
-
Credit
-
-
Ai-chan illustration: @poteriri@misskey.io
-
BGM: @ys@misskey.design
-
-
-
-
-
-
- Surrender
- Retry
-
-
-
-
+
+
+
+
+
diff --git a/packages/frontend/src/scripts/drop-and-fusion-engine.ts b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
index 342e818905..d64c6015a5 100644
--- a/packages/frontend/src/scripts/drop-and-fusion-engine.ts
+++ b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
@@ -33,6 +33,7 @@ type Log = {
operation: 'surrender';
};
+// TODO: インスタンスを作り直さなくてもゲームをリスタートできるようにする
export class DropAndFusionGame extends EventEmitter<{
changeScore: (newScore: number) => void;
changeCombo: (newCombo: number) => void;
@@ -307,7 +308,6 @@ export class DropAndFusionGame extends EventEmitter<{
async function loadSingleMonoTexture(mono: Mono, game: DropAndFusionGame) {
// Matter-js内にキャッシュがある場合はスキップ
if (game.render.textures[mono.img]) return;
- console.log('loading', mono.img);
let src = mono.img;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
From 762fa6a8d85691e2d5d94a46b23d7641feefd402 Mon Sep 17 00:00:00 2001
From: syuilo
Date: Thu, 11 Jan 2024 12:34:03 +0900
Subject: [PATCH 08/10] enhance(drop-and-fusion): make game engine headless for
server-side running
---
.../src/pages/drop-and-fusion.game.vue | 458 ++++++++++++------
.../src/scripts/drop-and-fusion-engine.ts | 359 ++++----------
2 files changed, 397 insertions(+), 420 deletions(-)
diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue
index acaebbadf7..3fefb49fae 100644
--- a/packages/frontend/src/pages/drop-and-fusion.game.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.game.vue
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@@ -65,7 +65,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:moveClass="$style.transition_picked_move"
mode="out-in"
>
-
+
@@ -81,14 +81,17 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.replaying }}
-
-
-
-
- END REPLAY
- x2
- x4
-
+
@@ -140,6 +143,7 @@ SPDX-License-Identifier: AGPL-3.0-only