Compare commits

...

10 Commits

16 changed files with 841 additions and 0 deletions

39
.gitignore vendored
View File

@ -100,6 +100,45 @@ fabric.properties
# Editor-based Rest Client # Editor-based Rest Client
.idea/httpRequests .idea/httpRequests
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
client/.idea/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
# Android studio 3.1+ serialized cache file # Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser .idea/caches/build_file_checksums.ser

149
client/pom.xml Normal file
View File

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>client</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lwjgl.version>3.3.2</lwjgl.version>
</properties>
<profiles>
<profile>
<id>lwjgl-natives-linux-amd64</id>
<activation>
<os>
<family>unix</family>
<arch>amd64</arch>
</os>
</activation>
<properties>
<lwjgl.natives>natives-linux</lwjgl.natives>
</properties>
</profile>
<profile>
<id>lwjgl-natives-windows-amd64</id>
<activation>
<os>
<family>windows</family>
<arch>amd64</arch>
</os>
</activation>
<properties>
<lwjgl.natives>natives-windows</lwjgl.natives>
</properties>
</profile>
</profiles>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bom</artifactId>
<version>${lwjgl.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-assimp</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bgfx</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-glfw</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nanovg</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nuklear</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openal</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-par</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-stb</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-assimp</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bgfx</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-glfw</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nanovg</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nuklear</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openal</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengl</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-par</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-stb</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,15 @@
package core;
import core.engine.Engine;
public class Main {
private static final Engine gameEngine = new Engine();
public static void main(String[] args) {
}
}

View File

@ -0,0 +1,135 @@
package core.engine;
import core.engine.model.RawModel;
import core.engine.shader.StaticShader;
import org.lwjgl.Version;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryStack;
import java.nio.IntBuffer;
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11C.*;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.NULL;
public class Engine {
private long window;
private final Loader loader = new Loader();
private final Renderer renderer = new Renderer();
public Engine() {
System.out.println("Hello LWJGL " + Version.getVersion() + "!");
init();
loop();
// Free the window callbacks and destroy the window
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
// Terminate GLFW and free the error callback
glfwTerminate();
glfwSetErrorCallback(null).free();
}
private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFWErrorCallback.createPrint(System.err).set();
// Initialize GLFW. Most GLFW functions will not work before doing this.
if ( !glfwInit() )
throw new IllegalStateException("Unable to initialize GLFW");
// Configure GLFW
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
// Create the window
window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL);
if ( window == NULL )
throw new RuntimeException("Failed to create the GLFW window");
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
});
// Get the thread stack and push a new frame
try ( MemoryStack stack = stackPush() ) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
// Get the window size passed to glfwCreateWindow
glfwGetWindowSize(window, pWidth, pHeight);
// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center the window
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
} // the stack frame is popped automatically
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
// Make the window visible
glfwShowWindow(window);
}
private void loop() {
// This line is critical for LWJGL's interoperation with GLFW's
// OpenGL context, or any context that is managed externally.
// LWJGL detects the context that is current in the current thread,
// creates the GLCapabilities instance and makes the OpenGL
// bindings available for use.
GL.createCapabilities();
// Set the clear color
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
StaticShader shader = new StaticShader();
float[] vertices = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
};
int[] indices = {
0,1,3,
3,1,2
};
RawModel model = loader.loadToVAO(vertices, indices);
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
while ( !glfwWindowShouldClose(window) ) {
renderer.prepare();
shader.start();
renderer.render(model);
shader.stop();
glfwSwapBuffers(window); // swap the color buffers
// Poll for window events. The key callback above will only be
// invoked during this call.
glfwPollEvents();
}
shader.cleanUp();
loader.cleanUp();
}
}

View File

@ -0,0 +1,84 @@
package core.engine;
import core.engine.model.RawModel;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
public class Loader {
private List<Integer> vaos = new ArrayList<>();
private List<Integer> vbos = new ArrayList<>();
public RawModel loadToVAO(float[] positions, int[] indices) {
int vaoID = createVAO();
bindIndicesBuffer(indices);
storeDataInAttributeList(0, positions);
unbindVAO();
return new RawModel(vaoID, indices.length);
}
private int createVAO() {
int vao = GL30.glGenVertexArrays();
vaos.add(vao);
GL30.glBindVertexArray(vao);
return vao;
}
private void storeDataInAttributeList(int attributeNumber, float[] data) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
FloatBuffer floatBuffer = storeInFloatBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, floatBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
private void unbindVAO() {
GL30.glBindVertexArray(0);
}
private void bindIndicesBuffer(int[] indices) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
IntBuffer buffer = storeInIntBuffer(indices);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
}
private IntBuffer storeInIntBuffer(int[] data) {
IntBuffer intBuffer = BufferUtils.createIntBuffer(data.length);
intBuffer.put(data);
//Buffer is until know expected to be written to. Flip it, so it can be read
intBuffer.flip();
return intBuffer;
}
private FloatBuffer storeInFloatBuffer(float[] data) {
FloatBuffer floatBuffer = BufferUtils.createFloatBuffer(data.length);
floatBuffer.put(data);
//Buffer is until know expected to be written to. Flip it, so it can be read
floatBuffer.flip();
return floatBuffer;
}
public void cleanUp() {
for(int vao: vaos) {
GL30.glDeleteVertexArrays(vao);
}
for(int vbo: vbos) {
GL15.glDeleteBuffers(vbo);
}
}
}

View File

@ -0,0 +1,24 @@
package core.engine;
import core.engine.model.RawModel;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import static org.lwjgl.opengl.GL11C.*;
public class Renderer {
public void prepare() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
GL11.glClearColor(1,0,0,1);
}
public void render(RawModel rawModel) {
GL30.glBindVertexArray(rawModel.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL11.glDrawElements(GL11.GL_TRIANGLES, rawModel.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}

View File

@ -0,0 +1,20 @@
package core.engine.model;
public class RawModel {
private final int vaoID;
private final int vertexCount;
public RawModel(int vaoID, int vertexCount) {
this.vaoID = vaoID;
this.vertexCount = vertexCount;
}
public int getVaoID() {
return vaoID;
}
public int getVertexCount() {
return vertexCount;
}
}

View File

@ -0,0 +1,77 @@
package core.engine.shader;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public abstract class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
public ShaderProgram(String vertexFile, String fragmentFile) {
vertexShaderID = loadShader(vertexFile, GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentFile, GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
GL20.glAttachShader(programID, vertexShaderID);
GL20.glAttachShader(programID, fragmentShaderID);
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
bindAttributes();
}
public void start() {
GL20.glUseProgram(programID);
}
public void stop() {
GL20.glUseProgram(0);
}
public void cleanUp() {
stop();
GL20.glDetachShader(programID, vertexShaderID);
GL20.glDetachShader(programID, fragmentShaderID);
GL20.glDeleteShader(vertexShaderID);
GL20.glDeleteShader(fragmentShaderID);
GL20.glDeleteProgram(programID);
}
protected abstract void bindAttributes();
protected void bindAttribute(int attribute, String variableName) {
GL20.glBindAttribLocation(programID, attribute, variableName);
}
private static int loadShader(String file, int type) {
StringBuilder shadersource = new StringBuilder();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line;
while((line = bufferedReader.readLine()) != null) {
shadersource.append(line).append(System.lineSeparator());
}
bufferedReader.close();
} catch (IOException e) {
System.err.println("Could not read file!");
e.printStackTrace();
System.exit(-1);
}
int shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID, shadersource);
GL20.glCompileShader(shaderID);
if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.out.println(GL20.glGetShaderInfoLog(shaderID));
System.err.println("Could not compile Shader");
System.exit(-1);
}
return shaderID;
}
}

View File

@ -0,0 +1,15 @@
package core.engine.shader;
public class StaticShader extends ShaderProgram{
private static final String VERTEX_FILE = "src/main/java/core/engine/shader/vertexShader.glsl";
private static final String FRAGMENT_FILE = "src/main/java/core/engine/shader/fragmentShader.glsl";
public StaticShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
@Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
}
}

View File

@ -0,0 +1,9 @@
#version 400 core
in vec3 color;
out vec4 out_Color;
void main(void) {
out_Color = vec4(color, 1.0);
}

View File

@ -0,0 +1,11 @@
#version 400 core
in vec3 position;
out vec3 color;
void main(void) {
gl_Position = vec4(position, 1.0);
color = vec3(position.x+0.5, 1.0, position.y+0.5);
}

View File

@ -0,0 +1,37 @@
package manager.attackinformations;
/**
* AttackInformations is just for the Informations of which field threw which
* Number with the current Dice, if the Attack was succesfull or not and
* if the Attack was allowed.
* **/
public class AttackInformations{
private int attack_field_dice;
private int defense_field_dice;
private boolean attack_success;
private boolean attack_allowed;
public AttackInformations(int input_att_field, int input_def_field,boolean input_attack_allowed){
attack_field_dice = input_att_field;
defense_field_dice = input_def_field;
attack_success = (input_att_field >= input_def_field);
attack_allowed = input_attack_allowed;
}
public int get_attack_field_dice(){
return attack_field_dice;
}
public int get_defense_field_dice(){
return defense_field_dice;
}
public boolean get_attack_success(){
return attack_success;
}
public boolean get_attack_allowed(){
return attack_allowed;
}
}

View File

@ -0,0 +1,46 @@
package manager.field;
import java.util.ArrayList;
/**
* Each Field has a number of dices on it, neighbours which they can attack
* and a owner who can be changed while the Game.
* The Neighbours can be set at the beginning of the game, so the class field
* must have an option to add a neighbour as a field.
* **/
public class Field {
private int dice_number;
private ArrayList<Field> neighbours;
private Player owner;
public Field(int input_dice_number, Player input_owner){
neighbours = new ArrayList<Field>();
dice_number = input_dice_number;
owner = input_owner;
}
public ArrayList<Field> get_neighbours(){
return neighbours;
}
public void add_neighbour(Field input){
neighbours.add(input);
}
public int get_dice_number(){
return dice_number;
}
public void set_dice_number(int number){
dice_number = number;
}
public Player get_owner(){
return owner;
}
public void set_owner(Player input){
owner = input;
}
}

View File

@ -0,0 +1,23 @@
package manager.field;
public class Player{
private String name;
private int playerid;
public Player(String input_name, int input_id){
name = input_name;
playerid = input_id;
}
public void set_name(String input_name){
name = input_name;
}
public String get_name(){
return name;
}
public int get_playerid(){
return playerid;
}
}

View File

@ -0,0 +1,108 @@
package manager;
import manager.attackinformations.AttackInformations;
import manager.field.Field;
import manager.field.Player;
import java.util.ArrayList;
import java.util.Random;
public class GameManager {
private ArrayList<Field> fields;
private ArrayList<Player> players;
private Random rand_num_gen;
public GameManager(){
fields = new ArrayList<Field>();
players = new ArrayList<Player>();
rand_num_gen = new Random();
}
public ArrayList<Player> get_players(){
return players;
}
public void add_player(String input){
if(players.size() < 8){
Player pl = new Player(input,players.size());
players.add(pl);
}
}
public AttackInformations attack_field(Field att_field, Field def_field){
// In the following in Lines we check if the attack is allowed or not
// For this we have to check, that the field exist in our ArrayList
// Fields and that they are Neighbours.
boolean attack_allowed= false;
boolean att_field_allowed = false;
boolean def_field_allowed = false;
for(Field field:fields){
if(field == att_field){
att_field_allowed = true;
}
if(field == def_field){
def_field_allowed = true;
}
}
if(att_field.get_dice_number()<= 1){
att_field_allowed = false;
}
for(Field neigh:att_field.get_neighbours()){
if(neigh == def_field){
attack_allowed = true;
break;
}
}
attack_allowed = att_field_allowed && def_field_allowed && attack_allowed && (att_field.get_owner() != def_field.get_owner());
AttackInformations infor;
if(attack_allowed){
// Now we know, that the Attack is allowed.
// Now we simulate the threw of the Dices.
int att_field_sum = 0;
int def_field_sum = 0;
// The sum of all dice-threws of the attacking Field get counted here:
for(int i = 0; i < att_field.get_dice_number();i++){
att_field_sum += 1 + rand_num_gen.nextInt(6);
}
// Analof the of all dice-threws of the defending Field get counted here:
for(int i = 0; i < def_field.get_dice_number();i++){
def_field_sum += 1 + rand_num_gen.nextInt(6);
}
// We save the Attackinformations here, so they can be given out at the end:
infor = new AttackInformations(att_field_sum, def_field_sum,true);
// We update the Status of the different Fields in this part:
if(infor.get_attack_success()){
def_field.set_dice_number(java.lang.Math.max(att_field.get_dice_number()-1,1));
def_field.set_owner(att_field.get_owner());
}
else{
att_field.set_dice_number(1);
}
}
else{
infor = new AttackInformations(-1,-1,false);
}
return infor;
}
public ArrayList<Field> get_fields(){
return fields;
}
public void new_game(ArrayList<Field> inp){
fields = inp;
}
}

View File

@ -0,0 +1,49 @@
package manager;
import manager.GameManager;
import manager.field.Field;
import manager.field.Player;
import java.util.ArrayList;
public class Test {
public static void main(String[] args){
GameManager gm = new GameManager();
// Test to add Players to the Gamemanager and print them:
gm.add_player("Sebastian");
gm.add_player("Lars");
gm.add_player("Nils");
gm.add_player("Felix");
for(Player current:gm.get_players()){
System.out.println(current.get_name());
}
// Test to add a Field-List to the Gamemanager:
ArrayList<Field> fields = new ArrayList<Field>();
Field f1 = new Field(4,gm.get_players().get(0));
Field f2 = new Field(3,gm.get_players().get(1));
Field f3 = new Field(5,gm.get_players().get(2));
f1.add_neighbour(f2);
f2.add_neighbour(f1);
fields.add(f1);
fields.add(f2);
fields.add(f3);
gm.new_game(fields);
// Test to attack a neighboured fields:
System.out.println("\n The Owner of the First Field is:");
System.out.println(gm.get_fields().get(0).get_owner().get_name());
System.out.println("The Number of Dices of the First Field is:");
System.out.println(gm.get_fields().get(0).get_dice_number());
System.out.println("\n");
gm.attack_field(gm.get_fields().get(1),gm.get_fields().get(0));
System.out.println("\n Attack Field 1 with Field 2: \n");
System.out.println("\n The Owner of the First Field is:");
System.out.println(gm.get_fields().get(0).get_owner().get_name());
System.out.println("The Number of Dices of the First Field is:");
System.out.println(gm.get_fields().get(0).get_dice_number());
System.out.println("\n");
}
}