Skip to content

Commit

Permalink
Fix validations.
Browse files Browse the repository at this point in the history
  • Loading branch information
peterarsentev committed Nov 28, 2024
1 parent 38d2a99 commit 34b03b1
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 87 deletions.
37 changes: 12 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,15 @@
# Games in Java - Object-Oriented Programming with JavaFX

This repository is designed to demonstrate core **Object-Oriented Programming (OOP)** concepts in Java using JavaFX through a series of popular game examples. The goal is to help developers learn and visualize OOP principles in action, from basic class structure to advanced inheritance and encapsulation.

## About This Project

Dive into the code for classic games like **Snake, Chess, Tic-Tac-Toe,** and **Pac-Man** to explore JavaFX's capabilities and understand how OOP principles can structure games effectively. Each game has been carefully crafted to illustrate specific OOP concepts, making it ideal for anyone wanting to learn Java through hands-on projects.

If you have suggestions or encounter issues with this project, please [create a new GitHub issue](https://github.com/peterarsentev/games_oop_javafx/issues).

If you’re looking to deepen your understanding of OOP in Java,
consider joining the course Mastering Object-Oriented Programming in Java.
This comprehensive, 104-lesson course is designed to build both a theoretical foundation
and practical skills essential for applying OOP in real-world scenarios.

## Join for Free! ##

**Contact me on Telegram:** [@parsentev](https://t.me/parsentev)

Let me know if you'd like any further adjustments!

## About the Course: *Mastering Object-Oriented Programming in Java*
Hi, I'm Peter. I created this project
to show my idea about
how to use **Object-Oriented Programming (OOP)** concepts
in Java using JavaFX through a series of popular game examples.

### Course Overview

This course, *Mastering Object-Oriented Programming in Java*, is designed to teach and reinforce the foundational concepts of **OOP in Java**. Through 104 structured lessons, you’ll gain both theoretical and practical skills essential for real-world applications.
This course, *Mastering Object-Oriented Programming in Java*,
is designed to teach and reinforce the foundational concepts of **OOP in Java**.
Through 104 structured lessons, you’ll gain both theoretical and practical skills essential for real-world applications.

### Course Structure

Expand All @@ -36,13 +22,14 @@ Each lesson is organized into three main sections:

Every solution you submit receives detailed, personalized feedback. This focuses on best practices and areas for improvement, ensuring continuous growth and a deep understanding of Java's OOP principles.

### Ideal for
### Join for free

This course is perfect for students and developers looking to build a strong OOP foundation in Java, supported by structured lessons and expert feedback.
In order to promote my course I have decided to start it for free,
so if you want to join my course contact me on email: [email protected]

---
How it will work. I will send you one lesson by email. Each lesson contains: theory, exercises and task.
You have to solve the task and send it back to me so I can check it and give you feedback.

Enhance your understanding of **Java OOP** with these interactive projects, and if you're interested, dive deeper with our course to truly master object-oriented programming.

## Game Examples

Expand Down
39 changes: 22 additions & 17 deletions packman/src/main/java/ru/job4j/packman/Enemies.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,15 @@
public class Enemies {
record Enemy(int x, int y) {
}
public GraphicsContext gc;
private final int width;
private final int height;
private final GraphicsContext gc;
private final int playerSize;
private final int enemySize;
private final int enemySpeed;
private final Set<Enemy> enemies = new HashSet<>();

public Enemies(int width, int height, int playerSize, int enemySize, int enemySpeed) {
this.width = width;
this.height = height;
public Enemies(GraphicsContext gc,
int playerSize, int enemySize, int enemySpeed) {
this.gc = gc;
this.playerSize = playerSize;
this.enemySize = enemySize;
this.enemySpeed = enemySpeed;
Expand All @@ -42,23 +40,23 @@ public void update(Pacman pacman, Walls walls) {
Set<Enemy> updatedEnemies = new HashSet<>();

for (var enemy : enemies) {
double diffX = pacman.playerX - enemy.x();
double diffY = pacman.playerY - enemy.y();
double diffX = pacman.getPlayerX() - enemy.x();
double diffY = pacman.getPlayerY() - enemy.y();

int newX = enemy.x();
int newY = enemy.y();

boolean moved = false;

// Prioritize movement based on same position on one axis
if (enemy.x() == pacman.playerX) {
if (enemy.x() == pacman.getPlayerX()) {
// Same x position, move by y coordinate
double nextY = enemy.y() + Math.signum(diffY) * enemySpeed;
if (!isCollision(enemy.x(), nextY, walls) && !isEnemyCollision(newX, (int) nextY)) {
newY = (int) nextY;
moved = true;
}
} else if (enemy.y() == pacman.playerY) {
} else if (enemy.y() == pacman.getPlayerY()) {
// Same y position, move by x coordinate
double nextX = enemy.x() + Math.signum(diffX) * enemySpeed;
if (!isCollision(nextX, enemy.y(), walls) && !isEnemyCollision((int) nextX, newY)) {
Expand All @@ -70,14 +68,16 @@ public void update(Pacman pacman, Walls walls) {
if (Math.abs(diffX) <= Math.abs(diffY)) {
// Move by x coordinate
double nextX = enemy.x() + Math.signum(diffX) * enemySpeed;
if (!isCollision(nextX, enemy.y(), walls) && !isEnemyCollision((int) nextX, newY)) {
if (!isCollision(nextX, enemy.y(), walls)
&& !isEnemyCollision((int) nextX, newY)) {
newX = (int) nextX;
moved = true;
}
} else {
// Move by y coordinate
double nextY = enemy.y() + Math.signum(diffY) * enemySpeed;
if (!isCollision(enemy.x(), nextY, walls) && !isEnemyCollision(newX, (int) nextY)) {
if (!isCollision(enemy.x(), nextY, walls)
&& !isEnemyCollision(newX, (int) nextY)) {
newY = (int) nextY;
moved = true;
}
Expand Down Expand Up @@ -117,11 +117,14 @@ private boolean isCollision(double x, double y, Walls walls) {
int gridYStart = (int) (y / playerSize);
int gridXEnd = (int) ((x + enemySize - 1) / playerSize);
int gridYEnd = (int) ((y + enemySize - 1) / playerSize);

if (gridXStart < 0 || gridXEnd >= maze.length || gridYStart < 0 || gridYEnd >= maze[0].length) {
if (gridXStart < 0 || gridXEnd >= maze.length
|| gridYStart < 0 || gridYEnd >= maze[0].length) {
return true;
}
return maze[gridXStart][gridYStart] || maze[gridXEnd][gridYStart] || maze[gridXStart][gridYEnd] || maze[gridXEnd][gridYEnd];
return maze[gridXStart][gridYStart]
|| maze[gridXEnd][gridYStart]
|| maze[gridXStart][gridYEnd]
|| maze[gridXEnd][gridYEnd];
}

public void draw() {
Expand All @@ -130,8 +133,10 @@ public void draw() {
gc.fillArc(enemy.x(), enemy.y(), enemySize, enemySize, 0, 180, ArcType.ROUND);
gc.fillRect(enemy.x(), enemy.y() + enemySize / 2, enemySize, enemySize / 2);
gc.setFill(Color.WHITE);
gc.fillOval(enemy.x() + enemySize * 0.2, enemy.y() + enemySize * 0.2, enemySize * 0.2, enemySize * 0.2);
gc.fillOval(enemy.x() + enemySize * 0.6, enemy.y() + enemySize * 0.2, enemySize * 0.2, enemySize * 0.2);
gc.fillOval(enemy.x() + enemySize * 0.2,
enemy.y() + enemySize * 0.2, enemySize * 0.2, enemySize * 0.2);
gc.fillOval(enemy.x() + enemySize * 0.6,
enemy.y() + enemySize * 0.2, enemySize * 0.2, enemySize * 0.2);
gc.setFill(Color.RED);
}
}
Expand Down
34 changes: 25 additions & 9 deletions packman/src/main/java/ru/job4j/packman/Pacman.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@

public class Pacman {
private static final int PLAYER_SIZE = 40;
public GraphicsContext gc;
public double playerX;
public double playerY;
public double playerSpeed = 5;
public double mouthAngle = 45;
public boolean mouthOpening = true;
public double mouthDirection = 90;
private final GraphicsContext gc;
private double playerX;
private double playerY;
private final double playerSpeed = 5;
private double mouthAngle = 45;
private boolean mouthOpening = true;
private double mouthDirection = 90;

public Pacman(GraphicsContext gc, double playerX, double playerY) {
this.playerX = playerX;
this.playerY = playerY;
this.gc = gc;
}

public void draw() {
gc.setFill(Color.YELLOW);
Expand Down Expand Up @@ -71,9 +77,19 @@ private boolean isCollision(double x, double y, Walls walls) {
int gridXEnd = (int) ((x + PLAYER_SIZE - 1) / PLAYER_SIZE);
int gridYEnd = (int) ((y + PLAYER_SIZE - 1) / PLAYER_SIZE);

if (gridXStart < 0 || gridXEnd >= maze.length || gridYStart < 0 || gridYEnd >= maze[0].length) {
if (gridXStart < 0 || gridXEnd >= maze.length
|| gridYStart < 0 || gridYEnd >= maze[0].length) {
return true;
}
return maze[gridXStart][gridYStart] || maze[gridXEnd][gridYStart] || maze[gridXStart][gridYEnd] || maze[gridXEnd][gridYEnd];
return maze[gridXStart][gridYStart] || maze[gridXEnd][gridYStart]
|| maze[gridXStart][gridYEnd] || maze[gridXEnd][gridYEnd];
}

public double getPlayerX() {
return playerX;
}

public double getPlayerY() {
return playerY;
}
}
22 changes: 9 additions & 13 deletions packman/src/main/java/ru/job4j/packman/PacmanGame.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,16 @@ public void start(Stage primaryStage) {
primaryStage.setScene(scene);
primaryStage.show();

walls = new Walls(WIDTH, HEIGHT, PLAYER_SIZE);
walls = new Walls(gc, WIDTH, HEIGHT, PLAYER_SIZE);
walls.initializeMaze();
walls.gc = gc;

pellets = new Pellets(WIDTH, HEIGHT, PLAYER_SIZE, PELLET_SIZE);
pellets = new Pellets(gc, WIDTH, HEIGHT, PLAYER_SIZE, PELLET_SIZE);
pellets.initializePellets(walls);
pellets.gc = gc;

enemies = new Enemies(WIDTH, HEIGHT, PLAYER_SIZE, ENEMY_SIZE, ENEMY_SPEED);
enemies = new Enemies(gc, PLAYER_SIZE, ENEMY_SIZE, ENEMY_SPEED);
enemies.initializeEnemies(walls);
enemies.gc = gc;

pacman = initializePlayerPosition();
pacman.gc = gc;
pacman = initializePlayerPosition(gc);

scene.setOnKeyPressed(event -> pressedKeys.add(event.getCode()));
scene.setOnKeyReleased(event -> pressedKeys.remove(event.getCode()));
Expand All @@ -69,14 +65,14 @@ public void handle(long now) {
timer.start();
}

private Pacman initializePlayerPosition() {
private Pacman initializePlayerPosition(GraphicsContext gc) {
for (int i = 0; i < walls.getMaze().length; i++) {
for (int j = 0; j < walls.getMaze()[i].length; j++) {
if (!walls.getMaze()[i][j]) {
var pacman = new Pacman();
pacman.playerX = i * PLAYER_SIZE;
pacman.playerY = j * PLAYER_SIZE;
return pacman;
return new Pacman(gc,
i * PLAYER_SIZE,
j * PLAYER_SIZE
);
}
}
}
Expand Down
17 changes: 12 additions & 5 deletions packman/src/main/java/ru/job4j/packman/Pellets.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,40 @@
import java.util.Set;

public class Pellets {
private final GraphicsContext gc;
private final int width;
private final int height;
private final int playerSize;
private final int pelletSize;
private final Set<double[]> pellets = new HashSet<>();
public GraphicsContext gc;

public Pellets(int width, int height, int playerSize, int pelletSize) {
public Pellets(GraphicsContext gc, int width, int height, int playerSize, int pelletSize) {
this.width = width;
this.height = height;
this.playerSize = playerSize;
this.pelletSize = pelletSize;
this.gc = gc;
}

public void initializePellets(Walls walls) {
for (int i = 0; i < width; i += playerSize) {
for (int j = 0; j < height; j += playerSize) {
if (!walls.getMaze()[i / playerSize][j / playerSize]) {
pellets.add(new double[]{i + playerSize / 2.0 - pelletSize / 2.0, j + playerSize / 2.0 - pelletSize / 2.0});
pellets.add(new double[] {
i + playerSize / 2.0 - pelletSize / 2.0,
j + playerSize / 2.0 - pelletSize / 2.0
});
}
}
}
}

public void checkCollision(Pacman pacman) {
pellets.removeIf(pellet -> pacman.playerX < pellet[0] + pelletSize && pacman.playerX + playerSize > pellet[0] &&
pacman.playerY < pellet[1] + pelletSize && pacman.playerY + playerSize > pellet[1]);
pellets.removeIf(
pellet -> pacman.getPlayerX() < pellet[0] + pelletSize
&& pacman.getPlayerX() + playerSize > pellet[0]
&& pacman.getPlayerY() < pellet[1] + pelletSize
&& pacman.getPlayerY() + playerSize > pellet[1]);
}

public void draw() {
Expand Down
17 changes: 6 additions & 11 deletions packman/src/main/java/ru/job4j/packman/Walls.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@

public class Walls {
private static final int PLAYER_SIZE = 40;
public GraphicsContext gc;
private final GraphicsContext gc;
private final boolean[][] maze;
private final int width;
private final int height;
private final int playerSize;

public Walls(int width, int height, int playerSize) {
this.width = width;
this.height = height;
this.playerSize = playerSize;
public Walls(GraphicsContext gc, int width, int height, int playerSize) {
this.gc = gc;
this.maze = new boolean[width / playerSize][height / playerSize];
}

Expand All @@ -23,10 +18,10 @@ public void initializeMaze() {
for (int j = 0; j < maze[i].length; j++) {
if (i == 0 || i == maze.length - 1 || j == 0 || j == maze[i].length - 1) {
maze[i][j] = true;
} else if (i % 2 == 0 && j % 2 == 0 && i != maze.length - 2 && j != maze[i].length - 2) {
maze[i][j] = true;
} else {
maze[i][j] = false;
maze[i][j] = i % 2 == 0 && j % 2 == 0
&& i != maze.length - 2
&& j != maze[i].length - 2;
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions snake/src/main/java/ru/job4j/tetris/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

public class Main extends Application {
private static final String JOB4J = "Snake";
private final int size = 10;
private static final int SIZE = 10;
private final Snake snake = new Snake(List.of(
new Cell(0, 0), new Cell(1, 0), new Cell(2, 0))
);
Expand Down Expand Up @@ -46,8 +46,8 @@ private Rectangle block(Cell cell, Color color) {

private Group buildGrid() {
Group panel = new Group();
for (int y = 0; y != this.size; y++) {
for (int x = 0; x != this.size; x++) {
for (int y = 0; y != this.SIZE; y++) {
for (int x = 0; x != this.SIZE; x++) {
panel.getChildren().add(
this.buildRectangle(x, y, 40)
);
Expand Down Expand Up @@ -127,7 +127,6 @@ private void redrawSnake(Group group) {
drawSnake(group);
}


public static void main(String[] args) {
Main.launch(args);
}
Expand Down
3 changes: 0 additions & 3 deletions tetris/src/main/java/ru/job4j/tetris/Figure.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package ru.job4j.tetris;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class Figure {
private List<Cell> body;
Expand All @@ -24,7 +22,6 @@ public void move() {
body = newBody;
}


List<Cell> asCells() {
return body;
}
Expand Down

0 comments on commit 34b03b1

Please sign in to comment.