Initial commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
sourceCompatibility = 1.7
|
||||
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
||||
|
||||
sourceSets.main.java.srcDirs = [ "src/" ]
|
||||
|
||||
eclipse.project.name = appName + "-core"
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
|
||||
|
||||
public class FontBuilder {
|
||||
|
||||
public static BitmapFont generate(int size, Color color, String fontPath) {
|
||||
try {
|
||||
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal(fontPath));
|
||||
FreeTypeFontParameter parameter = new FreeTypeFontParameter();
|
||||
parameter.size = size;
|
||||
parameter.color = color;
|
||||
|
||||
parameter.characters = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюяABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .,!?-";
|
||||
BitmapFont font = generator.generateFont(parameter);
|
||||
generator.dispose();
|
||||
return font;
|
||||
} catch (Exception e) {
|
||||
|
||||
BitmapFont font = new BitmapFont();
|
||||
font.getData().setScale(size / 24f);
|
||||
font.setColor(color);
|
||||
return font;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
public class GameResources {
|
||||
|
||||
// ангар
|
||||
public static final String BASIC_PATH = "textures/Air/basic.png";
|
||||
public static final String FAST_PATH = "textures/Air/Speed.png";
|
||||
public static final String TANK_PATH = "textures/Air/tanks.png";
|
||||
|
||||
// Текстуры для кнопок
|
||||
|
||||
public static final String BUTTON_PATH = "textures/button/button.png";
|
||||
|
||||
public static final String BUTTON_PAUSE_PATH = "textures/button/button_pause.png";
|
||||
|
||||
public static final String BUTTON_ATTACK_PATH = "textures/button/button_attack.png";
|
||||
public static final String BUTTON_WEAPON_PATH = "textures/button/button_weapon.png";
|
||||
public static final String BUTTON_LEFT_PATH = "textures/button/button_left.png";
|
||||
public static final String BUTTON_RIGHT_PATH = "textures/button/button_right.png";
|
||||
public static final String BUTTON_SPEED_PATH = "textures/button/button_speed.png";
|
||||
|
||||
|
||||
// Фоны экранов
|
||||
public static final String LEVEL_SELECT_BG_PATH = "textures/background/level_select_bg.png";
|
||||
public static final String PLAYER_SELECT_BG_PATH = "textures/background/player_select_bg.png";
|
||||
public static final String GAME_OVER_BG_PATH = "textures/background/game_over_bg.png";
|
||||
public static final String MENU_BG_IMG_PATH = "textures/background/menu_bg.png";
|
||||
// Фоны уровней
|
||||
public static final String LEVEL1_BG_PATH = "textures/background/level1_bg.jpg";
|
||||
public static final String LEVEL2_BG_PATH = "textures/background/level2_bg.jpg";
|
||||
public static final String LEVEL3_BG_PATH = "textures/background/level3_bg.png";
|
||||
// Игрок
|
||||
public static final String PLAYER_BASIC_PATH = "textures/Air/player_basic.png";
|
||||
public static final String PLAYER_FAST_PATH = "textures/Air/player_fast.png";
|
||||
public static final String PLAYER_TANK_PATH = "textures/Air/player_tank.png";
|
||||
|
||||
// Враги
|
||||
public static final String ENEMY_BASIC_PATH = "textures/Air/enemy_basic.png";
|
||||
public static final String ENEMY_FAST_PATH = "textures/Air/enemy_fast.png";
|
||||
public static final String ENEMY_TANK_PATH = "textures/Air/enemy_tank.png";
|
||||
public static final String ENEMY_BOSS_PATH = "textures/Air/enemy_boss.png";
|
||||
|
||||
// Обычный враг
|
||||
public static final String ENEMY_FALLING1_PATH = "textures/Air/enemy_falling1.png";
|
||||
public static final String ENEMY_FALLING2_PATH = "textures/Air/enemy_falling2.png";
|
||||
// Быстрый враг
|
||||
public static final String ENEMY_FAST_FALLING1_PATH = "textures/Air/enemy_fast_falling1.png";
|
||||
public static final String ENEMY_FAST_FALLING2_PATH = "textures/Air/enemy_fast_falling2.png";
|
||||
// Танк
|
||||
public static final String ENEMY_TANK_FALLING1_PATH = "textures/Air/enemy_tank_falling1.png";
|
||||
public static final String ENEMY_TANK_FALLING2_PATH = "textures/Air/enemy_tank_falling2.png";
|
||||
// Босс
|
||||
public static final String ENEMY_BOSS_FALLING1_PATH = "textures/Air/enemy_boss_falling1.png";
|
||||
public static final String ENEMY_BOSS_FALLING2_PATH = "textures/Air/enemy_boss_falling2.png";
|
||||
// Боеприпасы
|
||||
public static final String BULLET_BASIC_PATH = "textures/bullet_basic.png";
|
||||
public static final String BULLET_ROCKET_PATH = "textures/bullet_rocket.png";
|
||||
//
|
||||
public static final String HEALTH_BG_PATH = "textures/health_bg.png";
|
||||
public static final String HEALTH_FILL_PATH = "textures/health_fill.png";
|
||||
public static final String EXPLOSION_PATH = "textures/explosion.png";
|
||||
|
||||
// Звуки
|
||||
public static final String BACKGROUND_MUSIC_PATH = "sounds/background.mp3";
|
||||
public static final String SHOOT_SOUND_PATH = "sounds/shoot.mp3";
|
||||
public static final String ROCKET_SOUND_PATH = "sounds/rocket.mp3";
|
||||
public static final String EXPLOSION_SOUND_PATH = "sounds/explosion.mp3";
|
||||
public static final String SELECT_SOUND_PATH = "sounds/select.mp3";
|
||||
|
||||
// Шрифты
|
||||
public static final String FONT_PATH = "fonts/arial.ttf";
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
|
||||
public class GameSettings {
|
||||
public static final int SCREEN_WIDTH = 1280;
|
||||
public static final int SCREEN_HEIGHT = 720;
|
||||
|
||||
//Игрок
|
||||
|
||||
public static final float[] SPEED_LEVELS = {0.5f, 0.8f, 1.0f};
|
||||
|
||||
public static class PlayerConfig {
|
||||
public String texturePath;
|
||||
public float speed;
|
||||
public int health;
|
||||
public float rotationSpeed;
|
||||
public String name;
|
||||
public String description;
|
||||
|
||||
public PlayerConfig(String texture, float speed, int health,
|
||||
float rotation, String name, String desc) {
|
||||
this.texturePath = texture;
|
||||
this.speed = speed;
|
||||
this.health = health;
|
||||
this.rotationSpeed = rotation;
|
||||
this.name = name;
|
||||
this.description = desc;
|
||||
}
|
||||
}
|
||||
|
||||
public static final PlayerConfig[] PLAYERS = {
|
||||
new PlayerConfig(
|
||||
GameResources.PLAYER_BASIC_PATH,
|
||||
300, 100, 180,
|
||||
"БАЗОВЫЙ",
|
||||
"Баланс скорости и защиты"
|
||||
),
|
||||
new PlayerConfig(
|
||||
GameResources.PLAYER_FAST_PATH,
|
||||
450, 70, 220,
|
||||
"СКОРОСТНОЙ",
|
||||
"Высокая скорость, низкая защита"
|
||||
),
|
||||
new PlayerConfig(
|
||||
GameResources.PLAYER_TANK_PATH,
|
||||
200, 150, 160,
|
||||
"ТАНК",
|
||||
"Высокая защита, низкая скорость"
|
||||
)
|
||||
};
|
||||
|
||||
//Уровень
|
||||
|
||||
public static class LevelConfig {
|
||||
public String name;
|
||||
public String backgroundPath;
|
||||
public int enemyCount;
|
||||
public String description;
|
||||
|
||||
public LevelConfig(String name, String bgPath, int count, String desc) {
|
||||
this.name = name;
|
||||
this.backgroundPath = bgPath;
|
||||
this.enemyCount = count;
|
||||
this.description = desc;
|
||||
}
|
||||
}
|
||||
|
||||
public static final LevelConfig[] LEVELS = {
|
||||
new LevelConfig("ЛЕС", GameResources.LEVEL1_BG_PATH, 10, "Лесной уровень"),
|
||||
new LevelConfig("ПУСТЫНЯ", GameResources.LEVEL2_BG_PATH, 10, "Пустынный уровень"),
|
||||
new LevelConfig("КОСМОС", GameResources.LEVEL3_BG_PATH, 10, "Космический уровень")
|
||||
};
|
||||
|
||||
//стрельба
|
||||
|
||||
public static final float BULLET_SPEED = 1500f;
|
||||
public static final float ROCKET_SPEED = 1200f;
|
||||
|
||||
public static final int ROCKET_DAMAGE = 30;
|
||||
public static final int BULLET_DAMAGE = 10;
|
||||
|
||||
public static final float BULLET_COOLDOWN = 0.2f;
|
||||
public static final float ROCKET_COOLDOWN = 0.5f;
|
||||
|
||||
//враги
|
||||
|
||||
public static final float ENEMY_SHOOT_PROBABILITY = 0.003f;
|
||||
public static final float ENEMY_SPAWN_RATE = 3f;
|
||||
public static final float BOSS_CHANCE = 0.1f;
|
||||
|
||||
//механика
|
||||
|
||||
public static final int PLAYER_COLLISION_DAMAGE = 10;
|
||||
public static final int BULLET_COLLISION_DAMAGE = 5;
|
||||
|
||||
|
||||
public static final float BULLET_DESPAWN_DISTANCE = 3000f;
|
||||
public static final int SCORE_PER_ENEMY = 100;
|
||||
|
||||
//текст
|
||||
|
||||
public static final Color TEXT_COLOR_WHITE = Color.WHITE;
|
||||
public static final Color TEXT_COLOR_YELLOW = Color.YELLOW;
|
||||
|
||||
public static final int FONT_SIZE_TITLE = 72;
|
||||
public static final int FONT_SIZE_BUTTON = 36;
|
||||
public static final int FONT_SIZE_SMALL = 24;
|
||||
|
||||
public enum Difficulty {
|
||||
EASY,
|
||||
NORMAL,
|
||||
HARD
|
||||
}
|
||||
|
||||
public static Difficulty currentDifficulty = Difficulty.NORMAL;
|
||||
|
||||
public static float getDifficultyMultiplier() {
|
||||
switch (currentDifficulty) {
|
||||
case EASY: return 0.7f;
|
||||
case NORMAL: return 1.0f;
|
||||
case HARD: return 1.5f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getEnemyCountForLevel(int baseCount) {
|
||||
switch (currentDifficulty) {
|
||||
case EASY: return baseCount;
|
||||
case NORMAL: return (int)(baseCount * 1.3f);
|
||||
case HARD: return (int)(baseCount * 1.6f);
|
||||
default: return baseCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
import com.badlogic.gdx.Game;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.mygdx.game.managers.SoundManager;
|
||||
import com.mygdx.game.screens.GameOverScreen;
|
||||
import com.mygdx.game.screens.GameScreen;
|
||||
import com.mygdx.game.screens.LevelSelectScreen;
|
||||
import com.mygdx.game.screens.MenuScreen;
|
||||
import com.mygdx.game.screens.PlayerSelectScreen;
|
||||
import com.mygdx.game.screens.SettingsScreen;
|
||||
|
||||
public class MyGdxGame extends Game {
|
||||
public SpriteBatch batch;
|
||||
public OrthographicCamera camera;
|
||||
public Vector3 touch;
|
||||
public SoundManager soundManager;
|
||||
|
||||
public BitmapFont titleFont;
|
||||
public BitmapFont buttonFont;
|
||||
public BitmapFont smallFont;
|
||||
|
||||
public MenuScreen menuScreen;
|
||||
public PlayerSelectScreen playerSelectScreen;
|
||||
public LevelSelectScreen levelSelectScreen;
|
||||
public SettingsScreen settingsScreen;
|
||||
public GameScreen gameScreen;
|
||||
public GameOverScreen gameOverScreen;
|
||||
|
||||
public int selectedPlayer = 0;
|
||||
public int selectedLevel = 0;
|
||||
|
||||
public boolean isFromGame = false;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
Gdx.graphics.setForegroundFPS(60);
|
||||
System.out.println("MyGdxGame: create() начат");
|
||||
|
||||
try {
|
||||
camera = new OrthographicCamera();
|
||||
camera.setToOrtho(false, GameSettings.SCREEN_WIDTH, GameSettings.SCREEN_HEIGHT);
|
||||
|
||||
batch = new SpriteBatch();
|
||||
touch = new Vector3();
|
||||
|
||||
System.out.println("MyGdxGame: Основные компоненты созданы");
|
||||
|
||||
soundManager = new SoundManager();
|
||||
System.out.println("MyGdxGame: SoundManager создан");
|
||||
|
||||
createFonts();
|
||||
System.out.println("MyGdxGame: Шрифты созданы");
|
||||
|
||||
createScreens();
|
||||
System.out.println("MyGdxGame: Экраны созданы");
|
||||
|
||||
if (soundManager != null) {
|
||||
soundManager.playBackgroundMusic();
|
||||
System.out.println("MyGdxGame: Музыка включена");
|
||||
}
|
||||
|
||||
setScreen(menuScreen);
|
||||
System.out.println("MyGdxGame: Экран меню показан");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("MyGdxGame: Ошибка в create(): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void createFonts() {
|
||||
try {
|
||||
titleFont = FontBuilder.generate(GameSettings.FONT_SIZE_TITLE, GameSettings.TEXT_COLOR_YELLOW, GameResources.FONT_PATH);
|
||||
buttonFont = FontBuilder.generate(GameSettings.FONT_SIZE_BUTTON, GameSettings.TEXT_COLOR_WHITE, GameResources.FONT_PATH);
|
||||
smallFont = FontBuilder.generate(GameSettings.FONT_SIZE_SMALL, GameSettings.TEXT_COLOR_WHITE, GameResources.FONT_PATH);
|
||||
System.out.println("MyGdxGame: Шрифты успешно созданы");
|
||||
} catch (Exception e) {
|
||||
System.err.println("MyGdxGame: Ошибка создания шрифтов: " + e.getMessage());
|
||||
titleFont = new BitmapFont();
|
||||
buttonFont = new BitmapFont();
|
||||
smallFont = new BitmapFont();
|
||||
System.out.println("MyGdxGame: Используются стандартные шрифты");
|
||||
}
|
||||
}
|
||||
|
||||
private void createScreens() {
|
||||
try {
|
||||
menuScreen = new MenuScreen(this);
|
||||
System.out.println("MyGdxGame: MenuScreen создан");
|
||||
|
||||
playerSelectScreen = new PlayerSelectScreen(this);
|
||||
System.out.println("MyGdxGame: PlayerSelectScreen создан");
|
||||
|
||||
levelSelectScreen = new LevelSelectScreen(this);
|
||||
System.out.println("MyGdxGame: LevelSelectScreen создан");
|
||||
|
||||
settingsScreen = new SettingsScreen(this);
|
||||
System.out.println("MyGdxGame: SettingsScreen создан");
|
||||
|
||||
gameOverScreen = new GameOverScreen(this);
|
||||
System.out.println("MyGdxGame: GameOverScreen создан");
|
||||
|
||||
gameScreen = null;
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("MyGdxGame: Ошибка создания экранов: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void startNewGame() {
|
||||
System.out.println("MyGdxGame: startNewGame() вызван");
|
||||
|
||||
try {
|
||||
if (gameScreen != null) {
|
||||
gameScreen.dispose();
|
||||
System.out.println("MyGdxGame: Старый GameScreen удален");
|
||||
}
|
||||
|
||||
gameScreen = new GameScreen(this);
|
||||
System.out.println("MyGdxGame: Новый GameScreen создан");
|
||||
|
||||
setScreen(gameScreen);
|
||||
System.out.println("MyGdxGame: GameScreen показан");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("MyGdxGame: Ошибка в startNewGame(): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
setScreen(menuScreen);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
try {
|
||||
super.render();
|
||||
} catch (Exception e) {
|
||||
System.err.println("MyGdxGame: Ошибка в render(): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(int width, int height) {
|
||||
try {
|
||||
super.resize(width, height);
|
||||
} catch (Exception e) {
|
||||
System.err.println("MyGdxGame: Ошибка в resize(): " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
try {
|
||||
super.pause();
|
||||
if (soundManager != null) {
|
||||
soundManager.pauseBackgroundMusic();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("MyGdxGame: Ошибка в pause(): " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume() {
|
||||
try {
|
||||
super.resume();
|
||||
if (soundManager != null) {
|
||||
soundManager.resumeBackgroundMusic();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("MyGdxGame: Ошибка в resume(): " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
System.out.println("MyGdxGame: dispose() начат");
|
||||
|
||||
try {
|
||||
if (menuScreen != null) {
|
||||
menuScreen.dispose();
|
||||
menuScreen = null;
|
||||
}
|
||||
if (playerSelectScreen != null) {
|
||||
playerSelectScreen.dispose();
|
||||
playerSelectScreen = null;
|
||||
}
|
||||
if (levelSelectScreen != null) {
|
||||
levelSelectScreen.dispose();
|
||||
levelSelectScreen = null;
|
||||
}
|
||||
if (settingsScreen != null) {
|
||||
settingsScreen.dispose();
|
||||
settingsScreen = null;
|
||||
}
|
||||
if (gameScreen != null) {
|
||||
gameScreen.dispose();
|
||||
gameScreen = null;
|
||||
}
|
||||
if (gameOverScreen != null) {
|
||||
gameOverScreen.dispose();
|
||||
gameOverScreen = null;
|
||||
}
|
||||
|
||||
if (titleFont != null) {
|
||||
titleFont.dispose();
|
||||
titleFont = null;
|
||||
}
|
||||
if (buttonFont != null) {
|
||||
buttonFont.dispose();
|
||||
buttonFont = null;
|
||||
}
|
||||
if (smallFont != null) {
|
||||
smallFont.dispose();
|
||||
smallFont = null;
|
||||
}
|
||||
|
||||
if (soundManager != null) {
|
||||
soundManager.dispose();
|
||||
soundManager = null;
|
||||
}
|
||||
|
||||
if (batch != null) {
|
||||
batch.dispose();
|
||||
batch = null;
|
||||
}
|
||||
|
||||
System.out.println("MyGdxGame: Все ресурсы освобождены");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("MyGdxGame: Ошибка в dispose(): " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.mygdx.game.components;
|
||||
|
||||
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 ButtonView extends View {
|
||||
|
||||
Texture texture;
|
||||
BitmapFont bitmapFont;
|
||||
String text;
|
||||
float textX;
|
||||
float textY;
|
||||
Color textColor;
|
||||
|
||||
public ButtonView(float x, float y, float width, float height,
|
||||
BitmapFont font, String texturePath, String text) {
|
||||
super(x, y, width, height);
|
||||
this.text = text;
|
||||
this.bitmapFont = font;
|
||||
this.texture = new Texture(texturePath);
|
||||
this.textColor = Color.BLACK;
|
||||
|
||||
GlyphLayout glyphLayout = new GlyphLayout(bitmapFont, text);
|
||||
float textWidth = glyphLayout.width;
|
||||
float textHeight = glyphLayout.height;
|
||||
|
||||
textX = x + (width - textWidth) / 2;
|
||||
textY = y + (height + textHeight) / 2;
|
||||
}
|
||||
|
||||
public ButtonView(float x, float y, float width, float height, String texturePath) {
|
||||
super(x, y, width, height);
|
||||
this.texture = new Texture(texturePath);
|
||||
this.bitmapFont = null;
|
||||
}
|
||||
|
||||
public void setTextColor(Color color) {
|
||||
this.textColor = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(SpriteBatch batch) {
|
||||
batch.draw(texture, x, y, width, height);
|
||||
if (bitmapFont != null && text != null) {
|
||||
Color oldColor = bitmapFont.getColor();
|
||||
bitmapFont.setColor(textColor);
|
||||
bitmapFont.draw(batch, text, textX, textY);
|
||||
bitmapFont.setColor(oldColor);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHit(float touchX, float touchY) {
|
||||
return touchX >= x && touchX <= x + width &&
|
||||
touchY >= y && touchY <= y + height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (texture != null) {
|
||||
texture.dispose();
|
||||
texture = null;
|
||||
}
|
||||
bitmapFont = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.mygdx.game.components;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
|
||||
public class ImageView extends View {
|
||||
|
||||
Texture texture;
|
||||
|
||||
public ImageView(float x, float y, float width, float height, String imagePath) {
|
||||
super(x, y, width, height);
|
||||
texture = new Texture(imagePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(SpriteBatch batch) {
|
||||
batch.draw(texture, x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (texture != null) {
|
||||
texture.dispose();
|
||||
texture = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.mygdx.game.components;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
|
||||
public class TextView extends View {
|
||||
private BitmapFont font;
|
||||
private String text;
|
||||
private Color color;
|
||||
|
||||
public TextView(BitmapFont font, float x, float y, String text) {
|
||||
super(x, y);
|
||||
this.font = font;
|
||||
this.text = text;
|
||||
this.color = Color.WHITE;
|
||||
|
||||
GlyphLayout layout = new GlyphLayout(font, text);
|
||||
width = layout.width;
|
||||
height = layout.height;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
GlyphLayout layout = new GlyphLayout(font, text);
|
||||
width = layout.width;
|
||||
height = layout.height;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(SpriteBatch batch) {
|
||||
Color oldColor = font.getColor();
|
||||
font.setColor(color);
|
||||
font.draw(batch, text, x, y);
|
||||
font.setColor(oldColor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.mygdx.game.components;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
|
||||
public abstract class View {
|
||||
protected float x, y;
|
||||
protected float width, height;
|
||||
|
||||
public View(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
}
|
||||
|
||||
public View(float x, float y, float width, float height) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public abstract void draw(SpriteBatch batch);
|
||||
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
public float getX() { return x; }
|
||||
public float getY() { return y; }
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.mygdx.game.managers;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Preferences;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MemoryManager {
|
||||
|
||||
private static final Preferences preferences = Gdx.app.getPreferences("User saves");
|
||||
|
||||
public static void saveSoundSettings(boolean isOn) {
|
||||
preferences.putBoolean("isSoundOn", isOn);
|
||||
preferences.flush();
|
||||
}
|
||||
|
||||
public static boolean loadIsSoundOn() {
|
||||
return preferences.getBoolean("isSoundOn", true);
|
||||
}
|
||||
|
||||
public static void saveMusicSettings(boolean isOn) {
|
||||
preferences.putBoolean("isMusicOn", isOn);
|
||||
preferences.flush();
|
||||
}
|
||||
|
||||
public static boolean loadIsMusicOn() {
|
||||
return preferences.getBoolean("isMusicOn", true);
|
||||
}
|
||||
|
||||
public static void saveTableOfRecords(ArrayList<Integer> table) {
|
||||
Json json = new Json();
|
||||
String tableInString = json.toJson(table);
|
||||
preferences.putString("recordTable", tableInString);
|
||||
preferences.flush();
|
||||
}
|
||||
|
||||
public static ArrayList<Integer> loadRecordsTable() {
|
||||
if (!preferences.contains("recordTable"))
|
||||
return null;
|
||||
|
||||
String scores = preferences.getString("recordTable");
|
||||
Json json = new Json();
|
||||
ArrayList<Integer> table = json.fromJson(ArrayList.class, scores);
|
||||
return table;
|
||||
}
|
||||
|
||||
public static void saveHighScore(int score) {
|
||||
System.out.println("saveHighScore вызван, score = " + score);
|
||||
|
||||
ArrayList<Integer> records = loadRecordsTable();
|
||||
if (records == null) {
|
||||
records = new ArrayList<Integer>();
|
||||
System.out.println("Создан новый список рекордов");
|
||||
}
|
||||
records.add(score);
|
||||
System.out.println("Добавлен рекорд. Список: " + records.toString());
|
||||
|
||||
for (int i = 0; i < records.size() - 1; i++) {
|
||||
for (int j = i + 1; j < records.size(); j++) {
|
||||
if (records.get(i) < records.get(j)) {
|
||||
int temp = records.get(i);
|
||||
records.set(i, records.get(j));
|
||||
records.set(j, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("После сортировки: " + records.toString());
|
||||
|
||||
while (records.size() > 10) {
|
||||
records.remove(records.size() - 1);
|
||||
}
|
||||
|
||||
saveTableOfRecords(records);
|
||||
System.out.println("Рекорд сохранён. getHighScore = " + getHighScore());
|
||||
}
|
||||
|
||||
public static int getHighScore() {
|
||||
ArrayList<Integer> records = loadRecordsTable();
|
||||
if (records == null || records.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
return records.get(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.mygdx.game.managers;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.audio.Sound;
|
||||
import com.mygdx.game.GameResources;
|
||||
|
||||
public class SoundManager {
|
||||
private Music backgroundMusic;
|
||||
private Sound shootSound;
|
||||
private Sound rocketSound;
|
||||
private Sound explosionSound;
|
||||
private Sound selectSound;
|
||||
|
||||
private float musicVolume = 0.5f;
|
||||
private float soundVolume = 0.7f;
|
||||
|
||||
private boolean musicEnabled;
|
||||
private boolean soundEnabled;
|
||||
|
||||
public SoundManager() {
|
||||
musicEnabled = MemoryManager.loadIsMusicOn();
|
||||
soundEnabled = MemoryManager.loadIsSoundOn();
|
||||
loadSounds();
|
||||
}
|
||||
|
||||
private void loadSounds() {
|
||||
try {
|
||||
backgroundMusic = Gdx.audio.newMusic(Gdx.files.internal(GameResources.BACKGROUND_MUSIC_PATH));
|
||||
backgroundMusic.setLooping(true);
|
||||
backgroundMusic.setVolume(musicVolume);
|
||||
|
||||
shootSound = Gdx.audio.newSound(Gdx.files.internal(GameResources.SHOOT_SOUND_PATH));
|
||||
rocketSound = Gdx.audio.newSound(Gdx.files.internal(GameResources.ROCKET_SOUND_PATH));
|
||||
explosionSound = Gdx.audio.newSound(Gdx.files.internal(GameResources.EXPLOSION_SOUND_PATH));
|
||||
selectSound = Gdx.audio.newSound(Gdx.files.internal(GameResources.SELECT_SOUND_PATH));
|
||||
} catch (Exception e) {
|
||||
System.err.println("Не удалось загрузить звуки: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void playBackgroundMusic() {
|
||||
if (backgroundMusic != null && musicEnabled && !backgroundMusic.isPlaying()) {
|
||||
backgroundMusic.play();
|
||||
}
|
||||
}
|
||||
|
||||
public void pauseBackgroundMusic() {
|
||||
if (backgroundMusic != null && backgroundMusic.isPlaying()) {
|
||||
backgroundMusic.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public void resumeBackgroundMusic() {
|
||||
if (backgroundMusic != null && musicEnabled && !backgroundMusic.isPlaying()) {
|
||||
backgroundMusic.play();
|
||||
}
|
||||
}
|
||||
|
||||
public void playShootSound() {
|
||||
if (shootSound != null && soundEnabled) {
|
||||
shootSound.play(soundVolume);
|
||||
}
|
||||
}
|
||||
|
||||
public void playRocketSound() {
|
||||
if (rocketSound != null && soundEnabled) {
|
||||
rocketSound.play(soundVolume);
|
||||
}
|
||||
}
|
||||
|
||||
public void playExplosionSound() {
|
||||
if (explosionSound != null && soundEnabled) {
|
||||
explosionSound.play(soundVolume);
|
||||
}
|
||||
}
|
||||
|
||||
public void playSelectSound() {
|
||||
if (selectSound != null && soundEnabled) {
|
||||
selectSound.play(soundVolume);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMusicEnabled() {
|
||||
return musicEnabled;
|
||||
}
|
||||
|
||||
public void setMusicEnabled(boolean enabled) {
|
||||
musicEnabled = enabled;
|
||||
MemoryManager.saveMusicSettings(musicEnabled);
|
||||
if (musicEnabled) {
|
||||
playBackgroundMusic();
|
||||
} else {
|
||||
pauseBackgroundMusic();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSoundEnabled() {
|
||||
return soundEnabled;
|
||||
}
|
||||
|
||||
public void setSoundEnabled(boolean enabled) {
|
||||
soundEnabled = enabled;
|
||||
MemoryManager.saveSoundSettings(soundEnabled);
|
||||
}
|
||||
|
||||
public void toggleMusic() {
|
||||
setMusicEnabled(!musicEnabled);
|
||||
}
|
||||
|
||||
public void toggleSound() {
|
||||
setSoundEnabled(!soundEnabled);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (backgroundMusic != null) backgroundMusic.dispose();
|
||||
if (shootSound != null) shootSound.dispose();
|
||||
if (rocketSound != null) rocketSound.dispose();
|
||||
if (explosionSound != null) explosionSound.dispose();
|
||||
if (selectSound != null) selectSound.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.mygdx.game.objects;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.mygdx.game.GameResources;
|
||||
import com.mygdx.game.GameSettings;
|
||||
|
||||
public class Bullet {
|
||||
private float x, y;
|
||||
private float width = 10, height = 20;
|
||||
private Texture texture;
|
||||
private float speed;
|
||||
private float angle;
|
||||
private int damage;
|
||||
private boolean isPlayer;
|
||||
private boolean isRocket;
|
||||
private boolean active = true;
|
||||
|
||||
public Bullet() {
|
||||
|
||||
}
|
||||
|
||||
public void init(float x, float y, float angle, boolean isPlayer, boolean isRocket) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.angle = angle;
|
||||
this.isPlayer = isPlayer;
|
||||
this.isRocket = isRocket;
|
||||
|
||||
if (isRocket) {
|
||||
texture = new Texture(GameResources.BULLET_ROCKET_PATH);
|
||||
width = 15;
|
||||
height = 30;
|
||||
speed = GameSettings.ROCKET_SPEED;
|
||||
damage = GameSettings.ROCKET_DAMAGE;
|
||||
} else {
|
||||
texture = new Texture(GameResources.BULLET_BASIC_PATH);
|
||||
width = 8;
|
||||
height = 16;
|
||||
speed = GameSettings.BULLET_SPEED;
|
||||
damage = GameSettings.BULLET_DAMAGE;
|
||||
}
|
||||
}
|
||||
|
||||
public void update(float delta) {
|
||||
x += MathUtils.cos(angle) * speed * delta;
|
||||
y += MathUtils.sin(angle) * speed * delta;
|
||||
}
|
||||
|
||||
public void draw(SpriteBatch batch) {
|
||||
if (active && texture != null) {
|
||||
batch.draw(texture, x - width/2, y - height/2, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getDamage() {
|
||||
return damage;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (texture != null) {
|
||||
texture.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.mygdx.game.objects;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.mygdx.game.GameResources;
|
||||
import com.mygdx.game.GameSettings;
|
||||
|
||||
public class EnemyPlane {
|
||||
public float x, y;
|
||||
private float width, height;
|
||||
private Texture texture;
|
||||
private float speed;
|
||||
private float rotation;
|
||||
private float moveAngle;
|
||||
private int health;
|
||||
private int maxHealth;
|
||||
private int level;
|
||||
private int enemyType;
|
||||
|
||||
private boolean isDead = false;
|
||||
private float deadTimer = 0;
|
||||
private int deadFrame = 0;
|
||||
private Texture[] deadTextures;
|
||||
|
||||
|
||||
|
||||
public EnemyPlane(float startX, float startY, int level, float multiplier) {
|
||||
this.x = startX;
|
||||
this.y = startY;
|
||||
this.level = level;
|
||||
|
||||
enemyType = (int)(Math.random() * 3);
|
||||
|
||||
if (enemyType == 0) {
|
||||
texture = new Texture(GameResources.ENEMY_BASIC_PATH);
|
||||
health = (int)(30 * multiplier);
|
||||
speed = 150 * multiplier;
|
||||
width = 60;
|
||||
height = 60;
|
||||
// Анимация
|
||||
deadTextures = new Texture[3];
|
||||
deadTextures[0] = new Texture(GameResources.EXPLOSION_PATH);
|
||||
deadTextures[1] = new Texture(GameResources.ENEMY_FALLING1_PATH);
|
||||
deadTextures[2] = new Texture(GameResources.ENEMY_FALLING2_PATH);
|
||||
} else if (enemyType == 1) { // Быстрый
|
||||
texture = new Texture(GameResources.ENEMY_FAST_PATH);
|
||||
health = (int)(20 * multiplier);
|
||||
speed = 250 * multiplier;
|
||||
width = 50;
|
||||
height = 50;
|
||||
deadTextures = new Texture[3];
|
||||
deadTextures[0] = new Texture(GameResources.EXPLOSION_PATH);
|
||||
deadTextures[1] = new Texture(GameResources.ENEMY_FAST_FALLING1_PATH);
|
||||
deadTextures[2] = new Texture(GameResources.ENEMY_FAST_FALLING2_PATH);
|
||||
} else {
|
||||
texture = new Texture(GameResources.ENEMY_TANK_PATH);
|
||||
health = (int)(80 * multiplier);
|
||||
speed = 100 * multiplier;
|
||||
width = 80;
|
||||
height = 80;
|
||||
deadTextures = new Texture[3];
|
||||
deadTextures[0] = new Texture(GameResources.EXPLOSION_PATH);
|
||||
deadTextures[1] = new Texture(GameResources.ENEMY_TANK_FALLING1_PATH);
|
||||
deadTextures[2] = new Texture(GameResources.ENEMY_TANK_FALLING2_PATH);
|
||||
}
|
||||
|
||||
if (Math.random() < GameSettings.BOSS_CHANCE) {
|
||||
enemyType = 3;
|
||||
texture = new Texture(GameResources.ENEMY_BOSS_PATH);
|
||||
health = (int)(150 * multiplier);
|
||||
speed = 80 * multiplier;
|
||||
width = 120;
|
||||
height = 120;
|
||||
deadTextures = new Texture[3];
|
||||
deadTextures[0] = new Texture(GameResources.EXPLOSION_PATH);
|
||||
deadTextures[1] = new Texture(GameResources.ENEMY_BOSS_FALLING1_PATH);
|
||||
deadTextures[2] = new Texture(GameResources.ENEMY_BOSS_FALLING2_PATH);
|
||||
}
|
||||
|
||||
this.maxHealth = health;
|
||||
|
||||
moveAngle = (float)(Math.random() * Math.PI * 2);
|
||||
rotation = moveAngle * 180 / (float)Math.PI - 90;
|
||||
}
|
||||
|
||||
public void update(float delta, float playerX, float playerY) {
|
||||
if (isDead) {
|
||||
deadTimer += delta;
|
||||
|
||||
if (deadTimer >= 0.15f) {
|
||||
deadTimer = 0;
|
||||
deadFrame++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
x += MathUtils.cos(moveAngle) * speed * delta;
|
||||
y += MathUtils.sin(moveAngle) * speed * delta;
|
||||
|
||||
if (Math.random() < 0.005f) {
|
||||
moveAngle = (float)(Math.random() * Math.PI * 2);
|
||||
rotation = moveAngle * 180 / (float)Math.PI - 90;
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(SpriteBatch batch) {
|
||||
if (isDead) {
|
||||
int frame = deadFrame;
|
||||
if (frame >= deadTextures.length) {
|
||||
frame = deadTextures.length - 1;
|
||||
}
|
||||
|
||||
if (frame == 0) {
|
||||
batch.draw(deadTextures[frame], x - width, y - height, width * 2, height * 2);
|
||||
} else {
|
||||
batch.draw(deadTextures[frame], x - width/2, y - height/2, width, height);
|
||||
}
|
||||
} else {
|
||||
batch.draw(texture, x - width/2, y - height/2, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
if (!isDead) {
|
||||
isDead = true;
|
||||
deadTimer = 0;
|
||||
deadFrame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDead() {
|
||||
return isDead;
|
||||
}
|
||||
|
||||
public boolean isAnimationFinished() {
|
||||
return deadFrame >= deadTextures.length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getX() { return x; }
|
||||
public float getY() { return y; }
|
||||
public float getWidth() { return width; }
|
||||
|
||||
|
||||
public boolean takeDamage(int damage) {
|
||||
health -= damage;
|
||||
if (health <= 0) {
|
||||
kill();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean collidesWith(float bulletX, float bulletY, float bulletRadius) {
|
||||
if (isDead) return false;
|
||||
float dx = x - bulletX;
|
||||
float dy = y - bulletY;
|
||||
float distance = (float) Math.sqrt(dx * dx + dy * dy);
|
||||
return distance < (width/2 + bulletRadius);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (texture != null) texture.dispose();
|
||||
if (deadTextures != null) {
|
||||
for (Texture t : deadTextures) {
|
||||
if (t != null) t.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.mygdx.game.objects;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.mygdx.game.GameResources;
|
||||
import com.mygdx.game.GameSettings;
|
||||
|
||||
public class PlayerPlane {
|
||||
public float x, y;
|
||||
private float width = 80, height = 80;
|
||||
private Texture texture;
|
||||
|
||||
private float speed;
|
||||
private float speedMultiplier = 1.0f;
|
||||
private float rotation = 90f;
|
||||
private float rotationSpeed = 180f;
|
||||
|
||||
private int health;
|
||||
private int maxHealth;
|
||||
private int playerType;
|
||||
|
||||
private boolean isRocket = false;
|
||||
|
||||
public PlayerPlane(float startX, float startY, int playerType) {
|
||||
this.x = startX;
|
||||
this.y = startY;
|
||||
this.playerType = playerType;
|
||||
|
||||
System.out.println("PlayerPlane: Конструктор вызван");
|
||||
System.out.println("StartX = " + startX + " StartY = " + startY);
|
||||
|
||||
GameSettings.PlayerConfig config = GameSettings.PLAYERS[playerType];
|
||||
|
||||
switch (playerType) {
|
||||
case 0:
|
||||
texture = new Texture(GameResources.PLAYER_BASIC_PATH);
|
||||
break;
|
||||
case 1:
|
||||
texture = new Texture(GameResources.PLAYER_FAST_PATH);
|
||||
break;
|
||||
case 2:
|
||||
texture = new Texture(GameResources.PLAYER_TANK_PATH);
|
||||
break;
|
||||
default:
|
||||
texture = new Texture(GameResources.PLAYER_BASIC_PATH);
|
||||
}
|
||||
|
||||
this.speed = config.speed;
|
||||
this.rotationSpeed = config.rotationSpeed;
|
||||
this.health = config.health;
|
||||
this.maxHealth = config.health;
|
||||
|
||||
System.out.println("Speed = " + speed);
|
||||
System.out.println("RotationSpeed = " + rotationSpeed);
|
||||
System.out.println("Health = " + health);
|
||||
}
|
||||
|
||||
public void update(float delta) {
|
||||
float angleRad = rotation * MathUtils.degreesToRadians;
|
||||
float dx = MathUtils.cos(angleRad) * speed * speedMultiplier * delta;
|
||||
float dy = MathUtils.sin(angleRad) * speed * speedMultiplier * delta;
|
||||
|
||||
x += dx;
|
||||
y += dy;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void draw(SpriteBatch batch) {
|
||||
|
||||
batch.draw(texture,
|
||||
x - width/2, y - height/2,
|
||||
width/2, height/2,
|
||||
width, height,
|
||||
1, 1,
|
||||
rotation,
|
||||
0, 0,
|
||||
texture.getWidth(),
|
||||
texture.getHeight(),
|
||||
false, false);
|
||||
}
|
||||
|
||||
public void rotateLeft(float delta) {
|
||||
rotation += rotationSpeed * delta;
|
||||
|
||||
}
|
||||
|
||||
public void rotateRight(float delta) {
|
||||
rotation -= rotationSpeed * delta;
|
||||
|
||||
}
|
||||
|
||||
public void switchWeapon() {
|
||||
isRocket = !isRocket;
|
||||
System.out.println("switchWeapon: isRocket=" + isRocket);
|
||||
}
|
||||
|
||||
public boolean isRocket() {
|
||||
return isRocket;
|
||||
}
|
||||
|
||||
public float getShootAngle() {
|
||||
return rotation * MathUtils.degreesToRadians;
|
||||
}
|
||||
|
||||
public float[] getGunPosition() {
|
||||
float angleRad = rotation * MathUtils.degreesToRadians;
|
||||
float gunX = x + MathUtils.cos(angleRad) * 50;
|
||||
float gunY = y + MathUtils.sin(angleRad) * 50;
|
||||
return new float[]{gunX, gunY};
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setSpeedMultiplier(float multiplier) {
|
||||
this.speedMultiplier = multiplier;
|
||||
System.out.println("setSpeedMultiplier: " + multiplier);
|
||||
}
|
||||
|
||||
public int getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
public int getMaxHealth() {
|
||||
return maxHealth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void takeDamage(int damage) {
|
||||
health -= damage;
|
||||
if (health < 0) {
|
||||
health = 0;
|
||||
}
|
||||
System.out.println("takeDamage: damage=" + damage + " health=" + health);
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
return health > 0;
|
||||
}
|
||||
|
||||
public boolean collidesWith(float otherX, float otherY, float radius) {
|
||||
float dx = x - otherX;
|
||||
float dy = y - otherY;
|
||||
float distance = (float) Math.sqrt(dx * dx + dy * dy);
|
||||
boolean collision = distance < (width/2 + radius);
|
||||
if (collision) {
|
||||
System.out.println("COLLISION: distance=" + distance);
|
||||
}
|
||||
return collision;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
System.out.println("PlayerPlane: dispose");
|
||||
if (texture != null) {
|
||||
texture.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.mygdx.game.screens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.mygdx.game.GameResources;
|
||||
import com.mygdx.game.GameSettings;
|
||||
import com.mygdx.game.MyGdxGame;
|
||||
import com.mygdx.game.components.ButtonView;
|
||||
import com.mygdx.game.components.ImageView;
|
||||
import com.mygdx.game.components.TextView;
|
||||
import com.mygdx.game.managers.MemoryManager;
|
||||
|
||||
public class GameOverScreen extends ScreenAdapter {
|
||||
private MyGdxGame game;
|
||||
private SpriteBatch batch;
|
||||
private ImageView background;
|
||||
|
||||
private TextView titleTextView;
|
||||
private TextView scoreTextView;
|
||||
private TextView highScoreTextView;
|
||||
private ButtonView restartButton;
|
||||
private ButtonView menuButton;
|
||||
|
||||
private int finalScore;
|
||||
|
||||
public GameOverScreen(MyGdxGame game) {
|
||||
this.game = game;
|
||||
this.batch = game.batch;
|
||||
}
|
||||
|
||||
public void setScore(int score) {
|
||||
this.finalScore = score;
|
||||
MemoryManager.saveHighScore(score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0.3f, 0.1f, 0.1f, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
game.camera.update();
|
||||
batch.setProjectionMatrix(game.camera.combined);
|
||||
|
||||
handleInput();
|
||||
|
||||
batch.begin();
|
||||
|
||||
if (background == null) {
|
||||
background = new ImageView(0, 0,
|
||||
GameSettings.SCREEN_WIDTH,
|
||||
GameSettings.SCREEN_HEIGHT,
|
||||
GameResources.GAME_OVER_BG_PATH);
|
||||
}
|
||||
background.draw(batch);
|
||||
|
||||
titleTextView.draw(batch);
|
||||
scoreTextView.draw(batch);
|
||||
highScoreTextView.draw(batch);
|
||||
restartButton.draw(batch);
|
||||
menuButton.draw(batch);
|
||||
|
||||
batch.end();
|
||||
}
|
||||
|
||||
private void handleInput() {
|
||||
if (Gdx.input.justTouched()) {
|
||||
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
|
||||
game.camera.unproject(touchPos);
|
||||
|
||||
if (restartButton.isHit(touchPos.x, touchPos.y)) {
|
||||
game.startNewGame();
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (menuButton.isHit(touchPos.x, touchPos.y)) {
|
||||
game.setScreen(game.menuScreen);
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
float centerX = GameSettings.SCREEN_WIDTH / 2f;
|
||||
|
||||
if (background == null) {
|
||||
background = new ImageView(0, 0,
|
||||
GameSettings.SCREEN_WIDTH,
|
||||
GameSettings.SCREEN_HEIGHT,
|
||||
GameResources.GAME_OVER_BG_PATH);
|
||||
}
|
||||
|
||||
titleTextView = new TextView(game.titleFont,
|
||||
centerX - 150,
|
||||
GameSettings.SCREEN_HEIGHT - 200,
|
||||
"ИГРА ОКОНЧЕНА");
|
||||
|
||||
scoreTextView = new TextView(game.buttonFont,
|
||||
centerX - 100,
|
||||
GameSettings.SCREEN_HEIGHT - 300,
|
||||
"УНИЧТОЖЕНО: " + finalScore);
|
||||
|
||||
int bestRecord = MemoryManager.getHighScore();
|
||||
highScoreTextView = new TextView(game.buttonFont,
|
||||
centerX - 150,
|
||||
GameSettings.SCREEN_HEIGHT - 350,
|
||||
"ЛУЧШИЙ РЕЗУЛЬТАТ: " + bestRecord);
|
||||
|
||||
restartButton = new ButtonView(
|
||||
centerX - 150, 300, 300, 80,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"ЗАНОВО"
|
||||
);
|
||||
|
||||
menuButton = new ButtonView(
|
||||
centerX - 150, 200, 300, 80,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"МЕНЮ"
|
||||
);
|
||||
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playBackgroundMusic();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (background != null) background.dispose();
|
||||
if (restartButton != null) restartButton.dispose();
|
||||
if (menuButton != null) menuButton.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,704 @@
|
||||
package com.mygdx.game.screens;
|
||||
|
||||
import static com.mygdx.game.GameSettings.*;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.mygdx.game.*;
|
||||
import com.mygdx.game.components.*;
|
||||
import com.mygdx.game.objects.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class GameScreen extends ScreenAdapter {
|
||||
|
||||
private MyGdxGame game;
|
||||
private SpriteBatch batch;
|
||||
|
||||
private OrthographicCamera gameCamera;
|
||||
|
||||
private PlayerPlane player;
|
||||
private ArrayList<EnemyPlane> enemies;
|
||||
private ArrayList<Bullet> playerBullets;
|
||||
private ArrayList<Bullet> enemyBullets;
|
||||
private ArrayList<float[]> explosions;
|
||||
|
||||
private Texture backgroundTexture;
|
||||
private Texture healthBarBg;
|
||||
private Texture healthBarFill;
|
||||
private Texture explosionTexture;
|
||||
|
||||
private ButtonView pauseButton;
|
||||
private ButtonView weaponButton;
|
||||
private ButtonView rotateLeftButton;
|
||||
private ButtonView rotateRightButton;
|
||||
private ButtonView attackButton;
|
||||
private ButtonView speed50Button;
|
||||
private ButtonView speed80Button;
|
||||
private ButtonView speed100Button;
|
||||
|
||||
private ButtonView resumeButton;
|
||||
private ButtonView settingsButton;
|
||||
private ButtonView menuButton;
|
||||
|
||||
private TextView scoreText;
|
||||
private TextView levelText;
|
||||
private TextView enemiesText;
|
||||
private TextView speedText;
|
||||
private TextView weaponIndicator;
|
||||
|
||||
private int currentLevel;
|
||||
private float enemySpawnTimer;
|
||||
private int currentSpeedLevel;
|
||||
private boolean isPaused;
|
||||
private boolean rotatingLeft;
|
||||
private boolean rotatingRight;
|
||||
private boolean isAttacking;
|
||||
private float autoShootTimer;
|
||||
private int score;
|
||||
private float shootCooldown;
|
||||
private int enemiesToDefeat;
|
||||
private int defeatedEnemies;
|
||||
|
||||
public GameScreen(MyGdxGame game) {
|
||||
this.game = game;
|
||||
this.batch = game.batch;
|
||||
this.currentLevel = game.selectedLevel;
|
||||
|
||||
System.out.println("=== GameScreen создан ===");
|
||||
System.out.println("Выбран уровень: " + currentLevel);
|
||||
|
||||
startNewGame();
|
||||
}
|
||||
|
||||
private void startNewGame() {
|
||||
System.out.println("Запуск новой игры");
|
||||
|
||||
gameCamera = new OrthographicCamera();
|
||||
gameCamera.setToOrtho(false, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
|
||||
LevelConfig levelConfig = LEVELS[currentLevel];
|
||||
backgroundTexture = new Texture(Gdx.files.internal(levelConfig.backgroundPath));
|
||||
|
||||
healthBarBg = new Texture(Gdx.files.internal(GameResources.HEALTH_BG_PATH));
|
||||
healthBarFill = new Texture(Gdx.files.internal(GameResources.HEALTH_FILL_PATH));
|
||||
explosionTexture = new Texture(Gdx.files.internal(GameResources.EXPLOSION_PATH));
|
||||
|
||||
enemiesToDefeat = GameSettings.getEnemyCountForLevel(levelConfig.enemyCount);
|
||||
System.out.println("Врагов нужно убить: " + enemiesToDefeat);
|
||||
|
||||
player = new PlayerPlane(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, game.selectedPlayer);
|
||||
player.setSpeedMultiplier(SPEED_LEVELS[currentSpeedLevel]);
|
||||
|
||||
enemies = new ArrayList<>();
|
||||
playerBullets = new ArrayList<>();
|
||||
enemyBullets = new ArrayList<>();
|
||||
explosions = new ArrayList<>();
|
||||
|
||||
createButtons();
|
||||
createText();
|
||||
resetGameVariables();
|
||||
}
|
||||
|
||||
private void createButtons() {
|
||||
float btnSize = 80;
|
||||
float bigW = 300;
|
||||
float bigH = 100;
|
||||
|
||||
pauseButton = new ButtonView(
|
||||
SCREEN_WIDTH / 2 - btnSize / 2,
|
||||
SCREEN_HEIGHT - btnSize - 20,
|
||||
btnSize, btnSize,
|
||||
GameResources.BUTTON_PAUSE_PATH
|
||||
);
|
||||
|
||||
weaponButton = new ButtonView(
|
||||
20, 20,
|
||||
btnSize, btnSize,
|
||||
GameResources.BUTTON_WEAPON_PATH
|
||||
);
|
||||
|
||||
float rotY = 20;
|
||||
float rotSpacing = 10;
|
||||
|
||||
rotateLeftButton = new ButtonView(
|
||||
SCREEN_WIDTH - 1000 - btnSize - rotSpacing,
|
||||
rotY,
|
||||
btnSize, btnSize,
|
||||
GameResources.BUTTON_LEFT_PATH
|
||||
);
|
||||
|
||||
rotateRightButton = new ButtonView(
|
||||
SCREEN_WIDTH - 1000 + rotSpacing,
|
||||
rotY,
|
||||
btnSize, btnSize,
|
||||
GameResources.BUTTON_RIGHT_PATH
|
||||
);
|
||||
|
||||
attackButton = new ButtonView(
|
||||
SCREEN_WIDTH - btnSize - 20,
|
||||
20,
|
||||
btnSize, btnSize,
|
||||
GameResources.BUTTON_ATTACK_PATH
|
||||
);
|
||||
|
||||
float speedY = 150;
|
||||
float speedSize = 70;
|
||||
float speedSpacing = 10;
|
||||
|
||||
speed50Button = new ButtonView(
|
||||
SCREEN_WIDTH - speedSize - 20,
|
||||
speedY,
|
||||
speedSize, speedSize,
|
||||
GameResources.BUTTON_SPEED_PATH
|
||||
);
|
||||
|
||||
speed80Button = new ButtonView(
|
||||
SCREEN_WIDTH - speedSize - 20,
|
||||
speedY + speedSize + speedSpacing,
|
||||
speedSize, speedSize,
|
||||
GameResources.BUTTON_SPEED_PATH
|
||||
);
|
||||
|
||||
speed100Button = new ButtonView(
|
||||
SCREEN_WIDTH - speedSize - 20,
|
||||
speedY + (speedSize + speedSpacing) * 2,
|
||||
speedSize, speedSize,
|
||||
GameResources.BUTTON_SPEED_PATH
|
||||
);
|
||||
|
||||
float centerX = SCREEN_WIDTH / 2 - bigW / 2;
|
||||
float centerY = SCREEN_HEIGHT / 2;
|
||||
|
||||
resumeButton = new ButtonView(
|
||||
centerX, centerY + 120,
|
||||
bigW, bigH,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"ПРОДОЛЖИТЬ"
|
||||
);
|
||||
resumeButton.setTextColor(Color.BLACK);
|
||||
|
||||
settingsButton = new ButtonView(
|
||||
centerX, centerY,
|
||||
bigW, bigH,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"НАСТРОЙКИ"
|
||||
);
|
||||
settingsButton.setTextColor(Color.BLACK);
|
||||
|
||||
menuButton = new ButtonView(
|
||||
centerX, centerY - 120,
|
||||
bigW, bigH,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"ГЛАВНОЕ МЕНЮ"
|
||||
);
|
||||
menuButton.setTextColor(Color.BLACK);
|
||||
}
|
||||
|
||||
private void createText() {
|
||||
float leftX = 20;
|
||||
|
||||
levelText = new TextView(
|
||||
game.smallFont,
|
||||
leftX, SCREEN_HEIGHT - 40,
|
||||
"Уровень: " + LEVELS[currentLevel].name
|
||||
);
|
||||
levelText.setColor(Color.WHITE);
|
||||
|
||||
scoreText = new TextView(
|
||||
game.smallFont,
|
||||
leftX, SCREEN_HEIGHT - 70,
|
||||
"Очки: 0"
|
||||
);
|
||||
scoreText.setColor(Color.WHITE);
|
||||
|
||||
enemiesText = new TextView(
|
||||
game.smallFont,
|
||||
leftX, SCREEN_HEIGHT - 100,
|
||||
"Враги: 0/" + enemiesToDefeat
|
||||
);
|
||||
enemiesText.setColor(Color.WHITE);
|
||||
|
||||
speedText = new TextView(
|
||||
game.smallFont,
|
||||
SCREEN_WIDTH - 200, 130,
|
||||
"Скорость: 100%"
|
||||
);
|
||||
speedText.setColor(Color.WHITE);
|
||||
|
||||
weaponIndicator = new TextView(
|
||||
game.buttonFont,
|
||||
20, 200,
|
||||
"ОРУЖИЕ: ПУЛИ"
|
||||
);
|
||||
weaponIndicator.setColor(Color.WHITE);
|
||||
}
|
||||
|
||||
private void resetGameVariables() {
|
||||
enemySpawnTimer = 0;
|
||||
currentSpeedLevel = 2;
|
||||
isPaused = false;
|
||||
rotatingLeft = false;
|
||||
rotatingRight = false;
|
||||
isAttacking = false;
|
||||
autoShootTimer = 0;
|
||||
score = 0;
|
||||
shootCooldown = 0;
|
||||
defeatedEnemies = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0.1f, 0.1f, 0.2f, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (!isPaused) {
|
||||
updateGame(delta);
|
||||
}
|
||||
|
||||
updateCamera();
|
||||
drawGame();
|
||||
drawInterface();
|
||||
handleInput();
|
||||
}
|
||||
//-------------------------------
|
||||
private void updateGame(float delta) {
|
||||
player.update(delta);
|
||||
|
||||
if (rotatingLeft) {
|
||||
player.rotateLeft(delta);
|
||||
}
|
||||
if (rotatingRight) {
|
||||
player.rotateRight(delta);
|
||||
}
|
||||
|
||||
if (isAttacking) {
|
||||
if (autoShootTimer <= 0) {
|
||||
playerShoot();
|
||||
if (player.isRocket()) {
|
||||
autoShootTimer = ROCKET_COOLDOWN;
|
||||
} else {
|
||||
autoShootTimer = BULLET_COOLDOWN;
|
||||
}
|
||||
} else {
|
||||
autoShootTimer -= delta;
|
||||
}
|
||||
}
|
||||
|
||||
updateText();
|
||||
|
||||
if (shootCooldown > 0) {
|
||||
shootCooldown -= delta;
|
||||
}
|
||||
|
||||
updateEnemies(delta);
|
||||
updatePlayerBullets(delta);
|
||||
updateEnemyBullets(delta);
|
||||
updateEnemySpawn(delta);
|
||||
updateExplosions(delta);
|
||||
|
||||
if (!player.isAlive()) {
|
||||
gameOver();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEnemies(float delta) {
|
||||
Iterator<EnemyPlane> it = enemies.iterator();
|
||||
while (it.hasNext()) {
|
||||
EnemyPlane enemy = it.next();
|
||||
|
||||
if (enemy.isDead()) {
|
||||
enemy.update(delta, player.getX(), player.getY());
|
||||
if (enemy.isAnimationFinished()) {
|
||||
it.remove();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
enemy.update(delta, player.getX(), player.getY());
|
||||
|
||||
if (Math.random() < ENEMY_SHOOT_PROBABILITY) {
|
||||
shootFromEnemy(enemy);
|
||||
}
|
||||
|
||||
if (player.collidesWith(enemy.getX(), enemy.getY(), enemy.getWidth()/2)) {
|
||||
player.takeDamage(PLAYER_COLLISION_DAMAGE);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePlayerBullets(float delta) {
|
||||
Iterator<Bullet> it = playerBullets.iterator();
|
||||
while (it.hasNext()) {
|
||||
Bullet bullet = it.next();
|
||||
bullet.update(delta);
|
||||
|
||||
float dx = bullet.getX() - player.getX();
|
||||
float dy = bullet.getY() - player.getY();
|
||||
if (dx * dx + dy * dy > BULLET_DESPAWN_DISTANCE * BULLET_DESPAWN_DISTANCE) {
|
||||
it.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
Iterator<EnemyPlane> enemyIt = enemies.iterator();
|
||||
while (enemyIt.hasNext()) {
|
||||
EnemyPlane enemy = enemyIt.next();
|
||||
if (enemy.collidesWith(bullet.getX(), bullet.getY(), bullet.getWidth()/2)) {
|
||||
if (enemy.takeDamage(bullet.getDamage())) {
|
||||
score += SCORE_PER_ENEMY;
|
||||
defeatedEnemies++;
|
||||
game.soundManager.playExplosionSound();
|
||||
System.out.println("Враг уничтожен! " + defeatedEnemies + "/" + enemiesToDefeat);
|
||||
|
||||
if (defeatedEnemies >= enemiesToDefeat) {
|
||||
levelComplete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
it.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEnemyBullets(float delta) {
|
||||
Iterator<Bullet> it = enemyBullets.iterator();
|
||||
while (it.hasNext()) {
|
||||
Bullet bullet = it.next();
|
||||
bullet.update(delta);
|
||||
|
||||
if (player.collidesWith(bullet.getX(), bullet.getY(), bullet.getWidth()/2)) {
|
||||
player.takeDamage(BULLET_COLLISION_DAMAGE);
|
||||
it.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
float dx = bullet.getX() - player.getX();
|
||||
float dy = bullet.getY() - player.getY();
|
||||
if (dx * dx + dy * dy > BULLET_DESPAWN_DISTANCE * BULLET_DESPAWN_DISTANCE) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEnemySpawn(float delta) {
|
||||
enemySpawnTimer += delta;
|
||||
if (enemySpawnTimer >= ENEMY_SPAWN_RATE) {
|
||||
int maxSpawn = enemiesToDefeat * 2;
|
||||
if (enemies.size() < maxSpawn) {
|
||||
spawnEnemy();
|
||||
}
|
||||
enemySpawnTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void updateExplosions(float delta) {
|
||||
for (int i = 0; i < explosions.size(); i++) {
|
||||
float[] exp = explosions.get(i);
|
||||
exp[2] -= delta;
|
||||
if (exp[2] <= 0) {
|
||||
explosions.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------
|
||||
private void drawExplosions() {
|
||||
for (float[] exp : explosions) {
|
||||
float alpha = exp[2] / 0.3f;
|
||||
batch.setColor(1, 1, 1, alpha);
|
||||
batch.draw(explosionTexture, exp[0] - 40, exp[1] - 40, 80, 80);
|
||||
batch.setColor(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnEnemy() {
|
||||
float angle = (float) (Math.random() * Math.PI * 2);
|
||||
float distance = 600 + (float) (Math.random() * 300);
|
||||
|
||||
float x = player.getX() + (float) Math.cos(angle) * distance;
|
||||
float y = player.getY() + (float) Math.sin(angle) * distance;
|
||||
|
||||
float multiplier = getDifficultyMultiplier();
|
||||
enemies.add(new EnemyPlane(x, y, currentLevel, multiplier));
|
||||
}
|
||||
|
||||
private void shootFromEnemy(EnemyPlane enemy) {
|
||||
float dx = player.getX() - enemy.getX();
|
||||
float dy = player.getY() - enemy.getY();
|
||||
float angle = (float) Math.atan2(dy, dx);
|
||||
|
||||
Bullet bullet = new Bullet();
|
||||
bullet.init(enemy.getX(), enemy.getY(), angle, false, false);
|
||||
enemyBullets.add(bullet);
|
||||
}
|
||||
|
||||
private void playerShoot() {
|
||||
if (shootCooldown > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
float[] gunPos = player.getGunPosition();
|
||||
Bullet bullet = new Bullet();
|
||||
bullet.init(gunPos[0], gunPos[1], player.getShootAngle(), true, player.isRocket());
|
||||
playerBullets.add(bullet);
|
||||
|
||||
if (player.isRocket()) {
|
||||
game.soundManager.playRocketSound();
|
||||
shootCooldown = ROCKET_COOLDOWN;
|
||||
} else {
|
||||
game.soundManager.playShootSound();
|
||||
shootCooldown = BULLET_COOLDOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateText() {
|
||||
scoreText.setText("Очки: " + score);
|
||||
enemiesText.setText("Враги: " + defeatedEnemies + "/" + enemiesToDefeat);
|
||||
}
|
||||
|
||||
private void updateCamera() {
|
||||
gameCamera.position.set(player.getX(), player.getY(), 0);
|
||||
gameCamera.update();
|
||||
}
|
||||
|
||||
private void drawGame() {
|
||||
batch.setProjectionMatrix(gameCamera.combined);
|
||||
batch.begin();
|
||||
|
||||
float w = backgroundTexture.getWidth();
|
||||
float h = backgroundTexture.getHeight();
|
||||
|
||||
float left = gameCamera.position.x - SCREEN_WIDTH;
|
||||
float right = gameCamera.position.x + SCREEN_WIDTH;
|
||||
float bottom = gameCamera.position.y - SCREEN_HEIGHT;
|
||||
float top = gameCamera.position.y + SCREEN_HEIGHT;
|
||||
|
||||
int startCol = (int)Math.floor(left / w);
|
||||
int endCol = (int)Math.ceil(right / w);
|
||||
int startRow = (int)Math.floor(bottom / h);
|
||||
int endRow = (int)Math.ceil(top / h);
|
||||
|
||||
for (int col = startCol; col <= endCol; col++) {
|
||||
for (int row = startRow; row <= endRow; row++) {
|
||||
float x = col * w;
|
||||
float y = row * h;
|
||||
batch.draw(backgroundTexture, x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
player.draw(batch);
|
||||
|
||||
for (EnemyPlane enemy : enemies) {
|
||||
enemy.draw(batch);
|
||||
}
|
||||
|
||||
for (Bullet bullet : playerBullets) {
|
||||
bullet.draw(batch);
|
||||
}
|
||||
|
||||
for (Bullet bullet : enemyBullets) {
|
||||
bullet.draw(batch);
|
||||
}
|
||||
|
||||
drawExplosions();
|
||||
|
||||
batch.end();
|
||||
}
|
||||
|
||||
private void drawInterface() {
|
||||
batch.setProjectionMatrix(game.camera.combined);
|
||||
batch.begin();
|
||||
|
||||
pauseButton.draw(batch);
|
||||
weaponButton.draw(batch);
|
||||
rotateLeftButton.draw(batch);
|
||||
rotateRightButton.draw(batch);
|
||||
attackButton.draw(batch);
|
||||
speed50Button.draw(batch);
|
||||
speed80Button.draw(batch);
|
||||
speed100Button.draw(batch);
|
||||
|
||||
levelText.draw(batch);
|
||||
scoreText.draw(batch);
|
||||
enemiesText.draw(batch);
|
||||
speedText.draw(batch);
|
||||
weaponIndicator.draw(batch);
|
||||
|
||||
float healthPercent = (float)player.getHealth() / player.getMaxHealth();
|
||||
batch.draw(healthBarBg, SCREEN_WIDTH - 220, SCREEN_HEIGHT - 60, 200, 20);
|
||||
batch.draw(healthBarFill, SCREEN_WIDTH - 220, SCREEN_HEIGHT - 60, 200 * healthPercent, 20);
|
||||
|
||||
if (isPaused) {
|
||||
batch.setColor(0, 0, 0, 0.7f);
|
||||
Texture black = new Texture(Gdx.files.internal(GameResources.BUTTON_PATH));
|
||||
batch.draw(black, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
black.dispose();
|
||||
batch.setColor(Color.WHITE);
|
||||
|
||||
game.titleFont.draw(batch, "ПАУЗА", SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT - 100);
|
||||
|
||||
resumeButton.draw(batch);
|
||||
settingsButton.draw(batch);
|
||||
menuButton.draw(batch);
|
||||
}
|
||||
|
||||
batch.end();
|
||||
}
|
||||
|
||||
private void handleInput() {
|
||||
if (Gdx.input.justTouched()) {
|
||||
Vector3 touch = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
|
||||
game.camera.unproject(touch);
|
||||
|
||||
if (isPaused) {
|
||||
if (resumeButton.isHit(touch.x, touch.y)) {
|
||||
isPaused = false;
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (settingsButton.isHit(touch.x, touch.y)) {
|
||||
game.isFromGame = true;
|
||||
game.setScreen(game.settingsScreen);
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (menuButton.isHit(touch.x, touch.y)) {
|
||||
returnToMenu();
|
||||
}
|
||||
} else {
|
||||
if (pauseButton.isHit(touch.x, touch.y)) {
|
||||
isPaused = true;
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (weaponButton.isHit(touch.x, touch.y)) {
|
||||
player.switchWeapon();
|
||||
if (player.isRocket()) {
|
||||
weaponIndicator.setText("ОРУЖИЕ: РАКЕТЫ");
|
||||
} else {
|
||||
weaponIndicator.setText("ОРУЖИЕ: ПУЛИ");
|
||||
}
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (speed50Button.isHit(touch.x, touch.y)) {
|
||||
setSpeedLevel(0);
|
||||
}
|
||||
else if (speed80Button.isHit(touch.x, touch.y)) {
|
||||
setSpeedLevel(1);
|
||||
}
|
||||
else if (speed100Button.isHit(touch.x, touch.y)) {
|
||||
setSpeedLevel(2);
|
||||
}
|
||||
else if (rotateLeftButton.isHit(touch.x, touch.y)) {
|
||||
rotatingLeft = true;
|
||||
rotatingRight = false;
|
||||
}
|
||||
else if (rotateRightButton.isHit(touch.x, touch.y)) {
|
||||
rotatingRight = true;
|
||||
rotatingLeft = false;
|
||||
}
|
||||
else if (attackButton.isHit(touch.x, touch.y)) {
|
||||
isAttacking = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Gdx.input.isTouched()) {
|
||||
isAttacking = false;
|
||||
rotatingLeft = false;
|
||||
rotatingRight = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void setSpeedLevel(int level) {
|
||||
currentSpeedLevel = level;
|
||||
player.setSpeedMultiplier(SPEED_LEVELS[level]);
|
||||
|
||||
if (level == 0) {
|
||||
speedText.setText("Скорость: 50%");
|
||||
} else if (level == 1) {
|
||||
speedText.setText("Скорость: 80%");
|
||||
} else {
|
||||
speedText.setText("Скорость: 100%");
|
||||
}
|
||||
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
|
||||
private void gameOver() {
|
||||
game.gameOverScreen.setScore(score);
|
||||
game.setScreen(game.gameOverScreen);
|
||||
game.soundManager.playExplosionSound();
|
||||
}
|
||||
|
||||
private void levelComplete() {
|
||||
game.gameOverScreen.setScore(score);
|
||||
game.setScreen(game.gameOverScreen);
|
||||
}
|
||||
|
||||
private void returnToMenu() {
|
||||
disposeGameObjects();
|
||||
game.setScreen(game.menuScreen);
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
|
||||
private void disposeGameObjects() {
|
||||
if (player != null) player.dispose();
|
||||
for (EnemyPlane e : enemies) e.dispose();
|
||||
for (Bullet b : playerBullets) b.dispose();
|
||||
for (Bullet b : enemyBullets) b.dispose();
|
||||
|
||||
enemies.clear();
|
||||
playerBullets.clear();
|
||||
enemyBullets.clear();
|
||||
explosions.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playBackgroundMusic();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.pauseBackgroundMusic();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
disposeGameObjects();
|
||||
|
||||
if (backgroundTexture != null) backgroundTexture.dispose();
|
||||
if (healthBarBg != null) healthBarBg.dispose();
|
||||
if (healthBarFill != null) healthBarFill.dispose();
|
||||
if (explosionTexture != null) explosionTexture.dispose();
|
||||
|
||||
if (pauseButton != null) pauseButton.dispose();
|
||||
if (weaponButton != null) weaponButton.dispose();
|
||||
if (rotateLeftButton != null) rotateLeftButton.dispose();
|
||||
if (rotateRightButton != null) rotateRightButton.dispose();
|
||||
if (attackButton != null) attackButton.dispose();
|
||||
if (speed50Button != null) speed50Button.dispose();
|
||||
if (speed80Button != null) speed80Button.dispose();
|
||||
if (speed100Button != null) speed100Button.dispose();
|
||||
if (resumeButton != null) resumeButton.dispose();
|
||||
if (settingsButton != null) settingsButton.dispose();
|
||||
if (menuButton != null) menuButton.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
package com.mygdx.game.screens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.mygdx.game.GameResources;
|
||||
import com.mygdx.game.GameSettings;
|
||||
import com.mygdx.game.MyGdxGame;
|
||||
import com.mygdx.game.components.ButtonView;
|
||||
import com.mygdx.game.components.ImageView;
|
||||
import com.mygdx.game.components.TextView;
|
||||
|
||||
public class LevelSelectScreen extends ScreenAdapter {
|
||||
private MyGdxGame game;
|
||||
private SpriteBatch batch;
|
||||
private ImageView background;
|
||||
|
||||
private TextView titleTextView;
|
||||
private ButtonView[] levelButtons;
|
||||
private ButtonView backButton;
|
||||
|
||||
public LevelSelectScreen(MyGdxGame game) {
|
||||
this.game = game;
|
||||
this.batch = game.batch;
|
||||
this.background = null;
|
||||
this.levelButtons = null;
|
||||
this.backButton = null;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// Фон
|
||||
try {
|
||||
background = new ImageView(0, 0,
|
||||
GameSettings.SCREEN_WIDTH,
|
||||
GameSettings.SCREEN_HEIGHT,
|
||||
GameResources.LEVEL_SELECT_BG_PATH);
|
||||
} catch (Exception e) {
|
||||
background = new ImageView(0, 0,
|
||||
GameSettings.SCREEN_WIDTH,
|
||||
GameSettings.SCREEN_HEIGHT,
|
||||
GameResources.MENU_BG_IMG_PATH);
|
||||
}
|
||||
|
||||
float centerX = GameSettings.SCREEN_WIDTH / 2f;
|
||||
|
||||
titleTextView = new TextView(game.titleFont,
|
||||
centerX - 200,
|
||||
GameSettings.SCREEN_HEIGHT - 150,
|
||||
"ВЫБОР УРОВНЯ");
|
||||
|
||||
levelButtons = new ButtonView[GameSettings.LEVELS.length];
|
||||
|
||||
for (int i = 0; i < GameSettings.LEVELS.length; i++) {
|
||||
int levelNum = i + 1;
|
||||
String levelName = GameSettings.LEVELS[i].name;
|
||||
String buttonText = levelNum + ". " + levelName;
|
||||
|
||||
levelButtons[i] = new ButtonView(
|
||||
centerX - 150,
|
||||
400 - i * 100,
|
||||
300, 80,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
buttonText
|
||||
);
|
||||
}
|
||||
|
||||
backButton = new ButtonView(
|
||||
centerX - 150, 100, 300, 80,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"НАЗАД"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0.1f, 0.2f, 0.3f, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
game.camera.update();
|
||||
batch.setProjectionMatrix(game.camera.combined);
|
||||
|
||||
handleInput();
|
||||
|
||||
batch.begin();
|
||||
|
||||
if (background != null) {
|
||||
background.draw(batch);
|
||||
}
|
||||
|
||||
titleTextView.draw(batch);
|
||||
|
||||
if (levelButtons != null) {
|
||||
for (ButtonView button : levelButtons) {
|
||||
if (button != null) {
|
||||
button.draw(batch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (backButton != null) {
|
||||
backButton.draw(batch);
|
||||
}
|
||||
|
||||
batch.end();
|
||||
}
|
||||
|
||||
private void handleInput() {
|
||||
if (Gdx.input.justTouched()) {
|
||||
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
|
||||
game.camera.unproject(touchPos);
|
||||
|
||||
if (levelButtons != null) {
|
||||
for (int i = 0; i < levelButtons.length; i++) {
|
||||
if (levelButtons[i] != null && levelButtons[i].isHit(touchPos.x, touchPos.y)) {
|
||||
game.selectedLevel = i;
|
||||
System.out.println("Выбран уровень: " + (i + 1) + " - " + GameSettings.LEVELS[i].name);
|
||||
|
||||
if (game.gameScreen != null) {
|
||||
game.gameScreen.dispose();
|
||||
game.gameScreen = null;
|
||||
}
|
||||
game.gameScreen = new GameScreen(game);
|
||||
game.setScreen(game.gameScreen);
|
||||
|
||||
if (game.soundManager != null) game.soundManager.playSelectSound();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (backButton != null && backButton.isHit(touchPos.x, touchPos.y)) {
|
||||
System.out.println("Возврат в меню");
|
||||
game.setScreen(game.menuScreen);
|
||||
if (game.soundManager != null) game.soundManager.playSelectSound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
System.out.println("Показан экран выбора уровня");
|
||||
System.out.println("Доступно уровней: " + GameSettings.LEVELS.length);
|
||||
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playBackgroundMusic();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
System.out.println("Освобождение ресурсов LevelSelectScreen");
|
||||
|
||||
if (background != null) {
|
||||
background.dispose();
|
||||
background = null;
|
||||
}
|
||||
|
||||
if (levelButtons != null) {
|
||||
for (ButtonView button : levelButtons) {
|
||||
if (button != null) {
|
||||
button.dispose();
|
||||
}
|
||||
}
|
||||
levelButtons = null;
|
||||
}
|
||||
|
||||
if (backButton != null) {
|
||||
backButton.dispose();
|
||||
backButton = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package com.mygdx.game.screens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.mygdx.game.GameResources;
|
||||
import com.mygdx.game.GameSettings;
|
||||
import com.mygdx.game.MyGdxGame;
|
||||
import com.mygdx.game.components.ButtonView;
|
||||
import com.mygdx.game.components.ImageView;
|
||||
import com.mygdx.game.components.TextView;
|
||||
|
||||
public class MenuScreen extends ScreenAdapter {
|
||||
|
||||
private MyGdxGame game;
|
||||
private SpriteBatch batch;
|
||||
|
||||
private ImageView background;
|
||||
private TextView titleTextView;
|
||||
private ButtonView playButton;
|
||||
private ButtonView settingsButton;
|
||||
private ButtonView exitButton;
|
||||
|
||||
public MenuScreen(MyGdxGame game) {
|
||||
this.game = game;
|
||||
this.batch = game.batch;
|
||||
|
||||
background = new ImageView(
|
||||
0, 0,
|
||||
GameSettings.SCREEN_WIDTH,
|
||||
GameSettings.SCREEN_HEIGHT,
|
||||
GameResources.MENU_BG_IMG_PATH
|
||||
);
|
||||
|
||||
float centerX = GameSettings.SCREEN_WIDTH / 2f;
|
||||
|
||||
titleTextView = new TextView(
|
||||
game.titleFont,
|
||||
centerX - 200,
|
||||
GameSettings.SCREEN_HEIGHT - 150,
|
||||
"ВОЗДУШНЫЙ БОЙ"
|
||||
);
|
||||
|
||||
float buttonWidth = 300;
|
||||
float buttonHeight = 100;
|
||||
float buttonSpacing = 30;
|
||||
float startY = 350;
|
||||
|
||||
playButton = new ButtonView(
|
||||
centerX - buttonWidth / 2,
|
||||
startY,
|
||||
buttonWidth, buttonHeight,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"Играть"
|
||||
);
|
||||
|
||||
settingsButton = new ButtonView(
|
||||
centerX - buttonWidth / 2,
|
||||
startY - buttonHeight - buttonSpacing,
|
||||
buttonWidth, buttonHeight,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"Настройки"
|
||||
);
|
||||
|
||||
exitButton = new ButtonView(
|
||||
centerX - buttonWidth / 2,
|
||||
startY - (buttonHeight + buttonSpacing) * 2,
|
||||
buttonWidth, buttonHeight,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"Выход"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0, 0, 0, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
game.camera.update();
|
||||
batch.setProjectionMatrix(game.camera.combined);
|
||||
|
||||
handleInput();
|
||||
|
||||
batch.begin();
|
||||
|
||||
if (background != null) background.draw(batch);
|
||||
if (titleTextView != null) titleTextView.draw(batch);
|
||||
if (playButton != null) playButton.draw(batch);
|
||||
if (settingsButton != null) settingsButton.draw(batch);
|
||||
if (exitButton != null) exitButton.draw(batch);
|
||||
|
||||
batch.end();
|
||||
}
|
||||
|
||||
private void handleInput() {
|
||||
if (Gdx.input.justTouched()) {
|
||||
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
|
||||
game.camera.unproject(touchPos);
|
||||
|
||||
if (playButton != null && playButton.isHit(touchPos.x, touchPos.y)) {
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
if (game.playerSelectScreen == null) {
|
||||
game.playerSelectScreen = new PlayerSelectScreen(game);
|
||||
}
|
||||
game.setScreen(game.playerSelectScreen);
|
||||
}
|
||||
else if (settingsButton != null && settingsButton.isHit(touchPos.x, touchPos.y)) {
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
if (game.settingsScreen == null) {
|
||||
game.settingsScreen = new SettingsScreen(game);
|
||||
}
|
||||
game.setScreen(game.settingsScreen);
|
||||
}
|
||||
else if (exitButton != null && exitButton.isHit(touchPos.x, touchPos.y)) {
|
||||
Gdx.app.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playBackgroundMusic();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (background != null) background.dispose();
|
||||
if (playButton != null) playButton.dispose();
|
||||
if (settingsButton != null) settingsButton.dispose();
|
||||
if (exitButton != null) exitButton.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
package com.mygdx.game.screens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.mygdx.game.GameResources;
|
||||
import com.mygdx.game.GameSettings;
|
||||
import com.mygdx.game.MyGdxGame;
|
||||
import com.mygdx.game.components.ButtonView;
|
||||
import com.mygdx.game.components.ImageView;
|
||||
import com.mygdx.game.components.TextView;
|
||||
|
||||
public class PlayerSelectScreen extends ScreenAdapter {
|
||||
private MyGdxGame game;
|
||||
private SpriteBatch batch;
|
||||
private ImageView background;
|
||||
|
||||
private ButtonView leftButton;
|
||||
private ButtonView rightButton;
|
||||
private ButtonView selectButton;
|
||||
private ButtonView backButton;
|
||||
private TextView titleTextView;
|
||||
private TextView playerNameTextView;
|
||||
private TextView playerDescTextView;
|
||||
|
||||
private int selectedPlayer = 0;
|
||||
private String[] playerNames = {"БАЗОВЫЙ", "СКОРОСТНОЙ", "ТАНК"};
|
||||
private String[] playerDescs = {
|
||||
"Баланс скорости и защиты",
|
||||
"Высокая скорость, низкая защита",
|
||||
"Высокая защита, низкая скорость"
|
||||
};
|
||||
|
||||
private String[] playerTextures = {
|
||||
GameResources.BASIC_PATH,
|
||||
GameResources.FAST_PATH,
|
||||
GameResources.TANK_PATH
|
||||
};
|
||||
|
||||
private Texture currentPlayerTexture;
|
||||
|
||||
public PlayerSelectScreen(MyGdxGame game) {
|
||||
this.game = game;
|
||||
this.batch = game.batch;
|
||||
|
||||
background = new ImageView(0, 0,
|
||||
GameSettings.SCREEN_WIDTH,
|
||||
GameSettings.SCREEN_HEIGHT,
|
||||
GameResources.PLAYER_SELECT_BG_PATH);
|
||||
|
||||
float centerX = GameSettings.SCREEN_WIDTH / 2f;
|
||||
|
||||
titleTextView = new TextView(game.titleFont,
|
||||
centerX - 200,
|
||||
GameSettings.SCREEN_HEIGHT - 150,
|
||||
"ВЫБОР САМОЛЕТА");
|
||||
|
||||
float buttonSize = 100;
|
||||
leftButton = new ButtonView(
|
||||
100,
|
||||
GameSettings.SCREEN_HEIGHT / 2 - buttonSize/2,
|
||||
buttonSize, buttonSize,
|
||||
GameResources.BUTTON_LEFT_PATH
|
||||
);
|
||||
|
||||
rightButton = new ButtonView(
|
||||
GameSettings.SCREEN_WIDTH - 100 - buttonSize,
|
||||
GameSettings.SCREEN_HEIGHT / 2 - buttonSize/2,
|
||||
buttonSize, buttonSize,
|
||||
GameResources.BUTTON_RIGHT_PATH
|
||||
);
|
||||
|
||||
float bigButtonWidth = 300;
|
||||
float bigButtonHeight = 100;
|
||||
|
||||
selectButton = new ButtonView(
|
||||
centerX - bigButtonWidth/2,
|
||||
200,
|
||||
bigButtonWidth, bigButtonHeight,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"ВЫБРАТЬ"
|
||||
);
|
||||
selectButton.setTextColor(Color.BLACK);
|
||||
|
||||
backButton = new ButtonView(
|
||||
50,
|
||||
50,
|
||||
bigButtonWidth, bigButtonHeight,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"НАЗАД"
|
||||
);
|
||||
backButton.setTextColor(Color.BLACK);
|
||||
|
||||
currentPlayerTexture = new Texture(Gdx.files.internal(playerTextures[selectedPlayer]));
|
||||
updateText();
|
||||
}
|
||||
|
||||
private void updateText() {
|
||||
float centerX = GameSettings.SCREEN_WIDTH / 2f;
|
||||
|
||||
if (playerNameTextView != null) {
|
||||
playerNameTextView.setText(playerNames[selectedPlayer]);
|
||||
playerDescTextView.setText(playerDescs[selectedPlayer]);
|
||||
} else {
|
||||
playerNameTextView = new TextView(game.buttonFont,
|
||||
centerX - 100,
|
||||
400,
|
||||
playerNames[selectedPlayer]);
|
||||
|
||||
playerDescTextView = new TextView(game.smallFont,
|
||||
centerX - 200,
|
||||
350,
|
||||
playerDescs[selectedPlayer]);
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePlayerTexture() {
|
||||
if (currentPlayerTexture != null) {
|
||||
currentPlayerTexture.dispose();
|
||||
}
|
||||
currentPlayerTexture = new Texture(Gdx.files.internal(playerTextures[selectedPlayer]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0.2f, 0.1f, 0.3f, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
game.camera.update();
|
||||
batch.setProjectionMatrix(game.camera.combined);
|
||||
handleInput();
|
||||
|
||||
batch.begin();
|
||||
|
||||
if (background != null) background.draw(batch);
|
||||
|
||||
titleTextView.draw(batch);
|
||||
leftButton.draw(batch);
|
||||
rightButton.draw(batch);
|
||||
selectButton.draw(batch);
|
||||
backButton.draw(batch);
|
||||
playerNameTextView.draw(batch);
|
||||
playerDescTextView.draw(batch);
|
||||
|
||||
float planeSize = 200;
|
||||
float planeX = GameSettings.SCREEN_WIDTH / 2 - planeSize/2;
|
||||
float planeY = GameSettings.SCREEN_HEIGHT / 2 - planeSize/2 + 100;
|
||||
batch.draw(currentPlayerTexture, planeX, planeY, planeSize, planeSize);
|
||||
|
||||
batch.end();
|
||||
}
|
||||
|
||||
private void handleInput() {
|
||||
if (Gdx.input.justTouched()) {
|
||||
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
|
||||
game.camera.unproject(touchPos);
|
||||
|
||||
if (leftButton.isHit(touchPos.x, touchPos.y)) {
|
||||
selectedPlayer--;
|
||||
if (selectedPlayer < 0) {
|
||||
selectedPlayer = playerNames.length - 1;
|
||||
}
|
||||
updateText();
|
||||
updatePlayerTexture();
|
||||
if (game.soundManager != null) game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (rightButton.isHit(touchPos.x, touchPos.y)) {
|
||||
selectedPlayer++;
|
||||
if (selectedPlayer >= playerNames.length) {
|
||||
selectedPlayer = 0;
|
||||
}
|
||||
updateText();
|
||||
updatePlayerTexture();
|
||||
if (game.soundManager != null) game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (selectButton.isHit(touchPos.x, touchPos.y)) {
|
||||
game.selectedPlayer = selectedPlayer;
|
||||
game.setScreen(game.levelSelectScreen);
|
||||
if (game.soundManager != null) game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (backButton.isHit(touchPos.x, touchPos.y)) {
|
||||
game.setScreen(game.menuScreen);
|
||||
if (game.soundManager != null) game.soundManager.playSelectSound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playBackgroundMusic();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (background != null) background.dispose();
|
||||
if (currentPlayerTexture != null) currentPlayerTexture.dispose();
|
||||
if (leftButton != null) leftButton.dispose();
|
||||
if (rightButton != null) rightButton.dispose();
|
||||
if (selectButton != null) selectButton.dispose();
|
||||
if (backButton != null) backButton.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
package com.mygdx.game.screens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.mygdx.game.GameResources;
|
||||
import com.mygdx.game.GameSettings;
|
||||
import com.mygdx.game.MyGdxGame;
|
||||
import com.mygdx.game.components.ButtonView;
|
||||
import com.mygdx.game.components.ImageView;
|
||||
import com.mygdx.game.components.TextView;
|
||||
|
||||
public class SettingsScreen extends ScreenAdapter {
|
||||
private MyGdxGame game;
|
||||
private SpriteBatch batch;
|
||||
private ImageView background;
|
||||
|
||||
private TextView titleTextView;
|
||||
private ButtonView musicButton;
|
||||
private ButtonView soundButton;
|
||||
private ButtonView easyButton;
|
||||
private ButtonView normalButton;
|
||||
private ButtonView hardButton;
|
||||
private ButtonView backButton;
|
||||
|
||||
public SettingsScreen(MyGdxGame game) {
|
||||
this.game = game;
|
||||
this.batch = game.batch;
|
||||
|
||||
background = new ImageView(0, 0,
|
||||
GameSettings.SCREEN_WIDTH,
|
||||
GameSettings.SCREEN_HEIGHT,
|
||||
GameResources.MENU_BG_IMG_PATH);
|
||||
|
||||
float centerX = GameSettings.SCREEN_WIDTH / 2f;
|
||||
float buttonY = 500;
|
||||
float buttonSpacing = 80;
|
||||
|
||||
titleTextView = new TextView(game.titleFont,
|
||||
centerX - 200,
|
||||
GameSettings.SCREEN_HEIGHT - 150,
|
||||
"НАСТРОЙКИ");
|
||||
|
||||
musicButton = new ButtonView(
|
||||
centerX - 150, buttonY, 300, 60,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"МУЗЫКА: " + (game.soundManager.isMusicEnabled() ? "ВКЛ" : "ВЫКЛ")
|
||||
);
|
||||
|
||||
soundButton = new ButtonView(
|
||||
centerX - 150, buttonY - buttonSpacing, 300, 60,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"ЗВУКИ: " + (game.soundManager.isSoundEnabled() ? "ВКЛ" : "ВЫКЛ")
|
||||
);
|
||||
|
||||
easyButton = new ButtonView(
|
||||
centerX - 350, buttonY - buttonSpacing * 2, 200, 60,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"ЛЕГКИЙ"
|
||||
);
|
||||
|
||||
normalButton = new ButtonView(
|
||||
centerX - 100, buttonY - buttonSpacing * 2, 200, 60,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"СРЕДНИЙ"
|
||||
);
|
||||
|
||||
hardButton = new ButtonView(
|
||||
centerX + 150, buttonY - buttonSpacing * 2, 200, 60,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"СЛОЖНЫЙ"
|
||||
);
|
||||
|
||||
backButton = new ButtonView(
|
||||
centerX - 150, 100, 300, 60,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"НАЗАД"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0.3f, 0.3f, 0.4f, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
game.camera.update();
|
||||
batch.setProjectionMatrix(game.camera.combined);
|
||||
handleInput();
|
||||
|
||||
batch.begin();
|
||||
|
||||
if (background != null) background.draw(batch);
|
||||
|
||||
titleTextView.draw(batch);
|
||||
musicButton.draw(batch);
|
||||
soundButton.draw(batch);
|
||||
easyButton.draw(batch);
|
||||
normalButton.draw(batch);
|
||||
hardButton.draw(batch);
|
||||
backButton.draw(batch);
|
||||
|
||||
batch.end();
|
||||
}
|
||||
|
||||
private void handleInput() {
|
||||
if (Gdx.input.justTouched()) {
|
||||
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
|
||||
game.camera.unproject(touchPos);
|
||||
|
||||
if (musicButton.isHit(touchPos.x, touchPos.y)) {
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.toggleMusic();
|
||||
float x = musicButton.getX();
|
||||
float y = musicButton.getY();
|
||||
musicButton.dispose();
|
||||
musicButton = new ButtonView(
|
||||
x, y, 300, 60,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"МУЗЫКА: " + (game.soundManager.isMusicEnabled() ? "ВКЛ" : "ВЫКЛ")
|
||||
);
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
}
|
||||
else if (soundButton.isHit(touchPos.x, touchPos.y)) {
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.toggleSound();
|
||||
float x = soundButton.getX();
|
||||
float y = soundButton.getY();
|
||||
soundButton.dispose();
|
||||
soundButton = new ButtonView(
|
||||
x, y, 300, 60,
|
||||
game.buttonFont,
|
||||
GameResources.BUTTON_PATH,
|
||||
"ЗВУКИ: " + (game.soundManager.isSoundEnabled() ? "ВКЛ" : "ВЫКЛ")
|
||||
);
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
}
|
||||
else if (easyButton.isHit(touchPos.x, touchPos.y)) {
|
||||
GameSettings.currentDifficulty = GameSettings.Difficulty.EASY;
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (normalButton.isHit(touchPos.x, touchPos.y)) {
|
||||
GameSettings.currentDifficulty = GameSettings.Difficulty.NORMAL;
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (hardButton.isHit(touchPos.x, touchPos.y)) {
|
||||
GameSettings.currentDifficulty = GameSettings.Difficulty.HARD;
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
else if (backButton.isHit(touchPos.x, touchPos.y)) {
|
||||
if (game.isFromGame) {
|
||||
game.isFromGame = false;
|
||||
game.setScreen(game.gameScreen);
|
||||
} else {
|
||||
game.setScreen(game.menuScreen);
|
||||
}
|
||||
game.soundManager.playSelectSound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
if (game.soundManager != null) {
|
||||
game.soundManager.playBackgroundMusic();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (background != null) background.dispose();
|
||||
if (musicButton != null) musicButton.dispose();
|
||||
if (soundButton != null) soundButton.dispose();
|
||||
if (easyButton != null) easyButton.dispose();
|
||||
if (normalButton != null) normalButton.dispose();
|
||||
if (hardButton != null) hardButton.dispose();
|
||||
if (backButton != null) backButton.dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user