Untitled
unknown
java
2 years ago
19 kB
5
Indexable
Never
package com.company; import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.plaf.nimbus.State; import java.awt.*; import java.awt.event.*; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Random; class GeometryUtils { static boolean areRectsIntersecting(Rectangle2D a, Rectangle2D b) { return (a.getX() <= b.getX() + b.getWidth()) && (a.getX() + a.getWidth() >= b.getX()) && (a.getY() <= b.getY() + b.getHeight()) && (a.getY() + a.getHeight() >= b.getY()); } static Rectangle2D getRectsIntersection(Rectangle2D a, Rectangle2D b) { double x = Math.max(a.getX(), b.getX()); double y = Math.max(a.getY(), b.getY()); double width = Math.min(a.getX() + a.getWidth(), b.getX() + b.getWidth()) - Math.max(a.getX(), b.getX()); double height = Math.min(a.getY() + a.getHeight(), b.getY() + b.getHeight()) - Math.max(a.getY(), b.getY()); return new Rectangle2D.Double(x, y, width, height); } static float distanceBetween(GameObject a, GameObject b) { return (float)Math.sqrt((a.getX() - b.getX()) * (a.getX() - b.getX()) + (a.getY() - b.getY()) * (a.getY() - b.getY())); } } class ResourcesManager { private static ResourcesManager resourcesManager = new ResourcesManager(); private Map<String, Image> imagesMap = new HashMap<>(); public static ResourcesManager getInstance() { return resourcesManager; } private ResourcesManager() { } public Image loadImage(String path) { if (imagesMap.containsKey(path)) { return imagesMap.get(path); } try { Image image = ImageIO.read(new File(path)); imagesMap.put(path, image); return image; } catch (IOException e) { e.printStackTrace(); return null; } } } class GameObject { private float x; private float y; private float width; private float height; private boolean isStatic = false; GameObject() { } public boolean isStatic() { return isStatic; } public void setStatic(boolean isStatic) { this.isStatic = isStatic; } public void setPosition(float x, float y) { setX(x); setY(y); } public void move(float x, float y) { if (isStatic()) { throw new RuntimeException(); } this.x += x; this.y += y; } public void setSize(float width, float height) { setWidth(width); setHeight(height); } public float getX() { return x; } public void setX(float x) { this.x = x; } public float getY() { return y; } public void setY(float y) { this.y = y; } public float getWidth() { return width; } public void setWidth(float width) { this.width = width; } public float getHeight() { return height; } public void setHeight(float height) { this.height = height; } public Rectangle2D getRect() { return new Rectangle2D.Float(getX(), getY(), getWidth(), getHeight()); } public void update(float delta) { } public void render(Graphics2D g) { } public void handleKeyPress(char keyChar) { } public void handleKeyRelease(char keyChar) { } } class TexturedBlock extends GameObject { private Image image; TexturedBlock(Image image) { this.image = image; } @Override public void render(Graphics2D g) { g.drawImage(image, (int) getX(), (int) getY(), (int) getWidth(), (int) getHeight(), null); g.setColor(Color.BLACK); // g.drawRect((int) getX(), (int) getY(), (int) getWidth(), (int) getHeight()); } public Image getImage() { return image; } public void setImage(Image image) { this.image = image; } } enum PlayerState { Jump, OnPlatform, Falling, NotAlive } class Player extends TexturedBlock { private float direction = 0.0f; private final float acceleration = 50.8f; private float velocity = 0.0f; PlayerState state = PlayerState.Falling; private int scores = 0; private ArrayList<Platform> platforms; Player(ArrayList<Platform> platforms) { super(ResourcesManager.getInstance().loadImage("C:\\Users\\nikolai\\IdeaProjects\\untitled\\assets\\png\\player.png")); this.platforms = platforms; } boolean isOnPlatform() { return state == PlayerState.OnPlatform; } void setAlive(boolean alive) { if (alive) { state = PlayerState.Falling; } else { state = PlayerState.NotAlive; } } boolean isAlive() { return state != PlayerState.NotAlive; } void setScores(int scores) { this.scores = scores; } int getScores() { return scores; } void increaseScores(int increase) { scores += increase; } @Override public void update(float delta) { float speed = 300.0f; move(delta * speed * direction, 0); if (state != PlayerState.OnPlatform) { velocity += acceleration * delta; move(0, velocity); } // if (state == PlayerState.Falling) { // state = PlayerState.Falling; //// velocity = acceleration * 1.5f; // } boolean somePlatformIsFound = false; for (Platform platform : platforms) { if (GeometryUtils.areRectsIntersecting(getRect(), platform.getRect())) { Rectangle2D intersection = GeometryUtils.getRectsIntersection(getRect(), platform.getRect()); if (intersection.getWidth() < intersection.getHeight()) { move(-direction * (float) intersection.getWidth(), 0); } else { int pushingDirection = -1; if (getY() < platform.getY() + platform.getHeight() && getY() > platform.getY()) { pushingDirection = 1; } move(0, (float) intersection.getHeight() * pushingDirection); } if (intersection.getWidth() > 10) { if (intersection.getY() + intersection.getHeight() < getY() + getHeight() / 2.0f) { velocity = 0; } else { state = PlayerState.OnPlatform; velocity = 0; somePlatformIsFound = true; } } } } if (!somePlatformIsFound) { if (state == PlayerState.OnPlatform) { state = PlayerState.Falling; } } } @Override public void handleKeyPress(char keyChar) { // w a s d if (keyChar == 'd') { direction = 1.0f; } else if (keyChar == 'a') { direction = -1.0f; } else if (keyChar == ' ') { if (state == PlayerState.OnPlatform) { velocity = -acceleration * 0.4f; state = PlayerState.Falling; } } } @Override public void handleKeyRelease(char keyChar) { if (keyChar == 'd' || keyChar == 'a') { direction = 0.0f; } } } enum PlatformType { Grass, Wood } class Platform extends TexturedBlock { Platform(PlatformType type) { super(null); Image image = null; if (type == PlatformType.Grass) { image = ResourcesManager.getInstance().loadImage("C:\\Users\\nikolai\\IdeaProjects\\untitled\\assets\\grass_flat.png"); } else if (type == PlatformType.Wood) { image = ResourcesManager.getInstance().loadImage("C:\\Users\\nikolai\\IdeaProjects\\untitled\\assets\\wood.png"); } setImage(image); } @Override public void update(float delta) { } } class Coin extends TexturedBlock { Coin() { super(ResourcesManager.getInstance().loadImage("C:\\Users\\nikolai\\IdeaProjects\\untitled\\assets\\coin.png")); } } class Spike extends TexturedBlock { Spike() { super(ResourcesManager.getInstance().loadImage("C:\\Users\\nikolai\\IdeaProjects\\untitled\\assets\\spike_2.png")); } void setTriggered(boolean triggered) { if (triggered) { setImage(ResourcesManager.getInstance().loadImage("C:\\Users\\nikolai\\IdeaProjects\\untitled\\assets\\spike_1.png")); } else { setImage(ResourcesManager.getInstance().loadImage("C:\\Users\\nikolai\\IdeaProjects\\untitled\\assets\\spike_2.png")); } } } enum GameState { Loading, GameActive, GameOver, GameWin } class Viewport extends JPanel { private JFrame window; private Random random = new Random(); private final ArrayList<GameObject> gameObjects = new ArrayList<>(); private final ArrayList<Platform> platforms = new ArrayList<>(); private final ArrayList<Coin> coins = new ArrayList<>(); private final ArrayList<Spike> spikes = new ArrayList<>(); private Player player; private GameState gameState = GameState.Loading; private Font gameWinFont = new Font("TimesRoman", Font.PLAIN, 82); private Font gameOverFont = new Font("TimesRoman", Font.PLAIN, 82); private Font restartFont = new Font("TimesRoman", Font.PLAIN, 30); private Font scoresFont = new Font("TimesRoman", Font.PLAIN, 24); public Viewport(JFrame window) { this.window = window; } public void initializeGame() { TexturedBlock background = new TexturedBlock(ResourcesManager.getInstance().loadImage("C:\\Users\\nikolai\\IdeaProjects\\untitled\\assets\\cloudy2.jpg")); background.setPosition(0, 0); background.setSize(getWidth(), getHeight()); background.setStatic(true); gameObjects.add(background); player = new Player(platforms); player.setPosition(0.0f, 0.0f); player.setSize(50.0f, 75.0f); gameObjects.add(player); // addPlatform(PlatformType.Grass, 10, 50, 50, 50); // addPlatform(PlatformType.Grass, 10 + 50 * 1, 50, 50, 50); // addPlatform(PlatformType.Grass, 10 + 50 * 2, 50, 50, 50); // addPlatform(PlatformType.Grass, 10 + 50 * 3, 50, 50, 50); addPlatform(PlatformType.Grass, 10, 200, 50, 50); addPlatform(PlatformType.Grass, 10 + 50 * 1, 200, 50, 50); addPlatform(PlatformType.Grass, 10 + 50 * 2, 200, 50, 50); addPlatform(PlatformType.Grass, 10 + 50 * 3, 200, 50, 50); addPlatform(PlatformType.Grass, 300, 100, 50, 50); addPlatform(PlatformType.Grass, 300 + 50 * 1, 100, 50, 50); addPlatform(PlatformType.Grass, 300 + 50 * 2, 100, 50, 50); addPlatform(PlatformType.Grass, 300 + 50 * 3, 100, 50, 50); for (int index = 0; index < 50; index++) { addPlatform(PlatformType.Grass, 500 + 50 * index, 100, 50, 50); } addPlatform(PlatformType.Grass, 10 + 50 * 4, 200 + 70 * 1, 50, 50); addPlatform(PlatformType.Grass, 10 + 50 * 5, 200 + 70 * 1, 50, 50); addPlatform(PlatformType.Grass, 10 + 50 * 6, 200 + 70 * 1, 50, 50); addPlatform(PlatformType.Grass, 10 + 50 * 7, 200 + 70 * 2, 50, 50); addPlatform(PlatformType.Grass, 10 + 50 * 8, 200 + 70 * 2, 50, 50); addCoin(10 + 50 * 7 + 20, 200 + 70 * 2 - 50, 25, 25); addCoin(10 + 50 * 7 + 100, 200 + 70 * 2 - 50, 25, 25); addCoin(10 + 50 * 7 + 150, 200 + 70 * 2 - 50, 25, 25); addCoin(300 + 20, 100 - 45, 25, 25); addCoin(300 + 70, 100 - 45, 25, 25); addSpike(10 + 50 * 7 + 20, 200 + 70 * 2 - 25, 50, 25); addSpike(400 + 50 * 2, 100 - 25, 50, 25); addSpike(400 + 50 * 4, 100 - 25, 50, 25); addSpike(400 + 50 * 7, 100 - 25, 50, 25); gameState = GameState.GameActive; } public void deinitializeGame() { player = null; platforms.clear(); coins.clear(); spikes.clear(); gameObjects.clear(); } private void locateObject(GameObject object, float x, float y, float width, float height) { object.setPosition(x, y); object.setSize(width, height); } private void addPlatform(PlatformType platformType, float x, float y, float width, float height) { Platform platform = new Platform(platformType); locateObject(platform, x, y, width, height); gameObjects.add(platform); platforms.add(platform); } private void addCoin(float x, float y, float width, float height) { Coin coin = new Coin(); locateObject(coin, x, y, width, height); gameObjects.add(coin); coins.add(coin); } private void addSpike(float x, float y, float width, float height) { Spike spike = new Spike(); locateObject(spike, x, y, width, height); gameObjects.add(spike); spikes.add(spike); } public void handleKeyPress(KeyEvent event) { if (gameState == GameState.GameOver || gameState == GameState.GameWin) { switch (event.getExtendedKeyCode()) { case KeyEvent.VK_ESCAPE: deinitializeGame(); window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING)); break; case KeyEvent.VK_R: deinitializeGame(); initializeGame(); gameState = GameState.GameActive; break; default: break; } } else { for (GameObject object : gameObjects) { object.handleKeyPress(event.getKeyChar()); } } repaint(); } public void handleKeyRelease(KeyEvent event) { for (GameObject object : gameObjects) { object.handleKeyRelease(event.getKeyChar()); } repaint(); } public void updateGame(float delta) { if (gameState == GameState.Loading) { return; } if (gameState == GameState.GameActive) { for (GameObject object : gameObjects) { object.update(delta); } } // Сборка монет ArrayList<Coin> coinsToRemove = new ArrayList<>(); for (Coin coin : coins) { if (GeometryUtils.areRectsIntersecting(player.getRect(), coin.getRect())) { coinsToRemove.add(coin); player.increaseScores(1); } } for (Coin coin : coinsToRemove) { coins.remove(coin); gameObjects.remove(coin); } if (player.isOnPlatform()) { for (Spike spike : spikes) { spike.setTriggered(GeometryUtils.distanceBetween(player, spike) < 200.0f); if (GeometryUtils.areRectsIntersecting(player.getRect(), spike.getRect())) { player.setAlive(false); break; } } } if (player.getY() > getHeight()) { player.setAlive(false); } if (player.isAlive()) { if (player.getX() < getWidth() / 4.0f || player.getX() + player.getWidth() >= getWidth() * (3.0f / 4.0f)) { float movement = player.getX() < getWidth() / 4.0f ? getWidth() / 4.0f - player.getX() : (getWidth() * (3.0f / 4.0f) - (player.getX() + player.getWidth())); for (GameObject object : gameObjects) { if (!object.isStatic()) { object.move(movement, 0.0f); } } } } if (!player.isAlive()) { gameState = GameState.GameOver; } else { if (coins.isEmpty()) { gameState = GameState.GameWin; } } } public void paintComponent(Graphics g) { super.paintComponent(g); if (gameState == GameState.Loading) { return; } g.setColor(Color.BLACK); g.fillRect(0, 0, getWidth(), getHeight()); for (GameObject object : gameObjects) { object.render((Graphics2D) g); } // Рисуем GUI if (gameState == GameState.GameOver) { g.setFont(gameOverFont); g.drawString("Game over!", 100, 100); g.setFont(restartFont); g.drawString("Press R to restart", 100, 150); g.drawString("Press ESC to exit", 100, 180); } else if (gameState == GameState.GameWin) { g.setColor(Color.GREEN); g.setFont(gameWinFont); g.drawString("Winning!", 100, 100); g.setColor(Color.BLACK); g.setFont(restartFont); g.drawString("Press R to restart", 100, 150); g.drawString("Press ESC to exit", 100, 180); } else { g.setColor(Color.YELLOW); g.setFont(scoresFont); g.drawString("Scores: " + player.getScores(), 10, 40); } } } class GraphicsWindow extends JFrame { private final Viewport viewport; public GraphicsWindow(String title, int width, int height) throws IOException { super(title); viewport = new Viewport(this); add(viewport); pack(); setSize(width, height); setResizable(false); setFocusable(true); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); viewport.initializeGame(); addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent event) { event.consume(); viewport.handleKeyPress(event); } public void keyReleased(KeyEvent event) { event.consume(); viewport.handleKeyRelease(event); } }); Timer timer = new Timer(33, new ActionListener() { public void actionPerformed(ActionEvent evt) { long time = System.currentTimeMillis(); viewport.updateGame(33.0f / 1000.0f); viewport.repaint(); } }); timer.start(); } public Viewport getViewport() { return viewport; } } public class Main { public static void main(String[] args) throws IOException { new GraphicsWindow("Asteroids game", 640, 480); } }