package com.company;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
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 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;
GameObject() {
}
public void setPosition(float x, float y) {
setX(x);
setY(y);
}
public void move(float x, float y) {
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;
}
}
class Player extends TexturedBlock {
private float direction = 0.0f;
private float acceleration = 9.8f;
private float velocity = 0.0f;
private boolean isOnPlatform = false;
private boolean isGameOver = false;
private Font gameOverFont = new Font("TimesRoman", Font.PLAIN, 82);
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 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());
}
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);
}
@Override
public void render(Graphics2D g) {
super.render(g);
if (isGameOver) {
g.setFont(gameOverFont);
g.drawString("Game over!", 100, 100);
}
}
@Override
public void update(float delta) {
float speed = 300.0f;
move(delta * speed * direction, 0);
if (!isOnPlatform) {
velocity += acceleration * delta;
move(0, velocity);
}
isOnPlatform = false;
velocity = acceleration * 1.5f;
for (Platform platform : platforms) {
if (areRectsIntersecting(getRect(), platform.getRect())) {
Rectangle2D intersection = getRectsIntersection(getRect(), platform.getRect());
if (intersection.getWidth() < intersection.getHeight())
{
move(-direction * (float) intersection.getWidth(), 0);
}
else {
move(0, -(float) intersection.getHeight());
}
isOnPlatform = true;
velocity = 0;
}
}
if (getY() > 480) {
isGameOver = true;
}
}
@Override
public void handleKeyPress(char keyChar) {
// w a s d
if (keyChar == 'd') {
direction = 1.0f;
} else if (keyChar == 'a') {
direction = -1.0f;
}
}
@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 Viewport extends JPanel {
private Random random = new Random();
private final ArrayList<GameObject> gameObjects = new ArrayList<>();
private final ArrayList<Platform> platforms = new ArrayList<>();
public Viewport() {
}
public void initializeGame() throws IOException {
TexturedBlock background = new TexturedBlock(ResourcesManager.getInstance().loadImage("C:\\Users\\nikolai\\IdeaProjects\\untitled\\assets\\cloudy2.jpg"));
background.setPosition(0, 0);
background.setSize(getWidth(), getHeight());
gameObjects.add(background);
Player player = new Player(platforms);
player.setPosition(0.0f, 0.0f);
player.setSize(75.0f, 75.0f);
gameObjects.add(player);
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, 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);
}
private void addPlatform(PlatformType platformType, float x, float y, float width, float height) throws IOException {
Platform platform = new Platform(platformType);
platform.setPosition(x, y);
platform.setSize(width, height);
gameObjects.add(platform);
platforms.add(platform);
}
public void handleKeyPress(char keyChar) {
for (GameObject object : gameObjects) {
object.handleKeyPress(keyChar);
}
repaint();
}
public void handleKeyRelease(char keyChar) {
for (GameObject object : gameObjects) {
object.handleKeyRelease(keyChar);
}
repaint();
}
public void updateGame(float delta) {
for (GameObject object : gameObjects) {
object.update(delta);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
for (GameObject object : gameObjects) {
object.render((Graphics2D) g);
}
}
}
class GraphicsWindow extends JFrame {
private final Viewport viewport = new Viewport();
public GraphicsWindow(String title, int width, int height) throws IOException {
super(title);
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.getKeyChar());
}
public void keyReleased(KeyEvent event) {
event.consume();
viewport.handleKeyRelease(event.getKeyChar());
}
});
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);
}
}