feat: добавлены сохранения, достижения и локализация #1
@@ -11,8 +11,6 @@ import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.viewport.FitViewport;
|
||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
||||
@@ -21,9 +19,9 @@ import java.util.Random;
|
||||
|
||||
public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
// Константы
|
||||
private static final int WIDTH = 1700;
|
||||
private static final int HEIGHT = 950;
|
||||
private static final int UI_INPUT_HEIGHT = 210;
|
||||
private static final int WIDTH = GameConfig.WIDTH;
|
||||
private static final int HEIGHT = GameConfig.HEIGHT;
|
||||
private static final int UI_INPUT_HEIGHT = GameConfig.UI_INPUT_HEIGHT;
|
||||
|
||||
// Основные объекты
|
||||
private SpriteBatch batch;
|
||||
@@ -52,9 +50,9 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
private int selectedBuildingType = 0;
|
||||
private StringBuilder inputText = new StringBuilder();
|
||||
private boolean isTyping = false;
|
||||
private String messageText = "Добро пожаловать! Выберите здание и кликните на поле.";
|
||||
private String messageText = "";
|
||||
private Color messageColor = Color.WHITE;
|
||||
private String problemText = "Нажмите ESC для возврата в меню";
|
||||
private String problemText = "";
|
||||
|
||||
// Текстуры и рендереры
|
||||
private Texture backgroundTexture;
|
||||
@@ -62,6 +60,9 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
private UIRenderer uiRenderer;
|
||||
private MenuRenderer menuRenderer;
|
||||
|
||||
// Достижения
|
||||
private AchievementPopup achievementPopup;
|
||||
|
||||
// Планета
|
||||
private Planet currentPlanet;
|
||||
private float planetSwitchTimer = 0;
|
||||
@@ -95,6 +96,9 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
// Начинаем с Земли
|
||||
currentPlanet = Planet.EARTH;
|
||||
|
||||
// Загружаем настройки и достижения
|
||||
GameSave.loadSettings();
|
||||
|
||||
try {
|
||||
backgroundTexture = new Texture(Gdx.files.internal("фон4.png"));
|
||||
} catch (Exception e) {
|
||||
@@ -104,6 +108,11 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
buildingRenderer = new BuildingRenderer(shapeRenderer, batch, font, glyphLayout, whitePixel);
|
||||
uiRenderer = new UIRenderer(batch, font, glyphLayout, whitePixel, WIDTH, HEIGHT, UI_INPUT_HEIGHT);
|
||||
menuRenderer = new MenuRenderer(batch, font, glyphLayout, whitePixel, WIDTH, HEIGHT);
|
||||
achievementPopup = new AchievementPopup();
|
||||
|
||||
// Устанавливаем начальные сообщения
|
||||
messageText = Localization.welcomeTo(currentPlanet);
|
||||
problemText = Localization.isRu() ? "Нажмите ESC для возврата в меню" : "Press ESC to return to menu";
|
||||
|
||||
updateUI();
|
||||
}
|
||||
@@ -133,10 +142,18 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
case ABOUT:
|
||||
renderAbout();
|
||||
break;
|
||||
case ACHIEVEMENTS:
|
||||
renderAchievements();
|
||||
break;
|
||||
case PLAYING:
|
||||
renderGame();
|
||||
break;
|
||||
}
|
||||
|
||||
// Рендер уведомления о достижении поверх всего
|
||||
if (achievementPopup.isActive()) {
|
||||
achievementPopup.render(batch, font, glyphLayout, whitePixel, WIDTH, HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleInput() {
|
||||
@@ -152,12 +169,12 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
// Отмена ввода
|
||||
setTyping(false);
|
||||
getInputText().setLength(0);
|
||||
setMessageText("Ввод отменен.");
|
||||
setMessageText(Localization.inputCanceled());
|
||||
setMessageColor(Color.YELLOW);
|
||||
} else {
|
||||
// Возврат в главное меню
|
||||
// Возврат в главное меню с сохранением
|
||||
GameSave.save(this);
|
||||
gameState = GameState.MAIN_MENU;
|
||||
setMessageText("Игра приостановлена. Нажмите ESC для продолжения.");
|
||||
}
|
||||
} else if (gameState != GameState.MAIN_MENU) {
|
||||
// Возврат в главное меню из других состояний
|
||||
@@ -179,6 +196,9 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
case ABOUT:
|
||||
handleAboutInput(mouseX, mouseY, isClicked);
|
||||
break;
|
||||
case ACHIEVEMENTS:
|
||||
handleAchievementsInput(mouseX, mouseY, isClicked);
|
||||
break;
|
||||
case PLAYING:
|
||||
InputHandler.handleInput(this);
|
||||
break;
|
||||
@@ -189,19 +209,30 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
|
||||
private void handleMainMenuInput(float mouseX, float mouseY, boolean isClicked) {
|
||||
if (isClicked) {
|
||||
// Проверяем клик на переключатель языка
|
||||
if (menuRenderer.checkLanguageClick(mouseX, mouseY)) {
|
||||
Localization.toggleLanguage();
|
||||
GameSave.saveSettings();
|
||||
menuRenderer.refreshMenuTexts();
|
||||
return;
|
||||
}
|
||||
|
||||
MenuButton clickedButton = menuRenderer.getMainMenuButtonAt(mouseX, mouseY);
|
||||
if (clickedButton != null) {
|
||||
String buttonText = clickedButton.getText(); // Используйте геттер
|
||||
String buttonText = clickedButton.getText();
|
||||
|
||||
if (buttonText.contains("НОВАЯ ИГРА")) {
|
||||
if (buttonText.contains("ПРОДОЛЖИТЬ") || buttonText.contains("CONTINUE")) {
|
||||
continueGame();
|
||||
} else if (buttonText.contains("НОВАЯ") || buttonText.contains("NEW")) {
|
||||
startNewGame();
|
||||
} else if (buttonText.contains("ВЫБОР ПЛАНЕТЫ")) {
|
||||
} else if (buttonText.contains("ПЛАНЕТ") || buttonText.contains("PLANET")) {
|
||||
gameState = GameState.PLANET_SELECT;
|
||||
} else if (buttonText.contains("ПОМОЩЬ")) {
|
||||
} else if (buttonText.contains("ДОСТИЖЕНИЯ") || buttonText.contains("ACHIEVEMENTS")) {
|
||||
gameState = GameState.ACHIEVEMENTS;
|
||||
} else if (buttonText.contains("ПОМОЩЬ") || buttonText.contains("HELP")) {
|
||||
gameState = GameState.HELP;
|
||||
} else if (buttonText.contains("ОБ ИГРЕ")) {
|
||||
gameState = GameState.ABOUT;
|
||||
} else if (buttonText.contains("ВЫХОД")) {
|
||||
} else if (buttonText.contains("ВЫХОД") || buttonText.contains("EXIT")) {
|
||||
GameSave.saveSettings();
|
||||
Gdx.app.exit();
|
||||
}
|
||||
}
|
||||
@@ -212,15 +243,15 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
if (isClicked) {
|
||||
MenuButton clickedButton = menuRenderer.getPlanetSelectButtonAt(mouseX, mouseY);
|
||||
if (clickedButton != null) {
|
||||
String buttonText = clickedButton.getText(); // Используйте геттер
|
||||
String buttonText = clickedButton.getText();
|
||||
|
||||
if (buttonText.contains("ЗЕМЛЯ")) {
|
||||
if (buttonText.contains("ЗЕМЛЯ") || buttonText.contains("EARTH")) {
|
||||
startNewGameOnPlanet(Planet.EARTH);
|
||||
} else if (buttonText.contains("МАРС")) {
|
||||
} else if (buttonText.contains("МАРС") || buttonText.contains("MARS")) {
|
||||
startNewGameOnPlanet(Planet.MARS);
|
||||
} else if (buttonText.contains("ВЕНЕРА")) {
|
||||
} else if (buttonText.contains("ВЕНЕРА") || buttonText.contains("VENUS")) {
|
||||
startNewGameOnPlanet(Planet.VENUS);
|
||||
} else if (buttonText.contains("НАЗАД")) {
|
||||
} else if (buttonText.contains("НАЗАД") || buttonText.contains("BACK")) {
|
||||
gameState = GameState.MAIN_MENU;
|
||||
}
|
||||
}
|
||||
@@ -231,11 +262,7 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
if (isClicked) {
|
||||
MenuButton clickedButton = menuRenderer.getHelpButtonAt(mouseX, mouseY);
|
||||
if (clickedButton != null) {
|
||||
String buttonText = clickedButton.getText(); // Используйте геттер
|
||||
|
||||
if (buttonText.contains("НАЗАД")) {
|
||||
gameState = GameState.MAIN_MENU;
|
||||
}
|
||||
gameState = GameState.MAIN_MENU;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +276,50 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAchievementsInput(float mouseX, float mouseY, boolean isClicked) {
|
||||
if (isClicked) {
|
||||
MenuButton clickedButton = menuRenderer.getAchievementsButtonAt(mouseX, mouseY);
|
||||
if (clickedButton != null) {
|
||||
gameState = GameState.MAIN_MENU;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void continueGame() {
|
||||
// Загружаем сохранение и продолжаем игру
|
||||
GameSave.load(this);
|
||||
|
||||
// Загружаем здания и жителей
|
||||
jokeBubbles.clear();
|
||||
currentBuilding = null;
|
||||
currentProblem = null;
|
||||
selectedBuildingType = 0;
|
||||
inputText.setLength(0);
|
||||
isTyping = false;
|
||||
isSwitchingPlanets = false;
|
||||
|
||||
// Загружаем сохранённые здания
|
||||
GameSave.loadBuildings(buildings, citizens, random);
|
||||
|
||||
// Отмечаем посещение текущей планеты
|
||||
Achievements.visitPlanet(currentPlanet);
|
||||
|
||||
// Показываем прогресс
|
||||
String progressInfo = Localization.isRu()
|
||||
? " (Загружено зданий: " + buildings.size + ")"
|
||||
: " (Loaded buildings: " + buildings.size + ")";
|
||||
messageText = Localization.welcomeTo(currentPlanet) + progressInfo;
|
||||
messageColor = Color.GREEN;
|
||||
|
||||
gameState = GameState.PLAYING;
|
||||
updateUI();
|
||||
}
|
||||
|
||||
private void startNewGame() {
|
||||
// Сбрасываем ВСЮ статистику для новой игры
|
||||
GameSave.resetAll();
|
||||
Achievements.reset();
|
||||
|
||||
// Очищаем всё и начинаем новую игру на Земле
|
||||
buildings.clear();
|
||||
citizens.clear();
|
||||
@@ -263,7 +333,10 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
currentPlanet = Planet.EARTH;
|
||||
isSwitchingPlanets = false;
|
||||
|
||||
messageText = "Добро пожаловать на Землю! Выберите здание и кликните на поле.";
|
||||
// Отмечаем посещение Земли
|
||||
Achievements.visitPlanet(Planet.EARTH);
|
||||
|
||||
messageText = Localization.welcomeTo(currentPlanet);
|
||||
messageColor = Color.GREEN;
|
||||
|
||||
gameState = GameState.PLAYING;
|
||||
@@ -284,7 +357,10 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
currentPlanet = planet;
|
||||
isSwitchingPlanets = false;
|
||||
|
||||
messageText = "Добро пожаловать на " + planet.getName() + "! Выберите здание и кликните на поле.";
|
||||
// Отмечаем посещение планеты
|
||||
Achievements.visitPlanet(planet);
|
||||
|
||||
messageText = Localization.welcomeTo(planet);
|
||||
messageColor = Color.GREEN;
|
||||
|
||||
gameState = GameState.PLAYING;
|
||||
@@ -298,13 +374,32 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
// Обновляем меню
|
||||
menuRenderer.update(deltaTime);
|
||||
|
||||
// Обновляем уведомление о достижении
|
||||
achievementPopup.update(deltaTime);
|
||||
|
||||
// Проверяем новые достижения
|
||||
if (Achievements.hasNewUnlock()) {
|
||||
Achievement newAchievement = Achievements.getLastUnlocked();
|
||||
if (newAchievement != null && !achievementPopup.isActive()) {
|
||||
achievementPopup.show(newAchievement);
|
||||
GameSave.saveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
// Обработка плавной смены планет
|
||||
if (isSwitchingPlanets) {
|
||||
planetSwitchTimer += deltaTime;
|
||||
if (planetSwitchTimer >= 1.0f) {
|
||||
currentPlanet = targetPlanet;
|
||||
isSwitchingPlanets = false;
|
||||
setMessageText("Добро пожаловать на " + currentPlanet.getName() + "! 🌍");
|
||||
|
||||
// Отмечаем посещение новой планеты и сохраняем
|
||||
Achievements.visitPlanet(currentPlanet);
|
||||
Achievements.check(this);
|
||||
GameSave.savePlanet(currentPlanet);
|
||||
GameSave.saveSettings();
|
||||
|
||||
setMessageText(Localization.welcomeTo(currentPlanet));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,7 +454,7 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
currentProblem = null;
|
||||
selectedBuildingType = 0;
|
||||
|
||||
setMessageText("Запускаем космический корабль на " + newPlanet.getName() + "! 🚀");
|
||||
setMessageText(Localization.flying(newPlanet));
|
||||
setMessageColor(Color.YELLOW);
|
||||
updateUI();
|
||||
}
|
||||
@@ -392,6 +487,12 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
menuRenderer.renderAbout(mouseX, mouseY);
|
||||
}
|
||||
|
||||
private void renderAchievements() {
|
||||
float mouseX = Gdx.input.getX();
|
||||
float mouseY = HEIGHT - Gdx.input.getY();
|
||||
menuRenderer.renderAchievements(mouseX, mouseY);
|
||||
}
|
||||
|
||||
private void renderGame() {
|
||||
renderBackground();
|
||||
renderBuildings();
|
||||
@@ -473,9 +574,9 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
|
||||
String transitionText;
|
||||
if (planetSwitchTimer < 0.5f) {
|
||||
transitionText = "Покидаем " + currentPlanet.getName() + "...";
|
||||
transitionText = Localization.leaving(currentPlanet);
|
||||
} else {
|
||||
transitionText = "Прибываем на " + targetPlanet.getName() + "!";
|
||||
transitionText = Localization.arriving(targetPlanet);
|
||||
}
|
||||
|
||||
glyphLayout.setText(font, transitionText);
|
||||
@@ -500,6 +601,9 @@ public class AbsurdCityBuilder1 extends ApplicationAdapter {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
// Сохраняем настройки при выходе
|
||||
GameSave.saveSettings();
|
||||
|
||||
batch.dispose();
|
||||
shapeRenderer.dispose();
|
||||
font.dispose();
|
||||
|
||||
92
core/src/main/java/com/mygdx/game/Achievement.java
Normal file
92
core/src/main/java/com/mygdx/game/Achievement.java
Normal file
@@ -0,0 +1,92 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
// Перечисление всех достижений в игре.
|
||||
public enum Achievement {
|
||||
// Строительство
|
||||
FIRST_BUILDING("first_building",
|
||||
"Первый кирпич", "First Brick",
|
||||
"Построй первое здание", "Build your first building"),
|
||||
|
||||
BUILDER_5("builder_5",
|
||||
"Строитель", "Builder",
|
||||
"Построй 5 зданий", "Build 5 buildings"),
|
||||
|
||||
BUILDER_10("builder_10",
|
||||
"Архитектор", "Architect",
|
||||
"Построй 10 зданий", "Build 10 buildings"),
|
||||
|
||||
BUILDER_25("builder_25",
|
||||
"Мастер-строитель", "Master Builder",
|
||||
"Построй 25 зданий", "Build 25 buildings"),
|
||||
|
||||
// Планеты
|
||||
MARS_VISITOR("mars_visitor",
|
||||
"Марсианин", "Martian",
|
||||
"Посети Марс", "Visit Mars"),
|
||||
|
||||
VENUS_VISITOR("venus_visitor",
|
||||
"Венерианец", "Venusian",
|
||||
"Посети Венеру", "Visit Venus"),
|
||||
|
||||
ALL_PLANETS("all_planets",
|
||||
"Космонавт", "Astronaut",
|
||||
"Посети все планеты", "Visit all planets"),
|
||||
|
||||
// Математика
|
||||
MATH_STREAK_5("math_streak_5",
|
||||
"Умник", "Smart One",
|
||||
"5 правильных ответов подряд", "5 correct answers in a row"),
|
||||
|
||||
MATH_STREAK_10("math_streak_10",
|
||||
"Математик", "Mathematician",
|
||||
"10 правильных ответов подряд", "10 correct answers in a row"),
|
||||
|
||||
MATH_STREAK_20("math_streak_20",
|
||||
"Гений", "Genius",
|
||||
"20 правильных ответов подряд", "20 correct answers in a row");
|
||||
|
||||
private final String id;
|
||||
private final String titleRu;
|
||||
private final String titleEn;
|
||||
private final String descriptionRu;
|
||||
private final String descriptionEn;
|
||||
|
||||
Achievement(String id, String titleRu, String titleEn,
|
||||
String descriptionRu, String descriptionEn) {
|
||||
this.id = id;
|
||||
this.titleRu = titleRu;
|
||||
this.titleEn = titleEn;
|
||||
this.descriptionRu = descriptionRu;
|
||||
this.descriptionEn = descriptionEn;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return Localization.isRu() ? titleRu : titleEn;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return Localization.isRu() ? descriptionRu : descriptionEn;
|
||||
}
|
||||
|
||||
public String getTitleRu() {
|
||||
return titleRu;
|
||||
}
|
||||
|
||||
public String getTitleEn() {
|
||||
return titleEn;
|
||||
}
|
||||
|
||||
// Найти достижение по ID
|
||||
public static Achievement fromId(String id) {
|
||||
for (Achievement a : values()) {
|
||||
if (a.id.equals(id)) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
120
core/src/main/java/com/mygdx/game/AchievementPopup.java
Normal file
120
core/src/main/java/com/mygdx/game/AchievementPopup.java
Normal file
@@ -0,0 +1,120 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
|
||||
// Всплывающее уведомление о разблокировке достижения.
|
||||
|
||||
public class AchievementPopup {
|
||||
|
||||
private static final float POPUP_WIDTH = 400;
|
||||
private static final float POPUP_HEIGHT = 80;
|
||||
private static final float POPUP_DURATION = 3.0f;
|
||||
private static final Color BG_COLOR = new Color(0.1f, 0.1f, 0.2f, 0.95f);
|
||||
private static final Color BORDER_COLOR = new Color(1.0f, 0.8f, 0.2f, 1f);
|
||||
private static final Color TITLE_COLOR = new Color(1.0f, 0.9f, 0.3f, 1f);
|
||||
|
||||
private Achievement currentAchievement;
|
||||
private float timer;
|
||||
private boolean active;
|
||||
|
||||
public AchievementPopup() {
|
||||
this.currentAchievement = null;
|
||||
this.timer = 0;
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
// Показать уведомление о достижении
|
||||
public void show(Achievement achievement) {
|
||||
this.currentAchievement = achievement;
|
||||
this.timer = POPUP_DURATION;
|
||||
this.active = true;
|
||||
Achievements.clearNewUnlock();
|
||||
}
|
||||
|
||||
// Обновить таймер
|
||||
public void update(float deltaTime) {
|
||||
if (active) {
|
||||
timer -= deltaTime;
|
||||
if (timer <= 0) {
|
||||
active = false;
|
||||
currentAchievement = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Активен ли попап
|
||||
public boolean isActive() {
|
||||
return active && currentAchievement != null;
|
||||
}
|
||||
|
||||
// Отрисовать попап достижения
|
||||
public void render(SpriteBatch batch, BitmapFont font, GlyphLayout layout,
|
||||
Texture whitePixel, int screenWidth, int screenHeight) {
|
||||
if (!isActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
float progress = timer / POPUP_DURATION;
|
||||
|
||||
// Анимация появления/исчезновения
|
||||
float alpha = 1.0f;
|
||||
float offsetY = 0;
|
||||
|
||||
if (progress > 0.8f) {
|
||||
// Появление (первые 20% времени)
|
||||
float appearProgress = (1.0f - progress) / 0.2f;
|
||||
alpha = appearProgress;
|
||||
offsetY = (1.0f - appearProgress) * 50;
|
||||
} else if (progress < 0.2f) {
|
||||
// Исчезновение (последние 20% времени)
|
||||
alpha = progress / 0.2f;
|
||||
offsetY = (1.0f - alpha) * 50;
|
||||
}
|
||||
|
||||
float x = screenWidth / 2f - POPUP_WIDTH / 2f;
|
||||
float y = screenHeight - POPUP_HEIGHT - 20 - offsetY;
|
||||
|
||||
batch.begin();
|
||||
|
||||
// Фон
|
||||
batch.setColor(BG_COLOR.r, BG_COLOR.g, BG_COLOR.b, BG_COLOR.a * alpha);
|
||||
batch.draw(whitePixel, x, y, POPUP_WIDTH, POPUP_HEIGHT);
|
||||
|
||||
// Рамка
|
||||
batch.setColor(BORDER_COLOR.r, BORDER_COLOR.g, BORDER_COLOR.b, BORDER_COLOR.a * alpha);
|
||||
batch.draw(whitePixel, x, y, POPUP_WIDTH, 3); // низ
|
||||
batch.draw(whitePixel, x, y + POPUP_HEIGHT - 3, POPUP_WIDTH, 3); // верх
|
||||
batch.draw(whitePixel, x, y, 3, POPUP_HEIGHT); // лево
|
||||
batch.draw(whitePixel, x + POPUP_WIDTH - 3, y, 3, POPUP_HEIGHT); // право
|
||||
|
||||
// Заголовок "Достижение разблокировано!"
|
||||
font.setColor(TITLE_COLOR.r, TITLE_COLOR.g, TITLE_COLOR.b, alpha);
|
||||
font.getData().setScale(0.9f);
|
||||
String header = Localization.achievementUnlocked();
|
||||
layout.setText(font, header);
|
||||
font.draw(batch, header, x + POPUP_WIDTH / 2f - layout.width / 2f, y + POPUP_HEIGHT - 15);
|
||||
|
||||
// Название достижения
|
||||
font.setColor(1, 1, 1, alpha);
|
||||
font.getData().setScale(1.1f);
|
||||
String title = "🏆 " + currentAchievement.getTitle();
|
||||
layout.setText(font, title);
|
||||
font.draw(batch, title, x + POPUP_WIDTH / 2f - layout.width / 2f, y + POPUP_HEIGHT - 40);
|
||||
|
||||
// Описание
|
||||
font.setColor(0.8f, 0.8f, 0.8f, alpha);
|
||||
font.getData().setScale(0.8f);
|
||||
String desc = currentAchievement.getDescription();
|
||||
layout.setText(font, desc);
|
||||
font.draw(batch, desc, x + POPUP_WIDTH / 2f - layout.width / 2f, y + 20);
|
||||
|
||||
font.getData().setScale(1.0f);
|
||||
batch.setColor(Color.WHITE);
|
||||
|
||||
batch.end();
|
||||
}
|
||||
}
|
||||
184
core/src/main/java/com/mygdx/game/Achievements.java
Normal file
184
core/src/main/java/com/mygdx/game/Achievements.java
Normal file
@@ -0,0 +1,184 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
// Менеджер достижений - проверка условий и разблокировка.
|
||||
public class Achievements {
|
||||
private static Set<Achievement> unlocked = new HashSet<>();
|
||||
private static Achievement lastUnlocked = null;
|
||||
private static float popupTimer = 0;
|
||||
private static final float POPUP_DURATION = 3.0f;
|
||||
private static boolean hasNewUnlockFlag = false;
|
||||
|
||||
// Проверить все условия достижений
|
||||
public static void check(AbsurdCityBuilder1 game) {
|
||||
// Строительство
|
||||
int total = GameSave.getTotalBuildings();
|
||||
|
||||
if (total >= 1) {
|
||||
tryUnlock(Achievement.FIRST_BUILDING);
|
||||
}
|
||||
if (total >= 5) {
|
||||
tryUnlock(Achievement.BUILDER_5);
|
||||
}
|
||||
if (total >= 10) {
|
||||
tryUnlock(Achievement.BUILDER_10);
|
||||
}
|
||||
if (total >= 25) {
|
||||
tryUnlock(Achievement.BUILDER_25);
|
||||
}
|
||||
|
||||
// Планеты
|
||||
if (GameSave.hasVisitedMars()) {
|
||||
tryUnlock(Achievement.MARS_VISITOR);
|
||||
}
|
||||
if (GameSave.hasVisitedVenus()) {
|
||||
tryUnlock(Achievement.VENUS_VISITOR);
|
||||
}
|
||||
if (GameSave.hasVisitedAllPlanets()) {
|
||||
tryUnlock(Achievement.ALL_PLANETS);
|
||||
}
|
||||
|
||||
// Математика
|
||||
int streak = GameSave.getCorrectStreak();
|
||||
|
||||
if (streak >= 5) {
|
||||
tryUnlock(Achievement.MATH_STREAK_5);
|
||||
}
|
||||
if (streak >= 10) {
|
||||
tryUnlock(Achievement.MATH_STREAK_10);
|
||||
}
|
||||
if (streak >= 20) {
|
||||
tryUnlock(Achievement.MATH_STREAK_20);
|
||||
}
|
||||
}
|
||||
|
||||
// Попробовать разблокировать достижение
|
||||
private static void tryUnlock(Achievement achievement) {
|
||||
if (!unlocked.contains(achievement)) {
|
||||
unlock(achievement);
|
||||
}
|
||||
}
|
||||
|
||||
// Разблокировать достижение
|
||||
public static void unlock(Achievement achievement) {
|
||||
if (unlocked.contains(achievement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
unlocked.add(achievement);
|
||||
lastUnlocked = achievement;
|
||||
popupTimer = POPUP_DURATION;
|
||||
hasNewUnlockFlag = true;
|
||||
|
||||
// Сохраняем сразу
|
||||
GameSave.saveSettings();
|
||||
}
|
||||
|
||||
// Отметить посещение планеты
|
||||
public static void visitPlanet(Planet planet) {
|
||||
GameSave.onVisitPlanet(planet);
|
||||
}
|
||||
|
||||
// Есть ли новое непоказанное достижение
|
||||
public static boolean hasNewUnlock() {
|
||||
return hasNewUnlockFlag;
|
||||
}
|
||||
|
||||
// Сбросить флаг нового достижения
|
||||
public static void clearNewUnlock() {
|
||||
hasNewUnlockFlag = false;
|
||||
}
|
||||
|
||||
// Обновить таймер попапа
|
||||
public static void update(float deltaTime) {
|
||||
if (popupTimer > 0) {
|
||||
popupTimer -= deltaTime;
|
||||
if (popupTimer <= 0) {
|
||||
lastUnlocked = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Проверить, разблокировано ли достижение
|
||||
public static boolean isUnlocked(Achievement achievement) {
|
||||
return unlocked.contains(achievement);
|
||||
}
|
||||
|
||||
// Получить количество разблокированных достижений
|
||||
public static int getUnlockedCount() {
|
||||
return unlocked.size();
|
||||
}
|
||||
|
||||
// Получить общее количество достижений
|
||||
public static int getTotalCount() {
|
||||
return Achievement.values().length;
|
||||
}
|
||||
|
||||
// Получить последнее разблокированное достижение (для показа попапа)
|
||||
public static Achievement getLastUnlocked() {
|
||||
return lastUnlocked;
|
||||
}
|
||||
|
||||
// Показывается ли сейчас попап
|
||||
public static boolean isShowingPopup() {
|
||||
return popupTimer > 0 && lastUnlocked != null;
|
||||
}
|
||||
|
||||
// Получить прогресс попапа (0-1)
|
||||
public static float getPopupProgress() {
|
||||
return popupTimer / POPUP_DURATION;
|
||||
}
|
||||
|
||||
// Сериализация разблокированных достижений в строку
|
||||
public static String getUnlockedAsString() {
|
||||
if (unlocked.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Achievement a : unlocked) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(a.getId());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// Загрузка достижений из строки
|
||||
|
||||
public static void loadFromString(String data) {
|
||||
unlocked.clear();
|
||||
|
||||
if (data == null || data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] ids = data.split(",");
|
||||
for (String id : ids) {
|
||||
Achievement a = Achievement.fromId(id.trim());
|
||||
if (a != null) {
|
||||
unlocked.add(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Сбросить все достижения
|
||||
public static void reset() {
|
||||
unlocked.clear();
|
||||
lastUnlocked = null;
|
||||
popupTimer = 0;
|
||||
}
|
||||
|
||||
// Получить все разблокированные достижения
|
||||
public static Set<Achievement> getUnlocked() {
|
||||
return new HashSet<>(unlocked);
|
||||
}
|
||||
|
||||
// Получить все достижения
|
||||
public static Achievement[] getAll() {
|
||||
return Achievement.values();
|
||||
}
|
||||
}
|
||||
@@ -3,78 +3,10 @@ package com.mygdx.game;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
|
||||
public class AnswerChecker {
|
||||
private static final String[][] FUNNY_COMMENTS_BY_PLANET = {
|
||||
// Земля
|
||||
{
|
||||
"Вау! Такое здание видел только в мультиках!",
|
||||
"Архитектор сошел с ума от радости!",
|
||||
"Город стал похож на мультфильм!",
|
||||
"Это самое безумное здание в городе!",
|
||||
"Жители в восторге от этой абсурдности!",
|
||||
"Эй, это похоже на город из моих снов!",
|
||||
"Такое здание украсит любой мультфильм!"
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
"Отлично! Марсианская колония растёт! 🚀",
|
||||
"На Марсе теперь есть своё безумие!",
|
||||
"Эти здания переживут любую пылевую бурю!",
|
||||
"Марсиане будут в восторге! 👽",
|
||||
"Похоже, мы колонизируем Марс!",
|
||||
"Красная планета стала разноцветнее!",
|
||||
"Это здание выглядит инопланетно круто!"
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
"Горячо! Венерианский шедевр готов! 🔥",
|
||||
"Здание плавится от собственной красоты!",
|
||||
"Венера стала ещё ярче! 🌟",
|
||||
"Это здание сияет как сама Венера!",
|
||||
"Похоже, мы выживаем на Венере!",
|
||||
"Такая красота плавит сердце!",
|
||||
"Золотой век венерианской архитектуры!"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] WRONG_ANSWER_JOKES_BY_PLANET = {
|
||||
// Земля
|
||||
{
|
||||
"Твоя математика кривее моих зданий!",
|
||||
"Даже мультяшный архитектор считает лучше!",
|
||||
"Ты что, в мультиках учился математике?",
|
||||
"Ошибка! Попробуй посчитать на пальцах ног!",
|
||||
"Неправильно! Давай еще разочек, как в мультике!",
|
||||
"Бывает! Даже мультяшные гении ошибаются!",
|
||||
"Ой, кажется, ты перепутал с мультипликацией!",
|
||||
"Неверно! Но зато здание выглядит смешнее!"
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
"Неверно! Марсиане считают лучше! 👽",
|
||||
"Ошибка в расчётах! Пылевая буря съела цифры!",
|
||||
"Твоя математика не переживёт марсианскую зиму!",
|
||||
"Неудача! Даже марсоход считает точнее!",
|
||||
"Неправильно! Попробуй считать в скафандре!",
|
||||
"Ошибка! Кислородное голодание сказывается?",
|
||||
"Марсианские калькуляторы не одобряют!",
|
||||
"Неверно! Может, радиация помешала?"
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
"Горячая ошибка! 🔥 Попробуй ещё!",
|
||||
"Неверно! Даже венерианская жара не оправдывает!",
|
||||
"Ошибка! Кислотные облака затуманили разум?",
|
||||
"Неправильно! Слишком жарко для точных расчётов?",
|
||||
"Провал! Венерианские калькуляторы плавятся!",
|
||||
"Неудача! Давление в 90 атмосфер давит на мозги?",
|
||||
"Ошибка! Попробуй считать в теплозащитном костюме!",
|
||||
"Неверно! Золотое сечение не спасло!"
|
||||
}
|
||||
};
|
||||
|
||||
public static void checkAnswer(AbsurdCityBuilder1 game) {
|
||||
if (game.getCurrentBuilding() == null || game.getInputText().length() == 0) {
|
||||
game.setMessageText("Введите ответ!");
|
||||
game.setMessageText(Localization.isRu() ? "Введите ответ!" : "Enter an answer!");
|
||||
game.setMessageColor(Color.RED);
|
||||
return;
|
||||
}
|
||||
@@ -82,22 +14,32 @@ public class AnswerChecker {
|
||||
try {
|
||||
int userAnswer = Integer.parseInt(game.getInputText().toString());
|
||||
Planet currentPlanet = game.getCurrentPlanet();
|
||||
int planetIndex = currentPlanet.ordinal();
|
||||
|
||||
if (userAnswer == game.getCurrentProblem().getAnswer()) {
|
||||
// Правильный ответ
|
||||
game.getCurrentBuilding().addBlock();
|
||||
|
||||
String[] planetComments = FUNNY_COMMENTS_BY_PLANET[planetIndex];
|
||||
String successMessage = "Отлично! Блок построен!";
|
||||
// Увеличиваем счетчик серии правильных ответов
|
||||
GameSave.addCorrectAnswer();
|
||||
|
||||
String[] planetComments = Localization.getSuccessComments(currentPlanet);
|
||||
String successMessage = Localization.blockBuilt();
|
||||
|
||||
if (game.getCurrentBuilding().isComplete()) {
|
||||
successMessage = "Успех! " + planetComments[game.getRandom().nextInt(planetComments.length)];
|
||||
successMessage = Localization.buildingComplete() + " " +
|
||||
planetComments[game.getRandom().nextInt(planetComments.length)];
|
||||
game.getBuildings().add(game.getCurrentBuilding());
|
||||
|
||||
// Создаем жителей при завершении здания
|
||||
game.getCurrentBuilding().createCitizensForBuilding(game.getCitizens(), game.getRandom());
|
||||
|
||||
// Добавляем здание в статистику и сохраняем
|
||||
GameSave.addBuilding(currentPlanet);
|
||||
GameSave.saveSettings();
|
||||
|
||||
// Проверяем достижения
|
||||
Achievements.check(game);
|
||||
|
||||
// Проверяем разблокировку планет
|
||||
checkPlanetUnlock(game);
|
||||
|
||||
@@ -115,7 +57,10 @@ public class AnswerChecker {
|
||||
// Неправильный ответ
|
||||
game.getCurrentBuilding().removeBlock();
|
||||
|
||||
String[] planetJokes = WRONG_ANSWER_JOKES_BY_PLANET[planetIndex];
|
||||
// Сбрасываем счетчик серии
|
||||
GameSave.resetCorrectStreak();
|
||||
|
||||
String[] planetJokes = Localization.getWrongAnswerJokes(currentPlanet);
|
||||
String joke = planetJokes[game.getRandom().nextInt(planetJokes.length)];
|
||||
game.setWrongAnswerJoke(joke);
|
||||
game.setShowWrongAnswerJoke(true);
|
||||
@@ -129,12 +74,12 @@ public class AnswerChecker {
|
||||
|
||||
String message;
|
||||
if (game.getCurrentBuilding().constructionProgress == 0) {
|
||||
message = "Здание разрушено до основания! " + joke;
|
||||
message = (Localization.isRu() ? "Здание разрушено до основания! " : "Building destroyed! ") + joke;
|
||||
game.setCurrentBuilding(null);
|
||||
game.setCurrentProblem(null);
|
||||
game.setTyping(false);
|
||||
} else {
|
||||
message = "Неверно! Блок разрушен! " + joke;
|
||||
message = Localization.wrongAnswer() + " " + joke;
|
||||
game.setCurrentProblem(MathProblem.generateProblem(game.getBuildings().size, game.getRandom()));
|
||||
}
|
||||
|
||||
@@ -147,21 +92,7 @@ public class AnswerChecker {
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
// Обработка некорректного ввода
|
||||
Planet currentPlanet = game.getCurrentPlanet();
|
||||
String errorMessage;
|
||||
|
||||
switch (currentPlanet) {
|
||||
case MARS:
|
||||
errorMessage = "Марсиане не понимают такие цифры! Введите целое число!";
|
||||
break;
|
||||
case VENUS:
|
||||
errorMessage = "Слишком жарко для таких символов! Введите целое число!";
|
||||
break;
|
||||
default:
|
||||
errorMessage = "Введите целое число!";
|
||||
}
|
||||
|
||||
game.setMessageText(errorMessage);
|
||||
game.setMessageText(Localization.enterNumber());
|
||||
game.setMessageColor(Color.RED);
|
||||
game.getInputText().setLength(0);
|
||||
}
|
||||
@@ -173,19 +104,22 @@ public class AnswerChecker {
|
||||
|
||||
// Проверяем условия для разблокировки Марса
|
||||
if (currentPlanet == Planet.EARTH && buildingsCount >= 3) {
|
||||
// Марс уже разблокирован по умолчанию в нашей реализации
|
||||
// Но можно добавить специальное сообщение
|
||||
if (buildingsCount == 3) {
|
||||
game.setMessageText(game.getMessageText() + " 🚀 Марс доступен! Нажмите ↑ для полёта!");
|
||||
String extra = Localization.isRu()
|
||||
? " 🚀 Марс доступен! Нажмите ↑ для полёта!"
|
||||
: " 🚀 Mars unlocked! Press ↑ to fly!";
|
||||
game.setMessageText(game.getMessageText() + extra);
|
||||
game.setMessageColor(Color.CYAN);
|
||||
}
|
||||
}
|
||||
|
||||
// Проверяем условия для разблокировки Венеры
|
||||
if (currentPlanet == Planet.MARS && buildingsCount >= 6) {
|
||||
// Венера уже разблокирована
|
||||
if (buildingsCount == 6) {
|
||||
game.setMessageText(game.getMessageText() + " 🔥 Венера доступна! Нажмите ↑ для полёта!");
|
||||
String extra = Localization.isRu()
|
||||
? " 🔥 Венера доступна! Нажмите ↑ для полёта!"
|
||||
: " 🔥 Venus unlocked! Press ↑ to fly!";
|
||||
game.setMessageText(game.getMessageText() + extra);
|
||||
game.setMessageColor(Color.ORANGE);
|
||||
}
|
||||
}
|
||||
@@ -198,52 +132,95 @@ public class AnswerChecker {
|
||||
}
|
||||
|
||||
private static String getBonusMessage(Planet planet, int buildingsCount) {
|
||||
switch (planet) {
|
||||
case EARTH:
|
||||
return "🎉 Вы построили " + buildingsCount + " зданий на Земле!";
|
||||
case MARS:
|
||||
return "👽 Марсианская колония из " + buildingsCount + " зданий!";
|
||||
case VENUS:
|
||||
return "🌟 Венерианский мегаполис из " + buildingsCount + " зданий!";
|
||||
default:
|
||||
return "🏆 Достижение: " + buildingsCount + " зданий!";
|
||||
if (Localization.isRu()) {
|
||||
switch (planet) {
|
||||
case EARTH:
|
||||
return "🎉 Вы построили " + buildingsCount + " зданий на Земле!";
|
||||
case MARS:
|
||||
return "👽 Марсианская колония из " + buildingsCount + " зданий!";
|
||||
case VENUS:
|
||||
return "🌟 Венерианский мегаполис из " + buildingsCount + " зданий!";
|
||||
default:
|
||||
return "🏆 Достижение: " + buildingsCount + " зданий!";
|
||||
}
|
||||
} else {
|
||||
switch (planet) {
|
||||
case EARTH:
|
||||
return "🎉 You built " + buildingsCount + " buildings on Earth!";
|
||||
case MARS:
|
||||
return "👽 Martian colony of " + buildingsCount + " buildings!";
|
||||
case VENUS:
|
||||
return "🌟 Venusian metropolis of " + buildingsCount + " buildings!";
|
||||
default:
|
||||
return "🏆 Achievement: " + buildingsCount + " buildings!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Метод для получения подсказки (опционально)
|
||||
// Метод для получения подсказки
|
||||
public static String getHint(MathProblem problem, Planet planet) {
|
||||
int answer = problem.getAnswer();
|
||||
String question = problem.getQuestion();
|
||||
|
||||
switch (planet) {
|
||||
case MARS:
|
||||
if (question.contains("+")) {
|
||||
return "Подсказка: складывай как марсиане - от красного к красному!";
|
||||
} else if (question.contains("-")) {
|
||||
return "Подсказка: вычитай как улетающую ракету!";
|
||||
} else if (question.contains("×")) {
|
||||
return "Подсказка: умножай на количество марсоходов!";
|
||||
}
|
||||
break;
|
||||
case VENUS:
|
||||
if (question.contains("+")) {
|
||||
return "Подсказка: складывай жар как на Венере!";
|
||||
} else if (question.contains("-")) {
|
||||
return "Подсказка: вычитай облака кислоты!";
|
||||
} else if (question.contains("×")) {
|
||||
return "Подсказка: умножай как давление на Венере!";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (question.contains("+")) {
|
||||
return "Подсказка: представь, что складываешь мультяшных зверюшек!";
|
||||
} else if (question.contains("-")) {
|
||||
return "Подсказка: убери лишние мультяшные детали!";
|
||||
} else if (question.contains("×")) {
|
||||
return "Подсказка: умножай как в мультике - всё становится больше!";
|
||||
}
|
||||
if (Localization.isRu()) {
|
||||
switch (planet) {
|
||||
case MARS:
|
||||
if (question.contains("+")) {
|
||||
return "Подсказка: складывай как марсиане - от красного к красному!";
|
||||
} else if (question.contains("-")) {
|
||||
return "Подсказка: вычитай как улетающую ракету!";
|
||||
} else if (question.contains("×")) {
|
||||
return "Подсказка: умножай на количество марсоходов!";
|
||||
}
|
||||
break;
|
||||
case VENUS:
|
||||
if (question.contains("+")) {
|
||||
return "Подсказка: складывай жар как на Венере!";
|
||||
} else if (question.contains("-")) {
|
||||
return "Подсказка: вычитай облака кислоты!";
|
||||
} else if (question.contains("×")) {
|
||||
return "Подсказка: умножай как давление на Венере!";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (question.contains("+")) {
|
||||
return "Подсказка: представь, что складываешь мультяшных зверюшек!";
|
||||
} else if (question.contains("-")) {
|
||||
return "Подсказка: убери лишние мультяшные детали!";
|
||||
} else if (question.contains("×")) {
|
||||
return "Подсказка: умножай как в мультике - всё становится больше!";
|
||||
}
|
||||
}
|
||||
return "Подсказка: внимательно посчитай!";
|
||||
} else {
|
||||
switch (planet) {
|
||||
case MARS:
|
||||
if (question.contains("+")) {
|
||||
return "Hint: add like Martians - from red to red!";
|
||||
} else if (question.contains("-")) {
|
||||
return "Hint: subtract like a flying rocket!";
|
||||
} else if (question.contains("×")) {
|
||||
return "Hint: multiply by the number of rovers!";
|
||||
}
|
||||
break;
|
||||
case VENUS:
|
||||
if (question.contains("+")) {
|
||||
return "Hint: add heat like on Venus!";
|
||||
} else if (question.contains("-")) {
|
||||
return "Hint: subtract acid clouds!";
|
||||
} else if (question.contains("×")) {
|
||||
return "Hint: multiply like Venus pressure!";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (question.contains("+")) {
|
||||
return "Hint: imagine adding cartoon creatures!";
|
||||
} else if (question.contains("-")) {
|
||||
return "Hint: remove extra cartoon details!";
|
||||
} else if (question.contains("×")) {
|
||||
return "Hint: multiply like in cartoons - everything gets bigger!";
|
||||
}
|
||||
}
|
||||
return "Hint: calculate carefully!";
|
||||
}
|
||||
|
||||
return "Подсказка: внимательно посчитай!";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,302 +6,13 @@ import com.badlogic.gdx.utils.Array;
|
||||
import java.util.Random;
|
||||
|
||||
public class Building {
|
||||
// Названия зданий по планетам
|
||||
public static final String[][] BUILDING_TYPES_BY_PLANET = {
|
||||
// Земля (существующие здания)
|
||||
{
|
||||
"✨ Уютный Домик ✨",
|
||||
"🏥 Детская Больница 🏥",
|
||||
"🎒 Весёлая Школа 🎒",
|
||||
"🎪 Игровая Площадка 🎪",
|
||||
"💰 Надёжный Банк 💰",
|
||||
"💊 Здоровая Аптека 💊",
|
||||
"🎭 Волшебный Театр 🎭",
|
||||
"🎬 КиноМир 🎬"
|
||||
},
|
||||
// Марс (красные, технологичные)
|
||||
{
|
||||
"🚀 Марсианская База 🚀",
|
||||
"🔴 Красная Лаборатория 🔴",
|
||||
"🛰️ Космопорт 🛰️",
|
||||
"⚡ Энергокупол ⚡",
|
||||
"💧 Водородный Завод 💧",
|
||||
"🌌 Обсерватория 🌌",
|
||||
"🤖 Робо-Фабрика 🤖",
|
||||
"🧪 Биокупол 🧪"
|
||||
},
|
||||
// Венера (желтые, вулканические)
|
||||
{
|
||||
"🌋 Вулканический Дом 🌋",
|
||||
"🔥 Термальная Станция 🔥",
|
||||
"🌅 Золотой Дворец 🌅",
|
||||
"☁️ Облачный Город ☁️",
|
||||
"💎 Кристальная Шахта 💎",
|
||||
"🌡️ Теплица 🌡️",
|
||||
"🌀 Вихревой Генератор 🌀",
|
||||
"✨ Сияющая Башня ✨"
|
||||
}
|
||||
};
|
||||
|
||||
// Яркие цвета для разных планет
|
||||
public static final Color[][][] BUILDING_COLOR_THEMES_BY_PLANET = {
|
||||
// 0. Земля - тёплые цвета
|
||||
{
|
||||
// Дома - тёплые цвета
|
||||
{
|
||||
new Color(1.0f, 0.85f, 0.7f, 1), // Персиковый
|
||||
new Color(0.95f, 0.9f, 0.75f, 1), // Светло-бежевый
|
||||
new Color(0.9f, 0.8f, 0.85f, 1) // Розоватый
|
||||
},
|
||||
// Больницы - чистые светлые цвета
|
||||
{
|
||||
new Color(1.0f, 1.0f, 1.0f, 1), // Белоснежный
|
||||
new Color(0.98f, 0.98f, 1.0f, 1), // Голубоватый
|
||||
new Color(0.96f, 1.0f, 0.98f, 1) // Мятный
|
||||
},
|
||||
// Школы - яркие весёлые цвета
|
||||
{
|
||||
new Color(1.0f, 0.95f, 0.8f, 1), // Лимонный
|
||||
new Color(0.85f, 0.95f, 1.0f, 1), // Небесно-голубой
|
||||
new Color(0.95f, 0.85f, 1.0f, 1) // Лавандовый
|
||||
},
|
||||
// Игровые площадки - яркие игровые цвета
|
||||
{
|
||||
new Color(1.0f, 0.9f, 0.8f, 1), // Абрикосовый
|
||||
new Color(0.9f, 1.0f, 0.9f, 1), // Салатовый
|
||||
new Color(0.9f, 0.9f, 1.0f, 1) // Сиреневый
|
||||
},
|
||||
// Банки - солидные цвета
|
||||
{
|
||||
new Color(0.95f, 0.95f, 0.9f, 1), // Слоновая кость
|
||||
new Color(0.9f, 0.92f, 0.85f, 1), // Бежевый
|
||||
new Color(0.85f, 0.89f, 0.8f, 1) // Оливковый
|
||||
},
|
||||
// Аптеки - медицинские цвета
|
||||
{
|
||||
new Color(1.0f, 1.0f, 1.0f, 1), // Белый
|
||||
new Color(0.98f, 1.0f, 0.98f, 1), // Светло-зелёный
|
||||
new Color(0.96f, 0.98f, 1.0f, 1) // Светло-голубой
|
||||
},
|
||||
// Театры - благородные цвета
|
||||
{
|
||||
new Color(0.95f, 0.9f, 0.95f, 1), // Сиреневый
|
||||
new Color(0.9f, 0.95f, 1.0f, 1), // Лазурный
|
||||
new Color(1.0f, 0.95f, 0.9f, 1) // Кремовый
|
||||
},
|
||||
// Кинотеатры - тёмные с неоном
|
||||
{
|
||||
new Color(0.2f, 0.2f, 0.3f, 1), // Тёмно-синий
|
||||
new Color(0.3f, 0.2f, 0.4f, 1), // Фиолетовый
|
||||
new Color(0.4f, 0.3f, 0.5f, 1) // Пурпурный
|
||||
}
|
||||
},
|
||||
// 1. Марс - красные, оранжевые, коричневые
|
||||
{
|
||||
// Марсианская База
|
||||
{
|
||||
new Color(0.8f, 0.3f, 0.2f, 1), // Красный марсианский
|
||||
new Color(0.9f, 0.5f, 0.3f, 1), // Оранжевый
|
||||
new Color(0.7f, 0.4f, 0.3f, 1) // Коричневый
|
||||
},
|
||||
// Красная Лаборатория
|
||||
{
|
||||
new Color(0.9f, 0.4f, 0.4f, 1),
|
||||
new Color(1.0f, 0.6f, 0.5f, 1),
|
||||
new Color(0.8f, 0.5f, 0.5f, 1)
|
||||
},
|
||||
// Космопорт
|
||||
{
|
||||
new Color(0.7f, 0.5f, 0.4f, 1),
|
||||
new Color(0.8f, 0.6f, 0.5f, 1),
|
||||
new Color(0.6f, 0.4f, 0.3f, 1)
|
||||
},
|
||||
// Энергокупол
|
||||
{
|
||||
new Color(0.9f, 0.6f, 0.3f, 1),
|
||||
new Color(1.0f, 0.7f, 0.4f, 1),
|
||||
new Color(0.8f, 0.5f, 0.2f, 1)
|
||||
},
|
||||
// Водородный Завод
|
||||
{
|
||||
new Color(0.6f, 0.7f, 0.8f, 1),
|
||||
new Color(0.7f, 0.8f, 0.9f, 1),
|
||||
new Color(0.5f, 0.6f, 0.7f, 1)
|
||||
},
|
||||
// Обсерватория
|
||||
{
|
||||
new Color(0.3f, 0.4f, 0.6f, 1),
|
||||
new Color(0.4f, 0.5f, 0.7f, 1),
|
||||
new Color(0.2f, 0.3f, 0.5f, 1)
|
||||
},
|
||||
// Робо-Фабрика
|
||||
{
|
||||
new Color(0.5f, 0.5f, 0.5f, 1),
|
||||
new Color(0.6f, 0.6f, 0.6f, 1),
|
||||
new Color(0.4f, 0.4f, 0.4f, 1)
|
||||
},
|
||||
// Биокупол
|
||||
{
|
||||
new Color(0.4f, 0.7f, 0.4f, 1),
|
||||
new Color(0.5f, 0.8f, 0.5f, 1),
|
||||
new Color(0.3f, 0.6f, 0.3f, 1)
|
||||
}
|
||||
},
|
||||
// 2. Венера - желтые, золотые, оранжевые
|
||||
{
|
||||
// Вулканический Дом
|
||||
{
|
||||
new Color(1.0f, 0.7f, 0.3f, 1), // Золотистый
|
||||
new Color(1.0f, 0.8f, 0.4f, 1), // Желтый
|
||||
new Color(0.9f, 0.6f, 0.2f, 1) // Оранжевый
|
||||
},
|
||||
// Термальная Станция
|
||||
{
|
||||
new Color(1.0f, 0.6f, 0.2f, 1),
|
||||
new Color(1.0f, 0.7f, 0.3f, 1),
|
||||
new Color(0.9f, 0.5f, 0.1f, 1)
|
||||
},
|
||||
// Золотой Дворец
|
||||
{
|
||||
new Color(1.0f, 0.9f, 0.3f, 1),
|
||||
new Color(1.0f, 1.0f, 0.5f, 1),
|
||||
new Color(0.9f, 0.8f, 0.2f, 1)
|
||||
},
|
||||
// Облачный Город
|
||||
{
|
||||
new Color(1.0f, 0.95f, 0.8f, 1),
|
||||
new Color(1.0f, 1.0f, 0.9f, 1),
|
||||
new Color(0.95f, 0.9f, 0.7f, 1)
|
||||
},
|
||||
// Кристальная Шахта
|
||||
{
|
||||
new Color(0.8f, 0.9f, 1.0f, 1),
|
||||
new Color(0.9f, 1.0f, 1.0f, 1),
|
||||
new Color(0.7f, 0.8f, 0.9f, 1)
|
||||
},
|
||||
// Теплица
|
||||
{
|
||||
new Color(0.7f, 0.9f, 0.6f, 1),
|
||||
new Color(0.8f, 1.0f, 0.7f, 1),
|
||||
new Color(0.6f, 0.8f, 0.5f, 1)
|
||||
},
|
||||
// Вихревой Генератор
|
||||
{
|
||||
new Color(0.9f, 0.8f, 0.5f, 1),
|
||||
new Color(1.0f, 0.9f, 0.6f, 1),
|
||||
new Color(0.8f, 0.7f, 0.4f, 1)
|
||||
},
|
||||
// Сияющая Башня
|
||||
{
|
||||
new Color(1.0f, 0.95f, 0.7f, 1),
|
||||
new Color(1.0f, 1.0f, 0.8f, 1),
|
||||
new Color(0.95f, 0.9f, 0.6f, 1)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Крыши в мультяшных цветах по планетам
|
||||
public static final Color[][][] ROOF_COLORS_BY_PLANET = {
|
||||
// Земля
|
||||
{
|
||||
{ new Color(0.9f, 0.3f, 0.2f, 1), new Color(0.7f, 0.4f, 0.2f, 1) }, // Дома
|
||||
{ new Color(1.0f, 0.8f, 0.8f, 1), new Color(0.9f, 0.7f, 0.7f, 1) }, // Больницы
|
||||
{ new Color(0.4f, 0.7f, 1.0f, 1), new Color(0.3f, 0.6f, 0.9f, 1) }, // Школы
|
||||
{ new Color(1.0f, 0.8f, 0.4f, 1), new Color(0.9f, 0.5f, 0.9f, 1) }, // Площадки
|
||||
{ new Color(1.0f, 0.9f, 0.3f, 1), new Color(0.9f, 0.8f, 0.2f, 1) }, // Банки
|
||||
{ new Color(0.4f, 0.9f, 0.5f, 1), new Color(0.3f, 0.8f, 0.4f, 1) }, // Аптеки
|
||||
{ new Color(0.8f, 0.4f, 1.0f, 1), new Color(0.7f, 0.3f, 0.9f, 1) }, // Театры
|
||||
{ new Color(0.3f, 0.3f, 0.4f, 1), new Color(0.4f, 0.3f, 0.5f, 1) } // Кинотеатры
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
{ new Color(0.7f, 0.2f, 0.1f, 1), new Color(0.6f, 0.1f, 0.0f, 1) }, // Марсианская База
|
||||
{ new Color(0.8f, 0.3f, 0.2f, 1), new Color(0.7f, 0.2f, 0.1f, 1) }, // Красная Лаборатория
|
||||
{ new Color(0.5f, 0.4f, 0.3f, 1), new Color(0.4f, 0.3f, 0.2f, 1) }, // Космопорт
|
||||
{ new Color(0.8f, 0.5f, 0.2f, 1), new Color(0.7f, 0.4f, 0.1f, 1) }, // Энергокупол
|
||||
{ new Color(0.4f, 0.5f, 0.7f, 1), new Color(0.3f, 0.4f, 0.6f, 1) }, // Водородный Завод
|
||||
{ new Color(0.2f, 0.3f, 0.5f, 1), new Color(0.1f, 0.2f, 0.4f, 1) }, // Обсерватория
|
||||
{ new Color(0.4f, 0.4f, 0.4f, 1), new Color(0.3f, 0.3f, 0.3f, 1) }, // Робо-Фабрика
|
||||
{ new Color(0.3f, 0.6f, 0.3f, 1), new Color(0.2f, 0.5f, 0.2f, 1) } // Биокупол
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
{ new Color(0.8f, 0.4f, 0.1f, 1), new Color(0.7f, 0.3f, 0.0f, 1) }, // Вулканический Дом
|
||||
{ new Color(0.9f, 0.5f, 0.1f, 1), new Color(0.8f, 0.4f, 0.0f, 1) }, // Термальная Станция
|
||||
{ new Color(1.0f, 0.8f, 0.1f, 1), new Color(0.9f, 0.7f, 0.0f, 1) }, // Золотой Дворец
|
||||
{ new Color(1.0f, 1.0f, 0.8f, 1), new Color(0.9f, 0.9f, 0.7f, 1) }, // Облачный Город
|
||||
{ new Color(0.7f, 0.8f, 0.9f, 1), new Color(0.6f, 0.7f, 0.8f, 1) }, // Кристальная Шахта
|
||||
{ new Color(0.6f, 0.8f, 0.5f, 1), new Color(0.5f, 0.7f, 0.4f, 1) }, // Теплица
|
||||
{ new Color(0.8f, 0.7f, 0.4f, 1), new Color(0.7f, 0.6f, 0.3f, 1) }, // Вихревой Генератор
|
||||
{ new Color(0.95f, 0.9f, 0.6f, 1), new Color(0.85f, 0.8f, 0.5f, 1) } // Сияющая Башня
|
||||
}
|
||||
};
|
||||
|
||||
// Коэффициенты масштабирования для разных планет
|
||||
public static final float[][] SIZE_SCALE_FACTORS_BY_PLANET = {
|
||||
// Земля
|
||||
{1.0f, 0.75f, 0.8f, 0.85f, 0.7f, 0.65f, 0.8f, 0.85f},
|
||||
// Марс (компактнее)
|
||||
{0.9f, 0.7f, 0.8f, 0.75f, 0.65f, 0.6f, 0.7f, 0.75f},
|
||||
// Венера (выше)
|
||||
{1.1f, 1.0f, 1.05f, 1.0f, 0.9f, 0.85f, 1.0f, 1.05f}
|
||||
};
|
||||
|
||||
// Цвета для деталей по планетам
|
||||
public static final Color[][] DETAIL_COLORS_BY_PLANET = {
|
||||
// Земля
|
||||
{
|
||||
new Color(1.0f, 0.9f, 0.2f, 1), // Золотой
|
||||
new Color(1.0f, 0.5f, 0.5f, 1), // Коралловый
|
||||
new Color(0.5f, 0.8f, 1.0f, 1), // Голубой
|
||||
new Color(0.8f, 1.0f, 0.5f, 1), // Лаймовый
|
||||
new Color(1.0f, 0.7f, 1.0f, 1) // Розовый
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
new Color(1.0f, 0.6f, 0.2f, 1), // Оранжевый
|
||||
new Color(0.8f, 0.3f, 0.2f, 1), // Красный
|
||||
new Color(0.9f, 0.8f, 0.4f, 1), // Песочный
|
||||
new Color(0.7f, 0.8f, 0.9f, 1), // Стальной
|
||||
new Color(0.4f, 0.7f, 0.4f, 1) // Зеленый марсианский
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
new Color(1.0f, 0.9f, 0.3f, 1), // Золотой
|
||||
new Color(1.0f, 0.7f, 0.2f, 1), // Янтарный
|
||||
new Color(1.0f, 1.0f, 0.8f, 1), // Светло-желтый
|
||||
new Color(0.9f, 0.6f, 0.1f, 1), // Темно-оранжевый
|
||||
new Color(0.8f, 0.9f, 1.0f, 1) // Кристальный
|
||||
}
|
||||
};
|
||||
|
||||
// Цвета для названий по планетам
|
||||
public static final Color[][] GLOWING_NAME_COLORS_BY_PLANET = {
|
||||
// Земля
|
||||
{
|
||||
new Color(0.3f, 0.7f, 1.0f, 1), // Ярко-синий
|
||||
new Color(1.0f, 0.4f, 0.4f, 1), // Ярко-красный
|
||||
new Color(0.3f, 0.9f, 0.3f, 1), // Ярко-зелёный
|
||||
new Color(1.0f, 0.7f, 0.2f, 1), // Оранжевый
|
||||
new Color(0.8f, 0.4f, 1.0f, 1) // Фиолетовый
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
new Color(1.0f, 0.5f, 0.3f, 1), // Оранжево-красный
|
||||
new Color(0.8f, 0.3f, 0.2f, 1), // Марсианский красный
|
||||
new Color(0.9f, 0.7f, 0.4f, 1), // Песочный
|
||||
new Color(0.6f, 0.8f, 0.9f, 1), // Голубой стальной
|
||||
new Color(0.4f, 0.6f, 0.3f, 1) // Оливковый
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
new Color(1.0f, 0.9f, 0.3f, 1), // Золотой
|
||||
new Color(1.0f, 0.7f, 0.2f, 1), // Янтарный
|
||||
new Color(1.0f, 1.0f, 0.6f, 1), // Ярко-желтый
|
||||
new Color(0.9f, 0.5f, 0.1f, 1), // Теплый оранжевый
|
||||
new Color(1.0f, 0.95f, 0.8f, 1) // Светло-золотой
|
||||
}
|
||||
};
|
||||
// Ссылки на данные из GameConfig для обратной совместимости
|
||||
public static final String[][] BUILDING_TYPES_BY_PLANET = GameConfig.BUILDING_TYPES_BY_PLANET;
|
||||
public static final Color[][][] BUILDING_COLOR_THEMES_BY_PLANET = GameConfig.BUILDING_COLOR_THEMES_BY_PLANET;
|
||||
public static final Color[][][] ROOF_COLORS_BY_PLANET = GameConfig.ROOF_COLORS_BY_PLANET;
|
||||
public static final float[][] SIZE_SCALE_FACTORS_BY_PLANET = GameConfig.SIZE_SCALE_FACTORS_BY_PLANET;
|
||||
public static final Color[][] DETAIL_COLORS_BY_PLANET = GameConfig.DETAIL_COLORS_BY_PLANET;
|
||||
public static final Color[][] GLOWING_NAME_COLORS_BY_PLANET = GameConfig.GLOWING_NAME_COLORS_BY_PLANET;
|
||||
|
||||
String type;
|
||||
float x;
|
||||
|
||||
@@ -73,8 +73,8 @@ public class BuildingPlacer {
|
||||
game.updateUI();
|
||||
|
||||
game.setMessageText(tempBuilding.isOverlapping ?
|
||||
"🎨 Здание пересекается с существующими! Это добавляет уникальности! 🎨" :
|
||||
"🌟 Отличное место для строительства! Введите ответ: 🌟");
|
||||
Localization.buildingOverlaps() :
|
||||
Localization.greatPlace());
|
||||
game.setMessageColor(tempBuilding.isOverlapping ? com.badlogic.gdx.graphics.Color.ORANGE : com.badlogic.gdx.graphics.Color.GREEN);
|
||||
|
||||
game.setTyping(true);
|
||||
@@ -85,7 +85,7 @@ public class BuildingPlacer {
|
||||
if (game.getCurrentBuilding() != null) {
|
||||
Rectangle buildingBounds = game.getCurrentBuilding().getBounds();
|
||||
if (buildingBounds.contains(worldX, worldY)) {
|
||||
game.setMessageText("🎯 Кликните вне здания для нового строительства. Ctrl+Z или Delete для удаления. 🎯");
|
||||
game.setMessageText(Localization.clickOutside());
|
||||
game.setMessageColor(com.badlogic.gdx.graphics.Color.CYAN);
|
||||
} else {
|
||||
if (!game.isTyping()) {
|
||||
|
||||
@@ -1226,7 +1226,8 @@ public class BuildingRenderer {
|
||||
font.setColor(pulseColor);
|
||||
font.getData().setScale(1.1f * building.getSizeScale());
|
||||
|
||||
glyphLayout.setText(font, building.type);
|
||||
String localizedName = Localization.getBuildingName(building);
|
||||
glyphLayout.setText(font, localizedName);
|
||||
float textWidth = glyphLayout.width;
|
||||
|
||||
// Фон с закругленными краями
|
||||
@@ -1241,7 +1242,7 @@ public class BuildingRenderer {
|
||||
batch.draw(whitePixel, x - textWidth/2 - 15, y + 10, textWidth + 30, 5); // Низ
|
||||
|
||||
batch.setColor(Color.WHITE);
|
||||
font.draw(batch, building.type, x - textWidth/2, y);
|
||||
font.draw(batch, localizedName, x - textWidth/2, y);
|
||||
font.getData().setScale(1.0f);
|
||||
}
|
||||
|
||||
@@ -1252,9 +1253,8 @@ public class BuildingRenderer {
|
||||
font.setColor(Color.YELLOW);
|
||||
font.getData().setScale(0.9f * building.getSizeScale());
|
||||
|
||||
String cleanType = building.type.replace("✨", "").replace("🏥", "").replace("🎒", "")
|
||||
.replace("🎪", "").replace("💰", "").replace("💊", "")
|
||||
.replace("🎭", "").replace("🎬", "").trim();
|
||||
String localizedName = Localization.getBuildingName(building);
|
||||
String cleanType = localizedName.replaceAll("[✨🏥🎒🎪💰💊🎭🎬🚀🔴🛰️⚡💧🌌🤖🧪🌋🔥🌅☁️💎🌡️🌀]", "").trim();
|
||||
String progressText = cleanType + " (" + building.constructionProgress + "/3)";
|
||||
glyphLayout.setText(font, progressText);
|
||||
float textWidth = glyphLayout.width;
|
||||
@@ -1274,10 +1274,9 @@ public class BuildingRenderer {
|
||||
font.setColor(Color.YELLOW);
|
||||
font.getData().setScale(1.0f * building.getSizeScale());
|
||||
|
||||
String cleanType = building.type.replace("✨", "").replace("🏥", "").replace("🎒", "")
|
||||
.replace("🎪", "").replace("💰", "").replace("💊", "")
|
||||
.replace("🎭", "").replace("🎬", "").trim();
|
||||
String prefix = building.constructionProgress == 0 ? "Место для: " : "Строится: ";
|
||||
String localizedName = Localization.getBuildingName(building);
|
||||
String cleanType = localizedName.replaceAll("[✨🏥🎒🎪💰💊🎭🎬🚀🔴🛰️⚡💧🌌🤖🧪🌋🔥🌅☁️💎🌡️🌀]", "").trim();
|
||||
String prefix = building.constructionProgress == 0 ? Localization.placeFor() : Localization.constructing();
|
||||
String progressText = prefix + cleanType + " (" + building.constructionProgress + "/3)";
|
||||
glyphLayout.setText(font, progressText);
|
||||
float textWidth = glyphLayout.width;
|
||||
@@ -1291,7 +1290,7 @@ public class BuildingRenderer {
|
||||
if (building.isOverlapping) {
|
||||
font.setColor(Color.RED);
|
||||
font.getData().setScale(0.8f * building.getSizeScale());
|
||||
String warning = "⚠ Пересечение! ⚠";
|
||||
String warning = Localization.overlapWarning();
|
||||
glyphLayout.setText(font, warning);
|
||||
font.draw(batch, warning, x - glyphLayout.width/2, y - 25);
|
||||
font.getData().setScale(1.0f);
|
||||
|
||||
250
core/src/main/java/com/mygdx/game/GameConfig.java
Normal file
250
core/src/main/java/com/mygdx/game/GameConfig.java
Normal file
@@ -0,0 +1,250 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
|
||||
// Конфигурация игры - все цвета, константы и настройки в одном месте.
|
||||
public class GameConfig {
|
||||
|
||||
// ==================== РАЗМЕРЫ ЭКРАНА ====================
|
||||
public static final int WIDTH = 1700;
|
||||
public static final int HEIGHT = 950;
|
||||
public static final int UI_INPUT_HEIGHT = 210;
|
||||
|
||||
// ==================== ЦВЕТА UI ====================
|
||||
public static final Color UI_PANEL_BG = new Color(0.2f, 0.3f, 0.4f, 0.95f);
|
||||
public static final Color UI_PANEL_BORDER = new Color(0.4f, 0.6f, 0.8f, 1f);
|
||||
public static final Color UI_INPUT_BG = new Color(0.3f, 0.4f, 0.5f, 0.8f);
|
||||
public static final Color UI_WRONG_ANSWER_BG = new Color(1f, 0.2f, 0.2f, 0.3f);
|
||||
|
||||
// ==================== ЦВЕТА МЕНЮ ====================
|
||||
public static final Color MENU_SPACE_BG = new Color(0.05f, 0.05f, 0.1f, 1f);
|
||||
public static final Color MENU_BUTTON_BORDER = new Color(1f, 1f, 1f, 0.3f);
|
||||
public static final Color MENU_BUTTON_HOVER = new Color(1f, 1f, 1f, 0.1f);
|
||||
|
||||
// Цвета кнопок главного меню
|
||||
public static final Color BUTTON_NEW_GAME = new Color(0.2f, 0.5f, 0.8f, 0.9f);
|
||||
public static final Color BUTTON_NEW_GAME_HOVER = new Color(0.3f, 0.6f, 0.9f, 1f);
|
||||
public static final Color BUTTON_PLANET = new Color(0.8f, 0.4f, 0.2f, 0.9f);
|
||||
public static final Color BUTTON_PLANET_HOVER = new Color(0.9f, 0.5f, 0.3f, 1f);
|
||||
public static final Color BUTTON_HELP = new Color(0.2f, 0.7f, 0.3f, 0.9f);
|
||||
public static final Color BUTTON_HELP_HOVER = new Color(0.3f, 0.8f, 0.4f, 1f);
|
||||
public static final Color BUTTON_ABOUT = new Color(0.7f, 0.2f, 0.7f, 0.9f);
|
||||
public static final Color BUTTON_ABOUT_HOVER = new Color(0.8f, 0.3f, 0.8f, 1f);
|
||||
public static final Color BUTTON_EXIT = new Color(0.8f, 0.2f, 0.2f, 0.9f);
|
||||
public static final Color BUTTON_EXIT_HOVER = new Color(0.9f, 0.3f, 0.3f, 1f);
|
||||
public static final Color BUTTON_BACK = new Color(0.4f, 0.4f, 0.4f, 0.9f);
|
||||
public static final Color BUTTON_BACK_HOVER = new Color(0.5f, 0.5f, 0.5f, 1f);
|
||||
|
||||
// Цвета кнопок планет
|
||||
public static final Color BUTTON_EARTH = new Color(0.3f, 0.6f, 0.9f, 0.9f);
|
||||
public static final Color BUTTON_EARTH_HOVER = new Color(0.4f, 0.7f, 1.0f, 1f);
|
||||
public static final Color BUTTON_MARS = new Color(0.8f, 0.3f, 0.2f, 0.9f);
|
||||
public static final Color BUTTON_MARS_HOVER = new Color(0.9f, 0.4f, 0.3f, 1f);
|
||||
public static final Color BUTTON_VENUS = new Color(1.0f, 0.7f, 0.2f, 0.9f);
|
||||
public static final Color BUTTON_VENUS_HOVER = new Color(1.0f, 0.8f, 0.3f, 1f);
|
||||
|
||||
// ==================== НАЗВАНИЯ ЗДАНИЙ ПО ПЛАНЕТАМ ====================
|
||||
public static final String[][] BUILDING_TYPES_BY_PLANET = {
|
||||
// Земля
|
||||
{
|
||||
"✨ Уютный Домик ✨",
|
||||
"🏥 Детская Больница 🏥",
|
||||
"🎒 Весёлая Школа 🎒",
|
||||
"🎪 Игровая Площадка 🎪",
|
||||
"💰 Надёжный Банк 💰",
|
||||
"💊 Здоровая Аптека 💊",
|
||||
"🎭 Волшебный Театр 🎭",
|
||||
"🎬 КиноМир 🎬"
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
"🚀 Марсианская База 🚀",
|
||||
"🔴 Красная Лаборатория 🔴",
|
||||
"🛰️ Космопорт 🛰️",
|
||||
"⚡ Энергокупол ⚡",
|
||||
"💧 Водородный Завод 💧",
|
||||
"🌌 Обсерватория 🌌",
|
||||
"🤖 Робо-Фабрика 🤖",
|
||||
"🧪 Биокупол 🧪"
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
"🌋 Вулканический Дом 🌋",
|
||||
"🔥 Термальная Станция 🔥",
|
||||
"🌅 Золотой Дворец 🌅",
|
||||
"☁️ Облачный Город ☁️",
|
||||
"💎 Кристальная Шахта 💎",
|
||||
"🌡️ Теплица 🌡️",
|
||||
"🌀 Вихревой Генератор 🌀",
|
||||
"✨ Сияющая Башня ✨"
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== ЦВЕТА ЗДАНИЙ ПО ПЛАНЕТАМ ====================
|
||||
public static final Color[][][] BUILDING_COLOR_THEMES_BY_PLANET = {
|
||||
// 0. Земля - тёплые цвета
|
||||
{
|
||||
// Дома
|
||||
{ new Color(1.0f, 0.85f, 0.7f, 1), new Color(0.95f, 0.9f, 0.75f, 1), new Color(0.9f, 0.8f, 0.85f, 1) },
|
||||
// Больницы
|
||||
{ new Color(1.0f, 1.0f, 1.0f, 1), new Color(0.98f, 0.98f, 1.0f, 1), new Color(0.96f, 1.0f, 0.98f, 1) },
|
||||
// Школы
|
||||
{ new Color(1.0f, 0.95f, 0.8f, 1), new Color(0.85f, 0.95f, 1.0f, 1), new Color(0.95f, 0.85f, 1.0f, 1) },
|
||||
// Игровые площадки
|
||||
{ new Color(1.0f, 0.9f, 0.8f, 1), new Color(0.9f, 1.0f, 0.9f, 1), new Color(0.9f, 0.9f, 1.0f, 1) },
|
||||
// Банки
|
||||
{ new Color(0.95f, 0.95f, 0.9f, 1), new Color(0.9f, 0.92f, 0.85f, 1), new Color(0.85f, 0.89f, 0.8f, 1) },
|
||||
// Аптеки
|
||||
{ new Color(1.0f, 1.0f, 1.0f, 1), new Color(0.98f, 1.0f, 0.98f, 1), new Color(0.96f, 0.98f, 1.0f, 1) },
|
||||
// Театры
|
||||
{ new Color(0.95f, 0.9f, 0.95f, 1), new Color(0.9f, 0.95f, 1.0f, 1), new Color(1.0f, 0.95f, 0.9f, 1) },
|
||||
// Кинотеатры
|
||||
{ new Color(0.2f, 0.2f, 0.3f, 1), new Color(0.3f, 0.2f, 0.4f, 1), new Color(0.4f, 0.3f, 0.5f, 1) }
|
||||
},
|
||||
// 1. Марс - красные, оранжевые, коричневые
|
||||
{
|
||||
{ new Color(0.8f, 0.3f, 0.2f, 1), new Color(0.9f, 0.5f, 0.3f, 1), new Color(0.7f, 0.4f, 0.3f, 1) },
|
||||
{ new Color(0.9f, 0.4f, 0.4f, 1), new Color(1.0f, 0.6f, 0.5f, 1), new Color(0.8f, 0.5f, 0.5f, 1) },
|
||||
{ new Color(0.7f, 0.5f, 0.4f, 1), new Color(0.8f, 0.6f, 0.5f, 1), new Color(0.6f, 0.4f, 0.3f, 1) },
|
||||
{ new Color(0.9f, 0.6f, 0.3f, 1), new Color(1.0f, 0.7f, 0.4f, 1), new Color(0.8f, 0.5f, 0.2f, 1) },
|
||||
{ new Color(0.6f, 0.7f, 0.8f, 1), new Color(0.7f, 0.8f, 0.9f, 1), new Color(0.5f, 0.6f, 0.7f, 1) },
|
||||
{ new Color(0.3f, 0.4f, 0.6f, 1), new Color(0.4f, 0.5f, 0.7f, 1), new Color(0.2f, 0.3f, 0.5f, 1) },
|
||||
{ new Color(0.5f, 0.5f, 0.5f, 1), new Color(0.6f, 0.6f, 0.6f, 1), new Color(0.4f, 0.4f, 0.4f, 1) },
|
||||
{ new Color(0.4f, 0.7f, 0.4f, 1), new Color(0.5f, 0.8f, 0.5f, 1), new Color(0.3f, 0.6f, 0.3f, 1) }
|
||||
},
|
||||
// 2. Венера - желтые, золотые, оранжевые
|
||||
{
|
||||
{ new Color(1.0f, 0.7f, 0.3f, 1), new Color(1.0f, 0.8f, 0.4f, 1), new Color(0.9f, 0.6f, 0.2f, 1) },
|
||||
{ new Color(1.0f, 0.6f, 0.2f, 1), new Color(1.0f, 0.7f, 0.3f, 1), new Color(0.9f, 0.5f, 0.1f, 1) },
|
||||
{ new Color(1.0f, 0.9f, 0.3f, 1), new Color(1.0f, 1.0f, 0.5f, 1), new Color(0.9f, 0.8f, 0.2f, 1) },
|
||||
{ new Color(1.0f, 0.95f, 0.8f, 1), new Color(1.0f, 1.0f, 0.9f, 1), new Color(0.95f, 0.9f, 0.7f, 1) },
|
||||
{ new Color(0.8f, 0.9f, 1.0f, 1), new Color(0.9f, 1.0f, 1.0f, 1), new Color(0.7f, 0.8f, 0.9f, 1) },
|
||||
{ new Color(0.7f, 0.9f, 0.6f, 1), new Color(0.8f, 1.0f, 0.7f, 1), new Color(0.6f, 0.8f, 0.5f, 1) },
|
||||
{ new Color(0.9f, 0.8f, 0.5f, 1), new Color(1.0f, 0.9f, 0.6f, 1), new Color(0.8f, 0.7f, 0.4f, 1) },
|
||||
{ new Color(1.0f, 0.95f, 0.7f, 1), new Color(1.0f, 1.0f, 0.8f, 1), new Color(0.95f, 0.9f, 0.6f, 1) }
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== ЦВЕТА КРЫШ ПО ПЛАНЕТАМ ====================
|
||||
public static final Color[][][] ROOF_COLORS_BY_PLANET = {
|
||||
// Земля
|
||||
{
|
||||
{ new Color(0.9f, 0.3f, 0.2f, 1), new Color(0.7f, 0.4f, 0.2f, 1) },
|
||||
{ new Color(1.0f, 0.8f, 0.8f, 1), new Color(0.9f, 0.7f, 0.7f, 1) },
|
||||
{ new Color(0.4f, 0.7f, 1.0f, 1), new Color(0.3f, 0.6f, 0.9f, 1) },
|
||||
{ new Color(1.0f, 0.8f, 0.4f, 1), new Color(0.9f, 0.5f, 0.9f, 1) },
|
||||
{ new Color(1.0f, 0.9f, 0.3f, 1), new Color(0.9f, 0.8f, 0.2f, 1) },
|
||||
{ new Color(0.4f, 0.9f, 0.5f, 1), new Color(0.3f, 0.8f, 0.4f, 1) },
|
||||
{ new Color(0.8f, 0.4f, 1.0f, 1), new Color(0.7f, 0.3f, 0.9f, 1) },
|
||||
{ new Color(0.3f, 0.3f, 0.4f, 1), new Color(0.4f, 0.3f, 0.5f, 1) }
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
{ new Color(0.7f, 0.2f, 0.1f, 1), new Color(0.6f, 0.1f, 0.0f, 1) },
|
||||
{ new Color(0.8f, 0.3f, 0.2f, 1), new Color(0.7f, 0.2f, 0.1f, 1) },
|
||||
{ new Color(0.5f, 0.4f, 0.3f, 1), new Color(0.4f, 0.3f, 0.2f, 1) },
|
||||
{ new Color(0.8f, 0.5f, 0.2f, 1), new Color(0.7f, 0.4f, 0.1f, 1) },
|
||||
{ new Color(0.4f, 0.5f, 0.7f, 1), new Color(0.3f, 0.4f, 0.6f, 1) },
|
||||
{ new Color(0.2f, 0.3f, 0.5f, 1), new Color(0.1f, 0.2f, 0.4f, 1) },
|
||||
{ new Color(0.4f, 0.4f, 0.4f, 1), new Color(0.3f, 0.3f, 0.3f, 1) },
|
||||
{ new Color(0.3f, 0.6f, 0.3f, 1), new Color(0.2f, 0.5f, 0.2f, 1) }
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
{ new Color(0.8f, 0.4f, 0.1f, 1), new Color(0.7f, 0.3f, 0.0f, 1) },
|
||||
{ new Color(0.9f, 0.5f, 0.1f, 1), new Color(0.8f, 0.4f, 0.0f, 1) },
|
||||
{ new Color(1.0f, 0.8f, 0.1f, 1), new Color(0.9f, 0.7f, 0.0f, 1) },
|
||||
{ new Color(1.0f, 1.0f, 0.8f, 1), new Color(0.9f, 0.9f, 0.7f, 1) },
|
||||
{ new Color(0.7f, 0.8f, 0.9f, 1), new Color(0.6f, 0.7f, 0.8f, 1) },
|
||||
{ new Color(0.6f, 0.8f, 0.5f, 1), new Color(0.5f, 0.7f, 0.4f, 1) },
|
||||
{ new Color(0.8f, 0.7f, 0.4f, 1), new Color(0.7f, 0.6f, 0.3f, 1) },
|
||||
{ new Color(0.95f, 0.9f, 0.6f, 1), new Color(0.85f, 0.8f, 0.5f, 1) }
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== МАСШТАБЫ ЗДАНИЙ ПО ПЛАНЕТАМ ====================
|
||||
public static final float[][] SIZE_SCALE_FACTORS_BY_PLANET = {
|
||||
// Земля
|
||||
{1.0f, 0.75f, 0.8f, 0.85f, 0.7f, 0.65f, 0.8f, 0.85f},
|
||||
// Марс (компактнее)
|
||||
{0.9f, 0.7f, 0.8f, 0.75f, 0.65f, 0.6f, 0.7f, 0.75f},
|
||||
// Венера (выше)
|
||||
{1.1f, 1.0f, 1.05f, 1.0f, 0.9f, 0.85f, 1.0f, 1.05f}
|
||||
};
|
||||
|
||||
// ==================== ЦВЕТА ДЕТАЛЕЙ ПО ПЛАНЕТАМ ====================
|
||||
public static final Color[][] DETAIL_COLORS_BY_PLANET = {
|
||||
// Земля
|
||||
{
|
||||
new Color(1.0f, 0.9f, 0.2f, 1),
|
||||
new Color(1.0f, 0.5f, 0.5f, 1),
|
||||
new Color(0.5f, 0.8f, 1.0f, 1),
|
||||
new Color(0.8f, 1.0f, 0.5f, 1),
|
||||
new Color(1.0f, 0.7f, 1.0f, 1)
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
new Color(1.0f, 0.6f, 0.2f, 1),
|
||||
new Color(0.8f, 0.3f, 0.2f, 1),
|
||||
new Color(0.9f, 0.8f, 0.4f, 1),
|
||||
new Color(0.7f, 0.8f, 0.9f, 1),
|
||||
new Color(0.4f, 0.7f, 0.4f, 1)
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
new Color(1.0f, 0.9f, 0.3f, 1),
|
||||
new Color(1.0f, 0.7f, 0.2f, 1),
|
||||
new Color(1.0f, 1.0f, 0.8f, 1),
|
||||
new Color(0.9f, 0.6f, 0.1f, 1),
|
||||
new Color(0.8f, 0.9f, 1.0f, 1)
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== ЦВЕТА НАЗВАНИЙ ЗДАНИЙ ПО ПЛАНЕТАМ ====================
|
||||
public static final Color[][] GLOWING_NAME_COLORS_BY_PLANET = {
|
||||
// Земля
|
||||
{
|
||||
new Color(0.3f, 0.7f, 1.0f, 1),
|
||||
new Color(1.0f, 0.4f, 0.4f, 1),
|
||||
new Color(0.3f, 0.9f, 0.3f, 1),
|
||||
new Color(1.0f, 0.7f, 0.2f, 1),
|
||||
new Color(0.8f, 0.4f, 1.0f, 1)
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
new Color(1.0f, 0.5f, 0.3f, 1),
|
||||
new Color(0.8f, 0.3f, 0.2f, 1),
|
||||
new Color(0.9f, 0.7f, 0.4f, 1),
|
||||
new Color(0.6f, 0.8f, 0.9f, 1),
|
||||
new Color(0.4f, 0.6f, 0.3f, 1)
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
new Color(1.0f, 0.9f, 0.3f, 1),
|
||||
new Color(1.0f, 0.7f, 0.2f, 1),
|
||||
new Color(1.0f, 1.0f, 0.6f, 1),
|
||||
new Color(0.9f, 0.5f, 0.1f, 1),
|
||||
new Color(1.0f, 0.95f, 0.8f, 1)
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== ЦВЕТА ПЛАНЕТ ДЛЯ UI ====================
|
||||
public static Color getPlanetUIColor(Planet planet) {
|
||||
switch (planet) {
|
||||
case EARTH: return new Color(0.3f, 0.7f, 1.0f, 1);
|
||||
case MARS: return new Color(1.0f, 0.4f, 0.3f, 1);
|
||||
case VENUS: return new Color(1.0f, 0.8f, 0.3f, 1);
|
||||
default: return Color.WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getPlanetEmoji(Planet planet) {
|
||||
switch (planet) {
|
||||
case EARTH: return "🌍";
|
||||
case MARS: return "♂️";
|
||||
case VENUS: return "♀️";
|
||||
default: return "🪐";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
345
core/src/main/java/com/mygdx/game/GameSave.java
Normal file
345
core/src/main/java/com/mygdx/game/GameSave.java
Normal file
@@ -0,0 +1,345 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Preferences;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import java.util.Random;
|
||||
|
||||
// Система сохранения игры через LibGDX Preferences.
|
||||
public class GameSave {
|
||||
private static final String PREF_NAME = "AbsurdCityBuilder";
|
||||
|
||||
// Ключи для сохранения
|
||||
private static final String KEY_PLANET = "planet";
|
||||
private static final String KEY_TOTAL_BUILDINGS = "totalBuildings";
|
||||
private static final String KEY_EARTH_BUILDINGS = "earthBuildings";
|
||||
private static final String KEY_MARS_BUILDINGS = "marsBuildings";
|
||||
private static final String KEY_VENUS_BUILDINGS = "venusBuildings";
|
||||
private static final String KEY_LANGUAGE = "language";
|
||||
private static final String KEY_ACHIEVEMENTS = "achievements";
|
||||
private static final String KEY_CORRECT_STREAK = "correctStreak";
|
||||
private static final String KEY_VISITED_MARS = "visitedMars";
|
||||
private static final String KEY_VISITED_VENUS = "visitedVenus";
|
||||
private static final String KEY_BUILDINGS = "buildings";
|
||||
|
||||
// Статистика для достижений
|
||||
private static int totalBuildings = 0;
|
||||
private static int earthBuildings = 0;
|
||||
private static int marsBuildings = 0;
|
||||
private static int venusBuildings = 0;
|
||||
private static int correctStreak = 0;
|
||||
private static boolean visitedMars = false;
|
||||
private static boolean visitedVenus = false;
|
||||
|
||||
// Сохранить состояние игры
|
||||
public static void save(AbsurdCityBuilder1 game) {
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
|
||||
// Сохраняем текущую планету
|
||||
prefs.putString(KEY_PLANET, game.getCurrentPlanet().name());
|
||||
|
||||
// Сохраняем статистику
|
||||
prefs.putInteger(KEY_TOTAL_BUILDINGS, totalBuildings);
|
||||
prefs.putInteger(KEY_EARTH_BUILDINGS, earthBuildings);
|
||||
prefs.putInteger(KEY_MARS_BUILDINGS, marsBuildings);
|
||||
prefs.putInteger(KEY_VENUS_BUILDINGS, venusBuildings);
|
||||
prefs.putInteger(KEY_CORRECT_STREAK, correctStreak);
|
||||
prefs.putBoolean(KEY_VISITED_MARS, visitedMars);
|
||||
prefs.putBoolean(KEY_VISITED_VENUS, visitedVenus);
|
||||
|
||||
// Сохраняем язык
|
||||
prefs.putString(KEY_LANGUAGE, Localization.getCurrentLanguage());
|
||||
|
||||
// Сохраняем достижения
|
||||
prefs.putString(KEY_ACHIEVEMENTS, Achievements.getUnlockedAsString());
|
||||
|
||||
prefs.flush();
|
||||
|
||||
// Сохраняем здания отдельно
|
||||
saveBuildings(game.getBuildings());
|
||||
}
|
||||
|
||||
// Загрузить состояние игры
|
||||
public static void load(AbsurdCityBuilder1 game) {
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
|
||||
// Загружаем язык
|
||||
String language = prefs.getString(KEY_LANGUAGE, "ru");
|
||||
Localization.setLanguage(language);
|
||||
|
||||
// Загружаем статистику
|
||||
totalBuildings = prefs.getInteger(KEY_TOTAL_BUILDINGS, 0);
|
||||
earthBuildings = prefs.getInteger(KEY_EARTH_BUILDINGS, 0);
|
||||
marsBuildings = prefs.getInteger(KEY_MARS_BUILDINGS, 0);
|
||||
venusBuildings = prefs.getInteger(KEY_VENUS_BUILDINGS, 0);
|
||||
correctStreak = prefs.getInteger(KEY_CORRECT_STREAK, 0);
|
||||
visitedMars = prefs.getBoolean(KEY_VISITED_MARS, false);
|
||||
visitedVenus = prefs.getBoolean(KEY_VISITED_VENUS, false);
|
||||
|
||||
// Загружаем достижения
|
||||
String achievementsStr = prefs.getString(KEY_ACHIEVEMENTS, "");
|
||||
Achievements.loadFromString(achievementsStr);
|
||||
|
||||
// Загружаем планету для продолжения
|
||||
String planetStr = prefs.getString(KEY_PLANET, "EARTH");
|
||||
try {
|
||||
Planet planet = Planet.valueOf(planetStr);
|
||||
game.setCurrentPlanet(planet);
|
||||
} catch (Exception e) {
|
||||
game.setCurrentPlanet(Planet.EARTH);
|
||||
}
|
||||
}
|
||||
|
||||
// Проверить, есть ли сохранение
|
||||
public static boolean hasSave() {
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
// Есть сохранение если есть здания ИЛИ статистика
|
||||
String buildings = prefs.getString(KEY_BUILDINGS, "");
|
||||
int totalBuilt = prefs.getInteger(KEY_TOTAL_BUILDINGS, 0);
|
||||
return !buildings.isEmpty() || totalBuilt > 0;
|
||||
}
|
||||
|
||||
// Удалить сохранение
|
||||
public static void deleteSave() {
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
prefs.clear();
|
||||
prefs.flush();
|
||||
|
||||
resetAll();
|
||||
}
|
||||
|
||||
// Сбросить всю статистику (для новой игры)
|
||||
public static void resetAll() {
|
||||
totalBuildings = 0;
|
||||
earthBuildings = 0;
|
||||
marsBuildings = 0;
|
||||
venusBuildings = 0;
|
||||
correctStreak = 0;
|
||||
visitedMars = false;
|
||||
visitedVenus = false;
|
||||
|
||||
// Сохраняем сброс
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
prefs.putInteger(KEY_TOTAL_BUILDINGS, 0);
|
||||
prefs.putInteger(KEY_EARTH_BUILDINGS, 0);
|
||||
prefs.putInteger(KEY_MARS_BUILDINGS, 0);
|
||||
prefs.putInteger(KEY_VENUS_BUILDINGS, 0);
|
||||
prefs.putInteger(KEY_CORRECT_STREAK, 0);
|
||||
prefs.putBoolean(KEY_VISITED_MARS, false);
|
||||
prefs.putBoolean(KEY_VISITED_VENUS, false);
|
||||
prefs.putString(KEY_PLANET, "EARTH");
|
||||
prefs.putString(KEY_ACHIEVEMENTS, "");
|
||||
prefs.putString(KEY_BUILDINGS, ""); // Очищаем здания
|
||||
prefs.flush();
|
||||
}
|
||||
|
||||
// Загрузить только настройки (язык) при старте
|
||||
public static void loadSettings() {
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
String language = prefs.getString(KEY_LANGUAGE, "ru");
|
||||
Localization.setLanguage(language);
|
||||
|
||||
// Загружаем достижения
|
||||
String achievementsStr = prefs.getString(KEY_ACHIEVEMENTS, "");
|
||||
Achievements.loadFromString(achievementsStr);
|
||||
|
||||
// Загружаем статистику
|
||||
totalBuildings = prefs.getInteger(KEY_TOTAL_BUILDINGS, 0);
|
||||
earthBuildings = prefs.getInteger(KEY_EARTH_BUILDINGS, 0);
|
||||
marsBuildings = prefs.getInteger(KEY_MARS_BUILDINGS, 0);
|
||||
venusBuildings = prefs.getInteger(KEY_VENUS_BUILDINGS, 0);
|
||||
correctStreak = prefs.getInteger(KEY_CORRECT_STREAK, 0);
|
||||
visitedMars = prefs.getBoolean(KEY_VISITED_MARS, false);
|
||||
visitedVenus = prefs.getBoolean(KEY_VISITED_VENUS, false);
|
||||
}
|
||||
|
||||
// Сохранить настройки и статистику
|
||||
public static void saveSettings() {
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
|
||||
// Язык
|
||||
prefs.putString(KEY_LANGUAGE, Localization.getCurrentLanguage());
|
||||
|
||||
// Достижения
|
||||
prefs.putString(KEY_ACHIEVEMENTS, Achievements.getUnlockedAsString());
|
||||
|
||||
// Статистика
|
||||
prefs.putInteger(KEY_TOTAL_BUILDINGS, totalBuildings);
|
||||
prefs.putInteger(KEY_EARTH_BUILDINGS, earthBuildings);
|
||||
prefs.putInteger(KEY_MARS_BUILDINGS, marsBuildings);
|
||||
prefs.putInteger(KEY_VENUS_BUILDINGS, venusBuildings);
|
||||
prefs.putInteger(KEY_CORRECT_STREAK, correctStreak);
|
||||
prefs.putBoolean(KEY_VISITED_MARS, visitedMars);
|
||||
prefs.putBoolean(KEY_VISITED_VENUS, visitedVenus);
|
||||
|
||||
prefs.flush();
|
||||
}
|
||||
|
||||
// Сохранить текущую планету
|
||||
public static void savePlanet(Planet planet) {
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
prefs.putString(KEY_PLANET, planet.name());
|
||||
prefs.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Сохранить здания
|
||||
* Формат: type|x|y|width|height|planetIndex|progress;type|x|y|...
|
||||
*/
|
||||
public static void saveBuildings(Array<Building> buildings) {
|
||||
if (buildings == null || buildings.size == 0) {
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
prefs.putString(KEY_BUILDINGS, "");
|
||||
prefs.flush();
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < buildings.size; i++) {
|
||||
Building b = buildings.get(i);
|
||||
if (i > 0) sb.append(";");
|
||||
sb.append(b.type).append("|");
|
||||
sb.append((int)b.x).append("|");
|
||||
sb.append((int)b.y).append("|");
|
||||
sb.append((int)b.width).append("|");
|
||||
sb.append((int)b.height).append("|");
|
||||
sb.append(b.planetIndex).append("|");
|
||||
sb.append(b.constructionProgress);
|
||||
}
|
||||
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
prefs.putString(KEY_BUILDINGS, sb.toString());
|
||||
prefs.flush();
|
||||
}
|
||||
|
||||
// загружаем здания
|
||||
public static void loadBuildings(Array<Building> buildings, Array<Citizen> citizens, Random random) {
|
||||
buildings.clear();
|
||||
citizens.clear();
|
||||
|
||||
Preferences prefs = Gdx.app.getPreferences(PREF_NAME);
|
||||
String data = prefs.getString(KEY_BUILDINGS, "");
|
||||
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] buildingData = data.split(";");
|
||||
for (String bd : buildingData) {
|
||||
String[] parts = bd.split("\\|");
|
||||
if (parts.length >= 7) {
|
||||
try {
|
||||
String type = parts[0];
|
||||
float x = Float.parseFloat(parts[1]);
|
||||
float y = Float.parseFloat(parts[2]);
|
||||
float width = Float.parseFloat(parts[3]);
|
||||
float height = Float.parseFloat(parts[4]);
|
||||
int planetIndex = Integer.parseInt(parts[5]);
|
||||
int progress = Integer.parseInt(parts[6]);
|
||||
|
||||
Planet planet = Planet.values()[planetIndex];
|
||||
Building building = new Building(type, x, y, width, height, random, planet);
|
||||
|
||||
// Восстанавливаем прогресс
|
||||
for (int i = 0; i < progress; i++) {
|
||||
building.addBlock();
|
||||
}
|
||||
|
||||
buildings.add(building);
|
||||
|
||||
// Создаём жителей для завершённых зданий
|
||||
if (building.isComplete()) {
|
||||
building.createCitizensForBuilding(citizens, random);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Пропускаем битые данные
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== СТАТИСТИКА ====================
|
||||
|
||||
public static void onBuildingComplete(Planet planet) {
|
||||
totalBuildings++;
|
||||
switch (planet) {
|
||||
case EARTH:
|
||||
earthBuildings++;
|
||||
break;
|
||||
case MARS:
|
||||
marsBuildings++;
|
||||
break;
|
||||
case VENUS:
|
||||
venusBuildings++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void onCorrectAnswer() {
|
||||
correctStreak++;
|
||||
}
|
||||
|
||||
public static void onWrongAnswer() {
|
||||
correctStreak = 0;
|
||||
}
|
||||
|
||||
// Алиасы для AnswerChecker
|
||||
public static void addCorrectAnswer() {
|
||||
onCorrectAnswer();
|
||||
}
|
||||
|
||||
public static void resetCorrectStreak() {
|
||||
onWrongAnswer();
|
||||
}
|
||||
|
||||
public static void addBuilding(Planet planet) {
|
||||
onBuildingComplete(planet);
|
||||
}
|
||||
|
||||
public static void onVisitPlanet(Planet planet) {
|
||||
switch (planet) {
|
||||
case MARS:
|
||||
visitedMars = true;
|
||||
break;
|
||||
case VENUS:
|
||||
visitedVenus = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== ГЕТТЕРЫ ДЛЯ ДОСТИЖЕНИЙ ====================
|
||||
|
||||
public static int getTotalBuildings() {
|
||||
return totalBuildings;
|
||||
}
|
||||
|
||||
public static int getEarthBuildings() {
|
||||
return earthBuildings;
|
||||
}
|
||||
|
||||
public static int getMarsBuildings() {
|
||||
return marsBuildings;
|
||||
}
|
||||
|
||||
public static int getVenusBuildings() {
|
||||
return venusBuildings;
|
||||
}
|
||||
|
||||
public static int getCorrectStreak() {
|
||||
return correctStreak;
|
||||
}
|
||||
|
||||
public static boolean hasVisitedMars() {
|
||||
return visitedMars;
|
||||
}
|
||||
|
||||
public static boolean hasVisitedVenus() {
|
||||
return visitedVenus;
|
||||
}
|
||||
|
||||
public static boolean hasVisitedAllPlanets() {
|
||||
return visitedMars && visitedVenus;
|
||||
}
|
||||
}
|
||||
@@ -5,5 +5,6 @@ public enum GameState {
|
||||
PLAYING, // Игровой процесс
|
||||
PLANET_SELECT, // Выбор планеты
|
||||
HELP, // Помощь/инструкции
|
||||
ABOUT // Об игре
|
||||
ABOUT, // Об игре
|
||||
ACHIEVEMENTS // Достижения
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ public class InputHandler {
|
||||
game.setSelectedBuildingType(newType);
|
||||
game.updateUI();
|
||||
|
||||
game.setMessageText("Выбран: " +
|
||||
Building.BUILDING_TYPES_BY_PLANET[game.getCurrentPlanet().ordinal()][newType]);
|
||||
game.setMessageText(Localization.selected() + ": " +
|
||||
Localization.getBuildingName(game.getCurrentPlanet(), newType));
|
||||
game.setMessageColor(com.badlogic.gdx.graphics.Color.CYAN);
|
||||
}
|
||||
}
|
||||
@@ -31,8 +31,8 @@ public class InputHandler {
|
||||
game.setSelectedBuildingType(newType);
|
||||
game.updateUI();
|
||||
|
||||
game.setMessageText("Выбран: " +
|
||||
Building.BUILDING_TYPES_BY_PLANET[game.getCurrentPlanet().ordinal()][newType]);
|
||||
game.setMessageText(Localization.selected() + ": " +
|
||||
Localization.getBuildingName(game.getCurrentPlanet(), newType));
|
||||
game.setMessageColor(com.badlogic.gdx.graphics.Color.CYAN);
|
||||
}
|
||||
}
|
||||
@@ -72,15 +72,15 @@ public class InputHandler {
|
||||
game.setCurrentProblem(null);
|
||||
game.setTyping(false);
|
||||
game.getInputText().setLength(0);
|
||||
game.setMessageText("Строительство отменено. Выберите новое место.");
|
||||
game.setMessageText(Localization.constructionCancelled());
|
||||
game.setMessageColor(com.badlogic.gdx.graphics.Color.YELLOW);
|
||||
game.updateUI();
|
||||
} else if (game.getBuildings().size > 0) {
|
||||
game.getBuildings().removeIndex(game.getBuildings().size - 1);
|
||||
game.setMessageText("Последнее здание удалено.");
|
||||
game.setMessageText(Localization.lastBuildingRemoved());
|
||||
game.setMessageColor(com.badlogic.gdx.graphics.Color.ORANGE);
|
||||
} else {
|
||||
game.setMessageText("Нет зданий для удаления.");
|
||||
game.setMessageText(Localization.noBuildingsToRemove());
|
||||
game.setMessageColor(com.badlogic.gdx.graphics.Color.YELLOW);
|
||||
}
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class InputHandler {
|
||||
game.getInputText().deleteCharAt(game.getInputText().length() - 1);
|
||||
} else if (!game.isTyping() && game.getCurrentBuilding() != null && game.getCurrentBuilding().constructionProgress > 0) {
|
||||
game.getCurrentBuilding().removeBlock();
|
||||
game.setMessageText("Блок удален! Текущий прогресс: " + game.getCurrentBuilding().constructionProgress + "/3");
|
||||
game.setMessageText(Localization.blockRemoved(game.getCurrentBuilding().constructionProgress));
|
||||
game.setMessageColor(com.badlogic.gdx.graphics.Color.YELLOW);
|
||||
game.updateUI();
|
||||
}
|
||||
@@ -143,7 +143,7 @@ public class InputHandler {
|
||||
if (game.isTyping()) {
|
||||
game.setTyping(false);
|
||||
game.getInputText().setLength(0);
|
||||
game.setMessageText("Ввод отменен. Можно продолжить строительство.");
|
||||
game.setMessageText(Localization.inputCancelled());
|
||||
game.setMessageColor(com.badlogic.gdx.graphics.Color.YELLOW);
|
||||
}
|
||||
}
|
||||
|
||||
685
core/src/main/java/com/mygdx/game/Localization.java
Normal file
685
core/src/main/java/com/mygdx/game/Localization.java
Normal file
@@ -0,0 +1,685 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
// Локализация игры - все тексты на русском и английском.
|
||||
public class Localization {
|
||||
private static String currentLanguage = "ru";
|
||||
|
||||
// ==================== МЕНЮ ====================
|
||||
public static String newGame() {
|
||||
return isRu() ? "🚀 НОВАЯ ИГРА" : "🚀 NEW GAME";
|
||||
}
|
||||
|
||||
public static String continueGame() {
|
||||
return isRu() ? "▶️ ПРОДОЛЖИТЬ" : "▶️ CONTINUE";
|
||||
}
|
||||
|
||||
public static String selectPlanet() {
|
||||
return isRu() ? "🪐 ВЫБОР ПЛАНЕТЫ" : "🪐 SELECT PLANET";
|
||||
}
|
||||
|
||||
public static String help() {
|
||||
return isRu() ? "❓ ПОМОЩЬ" : "❓ HELP";
|
||||
}
|
||||
|
||||
public static String about() {
|
||||
return isRu() ? "ℹ️ ОБ ИГРЕ" : "ℹ️ ABOUT";
|
||||
}
|
||||
|
||||
public static String achievements() {
|
||||
return isRu() ? "🏆 ДОСТИЖЕНИЯ" : "🏆 ACHIEVEMENTS";
|
||||
}
|
||||
|
||||
public static String exit() {
|
||||
return isRu() ? "🚪 ВЫХОД" : "🚪 EXIT";
|
||||
}
|
||||
|
||||
public static String back() {
|
||||
return isRu() ? "⬅️ НАЗАД" : "⬅️ BACK";
|
||||
}
|
||||
|
||||
public static String gameTitle() {
|
||||
return "✨ ABSURD CITY BUILDER ✨";
|
||||
}
|
||||
|
||||
public static String gameSubtitle() {
|
||||
return isRu()
|
||||
? "Строй абсурдные города на разных планетах!"
|
||||
: "Build absurd cities on different planets!";
|
||||
}
|
||||
|
||||
public static String getLanguageLabel() {
|
||||
return isRu() ? "EN" : "RU";
|
||||
}
|
||||
|
||||
public static String welcomeTo(Planet planet) {
|
||||
String name = planetName(planet);
|
||||
return isRu()
|
||||
? "Добро пожаловать на " + name + "! Выберите здание и кликните на поле."
|
||||
: "Welcome to " + name + "! Select a building and click on the field.";
|
||||
}
|
||||
|
||||
public static String flying(Planet planet) {
|
||||
return isRu()
|
||||
? "Запускаем космический корабль на " + planetName(planet) + "! 🚀"
|
||||
: "Launching spaceship to " + planetName(planet) + "! 🚀";
|
||||
}
|
||||
|
||||
public static String blockBuilt() {
|
||||
return isRu() ? "Отлично! Блок построен!" : "Great! Block built!";
|
||||
}
|
||||
|
||||
public static String selected() {
|
||||
return isRu() ? "Выбран" : "Selected";
|
||||
}
|
||||
|
||||
public static String overlapping() {
|
||||
return isRu() ? "(пересекается!)" : "(overlapping!)";
|
||||
}
|
||||
|
||||
public static String colorTheme() {
|
||||
return isRu() ? "Цвет: Тема" : "Color: Theme";
|
||||
}
|
||||
|
||||
public static String building() {
|
||||
return isRu() ? "Строим" : "Building";
|
||||
}
|
||||
|
||||
public static String planet() {
|
||||
return isRu() ? "Планета" : "Planet";
|
||||
}
|
||||
|
||||
public static String buildingType() {
|
||||
return isRu() ? "Тип здания" : "Building type";
|
||||
}
|
||||
|
||||
public static String arrowsToSelect() {
|
||||
return isRu() ? "(←/→ для выбора, кликните для строительства)" : "(←/→ to select, click to build)";
|
||||
}
|
||||
|
||||
public static String menu() {
|
||||
return isRu() ? "меню" : "menu";
|
||||
}
|
||||
|
||||
public static String flyingTo() {
|
||||
return isRu() ? "Перелет на" : "Flying to";
|
||||
}
|
||||
|
||||
public static String placeFor() {
|
||||
return isRu() ? "Место для: " : "Place for: ";
|
||||
}
|
||||
|
||||
public static String constructing() {
|
||||
return isRu() ? "Строится: " : "Building: ";
|
||||
}
|
||||
|
||||
public static String overlapWarning() {
|
||||
return isRu() ? "⚠ Пересечение! ⚠" : "⚠ Overlap! ⚠";
|
||||
}
|
||||
|
||||
public static String buildingOverlaps() {
|
||||
return isRu()
|
||||
? "🎨 Здание пересекается с существующими! Это добавляет уникальности! 🎨"
|
||||
: "🎨 Building overlaps with existing ones! This adds uniqueness! 🎨";
|
||||
}
|
||||
|
||||
public static String greatPlace() {
|
||||
return isRu()
|
||||
? "🌟 Отличное место для строительства! Введите ответ: 🌟"
|
||||
: "🌟 Great place to build! Enter your answer: 🌟";
|
||||
}
|
||||
|
||||
public static String clickOutside() {
|
||||
return isRu()
|
||||
? "🎯 Кликните вне здания для нового строительства. Ctrl+Z или Delete для удаления. 🎯"
|
||||
: "🎯 Click outside building for new construction. Ctrl+Z or Delete to remove. 🎯";
|
||||
}
|
||||
|
||||
public static String constructionCancelled() {
|
||||
return isRu()
|
||||
? "Строительство отменено. Выберите новое место."
|
||||
: "Construction cancelled. Select a new place.";
|
||||
}
|
||||
|
||||
public static String lastBuildingRemoved() {
|
||||
return isRu() ? "Последнее здание удалено." : "Last building removed.";
|
||||
}
|
||||
|
||||
public static String inputCancelled() {
|
||||
return isRu()
|
||||
? "Ввод отменен. Можно продолжить строительство."
|
||||
: "Input cancelled. You can continue building.";
|
||||
}
|
||||
|
||||
public static String changePlanet() {
|
||||
return isRu() ? "↑/↓ - сменить планету" : "↑/↓ - change planet";
|
||||
}
|
||||
|
||||
public static String planetKeys() {
|
||||
return isRu() ? "1-Земля, 2-Марс, 3-Венера" : "1-Earth, 2-Mars, 3-Venus";
|
||||
}
|
||||
|
||||
public static String selectBuildingType() {
|
||||
return isRu() ? "←/→ - выбрать тип здания" : "←/→ - select building type";
|
||||
}
|
||||
|
||||
public static String task(String question) {
|
||||
return isRu() ? "🧮 Задача: " + question : "🧮 Problem: " + question;
|
||||
}
|
||||
|
||||
public static String enterSubmit() {
|
||||
return isRu() ? "⏎ Enter - отправить ответ" : "⏎ Enter - submit answer";
|
||||
}
|
||||
|
||||
public static String escCancel() {
|
||||
return isRu() ? "⎋ ESC - отмена ввода" : "⎋ ESC - cancel input";
|
||||
}
|
||||
|
||||
public static String backspaceDelete() {
|
||||
return isRu() ? "⌫ Backspace - удалить символ" : "⌫ Backspace - delete character";
|
||||
}
|
||||
|
||||
public static String clickToBuild() {
|
||||
return isRu()
|
||||
? "🖱️ Кликните на поле для строительства"
|
||||
: "🖱️ Click on the field to build";
|
||||
}
|
||||
|
||||
public static String controls() {
|
||||
return isRu()
|
||||
? "🗑️ Delete/Ctrl+Z - удалить здание | ⌫ Backspace - удалить блок | ⎋ ESC - меню"
|
||||
: "🗑️ Delete/Ctrl+Z - delete building | ⌫ Backspace - delete block | ⎋ ESC - menu";
|
||||
}
|
||||
|
||||
// ==================== ПЛАНЕТЫ ====================
|
||||
public static String earth() {
|
||||
return isRu() ? "🌍 ЗЕМЛЯ" : "🌍 EARTH";
|
||||
}
|
||||
|
||||
public static String mars() {
|
||||
return isRu() ? "♂️ МАРС" : "♂️ MARS";
|
||||
}
|
||||
|
||||
public static String venus() {
|
||||
return isRu() ? "♀️ ВЕНЕРА" : "♀️ VENUS";
|
||||
}
|
||||
|
||||
public static String planetName(Planet planet) {
|
||||
switch (planet) {
|
||||
case EARTH: return isRu() ? "Земля" : "Earth";
|
||||
case MARS: return isRu() ? "Марс" : "Mars";
|
||||
case VENUS: return isRu() ? "Венера" : "Venus";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== ИГРОВОЙ ПРОЦЕСС ====================
|
||||
public static String welcome(Planet planet) {
|
||||
String name = planetName(planet);
|
||||
return isRu()
|
||||
? "Добро пожаловать на " + name + "! Выберите здание и кликните на поле."
|
||||
: "Welcome to " + name + "! Select a building and click on the field.";
|
||||
}
|
||||
|
||||
public static String buildingProgress(int current, int max) {
|
||||
return isRu()
|
||||
? "📊 Прогресс: " + current + "/" + max + " блоков"
|
||||
: "📊 Progress: " + current + "/" + max + " blocks";
|
||||
}
|
||||
|
||||
public static String selectBuilding() {
|
||||
return isRu() ? "🏗️ Тип здания: " : "🏗️ Building type: ";
|
||||
}
|
||||
|
||||
public static String currentPlanet() {
|
||||
return isRu() ? "🌍 Планета: " : "🌍 Planet: ";
|
||||
}
|
||||
|
||||
public static String changePlanetHint() {
|
||||
return isRu() ? "↑/↓ - сменить планету" : "↑/↓ - change planet";
|
||||
}
|
||||
|
||||
public static String planetKeysHint() {
|
||||
return isRu() ? "1-Земля, 2-Марс, 3-Венера" : "1-Earth, 2-Mars, 3-Venus";
|
||||
}
|
||||
|
||||
public static String selectBuildingHint() {
|
||||
return isRu() ? "←/→ - выбрать тип здания" : "←/→ - select building type";
|
||||
}
|
||||
|
||||
public static String clickToPlace() {
|
||||
return isRu()
|
||||
? "🖱️ Кликните на поле для строительства"
|
||||
: "🖱️ Click on the field to build";
|
||||
}
|
||||
|
||||
public static String controlsHint() {
|
||||
return isRu()
|
||||
? "🗑️ Delete/Ctrl+Z - удалить здание | ⌫ Backspace - удалить блок | ⎋ ESC - меню"
|
||||
: "🗑️ Delete/Ctrl+Z - remove building | ⌫ Backspace - remove block | ⎋ ESC - menu";
|
||||
}
|
||||
|
||||
public static String enterAnswer() {
|
||||
return isRu() ? "✏️ Введите ответ:" : "✏️ Enter answer:";
|
||||
}
|
||||
|
||||
public static String mathProblem() {
|
||||
return isRu() ? "🧮 Задача: " : "🧮 Problem: ";
|
||||
}
|
||||
|
||||
public static String enterHint() {
|
||||
return isRu() ? "⏎ Enter - отправить ответ" : "⏎ Enter - submit answer";
|
||||
}
|
||||
|
||||
public static String escHint() {
|
||||
return isRu() ? "⎋ ESC - отмена ввода" : "⎋ ESC - cancel input";
|
||||
}
|
||||
|
||||
public static String backspaceHint() {
|
||||
return isRu() ? "⌫ Backspace - удалить символ" : "⌫ Backspace - delete character";
|
||||
}
|
||||
|
||||
public static String escForMenu() {
|
||||
return isRu() ? "Нажмите ESC для возврата в меню" : "Press ESC to return to menu";
|
||||
}
|
||||
|
||||
public static String inFlight() {
|
||||
return isRu() ? "(Перелет...)" : "(In flight...)";
|
||||
}
|
||||
|
||||
// ==================== СООБЩЕНИЯ ====================
|
||||
public static String correctAnswer() {
|
||||
return isRu() ? "Отлично! Блок построен!" : "Great! Block built!";
|
||||
}
|
||||
|
||||
public static String wrongAnswer() {
|
||||
return isRu() ? "Неверно! Блок разрушен!" : "Wrong! Block destroyed!";
|
||||
}
|
||||
|
||||
public static String buildingComplete() {
|
||||
return isRu() ? "Успех! " : "Success! ";
|
||||
}
|
||||
|
||||
public static String buildingDestroyed() {
|
||||
return isRu() ? "Здание разрушено до основания! " : "Building destroyed completely! ";
|
||||
}
|
||||
|
||||
public static String enterNumber() {
|
||||
return isRu() ? "Введите целое число!" : "Enter a whole number!";
|
||||
}
|
||||
|
||||
public static String enterAnswer2() {
|
||||
return isRu() ? "Введите ответ!" : "Enter an answer!";
|
||||
}
|
||||
|
||||
public static String inputCanceled() {
|
||||
return isRu() ? "Ввод отменен." : "Input canceled.";
|
||||
}
|
||||
|
||||
public static String gamePaused() {
|
||||
return isRu() ? "Игра приостановлена. Нажмите ESC для продолжения." : "Game paused. Press ESC to continue.";
|
||||
}
|
||||
|
||||
public static String buildingSelected(String name) {
|
||||
return isRu() ? "Выбран: " + name : "Selected: " + name;
|
||||
}
|
||||
|
||||
public static String buildingCanceled() {
|
||||
return isRu() ? "Строительство отменено. Выберите новое место." : "Construction canceled. Choose a new location.";
|
||||
}
|
||||
|
||||
public static String noBuildingsToRemove() {
|
||||
return isRu() ? "Нет зданий для удаления." : "No buildings to remove.";
|
||||
}
|
||||
|
||||
public static String blockRemoved(int progress) {
|
||||
return isRu()
|
||||
? "Блок удален! Текущий прогресс: " + progress + "/3"
|
||||
: "Block removed! Current progress: " + progress + "/3";
|
||||
}
|
||||
|
||||
public static String flyingTo(Planet planet) {
|
||||
return isRu()
|
||||
? "Запускаем космический корабль на " + planetName(planet) + "! 🚀"
|
||||
: "Launching spaceship to " + planetName(planet) + "! 🚀";
|
||||
}
|
||||
|
||||
public static String leaving(Planet planet) {
|
||||
return isRu() ? "Покидаем " + planetName(planet) + "..." : "Leaving " + planetName(planet) + "...";
|
||||
}
|
||||
|
||||
public static String arriving(Planet planet) {
|
||||
return isRu() ? "Прибываем на " + planetName(planet) + "!" : "Arriving at " + planetName(planet) + "!";
|
||||
}
|
||||
|
||||
// ==================== НАЗВАНИЯ ЗДАНИЙ ====================
|
||||
public static String[][] getBuildingNames() {
|
||||
if (isRu()) {
|
||||
return GameConfig.BUILDING_TYPES_BY_PLANET;
|
||||
}
|
||||
return BUILDING_NAMES_EN;
|
||||
}
|
||||
|
||||
// Получить локализованное название здания по индексам
|
||||
public static String getBuildingName(Planet planet, int typeIndex) {
|
||||
return getBuildingNames()[planet.ordinal()][typeIndex];
|
||||
}
|
||||
|
||||
// Получить локализованное название для Building объекта
|
||||
public static String getBuildingName(Building building) {
|
||||
return getBuildingNames()[building.planetIndex][building.buildingTypeIndex];
|
||||
}
|
||||
|
||||
private static final String[][] BUILDING_NAMES_EN = {
|
||||
// Earth
|
||||
{
|
||||
"✨ Cozy House ✨",
|
||||
"🏥 Children's Hospital 🏥",
|
||||
"🎒 Fun School 🎒",
|
||||
"🎪 Playground 🎪",
|
||||
"💰 Reliable Bank 💰",
|
||||
"💊 Healthy Pharmacy 💊",
|
||||
"🎭 Magic Theater 🎭",
|
||||
"🎬 CinemaWorld 🎬"
|
||||
},
|
||||
// Mars
|
||||
{
|
||||
"🚀 Martian Base 🚀",
|
||||
"🔴 Red Laboratory 🔴",
|
||||
"🛰️ Spaceport 🛰️",
|
||||
"⚡ Energy Dome ⚡",
|
||||
"💧 Hydrogen Plant 💧",
|
||||
"🌌 Observatory 🌌",
|
||||
"🤖 Robo-Factory 🤖",
|
||||
"🧪 Bio-Dome 🧪"
|
||||
},
|
||||
// Venus
|
||||
{
|
||||
"🌋 Volcanic House 🌋",
|
||||
"🔥 Thermal Station 🔥",
|
||||
"🌅 Golden Palace 🌅",
|
||||
"☁️ Cloud City ☁️",
|
||||
"💎 Crystal Mine 💎",
|
||||
"🌡️ Greenhouse 🌡️",
|
||||
"🌀 Vortex Generator 🌀",
|
||||
"✨ Shining Tower ✨"
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== ШУТКИ ПРИ ПРАВИЛЬНОМ ОТВЕТЕ ====================
|
||||
public static String[] getSuccessComments(Planet planet) {
|
||||
if (isRu()) {
|
||||
return SUCCESS_COMMENTS_RU[planet.ordinal()];
|
||||
}
|
||||
return SUCCESS_COMMENTS_EN[planet.ordinal()];
|
||||
}
|
||||
|
||||
private static final String[][] SUCCESS_COMMENTS_RU = {
|
||||
// Земля
|
||||
{
|
||||
"Вау! Такое здание видел только в мультиках!",
|
||||
"Архитектор сошел с ума от радости!",
|
||||
"Город стал похож на мультфильм!",
|
||||
"Это самое безумное здание в городе!",
|
||||
"Жители в восторге от этой абсурдности!",
|
||||
"Эй, это похоже на город из моих снов!",
|
||||
"Такое здание украсит любой мультфильм!"
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
"Отлично! Марсианская колония растёт! 🚀",
|
||||
"На Марсе теперь есть своё безумие!",
|
||||
"Эти здания переживут любую пылевую бурю!",
|
||||
"Марсиане будут в восторге! 👽",
|
||||
"Похоже, мы колонизируем Марс!",
|
||||
"Красная планета стала разноцветнее!",
|
||||
"Это здание выглядит инопланетно круто!"
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
"Горячо! Венерианский шедевр готов! 🔥",
|
||||
"Здание плавится от собственной красоты!",
|
||||
"Венера стала ещё ярче! 🌟",
|
||||
"Это здание сияет как сама Венера!",
|
||||
"Похоже, мы выживаем на Венере!",
|
||||
"Такая красота плавит сердце!",
|
||||
"Золотой век венерианской архитектуры!"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] SUCCESS_COMMENTS_EN = {
|
||||
// Earth
|
||||
{
|
||||
"Wow! I've only seen such buildings in cartoons!",
|
||||
"The architect went crazy with joy!",
|
||||
"The city looks like a cartoon now!",
|
||||
"This is the craziest building in town!",
|
||||
"Residents love this absurdity!",
|
||||
"Hey, this looks like a city from my dreams!",
|
||||
"Such a building would grace any cartoon!"
|
||||
},
|
||||
// Mars
|
||||
{
|
||||
"Great! The Martian colony is growing! 🚀",
|
||||
"Mars now has its own madness!",
|
||||
"These buildings will survive any dust storm!",
|
||||
"Martians will love it! 👽",
|
||||
"Looks like we're colonizing Mars!",
|
||||
"The red planet got more colorful!",
|
||||
"This building looks alien-cool!"
|
||||
},
|
||||
// Venus
|
||||
{
|
||||
"Hot! Venusian masterpiece complete! 🔥",
|
||||
"The building is melting from its own beauty!",
|
||||
"Venus got even brighter! 🌟",
|
||||
"This building shines like Venus itself!",
|
||||
"Looks like we're surviving on Venus!",
|
||||
"Such beauty melts the heart!",
|
||||
"The golden age of Venusian architecture!"
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== ШУТКИ ПРИ НЕПРАВИЛЬНОМ ОТВЕТЕ ====================
|
||||
public static String[] getWrongAnswerJokes(Planet planet) {
|
||||
if (isRu()) {
|
||||
return WRONG_ANSWER_JOKES_RU[planet.ordinal()];
|
||||
}
|
||||
return WRONG_ANSWER_JOKES_EN[planet.ordinal()];
|
||||
}
|
||||
|
||||
private static final String[][] WRONG_ANSWER_JOKES_RU = {
|
||||
// Земля
|
||||
{
|
||||
"Твоя математика кривее моих зданий!",
|
||||
"Даже мультяшный архитектор считает лучше!",
|
||||
"Ты что, в мультиках учился математике?",
|
||||
"Ошибка! Попробуй посчитать на пальцах ног!",
|
||||
"Неправильно! Давай еще разочек, как в мультике!",
|
||||
"Бывает! Даже мультяшные гении ошибаются!",
|
||||
"Ой, кажется, ты перепутал с мультипликацией!",
|
||||
"Неверно! Но зато здание выглядит смешнее!"
|
||||
},
|
||||
// Марс
|
||||
{
|
||||
"Неверно! Марсиане считают лучше! 👽",
|
||||
"Ошибка в расчётах! Пылевая буря съела цифры!",
|
||||
"Твоя математика не переживёт марсианскую зиму!",
|
||||
"Неудача! Даже марсоход считает точнее!",
|
||||
"Неправильно! Попробуй считать в скафандре!",
|
||||
"Ошибка! Кислородное голодание сказывается?",
|
||||
"Марсианские калькуляторы не одобряют!",
|
||||
"Неверно! Может, радиация помешала?"
|
||||
},
|
||||
// Венера
|
||||
{
|
||||
"Горячая ошибка! 🔥 Попробуй ещё!",
|
||||
"Неверно! Даже венерианская жара не оправдывает!",
|
||||
"Ошибка! Кислотные облака затуманили разум?",
|
||||
"Неправильно! Слишком жарко для точных расчётов?",
|
||||
"Провал! Венерианские калькуляторы плавятся!",
|
||||
"Неудача! Давление в 90 атмосфер давит на мозги?",
|
||||
"Ошибка! Попробуй считать в теплозащитном костюме!",
|
||||
"Неверно! Золотое сечение не спасло!"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] WRONG_ANSWER_JOKES_EN = {
|
||||
// Earth
|
||||
{
|
||||
"Your math is more crooked than my buildings!",
|
||||
"Even a cartoon architect counts better!",
|
||||
"Did you learn math from cartoons?",
|
||||
"Wrong! Try counting on your toes!",
|
||||
"Incorrect! Let's try again, cartoon style!",
|
||||
"It happens! Even cartoon geniuses make mistakes!",
|
||||
"Oops, looks like you confused it with animation!",
|
||||
"Wrong! But the building looks funnier now!"
|
||||
},
|
||||
// Mars
|
||||
{
|
||||
"Wrong! Martians count better! 👽",
|
||||
"Calculation error! Dust storm ate the numbers!",
|
||||
"Your math won't survive Martian winter!",
|
||||
"Failed! Even the rover counts better!",
|
||||
"Wrong! Try counting in a spacesuit!",
|
||||
"Error! Oxygen deprivation kicking in?",
|
||||
"Martian calculators disapprove!",
|
||||
"Wrong! Maybe radiation interfered?"
|
||||
},
|
||||
// Venus
|
||||
{
|
||||
"Hot mistake! 🔥 Try again!",
|
||||
"Wrong! Even Venusian heat doesn't excuse this!",
|
||||
"Error! Acid clouds clouding your mind?",
|
||||
"Wrong! Too hot for accurate calculations?",
|
||||
"Fail! Venusian calculators are melting!",
|
||||
"Failed! Is 90 atmospheres of pressure getting to you?",
|
||||
"Error! Try counting in a heat suit!",
|
||||
"Wrong! Golden ratio didn't save you!"
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== ДОСТИЖЕНИЯ ====================
|
||||
public static String achievementUnlocked() {
|
||||
return isRu() ? "🏆 Достижение разблокировано!" : "🏆 Achievement unlocked!";
|
||||
}
|
||||
|
||||
// ==================== ЭКРАН ПОМОЩИ ====================
|
||||
public static String helpTitle() {
|
||||
return isRu() ? "❓ ПОМОЩЬ И УПРАВЛЕНИЕ" : "❓ HELP & CONTROLS";
|
||||
}
|
||||
|
||||
public static String[] getHelpInstructions() {
|
||||
if (isRu()) {
|
||||
return HELP_INSTRUCTIONS_RU;
|
||||
}
|
||||
return HELP_INSTRUCTIONS_EN;
|
||||
}
|
||||
|
||||
private static final String[] HELP_INSTRUCTIONS_RU = {
|
||||
"🎮 ОСНОВНОЕ УПРАВЛЕНИЕ:",
|
||||
"• ЛКМ - кликнуть на поле для строительства",
|
||||
"• ←/→ - выбрать тип здания",
|
||||
"• Enter - отправить ответ на задачу",
|
||||
"• Backspace - удалить блок/символ",
|
||||
"• Delete/Ctrl+Z - удалить здание",
|
||||
"• ESC - отмена ввода",
|
||||
"",
|
||||
"🪐 УПРАВЛЕНИЕ ПЛАНЕТАМИ:",
|
||||
"• ↑/↓ - переключить планету",
|
||||
"• 1 - Земля, 2 - Марс, 3 - Венера",
|
||||
"",
|
||||
"🎯 КАК ИГРАТЬ:",
|
||||
"1. Выберите тип здания",
|
||||
"2. Кликните на игровом поле",
|
||||
"3. Решите математическую задачу",
|
||||
"4. Постройте 3 блока для завершения",
|
||||
"5. Стройте разные здания на разных планетах!"
|
||||
};
|
||||
|
||||
private static final String[] HELP_INSTRUCTIONS_EN = {
|
||||
"🎮 BASIC CONTROLS:",
|
||||
"• LMB - click on field to build",
|
||||
"• ←/→ - select building type",
|
||||
"• Enter - submit answer",
|
||||
"• Backspace - delete block/character",
|
||||
"• Delete/Ctrl+Z - remove building",
|
||||
"• ESC - cancel input",
|
||||
"",
|
||||
"🪐 PLANET CONTROLS:",
|
||||
"• ↑/↓ - switch planet",
|
||||
"• 1 - Earth, 2 - Mars, 3 - Venus",
|
||||
"",
|
||||
"🎯 HOW TO PLAY:",
|
||||
"1. Select building type",
|
||||
"2. Click on the game field",
|
||||
"3. Solve the math problem",
|
||||
"4. Build 3 blocks to complete",
|
||||
"5. Build different buildings on different planets!"
|
||||
};
|
||||
|
||||
// ==================== ЭКРАН "ОБ ИГРЕ" ====================
|
||||
public static String aboutTitle() {
|
||||
return isRu() ? "✨ ОБ ИГРЕ" : "✨ ABOUT";
|
||||
}
|
||||
|
||||
public static String[] getAboutText() {
|
||||
if (isRu()) {
|
||||
return ABOUT_TEXT_RU;
|
||||
}
|
||||
return ABOUT_TEXT_EN;
|
||||
}
|
||||
|
||||
private static final String[] ABOUT_TEXT_RU = {
|
||||
"Absurd City Builder - это уникальная игра,",
|
||||
"где вы строите безумные города на разных планетах!",
|
||||
"",
|
||||
"Особенности игры:",
|
||||
"• 3 уникальные планеты с разными зданиями",
|
||||
"• Забавные математические задачи",
|
||||
"• Мультяшная графика и анимации",
|
||||
"• Динамичные жители и шутки",
|
||||
"• Бесконечные возможности для творчества!",
|
||||
"",
|
||||
"Разработано с ❤️ для любителей абсурда и математики.",
|
||||
"",
|
||||
"Версия 1.0"
|
||||
};
|
||||
|
||||
private static final String[] ABOUT_TEXT_EN = {
|
||||
"Absurd City Builder is a unique game",
|
||||
"where you build crazy cities on different planets!",
|
||||
"",
|
||||
"Game features:",
|
||||
"• 3 unique planets with different buildings",
|
||||
"• Fun math problems",
|
||||
"• Cartoon graphics and animations",
|
||||
"• Dynamic citizens and jokes",
|
||||
"• Endless creative possibilities!",
|
||||
"",
|
||||
"Made with ❤️ for absurdity and math lovers.",
|
||||
"",
|
||||
"Version 1.0"
|
||||
};
|
||||
|
||||
// ==================== УПРАВЛЕНИЕ ЯЗЫКОМ ====================
|
||||
public static void setLanguage(String lang) {
|
||||
currentLanguage = lang;
|
||||
}
|
||||
|
||||
public static String getCurrentLanguage() {
|
||||
return currentLanguage;
|
||||
}
|
||||
|
||||
public static void toggleLanguage() {
|
||||
currentLanguage = isRu() ? "en" : "ru";
|
||||
}
|
||||
|
||||
public static boolean isRu() {
|
||||
return "ru".equals(currentLanguage);
|
||||
}
|
||||
|
||||
public static String languageButtonText() {
|
||||
return isRu() ? "🌐 EN" : "🌐 RU";
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ public class MenuRenderer {
|
||||
private List<MenuButton> mainMenuButtons;
|
||||
private List<MenuButton> planetSelectButtons;
|
||||
private List<MenuButton> helpButtons;
|
||||
private List<MenuButton> achievementsButtons;
|
||||
|
||||
private float titlePulse = 0;
|
||||
private float starTimer = 0;
|
||||
@@ -40,61 +41,79 @@ public class MenuRenderer {
|
||||
createMainMenuButtons();
|
||||
createPlanetSelectButtons();
|
||||
createHelpButtons();
|
||||
createAchievementsButtons();
|
||||
}
|
||||
|
||||
private void createMainMenuButtons() {
|
||||
mainMenuButtons = new ArrayList<>();
|
||||
float buttonWidth = 400;
|
||||
float buttonHeight = 70;
|
||||
float startY = height/2 - 50;
|
||||
float spacing = 85;
|
||||
float startY = height/2 + 30;
|
||||
float spacing = 75;
|
||||
|
||||
// Кнопка "Продолжить" (если есть сохранение)
|
||||
mainMenuButtons.add(new MenuButton(
|
||||
width/2 - buttonWidth/2, startY, buttonWidth, buttonHeight,
|
||||
Localization.continueGame(),
|
||||
GameConfig.BUTTON_HELP,
|
||||
GameConfig.BUTTON_HELP_HOVER,
|
||||
() -> {}
|
||||
).withTextColor(Color.WHITE));
|
||||
|
||||
// Кнопка "Новая игра"
|
||||
mainMenuButtons.add(new MenuButton(
|
||||
width/2 - buttonWidth/2, startY, buttonWidth, buttonHeight,
|
||||
"🚀 НОВАЯ ИГРА",
|
||||
new Color(0.2f, 0.5f, 0.8f, 0.9f),
|
||||
new Color(0.3f, 0.6f, 0.9f, 1f),
|
||||
width/2 - buttonWidth/2, startY - spacing, buttonWidth, buttonHeight,
|
||||
Localization.newGame(),
|
||||
GameConfig.BUTTON_NEW_GAME,
|
||||
GameConfig.BUTTON_NEW_GAME_HOVER,
|
||||
() -> {}
|
||||
).withTextColor(Color.YELLOW));
|
||||
|
||||
// Кнопка "Выбор планеты"
|
||||
mainMenuButtons.add(new MenuButton(
|
||||
width/2 - buttonWidth/2, startY - spacing, buttonWidth, buttonHeight,
|
||||
"🪐 ВЫБОР ПЛАНЕТЫ",
|
||||
new Color(0.8f, 0.4f, 0.2f, 0.9f),
|
||||
new Color(0.9f, 0.5f, 0.3f, 1f),
|
||||
width/2 - buttonWidth/2, startY - spacing * 2, buttonWidth, buttonHeight,
|
||||
Localization.selectPlanet(),
|
||||
GameConfig.BUTTON_PLANET,
|
||||
GameConfig.BUTTON_PLANET_HOVER,
|
||||
() -> {}
|
||||
));
|
||||
|
||||
// Кнопка "Достижения"
|
||||
mainMenuButtons.add(new MenuButton(
|
||||
width/2 - buttonWidth/2, startY - spacing * 3, buttonWidth, buttonHeight,
|
||||
Localization.achievements(),
|
||||
new Color(0.9f, 0.7f, 0.2f, 0.9f),
|
||||
new Color(1.0f, 0.8f, 0.3f, 1f),
|
||||
() -> {}
|
||||
));
|
||||
|
||||
// Кнопка "Помощь"
|
||||
mainMenuButtons.add(new MenuButton(
|
||||
width/2 - buttonWidth/2, startY - spacing * 2, buttonWidth, buttonHeight,
|
||||
"❓ ПОМОЩЬ",
|
||||
new Color(0.2f, 0.7f, 0.3f, 0.9f),
|
||||
new Color(0.3f, 0.8f, 0.4f, 1f),
|
||||
() -> {}
|
||||
));
|
||||
|
||||
// Кнопка "Об игре"
|
||||
mainMenuButtons.add(new MenuButton(
|
||||
width/2 - buttonWidth/2, startY - spacing * 3, buttonWidth, buttonHeight,
|
||||
"ℹ️ ОБ ИГРЕ",
|
||||
new Color(0.7f, 0.2f, 0.7f, 0.9f),
|
||||
new Color(0.8f, 0.3f, 0.8f, 1f),
|
||||
width/2 - buttonWidth/2, startY - spacing * 4, buttonWidth, buttonHeight,
|
||||
Localization.help(),
|
||||
GameConfig.BUTTON_HELP,
|
||||
GameConfig.BUTTON_HELP_HOVER,
|
||||
() -> {}
|
||||
));
|
||||
|
||||
// Кнопка "Выход"
|
||||
mainMenuButtons.add(new MenuButton(
|
||||
width/2 - buttonWidth/2, startY - spacing * 4, buttonWidth, buttonHeight,
|
||||
"🚪 ВЫХОД",
|
||||
new Color(0.8f, 0.2f, 0.2f, 0.9f),
|
||||
new Color(0.9f, 0.3f, 0.3f, 1f),
|
||||
width/2 - buttonWidth/2, startY - spacing * 5, buttonWidth, buttonHeight,
|
||||
Localization.exit(),
|
||||
GameConfig.BUTTON_EXIT,
|
||||
GameConfig.BUTTON_EXIT_HOVER,
|
||||
() -> System.exit(0)
|
||||
));
|
||||
}
|
||||
|
||||
// Обновить тексты кнопок меню (при смене языка).
|
||||
public void refreshMenuTexts() {
|
||||
createMainMenuButtons();
|
||||
createPlanetSelectButtons();
|
||||
createHelpButtons();
|
||||
createAchievementsButtons();
|
||||
}
|
||||
|
||||
private void createPlanetSelectButtons() {
|
||||
planetSelectButtons = new ArrayList<>();
|
||||
float buttonWidth = 350;
|
||||
@@ -105,36 +124,36 @@ public class MenuRenderer {
|
||||
// Земля
|
||||
planetSelectButtons.add(new MenuButton(
|
||||
width/2 - buttonWidth - 20, startY, buttonWidth, buttonHeight,
|
||||
"🌍 ЗЕМЛЯ",
|
||||
new Color(0.3f, 0.6f, 0.9f, 0.9f),
|
||||
new Color(0.4f, 0.7f, 1.0f, 1f),
|
||||
Localization.earth(),
|
||||
GameConfig.BUTTON_EARTH,
|
||||
GameConfig.BUTTON_EARTH_HOVER,
|
||||
() -> {}
|
||||
).withTextColor(Color.WHITE));
|
||||
|
||||
// Марс
|
||||
planetSelectButtons.add(new MenuButton(
|
||||
width/2 + 20, startY, buttonWidth, buttonHeight,
|
||||
"♂️ МАРС",
|
||||
new Color(0.8f, 0.3f, 0.2f, 0.9f),
|
||||
new Color(0.9f, 0.4f, 0.3f, 1f),
|
||||
Localization.mars(),
|
||||
GameConfig.BUTTON_MARS,
|
||||
GameConfig.BUTTON_MARS_HOVER,
|
||||
() -> {}
|
||||
));
|
||||
|
||||
// Венера
|
||||
planetSelectButtons.add(new MenuButton(
|
||||
width/2 - buttonWidth/2, startY - spacing, buttonWidth, buttonHeight,
|
||||
"♀️ ВЕНЕРА",
|
||||
new Color(1.0f, 0.7f, 0.2f, 0.9f),
|
||||
new Color(1.0f, 0.8f, 0.3f, 1f),
|
||||
Localization.venus(),
|
||||
GameConfig.BUTTON_VENUS,
|
||||
GameConfig.BUTTON_VENUS_HOVER,
|
||||
() -> {}
|
||||
));
|
||||
|
||||
// Кнопка "Назад"
|
||||
planetSelectButtons.add(new MenuButton(
|
||||
50, 50, 200, 60,
|
||||
"⬅️ НАЗАД",
|
||||
new Color(0.4f, 0.4f, 0.4f, 0.9f),
|
||||
new Color(0.5f, 0.5f, 0.5f, 1f),
|
||||
Localization.back(),
|
||||
GameConfig.BUTTON_BACK,
|
||||
GameConfig.BUTTON_BACK_HOVER,
|
||||
() -> {}
|
||||
));
|
||||
}
|
||||
@@ -145,9 +164,22 @@ public class MenuRenderer {
|
||||
// Кнопка "Назад"
|
||||
helpButtons.add(new MenuButton(
|
||||
50, 50, 200, 60,
|
||||
"⬅️ НАЗАД",
|
||||
new Color(0.4f, 0.4f, 0.4f, 0.9f),
|
||||
new Color(0.5f, 0.5f, 0.5f, 1f),
|
||||
Localization.back(),
|
||||
GameConfig.BUTTON_BACK,
|
||||
GameConfig.BUTTON_BACK_HOVER,
|
||||
() -> {}
|
||||
));
|
||||
}
|
||||
|
||||
private void createAchievementsButtons() {
|
||||
achievementsButtons = new ArrayList<>();
|
||||
|
||||
// Кнопка "Назад"
|
||||
achievementsButtons.add(new MenuButton(
|
||||
50, 50, 200, 60,
|
||||
Localization.back(),
|
||||
GameConfig.BUTTON_BACK,
|
||||
GameConfig.BUTTON_BACK_HOVER,
|
||||
() -> {}
|
||||
));
|
||||
}
|
||||
@@ -169,16 +201,28 @@ public class MenuRenderer {
|
||||
// Подзаголовок
|
||||
font.setColor(new Color(0.8f, 0.9f, 1.0f, 0.8f));
|
||||
font.getData().setScale(1.2f);
|
||||
String subtitle = "Строй абсурдные города на разных планетах!";
|
||||
String subtitle = Localization.gameSubtitle();
|
||||
layout.setText(font, subtitle);
|
||||
font.draw(batch, subtitle, width/2 - layout.width/2, height - 150);
|
||||
font.getData().setScale(1.0f);
|
||||
|
||||
// Кнопки
|
||||
for (MenuButton button : mainMenuButtons) {
|
||||
boolean hasSave = GameSave.hasSave();
|
||||
for (int i = 0; i < mainMenuButtons.size(); i++) {
|
||||
MenuButton button = mainMenuButtons.get(i);
|
||||
// Скрываем кнопку "Продолжить" если нет сохранения
|
||||
if (i == 0 && !hasSave) {
|
||||
continue;
|
||||
}
|
||||
button.render(batch, font, layout, whitePixel);
|
||||
}
|
||||
|
||||
// Переключатель языка
|
||||
renderLanguageSwitch(mouseX, mouseY);
|
||||
|
||||
// Статистика
|
||||
renderStats();
|
||||
|
||||
// Автор
|
||||
font.setColor(new Color(1, 1, 1, 0.5f));
|
||||
font.getData().setScale(0.8f);
|
||||
@@ -188,6 +232,61 @@ public class MenuRenderer {
|
||||
batch.end();
|
||||
}
|
||||
|
||||
private void renderLanguageSwitch(float mouseX, float mouseY) {
|
||||
float langX = width - 80;
|
||||
float langY = height - 50;
|
||||
float langW = 60;
|
||||
float langH = 35;
|
||||
|
||||
// Фон кнопки
|
||||
boolean hovered = mouseX >= langX && mouseX <= langX + langW &&
|
||||
mouseY >= langY && mouseY <= langY + langH;
|
||||
batch.setColor(hovered ? new Color(0.4f, 0.5f, 0.6f, 0.9f) : new Color(0.3f, 0.4f, 0.5f, 0.8f));
|
||||
batch.draw(whitePixel, langX, langY, langW, langH);
|
||||
|
||||
// Рамка
|
||||
batch.setColor(Color.WHITE);
|
||||
batch.draw(whitePixel, langX, langY, langW, 2);
|
||||
batch.draw(whitePixel, langX, langY + langH - 2, langW, 2);
|
||||
batch.draw(whitePixel, langX, langY, 2, langH);
|
||||
batch.draw(whitePixel, langX + langW - 2, langY, 2, langH);
|
||||
|
||||
// Текст языка
|
||||
font.setColor(Color.WHITE);
|
||||
font.getData().setScale(1.0f);
|
||||
String langText = Localization.getLanguageLabel();
|
||||
layout.setText(font, langText);
|
||||
font.draw(batch, langText, langX + langW/2 - layout.width/2, langY + langH/2 + layout.height/2);
|
||||
}
|
||||
|
||||
private void renderStats() {
|
||||
font.setColor(new Color(0.7f, 0.8f, 0.9f, 0.7f));
|
||||
font.getData().setScale(0.8f);
|
||||
|
||||
int total = GameSave.getTotalBuildings();
|
||||
int achievements = Achievements.getUnlockedCount();
|
||||
int totalAch = Achievements.getTotalCount();
|
||||
|
||||
String stats = Localization.isRu()
|
||||
? "Построено зданий: " + total + " | Достижения: " + achievements + "/" + totalAch
|
||||
: "Buildings: " + total + " | Achievements: " + achievements + "/" + totalAch;
|
||||
|
||||
layout.setText(font, stats);
|
||||
font.draw(batch, stats, width/2 - layout.width/2, 60);
|
||||
font.getData().setScale(1.0f);
|
||||
}
|
||||
|
||||
// Проверить клик на переключатель языка.
|
||||
public boolean checkLanguageClick(float mouseX, float mouseY) {
|
||||
float langX = width - 80;
|
||||
float langY = height - 50;
|
||||
float langW = 60;
|
||||
float langH = 35;
|
||||
|
||||
return mouseX >= langX && mouseX <= langX + langW &&
|
||||
mouseY >= langY && mouseY <= langY + langH;
|
||||
}
|
||||
|
||||
public void renderPlanetSelect(float mouseX, float mouseY) {
|
||||
batch.begin();
|
||||
|
||||
@@ -196,14 +295,14 @@ public class MenuRenderer {
|
||||
|
||||
// Заголовок
|
||||
titleFont.setColor(new Color(1, 1, 1, 0.9f));
|
||||
String title = "🪐 ВЫБОР ПЛАНЕТЫ";
|
||||
String title = Localization.selectPlanet();
|
||||
layout.setText(titleFont, title);
|
||||
titleFont.draw(batch, title, width/2 - layout.width/2, height - 100);
|
||||
|
||||
// Описание
|
||||
font.setColor(new Color(0.8f, 0.9f, 1.0f, 0.8f));
|
||||
font.getData().setScale(1.1f);
|
||||
String desc = "Выберите планету для строительства:";
|
||||
String desc = Localization.isRu() ? "Выберите планету для строительства:" : "Select a planet for building:";
|
||||
layout.setText(font, desc);
|
||||
font.draw(batch, desc, width/2 - layout.width/2, height - 170);
|
||||
font.getData().setScale(1.0f);
|
||||
@@ -213,18 +312,21 @@ public class MenuRenderer {
|
||||
font.getData().setScale(0.9f);
|
||||
|
||||
// Земля
|
||||
String earthText = "Мультяшные здания\nЯркие цвета\nМилые жители";
|
||||
layout.setText(font, earthText);
|
||||
String earthText = Localization.isRu()
|
||||
? "Мультяшные здания\nЯркие цвета\nМилые жители"
|
||||
: "Cartoon buildings\nBright colors\nCute residents";
|
||||
font.draw(batch, earthText, width/2 - 380, height/2 - 50);
|
||||
|
||||
// Марс
|
||||
String marsText = "Технологичные постройки\nКрасный пейзаж\nМарсианские роботы";
|
||||
layout.setText(font, marsText);
|
||||
// Марс
|
||||
String marsText = Localization.isRu()
|
||||
? "Технологичные постройки\nКрасный пейзаж\nМарсианские роботы"
|
||||
: "Tech buildings\nRed landscape\nMartian robots";
|
||||
font.draw(batch, marsText, width/2 + 30, height/2 - 50);
|
||||
|
||||
// Венера
|
||||
String venusText = "Вулканические здания\nРаскаленная атмосфера\nКристаллические формы";
|
||||
layout.setText(font, venusText);
|
||||
// Венера
|
||||
String venusText = Localization.isRu()
|
||||
? "Вулканические здания\nРаскаленная атмосфера\nКристаллические формы"
|
||||
: "Volcanic buildings\nHot atmosphere\nCrystal forms";
|
||||
font.draw(batch, venusText, width/2 - 175, height/2 - 200);
|
||||
font.getData().setScale(1.0f);
|
||||
|
||||
@@ -240,13 +342,13 @@ public class MenuRenderer {
|
||||
batch.begin();
|
||||
|
||||
// Фон
|
||||
batch.setColor(new Color(0.1f, 0.1f, 0.2f, 0.95f));
|
||||
batch.setColor(GameConfig.MENU_SPACE_BG);
|
||||
batch.draw(whitePixel, 0, 0, width, height);
|
||||
batch.setColor(Color.WHITE);
|
||||
|
||||
// Заголовок
|
||||
titleFont.setColor(Color.YELLOW);
|
||||
String title = "❓ ПОМОЩЬ И УПРАВЛЕНИЕ";
|
||||
String title = Localization.isRu() ? "❓ ПОМОЩЬ И УПРАВЛЕНИЕ" : "❓ HELP & CONTROLS";
|
||||
layout.setText(titleFont, title);
|
||||
titleFont.draw(batch, title, width/2 - layout.width/2, height - 100);
|
||||
|
||||
@@ -257,14 +359,14 @@ public class MenuRenderer {
|
||||
float textY = height - 200;
|
||||
float lineHeight = 35;
|
||||
|
||||
String[] instructions = {
|
||||
String[] instructions = Localization.isRu() ? new String[] {
|
||||
"🎮 ОСНОВНОЕ УПРАВЛЕНИЕ:",
|
||||
"• ЛКМ - кликнуть на поле для строительства",
|
||||
"• ←/→ - выбрать тип здания",
|
||||
"• Enter - отправить ответ на задачу",
|
||||
"• Backspace - удалить блок/символ",
|
||||
"• Delete/Ctrl+Z - удалить здание",
|
||||
"• ESC - отмена ввода",
|
||||
"• ESC - отмена ввода / меню",
|
||||
"",
|
||||
"🪐 УПРАВЛЕНИЕ ПЛАНЕТАМИ:",
|
||||
"• ↑/↓ - переключить планету",
|
||||
@@ -274,8 +376,25 @@ public class MenuRenderer {
|
||||
"1. Выберите тип здания",
|
||||
"2. Кликните на игровом поле",
|
||||
"3. Решите математическую задачу",
|
||||
"4. Постройте 3 блока для завершения",
|
||||
"5. Стройте разные здания на разных планетах!"
|
||||
"4. Постройте 3 блока для завершения"
|
||||
} : new String[] {
|
||||
"🎮 BASIC CONTROLS:",
|
||||
"• LMB - click on the field to build",
|
||||
"• ←/→ - select building type",
|
||||
"• Enter - submit answer",
|
||||
"• Backspace - delete block/character",
|
||||
"• Delete/Ctrl+Z - delete building",
|
||||
"• ESC - cancel input / menu",
|
||||
"",
|
||||
"🪐 PLANET CONTROLS:",
|
||||
"• ↑/↓ - switch planet",
|
||||
"• 1 - Earth, 2 - Mars, 3 - Venus",
|
||||
"",
|
||||
"🎯 HOW TO PLAY:",
|
||||
"1. Select building type",
|
||||
"2. Click on the game field",
|
||||
"3. Solve the math problem",
|
||||
"4. Build 3 blocks to complete"
|
||||
};
|
||||
|
||||
for (String line : instructions) {
|
||||
@@ -300,11 +419,83 @@ public class MenuRenderer {
|
||||
batch.end();
|
||||
}
|
||||
|
||||
public void renderAchievements(float mouseX, float mouseY) {
|
||||
batch.begin();
|
||||
|
||||
// Фон
|
||||
batch.setColor(new Color(0.08f, 0.05f, 0.12f, 1));
|
||||
batch.draw(whitePixel, 0, 0, width, height);
|
||||
batch.setColor(Color.WHITE);
|
||||
|
||||
// Заголовок
|
||||
titleFont.setColor(new Color(1f, 0.85f, 0.3f, 1));
|
||||
String title = Localization.achievements();
|
||||
layout.setText(titleFont, title);
|
||||
titleFont.draw(batch, title, width/2 - layout.width/2, height - 80);
|
||||
|
||||
// Прогресс
|
||||
font.setColor(new Color(0.8f, 0.8f, 0.8f, 1));
|
||||
font.getData().setScale(1.0f);
|
||||
String progress = Achievements.getUnlockedCount() + " / " + Achievements.getTotalCount();
|
||||
layout.setText(font, progress);
|
||||
font.draw(batch, progress, width/2 - layout.width/2, height - 120);
|
||||
|
||||
// Список достижений
|
||||
float startY = height - 180;
|
||||
float itemHeight = 70;
|
||||
float itemWidth = 600;
|
||||
float itemX = width/2 - itemWidth/2;
|
||||
|
||||
Achievement[] all = Achievements.getAll();
|
||||
for (int i = 0; i < all.length; i++) {
|
||||
Achievement a = all[i];
|
||||
boolean unlocked = Achievements.isUnlocked(a);
|
||||
float y = startY - i * itemHeight;
|
||||
|
||||
// Фон элемента
|
||||
if (unlocked) {
|
||||
batch.setColor(new Color(0.2f, 0.3f, 0.2f, 0.8f));
|
||||
} else {
|
||||
batch.setColor(new Color(0.15f, 0.15f, 0.2f, 0.6f));
|
||||
}
|
||||
batch.draw(whitePixel, itemX, y, itemWidth, itemHeight - 5);
|
||||
|
||||
// Рамка
|
||||
batch.setColor(unlocked ? new Color(0.5f, 0.8f, 0.5f, 0.5f) : new Color(0.3f, 0.3f, 0.4f, 0.3f));
|
||||
batch.draw(whitePixel, itemX, y, itemWidth, 2);
|
||||
batch.draw(whitePixel, itemX, y + itemHeight - 7, itemWidth, 2);
|
||||
|
||||
// Иконка
|
||||
font.getData().setScale(1.3f);
|
||||
font.setColor(unlocked ? new Color(0.3f, 0.9f, 0.3f, 1) : new Color(0.4f, 0.4f, 0.5f, 1));
|
||||
font.draw(batch, unlocked ? "✓" : "○", itemX + 15, y + itemHeight - 25);
|
||||
|
||||
// Название
|
||||
font.getData().setScale(1.1f);
|
||||
font.setColor(unlocked ? Color.WHITE : new Color(0.6f, 0.6f, 0.6f, 1));
|
||||
font.draw(batch, a.getTitle(), itemX + 55, y + itemHeight - 20);
|
||||
|
||||
// Описание
|
||||
font.getData().setScale(0.85f);
|
||||
font.setColor(unlocked ? new Color(0.8f, 0.8f, 0.8f, 1) : new Color(0.5f, 0.5f, 0.5f, 1));
|
||||
font.draw(batch, a.getDescription(), itemX + 55, y + itemHeight - 45);
|
||||
}
|
||||
|
||||
font.getData().setScale(1.0f);
|
||||
|
||||
// Кнопка назад
|
||||
for (MenuButton button : achievementsButtons) {
|
||||
button.render(batch, font, layout, whitePixel);
|
||||
}
|
||||
|
||||
batch.end();
|
||||
}
|
||||
|
||||
public void renderAbout(float mouseX, float mouseY) {
|
||||
batch.begin();
|
||||
|
||||
// Галактический фон
|
||||
batch.setColor(new Color(0.05f, 0.05f, 0.1f, 1));
|
||||
batch.setColor(GameConfig.MENU_SPACE_BG);
|
||||
batch.draw(whitePixel, 0, 0, width, height);
|
||||
|
||||
// Звезды
|
||||
@@ -320,7 +511,7 @@ public class MenuRenderer {
|
||||
|
||||
// Заголовок
|
||||
titleFont.setColor(new Color(0.8f, 0.4f, 1.0f, 1));
|
||||
String title = "✨ ОБ ИГРЕ";
|
||||
String title = Localization.about();
|
||||
layout.setText(titleFont, title);
|
||||
titleFont.draw(batch, title, width/2 - layout.width/2, height - 100);
|
||||
|
||||
@@ -328,7 +519,7 @@ public class MenuRenderer {
|
||||
font.setColor(new Color(0.9f, 0.9f, 1.0f, 0.9f));
|
||||
font.getData().setScale(1.2f);
|
||||
|
||||
String[] aboutText = {
|
||||
String[] aboutText = Localization.isRu() ? new String[] {
|
||||
"Absurd City Builder - это уникальная игра,",
|
||||
"где вы строите безумные города на разных планетах!",
|
||||
"",
|
||||
@@ -336,12 +527,26 @@ public class MenuRenderer {
|
||||
"• 3 уникальные планеты с разными зданиями",
|
||||
"• Забавные математические задачи",
|
||||
"• Мультяшная графика и анимации",
|
||||
"• Динамичные жители и шутки",
|
||||
"• Бесконечные возможности для творчества!",
|
||||
"• Система достижений",
|
||||
"• Поддержка русского и английского языков",
|
||||
"",
|
||||
"Разработано с ❤️ для любителей абсурда и математики.",
|
||||
"",
|
||||
"Версия 1.0"
|
||||
"Версия 1.1"
|
||||
} : new String[] {
|
||||
"Absurd City Builder is a unique game",
|
||||
"where you build crazy cities on different planets!",
|
||||
"",
|
||||
"Features:",
|
||||
"• 3 unique planets with different buildings",
|
||||
"• Fun math puzzles",
|
||||
"• Cartoon graphics and animations",
|
||||
"• Achievement system",
|
||||
"• Russian and English support",
|
||||
"",
|
||||
"Made with ❤️ for absurdity and math lovers.",
|
||||
"",
|
||||
"Version 1.1"
|
||||
};
|
||||
|
||||
float textY = height - 200;
|
||||
@@ -356,9 +561,9 @@ public class MenuRenderer {
|
||||
// Кнопка "Назад"
|
||||
MenuButton backButton = new MenuButton(
|
||||
50, 50, 200, 60,
|
||||
"⬅️ НАЗАД",
|
||||
new Color(0.4f, 0.4f, 0.4f, 0.9f),
|
||||
new Color(0.5f, 0.5f, 0.5f, 1f),
|
||||
Localization.back(),
|
||||
GameConfig.BUTTON_BACK,
|
||||
GameConfig.BUTTON_BACK_HOVER,
|
||||
() -> {}
|
||||
);
|
||||
backButton.render(batch, font, layout, whitePixel);
|
||||
@@ -368,7 +573,7 @@ public class MenuRenderer {
|
||||
|
||||
private void renderSpaceBackground() {
|
||||
// Темный космический фон
|
||||
batch.setColor(new Color(0.05f, 0.05f, 0.1f, 1));
|
||||
batch.setColor(GameConfig.MENU_SPACE_BG);
|
||||
batch.draw(whitePixel, 0, 0, width, height);
|
||||
|
||||
// Звезды
|
||||
@@ -399,7 +604,7 @@ public class MenuRenderer {
|
||||
float pulse = 0.8f + 0.2f * (float)Math.sin(titlePulse);
|
||||
titleFont.setColor(new Color(1, pulse, 0.5f, 1));
|
||||
|
||||
String title = "✨ ABSURD CITY BUILDER ✨";
|
||||
String title = Localization.gameTitle();
|
||||
layout.setText(titleFont, title);
|
||||
titleFont.draw(batch, title, width/2 - layout.width/2, height - 100);
|
||||
|
||||
@@ -415,7 +620,13 @@ public class MenuRenderer {
|
||||
}
|
||||
|
||||
public MenuButton getMainMenuButtonAt(float x, float y) {
|
||||
for (MenuButton button : mainMenuButtons) {
|
||||
boolean hasSave = GameSave.hasSave();
|
||||
for (int i = 0; i < mainMenuButtons.size(); i++) {
|
||||
// Пропускаем кнопку "Продолжить" если нет сохранения
|
||||
if (i == 0 && !hasSave) {
|
||||
continue;
|
||||
}
|
||||
MenuButton button = mainMenuButtons.get(i);
|
||||
if (button.contains(x, y)) {
|
||||
return button;
|
||||
}
|
||||
@@ -441,6 +652,15 @@ public class MenuRenderer {
|
||||
return null;
|
||||
}
|
||||
|
||||
public MenuButton getAchievementsButtonAt(float x, float y) {
|
||||
for (MenuButton button : achievementsButtons) {
|
||||
if (button.contains(x, y)) {
|
||||
return button;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
titleFont.dispose();
|
||||
}
|
||||
|
||||
@@ -32,11 +32,13 @@ public class UIRenderer {
|
||||
Building currentBuilding, Planet currentPlanet, boolean isSwitchingPlanets) {
|
||||
batch.begin();
|
||||
|
||||
batch.setColor(0.2f, 0.3f, 0.4f, 0.95f);
|
||||
// Фон панели
|
||||
batch.setColor(GameConfig.UI_PANEL_BG);
|
||||
batch.draw(whitePixel, 0, 0, WIDTH, UI_INPUT_HEIGHT);
|
||||
batch.setColor(Color.WHITE);
|
||||
|
||||
batch.setColor(0.4f, 0.6f, 0.8f, 1);
|
||||
// Граница панели
|
||||
batch.setColor(GameConfig.UI_PANEL_BORDER);
|
||||
batch.draw(whitePixel, 0, UI_INPUT_HEIGHT, WIDTH, 3);
|
||||
batch.setColor(Color.WHITE);
|
||||
|
||||
@@ -47,19 +49,20 @@ public class UIRenderer {
|
||||
|
||||
// ==================== ЛЕВАЯ КОЛОНКА ====================
|
||||
// Отображение текущей планеты
|
||||
String planetDisplay = "🌍 Планета: " + currentPlanet.getName();
|
||||
String planetLabel = Localization.isRu() ? "🌍 Планета: " : "🌍 Planet: ";
|
||||
String planetDisplay = planetLabel + Localization.planetName(currentPlanet);
|
||||
if (isSwitchingPlanets) {
|
||||
planetDisplay += " (Перелет...)";
|
||||
planetDisplay += Localization.isRu() ? " (Перелет...)" : " (Flying...)";
|
||||
}
|
||||
font.draw(batch, planetDisplay, 20, currentY);
|
||||
currentY -= lineHeight;
|
||||
|
||||
// Управление планетой
|
||||
font.setColor(Color.YELLOW);
|
||||
font.draw(batch, "↑/↓ - сменить планету", 20, currentY);
|
||||
font.draw(batch, Localization.changePlanet(), 20, currentY);
|
||||
currentY -= lineHeight;
|
||||
font.setColor(Color.LIGHT_GRAY);
|
||||
font.draw(batch, "1-Земля, 2-Марс, 3-Венера", 20, currentY);
|
||||
font.draw(batch, Localization.planetKeys(), 20, currentY);
|
||||
currentY -= lineHeight;
|
||||
|
||||
font.setColor(Color.WHITE);
|
||||
@@ -67,13 +70,14 @@ public class UIRenderer {
|
||||
currentY -= lineHeight;
|
||||
|
||||
// Тип здания
|
||||
String[] planetBuildings = Building.BUILDING_TYPES_BY_PLANET[currentPlanet.ordinal()];
|
||||
font.draw(batch, "🏗️ Тип здания: " + planetBuildings[selectedBuildingType], 20, currentY);
|
||||
String[][] buildingNames = Localization.getBuildingNames();
|
||||
String buildingLabel = Localization.isRu() ? "🏗️ Тип здания: " : "🏗️ Building: ";
|
||||
font.draw(batch, buildingLabel + buildingNames[currentPlanet.ordinal()][selectedBuildingType], 20, currentY);
|
||||
currentY -= lineHeight;
|
||||
|
||||
// Управление зданиями
|
||||
font.setColor(Color.CYAN);
|
||||
font.draw(batch, "←/→ - выбрать тип здания", 20, currentY);
|
||||
font.draw(batch, Localization.selectBuildingType(), 20, currentY);
|
||||
currentY -= lineHeight;
|
||||
|
||||
font.setColor(Color.WHITE);
|
||||
@@ -99,12 +103,8 @@ public class UIRenderer {
|
||||
currentY -= lineHeight;
|
||||
|
||||
// Прогресс строительства
|
||||
if (currentBuilding != null) {
|
||||
font.draw(batch, "📊 Прогресс: " + currentBuilding.constructionProgress + "/3 блоков",
|
||||
20, currentY);
|
||||
} else {
|
||||
font.draw(batch, "📊 Прогресс: 0/3 блоков", 20, currentY);
|
||||
}
|
||||
int progress = currentBuilding != null ? currentBuilding.constructionProgress : 0;
|
||||
font.draw(batch, Localization.buildingProgress(progress, 3), 20, currentY);
|
||||
currentY -= lineHeight;
|
||||
|
||||
// ==================== ПРАВАЯ КОЛОНКА ====================
|
||||
@@ -131,13 +131,13 @@ public class UIRenderer {
|
||||
|
||||
private void renderInputSection(MathProblem currentProblem, String inputText, float time) {
|
||||
// Фон для ввода
|
||||
batch.setColor(0.3f, 0.4f, 0.5f, 0.8f);
|
||||
batch.setColor(GameConfig.UI_INPUT_BG);
|
||||
batch.draw(whitePixel, WIDTH/2 - 250, UI_INPUT_HEIGHT - 150, 500, 130);
|
||||
batch.setColor(Color.WHITE);
|
||||
|
||||
// Задача
|
||||
font.setColor(Color.YELLOW);
|
||||
String mathProblem = "🧮 Задача: " + currentProblem.getQuestion();
|
||||
String mathProblem = Localization.task(currentProblem.getQuestion());
|
||||
glyphLayout.setText(font, mathProblem);
|
||||
font.draw(batch, mathProblem,
|
||||
WIDTH/2 - glyphLayout.width/2,
|
||||
@@ -145,7 +145,7 @@ public class UIRenderer {
|
||||
|
||||
// Поле ввода
|
||||
font.setColor(Color.WHITE);
|
||||
font.draw(batch, "✏️ Введите ответ:", WIDTH/2 - 230, UI_INPUT_HEIGHT - 95);
|
||||
font.draw(batch, Localization.enterAnswer(), WIDTH/2 - 230, UI_INPUT_HEIGHT - 95);
|
||||
|
||||
// Введенный текст
|
||||
String inputStr = inputText.isEmpty() ? "_" : inputText;
|
||||
@@ -161,15 +161,15 @@ public class UIRenderer {
|
||||
// Подсказки
|
||||
font.setColor(Color.LIGHT_GRAY);
|
||||
font.getData().setScale(0.7f);
|
||||
font.draw(batch, "⏎ Enter - отправить ответ", WIDTH/2 - 230, UI_INPUT_HEIGHT - 160);
|
||||
font.draw(batch, "⎋ ESC - отмена ввода", WIDTH/2 - 230, UI_INPUT_HEIGHT - 180);
|
||||
font.draw(batch, "⌫ Backspace - удалить символ", WIDTH/2 - 230, UI_INPUT_HEIGHT - 200);
|
||||
font.draw(batch, Localization.enterSubmit(), WIDTH/2 - 230, UI_INPUT_HEIGHT - 160);
|
||||
font.draw(batch, Localization.escCancel(), WIDTH/2 - 230, UI_INPUT_HEIGHT - 180);
|
||||
font.draw(batch, Localization.backspaceDelete(), WIDTH/2 - 230, UI_INPUT_HEIGHT - 200);
|
||||
font.getData().setScale(1.0f);
|
||||
}
|
||||
|
||||
private void renderWrongAnswerJoke(String wrongAnswerJoke) {
|
||||
// Фон для шутки
|
||||
batch.setColor(1, 0.2f, 0.2f, 0.3f);
|
||||
batch.setColor(GameConfig.UI_WRONG_ANSWER_BG);
|
||||
batch.draw(whitePixel, WIDTH/2 - 300, HEIGHT/2 - 50, 600, 100);
|
||||
batch.setColor(Color.WHITE);
|
||||
|
||||
@@ -183,25 +183,24 @@ public class UIRenderer {
|
||||
font.getData().setScale(1.0f);
|
||||
}
|
||||
|
||||
// ВОТ ТОТ САМЫЙ МЕТОД, КОТОРЫЙ ВЫ СПРАШИВАЛИ:
|
||||
private void renderBottomPanel(Planet planet, boolean isSwitchingPlanets) {
|
||||
font.setColor(Color.LIGHT_GRAY);
|
||||
font.getData().setScale(0.6f);
|
||||
|
||||
// Основные инструкции
|
||||
String instruction = "🖱️ Кликните на поле для строительства";
|
||||
String instruction = Localization.clickToBuild();
|
||||
glyphLayout.setText(font, instruction);
|
||||
font.draw(batch, instruction, WIDTH/2 - glyphLayout.width/2, 30);
|
||||
|
||||
// Управление
|
||||
String controls = "🗑️ Delete/Ctrl+Z - удалить здание | ⌫ Backspace - удалить блок | ⎋ ESC - меню";
|
||||
String controls = Localization.controls();
|
||||
glyphLayout.setText(font, controls);
|
||||
font.draw(batch, controls, WIDTH/2 - glyphLayout.width/2, 15);
|
||||
|
||||
// Индикатор планеты
|
||||
font.setColor(getPlanetColor(planet));
|
||||
font.setColor(GameConfig.getPlanetUIColor(planet));
|
||||
font.getData().setScale(0.8f);
|
||||
String planetInfo = getPlanetEmoji(planet) + " " + planet.getName();
|
||||
String planetInfo = GameConfig.getPlanetEmoji(planet) + " " + Localization.planetName(planet);
|
||||
if (isSwitchingPlanets) {
|
||||
planetInfo += " 🚀";
|
||||
}
|
||||
@@ -210,25 +209,6 @@ public class UIRenderer {
|
||||
font.getData().setScale(1.0f);
|
||||
}
|
||||
|
||||
// Вспомогательные методы для работы с планетами:
|
||||
private Color getPlanetColor(Planet planet) {
|
||||
switch (planet) {
|
||||
case EARTH: return new Color(0.3f, 0.7f, 1.0f, 1);
|
||||
case MARS: return new Color(1.0f, 0.4f, 0.3f, 1);
|
||||
case VENUS: return new Color(1.0f, 0.8f, 0.3f, 1);
|
||||
default: return Color.WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
private String getPlanetEmoji(Planet planet) {
|
||||
switch (planet) {
|
||||
case EARTH: return "🌍";
|
||||
case MARS: return "♂️";
|
||||
case VENUS: return "♀️";
|
||||
default: return "🪐";
|
||||
}
|
||||
}
|
||||
|
||||
private void drawWrappedText(String text, float x, float y, float maxWidth) {
|
||||
String[] words = text.split(" ");
|
||||
StringBuilder line = new StringBuilder();
|
||||
|
||||
@@ -7,27 +7,26 @@ public class UIUpdater {
|
||||
}
|
||||
|
||||
Planet planet = game.getCurrentPlanet();
|
||||
String[] planetBuildings = Building.BUILDING_TYPES_BY_PLANET[planet.ordinal()];
|
||||
|
||||
if (game.getCurrentBuilding() != null && game.getCurrentProblem() != null) {
|
||||
String overlapText = game.getCurrentBuilding().isOverlapping ? " (пересекается!)" : "";
|
||||
String overlapText = game.getCurrentBuilding().isOverlapping ? " " + Localization.overlapping() : "";
|
||||
String colorInfo = "";
|
||||
if (game.getCurrentBuilding().isComplete()) {
|
||||
colorInfo = String.format(" [Цвет: Тема %d]", game.getCurrentBuilding().colorThemeIndex + 1);
|
||||
colorInfo = String.format(" [%s %d]", Localization.colorTheme(), game.getCurrentBuilding().colorThemeIndex + 1);
|
||||
}
|
||||
String fullText = "Строим " + game.getCurrentBuilding().type +
|
||||
String fullText = Localization.building() + " " + Localization.getBuildingName(game.getCurrentBuilding()) +
|
||||
" (" + game.getCurrentBuilding().constructionProgress + "/3)" + colorInfo +
|
||||
": " + game.getCurrentProblem().getQuestion() + overlapText;
|
||||
game.setProblemText(fullText);
|
||||
} else {
|
||||
String planetText = game.isSwitchingPlanets() ?
|
||||
"Перелет на " + game.getTargetPlanet().getName() + "..." :
|
||||
"Планета: " + planet.getName();
|
||||
Localization.flyingTo() + " " + Localization.planetName(game.getTargetPlanet()) + "..." :
|
||||
Localization.planet() + ": " + Localization.planetName(planet);
|
||||
|
||||
game.setProblemText(planetText +
|
||||
" | Тип здания: " + planetBuildings[game.getSelectedBuildingType()] +
|
||||
" (←/→ для выбора, кликните на поле для строительства)" +
|
||||
" | ESC - меню");
|
||||
" | " + Localization.buildingType() + ": " + Localization.getBuildingName(planet, game.getSelectedBuildingType()) +
|
||||
" " + Localization.arrowsToSelect() +
|
||||
" | ESC - " + Localization.menu());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user