Skip to content

Commit

Permalink
Merge pull request #4 from ololx/develop
Browse files Browse the repository at this point in the history
Add split server into internal and dedicated services for running the game multiplayer
  • Loading branch information
ololx authored Aug 26, 2020
2 parents 8e22bce + c01c22d commit 63e2cca
Show file tree
Hide file tree
Showing 28 changed files with 467 additions and 246 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p

- Refactor old project classes via game dev patterns implemetation.

## [0.2.2-alpha.2] - 2020-08-26

### Changed

- Add split server into internal and dedicated services for running the game multiplayer:
- server and clients separately;
- main client (with server) and clients.

### Fixed

- The concurrent units access.

## [0.1.1-alpha.2] - 2020-08-23

### Fixed
Expand Down
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

The Plain Old Retro Shooter is a 2.5D FPS game engine based on the raycasting technology.

[![status](https://img.shields.io/badge/status-active-active?style=flat-square)](BADGES_GUIDE.md#status) [![version](https://img.shields.io/badge/version-0.1.1--alpha.2-informational?style=flat-square)](BADGES_GUIDE.md#version) [![stable](https://img.shields.io/badge/stable-no-important?style=flat-square)](BADGES_GUIDE.md#stable) [![build](https://img.shields.io/badge/build-passing-success?style=flat-square)](BADGES_GUIDE.md#build) [![oss lifecycle](https://img.shields.io/badge/oss_lifecycle-active-important?style=flat-square)](BADGES_GUIDE.md#oss-lifecycle) [![maintenance](https://img.shields.io/badge/maintenance-yes-informational?style=flat-square)](BADGES_GUIDE.md#maintenance) [![latest release date](https://img.shields.io/badge/latest_release_date-August_23,_2020-informational?style=flat-square)](BADGES_GUIDE.md#release-date) [![last commit](https://img.shields.io/badge/last_commit-August_23,_2020-informational?style=flat-square)](BADGES_GUIDE.md#commit-date)
[![status](https://img.shields.io/badge/status-active-active?style=flat-square)](BADGES_GUIDE.md#status) [![version](https://img.shields.io/badge/version-0.2.2--alpha.2-informational?style=flat-square)](BADGES_GUIDE.md#version) [![stable](https://img.shields.io/badge/stable-no-important?style=flat-square)](BADGES_GUIDE.md#stable) [![build](https://img.shields.io/badge/build-passing-success?style=flat-square)](BADGES_GUIDE.md#build) [![oss lifecycle](https://img.shields.io/badge/oss_lifecycle-active-important?style=flat-square)](BADGES_GUIDE.md#oss-lifecycle) [![maintenance](https://img.shields.io/badge/maintenance-yes-informational?style=flat-square)](BADGES_GUIDE.md#maintenance) [![latest release date](https://img.shields.io/badge/latest_release_date-August_26,_2020-informational?style=flat-square)](BADGES_GUIDE.md#release-date) [![last commit](https://img.shields.io/badge/last_commit-August_26,_2020-informational?style=flat-square)](BADGES_GUIDE.md#commit-date)

[![license](https://img.shields.io/badge/license-MIT-informational?style=flat-square)](LICENSE) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)

Expand Down Expand Up @@ -37,6 +37,8 @@ The demonstration shows the one small scene with enemies, shooting and player mo

The demonstration shows the multiplayer scene with 2 players.

<img src="https://github.com/ololx/plain-old-retro-shooter/blob/assets/plain-old-retro-shooter-demo-3.gif?raw=true" width="640"/>

<img src="https://github.com/ololx/plain-old-retro-shooter/blob/assets/plain-old-retro-shooter-demo-2.gif?raw=true" width="640"/>

## 🎚 Features
Expand Down Expand Up @@ -82,8 +84,22 @@ https://github.com/ololx/plain-old-retro-shooter.git
### Using

To use it is necessary to:
1 - Build the project.
2 - Launch the instance .jar.
1. Build the project.

2. Launch the instance .jar without args (for single mode) or with the follows args:

For the service instance running

```bash
"ip address" port
```
​ For the client instance running

```bash
port
```



## 🛠 Built With

Expand All @@ -109,3 +125,7 @@ For the versioning is used [Semantic Versioning](http://semver.org/). For the ve
## 🔏 Licensing

This project is licensed under the MIT license - see the [lisence](LICENSE) document for details.

```
```
21 changes: 21 additions & 0 deletions src/org/plain/old/retro/shooter/DedicatedServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.plain.old.retro.shooter;

import org.plain.old.retro.shooter.multi.Server;

/**
* @project plain-old-retro-shooter
* @created 14.08.2020 14:28
* <p>
* @author Alexander A. Kropotin
*/
public class DedicatedServer {

public static void main(String args[]) {

if (args.length > 0) {
Server server = new Server(Integer.valueOf(args[0]));
server.start();
}
}
}

26 changes: 21 additions & 5 deletions src/org/plain/old/retro/shooter/DemoScene.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.plain.old.retro.shooter;

import org.plain.old.retro.shooter.engine.Scene;
import org.plain.old.retro.shooter.multi.DedicatedClient;
import org.plain.old.retro.shooter.multi.Client;
import org.plain.old.retro.shooter.multi.Server;

import java.io.IOException;

Expand All @@ -10,16 +10,32 @@
*/
public class DemoScene {

public static final String DEFAULT_ADDRESS = "127.0.0.1";

public static final int DEFAULT_PORT = 6666;

/**
* The entry point of application.
*
* @param args the input arguments
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
DedicatedClient client = null;
Server server = null;
Client client = null;

if (args.length == 2) {
client = new DedicatedClient(args[0], Integer.valueOf(args[1]));
switch (args.length) {
case 1:
server = new Server(Integer.valueOf(args[0]));
server.start();
client = new Client(DEFAULT_ADDRESS, Integer.valueOf(args[0]));
break;
case 2:
client = new Client(args[0], Integer.valueOf(args[1]));
break;
default:
server = new Server(DEFAULT_PORT);
server.start();
client = new Client(DEFAULT_ADDRESS, DEFAULT_PORT);
}

Scene game = new Scene(client);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.plain.old.retro.shooter.engine;
package org.plain.old.retro.shooter;

import org.plain.old.retro.shooter.engine.Space2d;
import org.plain.old.retro.shooter.engine.clock.Clock;
import org.plain.old.retro.shooter.engine.clock.LowIntensiveClock;
import org.plain.old.retro.shooter.engine.graphics.Camera;
Expand All @@ -8,30 +9,31 @@
import org.plain.old.retro.shooter.engine.listener.KeyboardController;
import org.plain.old.retro.shooter.engine.physics.BulletHitScanner;
import org.plain.old.retro.shooter.engine.unit.Enemy;
import org.plain.old.retro.shooter.engine.unit.Player;
import org.plain.old.retro.shooter.engine.unit.RegisterEntity;
import org.plain.old.retro.shooter.engine.unit.Unit;
import org.plain.old.retro.shooter.engine.unit.equipment.bullet.Bullet;
import org.plain.old.retro.shooter.engine.unit.equipment.weapon.BoomStick;
import org.plain.old.retro.shooter.multi.DedicatedClient;
import org.plain.old.retro.shooter.multi.Client;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet;

/**
* The type Game.
* <p>
* This is a main scene class, which is runnable and
* will manage all scene logics (such as fps, screen update && e.t.c.)
*
* <p>
* @author Alexander A. Kropotin
* @project plain -old-retro-shooter
* @created 19.06.2020 08:58 <p>
* @created 19.06.2020 08:58
*/
public class Scene extends JFrame {

Expand All @@ -43,30 +45,34 @@ public class Scene extends JFrame {

private Clock renderTemp;

private Clock serverTemp;
private Clock clientTemp;

private Camera mainPlayer;

private BufferedImage image;

public int[] pixels;

public Screen screen;

private BoomStick stick;

private Vector<Enemy> enemies;
private ConcurrentSkipListSet<Enemy> enemies;

private Vector<Bullet> bullets = new Vector<>();
private ConcurrentSkipListSet<Bullet> tempBullets = new ConcurrentSkipListSet<>();

private Vector<Player> players = new Vector<>();
private ConcurrentSkipListSet<Bullet> bullets = new ConcurrentSkipListSet<>();

DedicatedClient client;
private ConcurrentSkipListMap<UUID, Unit> otherUnits = new ConcurrentSkipListMap<>();

private Client client;

//TODO: Refactor It when main entities will be completed - it's just for tests
/**
* Instantiates a new Game.
* @param client
*/
public Scene(DedicatedClient client) {
public Scene(Client client) {
this.client = client;
Space2d map = new Space2d(
new int[][]{
Expand Down Expand Up @@ -114,7 +120,7 @@ public Scene(DedicatedClient client) {
put(KeyEvent.VK_SPACE, "SHOT");
put(KeyEvent.VK_R, "RELOAD");
}});
this.enemies = new Vector<>(){{
this.enemies = new ConcurrentSkipListSet<>(){{
add(new Enemy(7.5, 7.5, new Sprite("src/resources/enemy-1.png")));
add(new Enemy(25.5, 3.5, new Sprite("src/resources/enemy-1.png")));
add(new Enemy(21.5, 7.5, new Sprite("src/resources/enemy-1.png")));
Expand All @@ -125,9 +131,6 @@ public Scene(DedicatedClient client) {
add(new Enemy(14.5, 19.5, new Sprite("src/resources/enemy-3.png")));
add(new Enemy(12.5, 10.5, new Sprite("src/resources/enemy-3.png")));
}};
this.players = new Vector<>(){{
add(new Player(1, 1, new Sprite("src/resources/player.png")));
}};
mainPlayer = new Camera(1, 2, 1, 0, SCENE_WIDTH, SCENE_HEIGHT, 1.20);
image = new BufferedImage(SCENE_WIDTH, SCENE_HEIGHT, BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
Expand Down Expand Up @@ -185,7 +188,9 @@ public Scene(DedicatedClient client) {
}

if (state.getKey().equals("SHOT")) {
this.bullets.addAll(stick.shoot(mainPlayer.getPosition(), mainPlayer.getDirection()));
Vector<Bullet> bullets = stick.shoot(mainPlayer.getPosition(), mainPlayer.getDirection());
this.bullets.addAll(bullets);
this.tempBullets.addAll(bullets);
}

if (state.getKey().equals("RELOAD")) {
Expand All @@ -197,14 +202,16 @@ public Scene(DedicatedClient client) {
() -> {
this.stick.update();

for (int i = 0; i < this.bullets.size(); i++) {
Bullet bullet = this.bullets.get(i);
if (!bullet.isExist()) this.bullets.remove(i);
synchronized (bullets) {
for (Bullet bullet : bullets) {
if (!bullet.isExist()) this.bullets.remove(bullet);
}
}

for (int j = 0; j < this.enemies.size(); j++) {
Enemy enemy = this.enemies.get(j);
if (!enemy.isExist()) this.enemies.remove(j);
synchronized (bullets) {
for (Enemy enemy : enemies) {
if (!enemy.isExist()) this.enemies.remove(enemy);
}
}

BulletHitScanner.scan(this.bullets, this.enemies, sceneTemp.getFrequency(), map);
Expand All @@ -218,32 +225,45 @@ public Scene(DedicatedClient client) {
this.stick,
this.enemies,
this.bullets,
this.players
this.otherUnits.values()
),
() -> this.render(
map, String.format(
"UPS: %s \n FPS: %s \n NETPS: %s",
sceneTemp.getFrequency(),
renderTemp.getFrequency(),
serverTemp.getFrequency()
clientTemp.getFrequency()
)
)
);

serverTemp = new LowIntensiveClock(
renderTemp.getFrequency() << 1,
clientTemp = new LowIntensiveClock(
sceneTemp.getFrequency(),
() -> {

Set<Object> responseMessages = new HashSet<>();
this.client.connect();
String requestMessage = mainPlayer.getMessage();
String responseMessage = this.client.sendMessage(requestMessage);
String[] coords = null;
if (responseMessage != null && (coords = responseMessage.split("&")).length > 1) {
this.players.get(0).setPosition(
Double.valueOf(coords[0]),
Double.valueOf(coords[1])
);
}
Object requestMessage = mainPlayer;
Object responseMessage = this.client.sendMessage(requestMessage);
this.client.disconnect();
if (responseMessage != null) responseMessages.add(responseMessage);

for (Bullet bullet : tempBullets) {
this.client.connect();
responseMessage = this.client.sendMessage(bullet);
if (responseMessage != null) responseMessages.add(responseMessage);
this.client.disconnect();
}
tempBullets.clear();

for (Object unit : responseMessages) {
if (unit instanceof Bullet && !this.bullets.contains((unit))) {
this.bullets.add((Bullet) unit);
} else {
this.otherUnits.put(((RegisterEntity) unit).getUid(), (Unit) unit);
}
}

}
);
}
Expand Down Expand Up @@ -275,7 +295,7 @@ public void init() {
);
this.renderTemp.start();
this.sceneTemp.start();
this.serverTemp.start();
this.clientTemp.start();
}

public void render(Space2d map, String rateInfo) {
Expand Down
10 changes: 0 additions & 10 deletions src/org/plain/old/retro/shooter/calculus/linear/Matrix.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.plain.old.retro.shooter.calculus;
package org.plain.old.retro.shooter.engine.calculus;

/**
* @project plain-old-retro-shooter
Expand Down
12 changes: 12 additions & 0 deletions src/org/plain/old/retro/shooter/engine/calculus/linear/Matrix.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.plain.old.retro.shooter.engine.calculus.linear;

import java.io.Serializable;

/**
* @project plain-old-retro-shooter
* @created 23.07.2020 09:51
* <p>
* @author Alexander A. Kropotin
*/
public interface Matrix extends Serializable {
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.plain.old.retro.shooter.calculus.linear;
package org.plain.old.retro.shooter.engine.calculus.linear;

/**
* @project plain-old-retro-shooter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.plain.old.retro.shooter.calculus.linear;
package org.plain.old.retro.shooter.engine.calculus.linear;

/**
* @project plain-old-retro-shooter
Expand Down
Loading

0 comments on commit 63e2cca

Please sign in to comment.