mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-04-24 14:06:16 -04:00
wip
This commit is contained in:
parent
11c797bc59
commit
64a85200b9
23 changed files with 1849 additions and 329 deletions
|
@ -1,5 +1,5 @@
|
|||
// The version of the cache.
|
||||
const VERSION = "29075517";
|
||||
const VERSION = "29077162";
|
||||
|
||||
// The name of the cache
|
||||
const CACHE_NAME = `breakout-71-${VERSION}`;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { GameState, Level, PerkId, Upgrade } from "./types";
|
||||
import { allLevels, icons, upgrades } from "./loadGameData";
|
||||
import { GameState, Level, PerkId, RawLevel, Upgrade } from "./types";
|
||||
import { allLevels, icons, transformRawLevel, upgrades } from "./loadGameData";
|
||||
import { t } from "./i18n/i18n";
|
||||
import { getSettingValue, getTotalScore, setSettingValue } from "./settings";
|
||||
import {
|
||||
|
@ -17,6 +17,7 @@ import {
|
|||
} from "./game_utils";
|
||||
import { getHistory } from "./gameOver";
|
||||
import { noCreative } from "./upgrades";
|
||||
import { levelIconHTML } from "./levelIcon";
|
||||
|
||||
export function creativeMode(gameState: GameState) {
|
||||
return {
|
||||
|
@ -39,7 +40,9 @@ export async function openCreativeModePerksPicker() {
|
|||
{},
|
||||
),
|
||||
choice: Upgrade | Level | "reset" | void;
|
||||
|
||||
const customLevels = (getSettingValue("custom_levels", []) as RawLevel[]).map(
|
||||
transformRawLevel,
|
||||
);
|
||||
while (
|
||||
(choice = await asyncAlert<Upgrade | Level | "reset">({
|
||||
title: t("lab.menu_entry"),
|
||||
|
@ -78,6 +81,13 @@ export async function openCreativeModePerksPicker() {
|
|||
tooltip: problem || describeLevel(l),
|
||||
};
|
||||
}),
|
||||
...customLevels.map((l) => ({
|
||||
icon: levelIconHTML(l.bricks, l.size, l.color),
|
||||
text: l.name,
|
||||
value: l,
|
||||
disabled: !l.bricks.filter((b) => b !== "_").length,
|
||||
tooltip: describeLevel(l),
|
||||
})),
|
||||
],
|
||||
}))
|
||||
) {
|
||||
|
@ -88,7 +98,7 @@ export async function openCreativeModePerksPicker() {
|
|||
} else if ("bricks" in choice) {
|
||||
setSettingValue("creativeModePerks", creativeModePerks);
|
||||
if (await confirmRestart(gameState)) {
|
||||
restart({ perks: creativeModePerks, level: choice.name });
|
||||
restart({ perks: creativeModePerks, level: choice });
|
||||
}
|
||||
return;
|
||||
} else if (choice) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1 +1 @@
|
|||
"29075517"
|
||||
"29077162"
|
||||
|
|
|
@ -70,6 +70,7 @@ canvas:not(#game) {
|
|||
color: gold;
|
||||
transition: color 0.01s;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
@ -477,6 +478,7 @@ h2.histogram-title strong {
|
|||
cursor: pointer;
|
||||
background: black;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 0 5px;
|
||||
|
@ -488,11 +490,13 @@ h2.histogram-title strong {
|
|||
td:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 20px;
|
||||
height: auto;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
tr:nth-child(2n) {
|
||||
background: rgba(0, 0, 0, 0.58);
|
||||
}
|
||||
|
@ -508,6 +512,7 @@ h2.histogram-title strong {
|
|||
height: 7px;
|
||||
bottom: 2px;
|
||||
border-radius: 2px;
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
inset: 1px;
|
||||
|
@ -544,3 +549,40 @@ h2.histogram-title strong {
|
|||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.gridEdit > div > span,
|
||||
.palette > span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 1px solid;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
border-color: gold;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
box-shadow: inset 2px 2px 4px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
.gridEdit {
|
||||
& > div {
|
||||
display: flex;
|
||||
|
||||
& > span {
|
||||
width: calc(min(500px, 100vw, 100vh - 200px) / var(--grid-size));
|
||||
height: calc(min(500px, 100vw, 100vh - 200px) / var(--grid-size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.palette {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
& > span {
|
||||
&[data-selected="true"] {
|
||||
border: 2px solid white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
17
src/game.ts
17
src/game.ts
|
@ -1,4 +1,10 @@
|
|||
import { allLevels, appVersion, icons, upgrades } from "./loadGameData";
|
||||
import {
|
||||
allLevels,
|
||||
allLevelsAndIcons,
|
||||
appVersion,
|
||||
icons,
|
||||
upgrades,
|
||||
} from "./loadGameData";
|
||||
import {
|
||||
Ball,
|
||||
Coin,
|
||||
|
@ -89,6 +95,7 @@ import { generateSaveFileContent } from "./generateSaveFileContent";
|
|||
import { runHistoryViewerMenuEntry } from "./runHistoryViewer";
|
||||
import { getNearestUnlockHTML, openScorePanel } from "./openScorePanel";
|
||||
import { monitorLevelsUnlocks } from "./monitorLevelsUnlocks";
|
||||
import { levelEditorMenuEntry } from "./levelEditor";
|
||||
|
||||
export async function play() {
|
||||
if (await applyFullScreenChoice()) return;
|
||||
|
@ -518,6 +525,7 @@ export async function openMainMenu() {
|
|||
},
|
||||
creativeMode(gameState),
|
||||
runHistoryViewerMenuEntry(),
|
||||
levelEditorMenuEntry(),
|
||||
{
|
||||
icon: icons["icon:unlocks"],
|
||||
text: t("main_menu.unlocks"),
|
||||
|
@ -849,7 +857,10 @@ async function openUnlocksList() {
|
|||
.map(({ name, id, threshold, icon, help }) => ({
|
||||
text: name,
|
||||
disabled: ts < threshold,
|
||||
value: { perks: { [id]: 1 }, level: "icon:" + id } as RunParams,
|
||||
value: {
|
||||
perks: { [id]: 1 },
|
||||
level: allLevelsAndIcons.find((l) => l.name === "icon:" + id),
|
||||
} as RunParams,
|
||||
icon,
|
||||
[hintField]:
|
||||
ts < threshold
|
||||
|
@ -871,7 +882,7 @@ async function openUnlocksList() {
|
|||
return {
|
||||
text: l.name + percentUnlocked,
|
||||
disabled: !!lockedBecause,
|
||||
value: { level: l.name } as RunParams,
|
||||
value: { level: l } as RunParams,
|
||||
icon: icons[l.name],
|
||||
[hintField]: lockedBecause?.text || describeLevel(l),
|
||||
};
|
||||
|
|
|
@ -9,11 +9,12 @@ import {
|
|||
pickedUpgradesHTMl,
|
||||
reasonLevelIsLocked,
|
||||
} from "./game_utils";
|
||||
import { getTotalScore } from "./settings";
|
||||
import { getSettingValue, getTotalScore } from "./settings";
|
||||
import { stopRecording } from "./recording";
|
||||
import { asyncAlert } from "./asyncAlert";
|
||||
import { rawUpgrades } from "./upgrades";
|
||||
import { run } from "jest";
|
||||
import { editRawLevelList } from "./levelEditor";
|
||||
|
||||
export function addToTotalPlayTime(ms: number) {
|
||||
try {
|
||||
|
@ -30,11 +31,18 @@ export function addToTotalPlayTime(ms: number) {
|
|||
export function gameOver(title: string, intro: string) {
|
||||
if (!gameState.running) return;
|
||||
if (gameState.isGameOver) return;
|
||||
|
||||
gameState.isGameOver = true;
|
||||
pause(true);
|
||||
stopRecording();
|
||||
addToTotalPlayTime(gameState.runStatistics.runTime);
|
||||
|
||||
if (typeof gameState.isEditorTrialRun === "number") {
|
||||
editRawLevelList(gameState.isEditorTrialRun);
|
||||
restart({});
|
||||
return;
|
||||
}
|
||||
|
||||
// unlocks
|
||||
const endTs = getTotalScore();
|
||||
const startTs = endTs - gameState.score;
|
||||
|
|
|
@ -3,6 +3,29 @@
|
|||
"confirmRestart.text": "أنت على وشك بدء لعبة جديدة. هل أنت متأكد من رغبتك في المتابعة؟",
|
||||
"confirmRestart.title": "بدء لعبة جديدة؟",
|
||||
"confirmRestart.yes": "إعادة تشغيل اللعبة",
|
||||
"editor.editing.bigger": "زيادة حجم المستوى",
|
||||
"editor.editing.color": "اختر لونًا من قائمة الألوان (بحد أقصى 5 لكل مستوى)",
|
||||
"editor.editing.copy": "نسخ رمز المستوى",
|
||||
"editor.editing.copy_help": "ألصقه في قناة #levels في Discord الخاص بنا",
|
||||
"editor.editing.credit": "الاعتمادات والمصدر",
|
||||
"editor.editing.credit_prompt": "أدخل عنوان URL المصدر أو شرحًا لمستواك.",
|
||||
"editor.editing.delete": "حذف المستوى",
|
||||
"editor.editing.down": "انزل كل الطوب إلى الأسفل",
|
||||
"editor.editing.help": "ثم انقر على البلاط لتلوينه.",
|
||||
"editor.editing.left": "نقل جميع الطوب إلى اليسار",
|
||||
"editor.editing.play": "العب هذا المستوى",
|
||||
"editor.editing.rename": "اسم المستوى",
|
||||
"editor.editing.rename_prompt": "الرجاء إدخال اسم جديد للمستوى",
|
||||
"editor.editing.right": "حرك كل الطوب إلى اليمين",
|
||||
"editor.editing.smaller": "تقليل حجم المستوى",
|
||||
"editor.editing.title": "مستوى التحرير: {{name}}",
|
||||
"editor.editing.up": "حرك كل الطوب لأعلى",
|
||||
"editor.help": "إنشاء مستويات مخصصة ومشاركتها لتضمينها في اللعبة.",
|
||||
"editor.import": "استيراد المستوى",
|
||||
"editor.import_instruction": "الصق رمز المستوى لاستيراده في قائمة المستويات الخاصة بك",
|
||||
"editor.locked": "احصل على مجموع نقاط قدره {{min}} لفتح القفل",
|
||||
"editor.new_level": "مستوى جديد",
|
||||
"editor.title": "محرر المستويات",
|
||||
"gameOver.creative": "لن يتم تسجيل هذا التشغيل.",
|
||||
"gameOver.cumulative_total": "لقد ارتفع مجموع درجاتك التراكمية من {{startTs}} إلى {{endTs}}.",
|
||||
"gameOver.lost.summary": "لقد أسقطت الكرة بعد التقاط {{score}} قطعة نقدية.",
|
||||
|
|
|
@ -164,6 +164,821 @@
|
|||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>editor</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>editing</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>bigger</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>color</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>copy</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>copy_help</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>credit</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>credit_prompt</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>delete</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>down</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>help</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>left</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>play</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>rename</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>rename_prompt</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>right</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>smaller</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>title</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>up</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<concept_node>
|
||||
<name>help</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>import</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>import_instruction</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>locked</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>new_level</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>title</name>
|
||||
<description/>
|
||||
<comment/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>ar-LB</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-CL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>gameOver</name>
|
||||
<children>
|
||||
|
|
|
@ -3,6 +3,29 @@
|
|||
"confirmRestart.text": "Sie sind dabei, ein neues Spiel zu beginnen. Sind Sie sicher, dass Sie weitermachen wollen?",
|
||||
"confirmRestart.title": "Ein neues Spiel beginnen?",
|
||||
"confirmRestart.yes": "Spiel neu starten",
|
||||
"editor.editing.bigger": "Levelgröße erhöhen",
|
||||
"editor.editing.color": "Wählen Sie eine Farbe aus der Farbliste (max. 5 pro Level)",
|
||||
"editor.editing.copy": "Levelcode kopieren",
|
||||
"editor.editing.copy_help": "Fügen Sie es in den Kanal #levels in unserem Discord ein",
|
||||
"editor.editing.credit": "Credits und Quelle",
|
||||
"editor.editing.credit_prompt": "Geben Sie die Quell-URL oder Erklärung Ihres Levels ein.",
|
||||
"editor.editing.delete": "Ebene löschen",
|
||||
"editor.editing.down": "Bewegen Sie alle Steine nach unten",
|
||||
"editor.editing.help": "Klicken Sie dann auf eine Kachel, um sie einzufärben.",
|
||||
"editor.editing.left": "Bewege alle Steine nach links",
|
||||
"editor.editing.play": "Spiele dieses Level",
|
||||
"editor.editing.rename": "Ebenenname",
|
||||
"editor.editing.rename_prompt": "Bitte geben Sie einen neuen Namen für das Level ein",
|
||||
"editor.editing.right": "Bewege alle Steine nach rechts",
|
||||
"editor.editing.smaller": "Verringern der Levelgröße",
|
||||
"editor.editing.title": "Bearbeitungsebene: {{name}}",
|
||||
"editor.editing.up": "Bewegen Sie alle Steine nach oben",
|
||||
"editor.help": "Erstellen Sie benutzerdefinierte Level und geben Sie sie frei, um sie in das Spiel aufzunehmen.",
|
||||
"editor.import": "Importieren einer Ebene",
|
||||
"editor.import_instruction": "Fügen Sie einen Levelcode ein, um ihn in Ihre Levelliste zu importieren",
|
||||
"editor.locked": "Erreichen Sie eine Gesamtpunktzahl von {{min}} , um freizuschalten",
|
||||
"editor.new_level": "Neues Level",
|
||||
"editor.title": "Level-Editor",
|
||||
"gameOver.creative": "Dieser Lauf wird nicht aufgezeichnet.",
|
||||
"gameOver.cumulative_total": "Ihre kumulative Gesamtpunktzahl ist von {{startTs}} auf {{endTs}}gestiegen.",
|
||||
"gameOver.lost.summary": "Du hast den Ball fallen lassen, nachdem du {{score}} Münzen gefangen hast.",
|
||||
|
|
|
@ -3,6 +3,29 @@
|
|||
"confirmRestart.text": "You're about to start a new game. Are you sure you want to continue?",
|
||||
"confirmRestart.title": "Start a new game?",
|
||||
"confirmRestart.yes": "Restart game",
|
||||
"editor.editing.bigger": "Increase level size",
|
||||
"editor.editing.color": "Pick a color in the color list (max 5 per level)",
|
||||
"editor.editing.copy": "Copy level code",
|
||||
"editor.editing.copy_help": "Paste it in the #levels channel in our discord",
|
||||
"editor.editing.credit": "Credits and source",
|
||||
"editor.editing.credit_prompt": "Enter the source url or explanation of your level.",
|
||||
"editor.editing.delete": "Delete level",
|
||||
"editor.editing.down": "Move down all the bricks",
|
||||
"editor.editing.help": "Then click a tile to color it.",
|
||||
"editor.editing.left": "Move all bricks to the left",
|
||||
"editor.editing.play": "Play this level",
|
||||
"editor.editing.rename": "Level name",
|
||||
"editor.editing.rename_prompt": "Please enter a new name for the level",
|
||||
"editor.editing.right": "Move all bricks to the right",
|
||||
"editor.editing.smaller": "Decrease level size",
|
||||
"editor.editing.title": "Editing level : {{name}}",
|
||||
"editor.editing.up": "Move up all the bricks",
|
||||
"editor.help": "Create custom levels and share them for inclusion in the game.",
|
||||
"editor.import": "Import a level",
|
||||
"editor.import_instruction": "Paste a level code to import it in your level list",
|
||||
"editor.locked": "Reach a total score of {{min}} to unlock",
|
||||
"editor.new_level": "New level",
|
||||
"editor.title": "Level Editor",
|
||||
"gameOver.creative": "This run will not be recorded. ",
|
||||
"gameOver.cumulative_total": "Your total cumulative score went from {{startTs}} to {{endTs}}.",
|
||||
"gameOver.lost.summary": "You dropped the ball after catching {{score}} coins.",
|
||||
|
|
|
@ -3,6 +3,29 @@
|
|||
"confirmRestart.text": "Estás a punto de empezar un nuevo partido: ¿es esto realmente lo que querías?",
|
||||
"confirmRestart.title": "¿Empezar una nueva partida?",
|
||||
"confirmRestart.yes": "Empezar una nueva partida",
|
||||
"editor.editing.bigger": "Aumentar el tamaño del nivel",
|
||||
"editor.editing.color": "Elige un color de la lista de colores (máximo 5 por nivel)",
|
||||
"editor.editing.copy": "Copiar código de nivel",
|
||||
"editor.editing.copy_help": "Pégalo en el canal #levels en nuestro discord",
|
||||
"editor.editing.credit": "Créditos y fuente",
|
||||
"editor.editing.credit_prompt": "Introduce la URL de origen o la explicación de tu nivel.",
|
||||
"editor.editing.delete": "Eliminar nivel",
|
||||
"editor.editing.down": "Baja todos los ladrillos",
|
||||
"editor.editing.help": "Luego haz clic en un mosaico para colorearlo.",
|
||||
"editor.editing.left": "Mueve todos los ladrillos hacia la izquierda",
|
||||
"editor.editing.play": "Juega este nivel",
|
||||
"editor.editing.rename": "Nombre del nivel",
|
||||
"editor.editing.rename_prompt": "Por favor, introduzca un nuevo nombre para el nivel",
|
||||
"editor.editing.right": "Mueve todos los ladrillos hacia la derecha",
|
||||
"editor.editing.smaller": "Disminuir el tamaño del nivel",
|
||||
"editor.editing.title": "Nivel de edición: {{name}}",
|
||||
"editor.editing.up": "Mueve todos los ladrillos hacia arriba",
|
||||
"editor.help": "Crea niveles personalizados y compártelos para incluirlos en el juego.",
|
||||
"editor.import": "Importar un nivel",
|
||||
"editor.import_instruction": "Pegue un código de nivel para importarlo en su lista de niveles",
|
||||
"editor.locked": "Alcanza una puntuación total de {{min}} para desbloquear",
|
||||
"editor.new_level": "Nuevo nivel",
|
||||
"editor.title": "Editor de niveles",
|
||||
"gameOver.creative": "Esta parte de la prueba no se grabará.",
|
||||
"gameOver.cumulative_total": "Su puntuación total acumulada ha pasado de {{startTs}} a {{endTs}}.",
|
||||
"gameOver.lost.summary": "Se te ha caído la bola después de coger {{score}} monedas.",
|
||||
|
|
|
@ -3,6 +3,29 @@
|
|||
"confirmRestart.text": "Vous êtes sur le point de commencer une nouvelle partie, est-ce vraiment ce que vous vouliez ?",
|
||||
"confirmRestart.title": "Démarrer une nouvelle partie ?",
|
||||
"confirmRestart.yes": "Commencer une nouvelle partie",
|
||||
"editor.editing.bigger": "Augmenter la taille du niveau",
|
||||
"editor.editing.color": "Choisissez une couleur dans la liste des couleurs (max 5 par niveau)",
|
||||
"editor.editing.copy": "Copier le code du niveau",
|
||||
"editor.editing.copy_help": "Collez-le dans le canal #levels de notre discord",
|
||||
"editor.editing.credit": "Crédits et source",
|
||||
"editor.editing.credit_prompt": "Entrez l'url source ou l'explication de votre niveau.",
|
||||
"editor.editing.delete": "Supprimer le niveau",
|
||||
"editor.editing.down": "Déplacez toutes les briques vers le bas",
|
||||
"editor.editing.help": "Cliquez ensuite sur une tuile pour la colorier.",
|
||||
"editor.editing.left": "Déplacer toutes les briques vers la gauche",
|
||||
"editor.editing.play": "Jouez à ce niveau",
|
||||
"editor.editing.rename": "Nom du niveau",
|
||||
"editor.editing.rename_prompt": "Veuillez saisir un nouveau nom pour le niveau",
|
||||
"editor.editing.right": "Déplacer toutes les briques vers la droite",
|
||||
"editor.editing.smaller": "Diminuer la taille du niveau",
|
||||
"editor.editing.title": "Niveau d'édition : {{name}}",
|
||||
"editor.editing.up": "Déplacez toutes les briques",
|
||||
"editor.help": "Créez des niveaux personnalisés et partagez-les pour les inclure dans le jeu.",
|
||||
"editor.import": "Importer un niveau",
|
||||
"editor.import_instruction": "Collez un code de niveau pour l'importer dans votre liste de niveaux",
|
||||
"editor.locked": "Atteignez un score total de {{min}} pour débloquer",
|
||||
"editor.new_level": "Nouveau niveau",
|
||||
"editor.title": "Éditeur de niveau",
|
||||
"gameOver.creative": "Cette partie de test ne sera pas enregistrée.",
|
||||
"gameOver.cumulative_total": "Votre score total cumulé est passé de {{startTs}} à {{endTs}}.",
|
||||
"gameOver.lost.summary": "Vous avez fait tomber la balle après avoir attrapé {{score}} pièces.",
|
||||
|
|
|
@ -3,6 +3,29 @@
|
|||
"confirmRestart.text": "Вы собираетесь начать новую игру. Вы уверены, что хотите продолжить?",
|
||||
"confirmRestart.title": "Начать новую игру?",
|
||||
"confirmRestart.yes": "Перезапустите игру",
|
||||
"editor.editing.bigger": "Увеличить размер уровня",
|
||||
"editor.editing.color": "Выберите цвет из списка цветов (максимум 5 на уровень)",
|
||||
"editor.editing.copy": "Скопировать код уровня",
|
||||
"editor.editing.copy_help": "Вставьте его в канал #levels в нашем Discord",
|
||||
"editor.editing.credit": "Кредиты и источник",
|
||||
"editor.editing.credit_prompt": "Введите исходный URL-адрес или пояснение вашего уровня.",
|
||||
"editor.editing.delete": "Удалить уровень",
|
||||
"editor.editing.down": "Сдвиньте все кирпичи вниз.",
|
||||
"editor.editing.help": "Затем щелкните по плитке, чтобы раскрасить ее.",
|
||||
"editor.editing.left": "Переместите все кирпичи влево.",
|
||||
"editor.editing.play": "Пройти этот уровень",
|
||||
"editor.editing.rename": "Название уровня",
|
||||
"editor.editing.rename_prompt": "Введите новое название уровня.",
|
||||
"editor.editing.right": "Переместите все кирпичи вправо.",
|
||||
"editor.editing.smaller": "Уменьшить размер уровня",
|
||||
"editor.editing.title": "Уровень редактирования: {{name}}",
|
||||
"editor.editing.up": "Поднимите все кирпичи.",
|
||||
"editor.help": "Создавайте собственные уровни и делитесь ими для включения в игру.",
|
||||
"editor.import": "Импортировать уровень",
|
||||
"editor.import_instruction": "Вставьте код уровня, чтобы импортировать его в список уровней.",
|
||||
"editor.locked": "Наберите в общей сложности {{min}} очков, чтобы разблокировать",
|
||||
"editor.new_level": "Новый уровень",
|
||||
"editor.title": "Редактор уровней",
|
||||
"gameOver.creative": "Этот забег не будет записываться.",
|
||||
"gameOver.cumulative_total": "Ваш общий суммарный балл увеличился с {{startTs}} до {{endTs}}.",
|
||||
"gameOver.lost.summary": "Вы уронили мяч, поймав {{score}} монет.",
|
||||
|
|
|
@ -3,6 +3,29 @@
|
|||
"confirmRestart.text": "Yeni bir oyuna başlamak üzeresiniz. Devam etmek istediğinizden emin misiniz?",
|
||||
"confirmRestart.title": "Yeni bir oyuna mı başlasam?",
|
||||
"confirmRestart.yes": "Oyunu yeniden başlat",
|
||||
"editor.editing.bigger": "Seviye boyutunu artır",
|
||||
"editor.editing.color": "Renk listesinden bir renk seçin (seviye başına en fazla 5)",
|
||||
"editor.editing.copy": "Kopyalama seviyesi kodu",
|
||||
"editor.editing.copy_help": "Bunu Discord'umuzdaki #levels kanalına yapıştırın",
|
||||
"editor.editing.credit": "Krediler ve kaynak",
|
||||
"editor.editing.credit_prompt": "Seviyenizin kaynak URL'sini veya açıklamasını girin.",
|
||||
"editor.editing.delete": "Seviyeyi Sil",
|
||||
"editor.editing.down": "Tüm tuğlaları aşağı doğru hareket ettirin",
|
||||
"editor.editing.help": "Daha sonra renklendirmek istediğiniz kutucuğa tıklayın.",
|
||||
"editor.editing.left": "Tüm tuğlaları sola taşı",
|
||||
"editor.editing.play": "Bu seviyeyi oyna",
|
||||
"editor.editing.rename": "Seviye Adı",
|
||||
"editor.editing.rename_prompt": "Lütfen seviye için yeni bir ad girin",
|
||||
"editor.editing.right": "Tüm tuğlaları sağa taşı",
|
||||
"editor.editing.smaller": "Seviye boyutunu azalt",
|
||||
"editor.editing.title": "Düzenleme düzeyi : {{name}}",
|
||||
"editor.editing.up": "Tüm tuğlaları yukarı taşı",
|
||||
"editor.help": "Özel seviyeler yaratın ve bunları oyuna dahil etmek için paylaşın.",
|
||||
"editor.import": "Bir seviyeyi içe aktar",
|
||||
"editor.import_instruction": "Seviye listenize aktarmak için bir seviye kodunu yapıştırın",
|
||||
"editor.locked": "Kilidi açmak için toplam {{min}} puanına ulaşın",
|
||||
"editor.new_level": "Yeni seviye",
|
||||
"editor.title": "Seviye Editörü",
|
||||
"gameOver.creative": "Bu koşu kaydedilmeyecek.",
|
||||
"gameOver.cumulative_total": "Toplam kümülatif puanınız {{startTs}} 'dan {{endTs}}'e çıktı.",
|
||||
"gameOver.lost.summary": " {{score}} jeton yakaladıktan sonra topu düşürdün.",
|
||||
|
@ -320,7 +343,7 @@
|
|||
"upgrades.pierce_color.name": "Renk delme",
|
||||
"upgrades.pierce_color.tooltip": "+{{lvl}} topun rengindeki tuğlalara hasar",
|
||||
"upgrades.pierce_color.verbose_description": "Bir top aynı renkteki bir tuğlaya çarptığında, engellenmeden geçecektir. \n\nFarklı renkteki bir tuğlaya ulaştığında, onu kıracak, rengini alacak ve sekecektir.\n\nSağlam tuğlalarınız varsa, top yine de aynı renkteki bir tuğladan sekebilir.",
|
||||
"upgrades.puck_repulse_ball.help_plural": "",
|
||||
"upgrades.puck_repulse_ball.help_plural": "Daha güçlü itme kuvveti",
|
||||
"upgrades.puck_repulse_ball.name": "Yumuşak iniş",
|
||||
"upgrades.puck_repulse_ball.tooltip": "Kürek topları iter",
|
||||
"upgrades.puck_repulse_ball.verbose_description": "Bir top küreğe yaklaştığında yavaşlamaya başlayacak ve hatta küreğe değmeden bile zıplamaya başlayacaktır.",
|
||||
|
|
292
src/levelEditor.ts
Normal file
292
src/levelEditor.ts
Normal file
|
@ -0,0 +1,292 @@
|
|||
import { icons, transformRawLevel } from "./loadGameData";
|
||||
import { t } from "./i18n/i18n";
|
||||
import { getSettingValue, getTotalScore, setSettingValue } from "./settings";
|
||||
import { asyncAlert } from "./asyncAlert";
|
||||
import { Palette, RawLevel } from "./types";
|
||||
import { levelIconHTML } from "./levelIcon";
|
||||
|
||||
import _palette from "./data/palette.json";
|
||||
import { restart } from "./game";
|
||||
import { describeLevel } from "./game_utils";
|
||||
|
||||
const palette = _palette as Palette;
|
||||
|
||||
export function levelEditorMenuEntry() {
|
||||
const min = 10000;
|
||||
const disabled = getTotalScore() < min;
|
||||
return {
|
||||
icon: icons["icon:editor"],
|
||||
text: t("editor.title"),
|
||||
disabled,
|
||||
help: disabled ? t("editor.locked", { min }) : t("editor.help"),
|
||||
async value() {
|
||||
openLevelEditorLevelsList().then();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function openLevelEditorLevelsList() {
|
||||
const rawList = getSettingValue("custom_levels", []) as RawLevel[];
|
||||
const customLevels = rawList.map(transformRawLevel);
|
||||
|
||||
let choice = await asyncAlert({
|
||||
title: t("editor.title"),
|
||||
content: [
|
||||
...customLevels.map((l, li) => ({
|
||||
text: l.name,
|
||||
icon: levelIconHTML(l.bricks, l.size, l.color),
|
||||
value() {
|
||||
editRawLevelList(li);
|
||||
},
|
||||
help: l.credit || describeLevel(l),
|
||||
})),
|
||||
{
|
||||
text: t("editor.new_level"),
|
||||
icon: icons["icon:editor"],
|
||||
value() {
|
||||
rawList.push({
|
||||
color: "",
|
||||
size: 6,
|
||||
bricks: "____________________________________",
|
||||
name: "custom level" + (rawList.length + 1),
|
||||
credit: "",
|
||||
});
|
||||
setSettingValue("custom_levels", rawList);
|
||||
editRawLevelList(rawList.length - 1);
|
||||
},
|
||||
},
|
||||
{
|
||||
text: t("editor.import"),
|
||||
help: t("editor.import_instruction"),
|
||||
value() {
|
||||
const code = prompt(t("editor.import_instruction"))?.trim();
|
||||
if (code) {
|
||||
let [name, credit] = code.match(/\[([^\]]+)]/gi);
|
||||
|
||||
let bricks = code
|
||||
.split(name)[1]
|
||||
.split(credit)[0]
|
||||
.replace(/\s/gi, "");
|
||||
name = name.slice(1, -1);
|
||||
credit = credit.slice(1, -1);
|
||||
name ||= "Imported on " + new Date().toISOString().slice(0, 10);
|
||||
credit ||= "";
|
||||
const size = Math.sqrt(bricks.length);
|
||||
if (Math.floor(size) === size && size >= 2 && size <= 20) {
|
||||
rawList.push({
|
||||
color: automaticBackgroundColor(bricks.split("")),
|
||||
size,
|
||||
bricks,
|
||||
name,
|
||||
credit,
|
||||
});
|
||||
setSettingValue("custom_levels", rawList);
|
||||
}
|
||||
}
|
||||
openLevelEditorLevelsList();
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
if (typeof choice == "function") choice();
|
||||
}
|
||||
|
||||
export async function editRawLevelList(nth: number, color = "W") {
|
||||
let rawList = getSettingValue("custom_levels", []) as RawLevel[];
|
||||
const level = rawList[nth];
|
||||
const bricks = level.bricks.split("");
|
||||
let grid = "";
|
||||
for (let y = 0; y < level.size; y++) {
|
||||
grid += '<div style="background: ' + (level.color || "black") + ';">';
|
||||
for (let x = 0; x < level.size; x++) {
|
||||
const c = bricks[y * level.size + x];
|
||||
grid += `<span data-resolve-to="paint_brick:${x}:${y}" style="background: ${palette[c]}">${c == "B" ? "💣" : ""}</span>`;
|
||||
}
|
||||
grid += "</div>";
|
||||
}
|
||||
|
||||
const levelColors = new Set(bricks);
|
||||
levelColors.delete("_");
|
||||
levelColors.delete("B");
|
||||
|
||||
let colorList =
|
||||
'<div class="palette">' +
|
||||
Object.entries(palette)
|
||||
.filter(([key, value]) => key !== "_")
|
||||
.filter(
|
||||
([key, value]) =>
|
||||
levelColors.size < 5 || levelColors.has(key) || key === "B",
|
||||
)
|
||||
.map(
|
||||
([key, value]) =>
|
||||
`<span data-resolve-to="set_color:${key}" data-selected="${key == color}" style="background: ${value}">${key == "B" ? "💣" : ""}</span>`,
|
||||
)
|
||||
.join("") +
|
||||
"</div>";
|
||||
|
||||
const clicked = await asyncAlert<string | null>({
|
||||
title: t("editor.editing.title", { name: level.name }),
|
||||
content: [
|
||||
t("editor.editing.color"),
|
||||
colorList,
|
||||
t("editor.editing.help"),
|
||||
`<div class="gridEdit" style="--grid-size:${level.size};">${grid}</div>`,
|
||||
|
||||
{
|
||||
icon: icons["icon:new_run"],
|
||||
text: t("editor.editing.play"),
|
||||
value: "play",
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.rename"),
|
||||
value: "rename",
|
||||
help: level.name,
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.credit"),
|
||||
value: "credit",
|
||||
help: level.credit,
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.delete"),
|
||||
value: "delete",
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.copy"),
|
||||
value: "copy",
|
||||
help: t("editor.editing.copy_help"),
|
||||
disabled:
|
||||
!level.name ||
|
||||
!level.credit ||
|
||||
bricks.filter((b) => b !== "_").length < 6,
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.bigger"),
|
||||
value: "size:+1",
|
||||
disabled: level.size > 20,
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.smaller"),
|
||||
value: "size:-1",
|
||||
disabled: level.size < 3,
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.left"),
|
||||
value: "move:-1:0",
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.right"),
|
||||
value: "move:1:0",
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.up"),
|
||||
value: "move:0:-1",
|
||||
},
|
||||
{
|
||||
text: t("editor.editing.down"),
|
||||
value: "move:0:1",
|
||||
},
|
||||
],
|
||||
});
|
||||
if (!clicked) return;
|
||||
if (typeof clicked === "string") {
|
||||
const [action, a, b] = clicked.split(":");
|
||||
if (action == "paint_brick") {
|
||||
const x = parseInt(a),
|
||||
y = parseInt(b);
|
||||
bricks[y * level.size + x] =
|
||||
bricks[y * level.size + x] === color ? "_" : color;
|
||||
level.bricks = bricks.join("");
|
||||
}
|
||||
if (action == "set_color") {
|
||||
color = a;
|
||||
}
|
||||
if (action == "size") {
|
||||
const newSize = level.size + parseInt(a);
|
||||
const newBricks = [];
|
||||
for (let y = 0; y < newSize; y++) {
|
||||
for (let x = 0; x < newSize; x++) {
|
||||
newBricks.push(
|
||||
(x < level.size && y < level.size && bricks[y * level.size + x]) ||
|
||||
"_",
|
||||
);
|
||||
}
|
||||
}
|
||||
level.size = newSize;
|
||||
level.bricks = newBricks.join("");
|
||||
}
|
||||
if (action == "move") {
|
||||
const dx = parseInt(a),
|
||||
dy = parseInt(b);
|
||||
const newBricks = [];
|
||||
for (let y = 0; y < level.size; y++) {
|
||||
for (let x = 0; x < level.size; x++) {
|
||||
const tx = x - dx;
|
||||
const ty = y - dy;
|
||||
if (tx < 0 || tx >= level.size || ty < 0 || ty >= level.size) {
|
||||
newBricks.push("_");
|
||||
} else {
|
||||
newBricks.push(bricks[ty * level.size + tx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
level.bricks = newBricks.join("");
|
||||
}
|
||||
if (action === "play") {
|
||||
restart({
|
||||
level: transformRawLevel(level),
|
||||
isEditorTrialRun: nth,
|
||||
perks: {
|
||||
base_combo: 7,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (action === "copy") {
|
||||
let text = "```\n[" + level.name?.replace(/\[|\]/gi, " ") + "]";
|
||||
bricks.forEach((b, bi) => {
|
||||
if (!(bi % level.size)) text += "\n";
|
||||
text += b;
|
||||
});
|
||||
text +=
|
||||
"\n[" +
|
||||
(level.credit?.replace(/\[|\]/gi, " ") || "Missing credits!") +
|
||||
"]\n```";
|
||||
navigator.clipboard.writeText(text);
|
||||
// return
|
||||
}
|
||||
if (action === "rename") {
|
||||
const name = prompt(t("editor.editing.rename_prompt"), level.name);
|
||||
if (name) {
|
||||
level.name = name;
|
||||
}
|
||||
}
|
||||
if (action === "credit") {
|
||||
const credit = prompt(
|
||||
t("editor.editing.credit_prompt"),
|
||||
level.credit || "",
|
||||
);
|
||||
if (credit !== "null") {
|
||||
level.credit = credit || "";
|
||||
}
|
||||
}
|
||||
if (action === "delete") {
|
||||
rawList = rawList.filter((l, li) => li !== nth);
|
||||
setSettingValue("custom_levels", rawList);
|
||||
openLevelEditorLevelsList();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
level.color = automaticBackgroundColor(bricks);
|
||||
|
||||
setSettingValue("custom_levels", rawList);
|
||||
editRawLevelList(nth, color);
|
||||
}
|
||||
|
||||
function automaticBackgroundColor(bricks: string[]) {
|
||||
return bricks.filter((b) => b === "g").length >
|
||||
bricks.filter((b) => b !== "_").length * 0.05
|
||||
? "#115988"
|
||||
: "";
|
||||
}
|
|
@ -13,28 +13,29 @@ const rawLevelsList = _rawLevelsList as RawLevel[];
|
|||
export const appVersion = _appVersion as string;
|
||||
|
||||
export const icons = {} as { [k: string]: string };
|
||||
export const allLevelsAndIcons = rawLevelsList
|
||||
.map((level, i) => {
|
||||
const bricks = level.bricks
|
||||
.split("")
|
||||
.map((c) => palette[c])
|
||||
.slice(0, level.size * level.size);
|
||||
const bricksCount = bricks.filter((i) => i).length;
|
||||
const icon = levelIconHTML(bricks, level.size, level.color);
|
||||
icons[level.name] = icon;
|
||||
return {
|
||||
...level,
|
||||
bricks,
|
||||
bricksCount,
|
||||
icon,
|
||||
color: level.color || "#000000",
|
||||
svg: getLevelBackground(level),
|
||||
};
|
||||
})
|
||||
.map((l, li) => ({
|
||||
...l,
|
||||
sortKey: ((Math.random() + 3) / 3.5) * l.bricksCount,
|
||||
})) as Level[];
|
||||
|
||||
export function transformRawLevel(level: RawLevel) {
|
||||
const bricks = level.bricks
|
||||
.split("")
|
||||
.map((c) => palette[c])
|
||||
.slice(0, level.size * level.size);
|
||||
const bricksCount = bricks.filter((i) => i).length;
|
||||
const icon = levelIconHTML(bricks, level.size, level.color);
|
||||
icons[level.name] = icon;
|
||||
return {
|
||||
...level,
|
||||
bricks,
|
||||
bricksCount,
|
||||
icon,
|
||||
color: level.color || "#000000",
|
||||
svg: getLevelBackground(level),
|
||||
sortKey: ((Math.random() + 3) / 3.5) * bricksCount,
|
||||
};
|
||||
}
|
||||
|
||||
export const allLevelsAndIcons = rawLevelsList.map(
|
||||
transformRawLevel,
|
||||
) as Level[];
|
||||
|
||||
export const allLevels = allLevelsAndIcons.filter(
|
||||
(l) => !l.name.startsWith("icon:"),
|
||||
|
|
|
@ -28,12 +28,12 @@ export function getRunLevels(
|
|||
(l, li) =>
|
||||
unlockedBefore.has(l.name) || !reasonLevelIsLocked(li, history, false),
|
||||
);
|
||||
const firstLevel = allLevelsAndIcons.filter(
|
||||
(l) => l.name == (params?.level || "icon:" + randomGift),
|
||||
);
|
||||
const firstLevel = params?.level
|
||||
? [params.level]
|
||||
: allLevelsAndIcons.filter((l) => l.name == "icon:" + randomGift);
|
||||
|
||||
const restInRandomOrder = unlocked
|
||||
.filter((l) => l.name !== params?.level)
|
||||
.filter((l) => l.name !== params?.level?.name)
|
||||
.filter((l) => l.name !== params?.levelToAvoid)
|
||||
.sort(() => Math.random() - 0.5);
|
||||
|
||||
|
@ -141,8 +141,9 @@ export function newGameState(params: RunParams): GameState {
|
|||
creative:
|
||||
params?.computer_controlled ||
|
||||
sumOfValues(params.perks) > 1 ||
|
||||
(params.level && !params.level.startsWith("icon:")),
|
||||
(params.level && !params.level.name.startsWith("icon:")),
|
||||
computer_controlled: params?.computer_controlled || false,
|
||||
isEditorTrialRun: params?.isEditorTrialRun,
|
||||
};
|
||||
resetBalls(gameState);
|
||||
|
||||
|
|
5
src/types.d.ts
vendored
5
src/types.d.ts
vendored
|
@ -7,7 +7,6 @@ export type RawLevel = {
|
|||
name: string;
|
||||
size: number;
|
||||
bricks: string;
|
||||
svg: number | null;
|
||||
color: string;
|
||||
credit?: string;
|
||||
};
|
||||
|
@ -282,14 +281,16 @@ export type GameState = {
|
|||
rerolls: number;
|
||||
creative: boolean;
|
||||
computer_controlled: boolean;
|
||||
isEditorTrialRun?: number;
|
||||
};
|
||||
|
||||
export type RunParams = {
|
||||
level?: string;
|
||||
level?: Level;
|
||||
levelToAvoid?: string;
|
||||
perkToAvoid?: PerkId;
|
||||
perks?: Partial<PerksMap>;
|
||||
computer_controlled?: boolean;
|
||||
isEditorTrialRun?: number;
|
||||
};
|
||||
export type OptionDef = {
|
||||
default: boolean;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue