commit 0bd5b7e10918df791a6bf2449c11ff8be72fd4b8 Author: Optioneel Date: Thu Jul 6 22:51:32 2023 +0200 lets go mario diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3d9d087 --- /dev/null +++ b/.gitignore @@ -0,0 +1,114 @@ +## Java + +*.class +*.war +*.ear +hs_err_pid* + +## Robovm +/ios/robovm-build/ + +## GWT +/html/war/ +/html/gwt-unitCache/ +.apt_generated/ +.gwt/ +gwt-unitCache/ +www-test/ +.gwt-tmp/ + +## Android Studio and Intellij and Android in general +/android/libs/armeabi-v7a/ +/android/libs/arm64-v8a/ +/android/libs/x86/ +/android/libs/x86_64/ +/android/gen/ +.idea/ +*.ipr +*.iws +*.iml +/android/out/ +com_crashlytics_export_strings.xml + +## Eclipse + +.classpath +.project +.metadata/ +/android/bin/ +/core/bin/ +/desktop/bin/ +/html/bin/ +/ios/bin/ +*.tmp +*.bak +*.swp +*~.nib +.settings/ +.loadpath +.externalToolBuilders/ +*.launch + +## NetBeans + +/nbproject/private/ +/android/nbproject/private/ +/core/nbproject/private/ +/desktop/nbproject/private/ +/html/nbproject/private/ +/ios/nbproject/private/ + +/build/ +/android/build/ +/core/build/ +/desktop/build/ +/html/build/ +/ios/build/ + +/nbbuild/ +/android/nbbuild/ +/core/nbbuild/ +/desktop/nbbuild/ +/html/nbbuild/ +/ios/nbbuild/ + +/dist/ +/android/dist/ +/core/dist/ +/desktop/dist/ +/html/dist/ +/ios/dist/ + +/nbdist/ +/android/nbdist/ +/core/nbdist/ +/desktop/nbdist/ +/html/nbdist/ +/ios/nbdist/ + +nbactions.xml +nb-configuration.xml + +## Gradle + +/local.properties +.gradle/ +gradle-app.setting +/build/ +/android/build/ +/core/build/ +/desktop/build/ +/html/build/ +/ios/build/ + +## OS Specific +.DS_Store +Thumbs.db + +## iOS +/ios/xcode/*.xcodeproj/* +!/ios/xcode/*.xcodeproj/xcshareddata +!/ios/xcode/*.xcodeproj/project.pbxproj +/ios/xcode/native/ +/ios/IOSLauncher.app +/ios/IOSLauncher.app.dSYM diff --git a/assets/animations/TestAnimator.json b/assets/animations/TestAnimator.json new file mode 100644 index 0000000..ac05ef9 --- /dev/null +++ b/assets/animations/TestAnimator.json @@ -0,0 +1 @@ +[{name:Jan,path:TestAnim.png,rows:5,collumns:5,speed:0.054f}] \ No newline at end of file diff --git a/assets/badlogic.jpg b/assets/badlogic.jpg new file mode 100644 index 0000000..4390da6 Binary files /dev/null and b/assets/badlogic.jpg differ diff --git a/assets/images/83719-de-klok-halve-liter-blik.jpeg b/assets/images/83719-de-klok-halve-liter-blik.jpeg new file mode 100644 index 0000000..a842980 Binary files /dev/null and b/assets/images/83719-de-klok-halve-liter-blik.jpeg differ diff --git a/assets/images/KlokZon.png b/assets/images/KlokZon.png new file mode 100644 index 0000000..0ea6070 Binary files /dev/null and b/assets/images/KlokZon.png differ diff --git a/assets/images/TestAnim.png b/assets/images/TestAnim.png new file mode 100644 index 0000000..bb3b3e1 Binary files /dev/null and b/assets/images/TestAnim.png differ diff --git a/assets/images/bg.png b/assets/images/bg.png new file mode 100644 index 0000000..d015564 Binary files /dev/null and b/assets/images/bg.png differ diff --git a/assets/maps/testLevel1.tmx b/assets/maps/testLevel1.tmx new file mode 100644 index 0000000..0e33636 --- /dev/null +++ b/assets/maps/testLevel1.tmx @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,10,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,8,8,9,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,6,0,0,0,0,0, +1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +3,3,3,3,3,3,3,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/tilesets/Untitled-5.png b/assets/tilesets/Untitled-5.png new file mode 100644 index 0000000..16ee49c Binary files /dev/null and b/assets/tilesets/Untitled-5.png differ diff --git a/assets/tilesets/testTileSet.tsx b/assets/tilesets/testTileSet.tsx new file mode 100644 index 0000000..48fea4e --- /dev/null +++ b/assets/tilesets/testTileSet.tsx @@ -0,0 +1,4 @@ + + + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..5a4d206 --- /dev/null +++ b/build.gradle @@ -0,0 +1,64 @@ +buildscript { + + + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } + google() + } + dependencies { + + + } +} + +allprojects { + apply plugin: "eclipse" + + version = '1.0' + ext { + appName = "Jan" + gdxVersion = '1.11.0' + roboVMVersion = '2.3.19' + box2DLightsVersion = '1.5' + ashleyVersion = '1.7.4' + aiVersion = '1.8.2' + gdxControllersVersion = '2.2.1' + } + + repositories { + mavenLocal() + mavenCentral() + google() + gradlePluginPortal() + maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } + maven { url "https://oss.sonatype.org/content/repositories/releases/" } + maven { url "https://jitpack.io" } + } +} + +project(":desktop") { + apply plugin: "java-library" + + + dependencies { + implementation project(":core") + api "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" + api "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" + api "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" + + } +} + +project(":core") { + apply plugin: "java-library" + + + dependencies { + api "com.badlogicgames.gdx:gdx:$gdxVersion" + api "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" + + } +} diff --git a/core/build.gradle b/core/build.gradle new file mode 100644 index 0000000..d192d04 --- /dev/null +++ b/core/build.gradle @@ -0,0 +1,6 @@ +sourceCompatibility = 1.7 +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' + +sourceSets.main.java.srcDirs = [ "src/" ] + +eclipse.project.name = appName + "-core" diff --git a/core/src/com/jan/Collision/Colider.java b/core/src/com/jan/Collision/Colider.java new file mode 100644 index 0000000..98eb253 --- /dev/null +++ b/core/src/com/jan/Collision/Colider.java @@ -0,0 +1,75 @@ +package com.jan.Collision; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.FixtureDef; +import com.badlogic.gdx.physics.box2d.World; +import com.badlogic.gdx.physics.box2d.BodyDef.BodyType; +import com.jan.entity.GameObject; +import com.jan.game.Display; +import com.badlogic.gdx.physics.box2d.PolygonShape; + +public class Colider { + public static final String BODY_PROPERTY = "BodyType"; + public static final String BODY_COLLIDER = "Colider"; + + private Body body; + private GameObject target; + + private String bodyType; + private String colider; + private boolean isSolid = true; + + public Colider(GameObject target, String bodyType, String colider, boolean isSolid){ + this(target, bodyType, colider); + this.isSolid = isSolid; + } + public Colider(GameObject target, String bodyType, String colider){ + this.target = target; + this.bodyType = bodyType; + this.colider = colider; + } + + public void loadBody(World world){ + BodyDef bodyDef = new BodyDef(); + bodyDef.type = getType(bodyType); + float scale = Display.getScale(); + bodyDef.position.set((target.getX() + (target.getWidth() /2)) / scale, (target.getY() + (target.getHeight() /2)) /scale); + body = world.createBody(bodyDef); + body.setUserData(this); + getColider(); + } + + public BodyType getType(String bodyType){ + switch(bodyType){ + case "Dynamic": return BodyType.DynamicBody; + case "Static": return BodyType.StaticBody; + case "Kinematic": return BodyType.KinematicBody; + } + return BodyType.StaticBody; + } + + private void getColider(){ + float scale = Display.getScale(); + if(colider.equals("auto")){ + PolygonShape groundBox = new PolygonShape(); + groundBox.setAsBox((target.getWidth() / scale) /2, (target.getHeight() / scale) /2); + FixtureDef fixture = new FixtureDef(); + fixture.shape = groundBox; + fixture.isSensor = !isSolid; + body.createFixture(fixture); + groundBox.dispose(); + } + } + + public void updatePos(){ + Vector2 pos = body.getPosition(); + float scale = Display.getScale(); + target.setX((pos.x * scale) - target.getWidth() / 2); + target.setY((pos.y * scale) - target.getHeight() / 2); + } + + public Body getBody(){ return body; } + public GameObject getEntity(){return target;} +} diff --git a/core/src/com/jan/Collision/ColiderInterface.java b/core/src/com/jan/Collision/ColiderInterface.java new file mode 100644 index 0000000..965e75d --- /dev/null +++ b/core/src/com/jan/Collision/ColiderInterface.java @@ -0,0 +1,5 @@ +package com.jan.Collision; + +public interface ColiderInterface { + public Colider getColider(); +} diff --git a/core/src/com/jan/Collision/Collision.java b/core/src/com/jan/Collision/Collision.java new file mode 100644 index 0000000..7c7cd67 --- /dev/null +++ b/core/src/com/jan/Collision/Collision.java @@ -0,0 +1,149 @@ +package com.jan.Collision; + +import java.util.ArrayList; + +import com.badlogic.gdx.maps.MapLayer; +import com.badlogic.gdx.maps.MapObject; +import com.badlogic.gdx.maps.objects.RectangleMapObject; +import com.badlogic.gdx.maps.tiled.TiledMap; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer; +import com.badlogic.gdx.physics.box2d.Contact; +import com.badlogic.gdx.physics.box2d.ContactImpulse; +import com.badlogic.gdx.physics.box2d.ContactListener; +import com.badlogic.gdx.physics.box2d.Manifold; +import com.badlogic.gdx.physics.box2d.PolygonShape; +import com.badlogic.gdx.physics.box2d.World; +import com.badlogic.gdx.physics.box2d.BodyDef.BodyType; +import com.jan.Collision.CollisionEvent.COLLISION_STATE; +import com.jan.game.Display; +import com.jan.game.SceneManager; +import com.jan.scene.Entity; + +public class Collision { + public static final String GEOMETRY_LAYER = "Geometry"; + private String[] collisionTypes = {"Actor", "Trigger"}; + + private Box2DDebugRenderer debugRenderer = new Box2DDebugRenderer(); + + private float accumulator = 0; + private World physicsWorld; + + private ArrayList colliders; + + public Collision(TiledMap world){ + debugRenderer = new Box2DDebugRenderer(); + physicsWorld = new World(new Vector2(0, -98f), true); + MapLayer geometryLayer = world.getLayers().get(GEOMETRY_LAYER); + GeometryLoader loader = new GeometryLoader(geometryLayer); + physicsWorld = loader.getWorld(); + loader = null; + colliders = new ArrayList<>(); + physicsWorld.setContactListener(new ListenerClass()); + } + + public void loadColiders(ArrayList renderables){ + for(int i = 0; i < renderables.size(); i++){ + if(hasCollider(renderables.get(i).getEntityClass())){ + ColiderInterface actor = (ColiderInterface) renderables.get(i); + actor.getColider().loadBody(physicsWorld); + colliders.add(actor); + } + } + } + + private boolean hasCollider(String entityType){ + for(int i = 0; i < collisionTypes.length; i++){ + if(entityType.equals(collisionTypes[i])) + return true; + } + return false; + } + + public void update(float deltaTime){ + float frameTime = Math.min(deltaTime, 0.25f); + accumulator += frameTime; + while (accumulator >= 1/60f) { + physicsWorld.step(1/60f, 6, 2); + accumulator -= 1/60f; + } + updateBody(); + debugRenderer.render(physicsWorld, Display.getCamera().combined); + } + + private void updateBody(){ + for(int i = 0; i < colliders.size(); i++) + colliders.get(i).getColider().updatePos(); + } +} + +class GeometryLoader{ + private World collWorld; + + public GeometryLoader(MapLayer collisionData){ + collWorld = new World(new Vector2(0, -98f), true); + for(int i = 0; i < collisionData.getObjects().getCount(); i++) + loadBody(collisionData.getObjects().get(i)); + } + + private void loadBody(MapObject curr){ + if(curr instanceof RectangleMapObject){ + RectangleMapObject a = (RectangleMapObject)curr; + loadRectangle(a.getRectangle()); + } + } + + private void loadRectangle(Rectangle objRect){ + BodyDef bodyDef = new BodyDef(); + bodyDef.type = BodyType.StaticBody; + float bodyX = (objRect.getX() + (objRect.getWidth() / 2)) / Display.getScale(); + float bodyY = (objRect.getY() + (objRect.getHeight() / 2)) / Display.getScale(); + bodyDef.position.set(bodyX, bodyY); + + Body groundBody = collWorld.createBody(bodyDef); + PolygonShape groundBox = new PolygonShape(); + groundBox.setAsBox((objRect.width /2) / Display.getScale(), (objRect.height /2) / Display.getScale()); + groundBody.createFixture(groundBox, 0.0f); + groundBody.setUserData(0); + groundBox.dispose(); + } + + public World getWorld(){ return collWorld; } +} + +class ListenerClass implements ContactListener { + + public void beginContact(Contact contact){ + determenCollision(contact.getFixtureA().getBody().getUserData(), contact.getFixtureB().getBody().getUserData(), COLLISION_STATE.BEGIN, contact); + } + + public void endContact(Contact contact) { + determenCollision(contact.getFixtureA().getBody().getUserData(), contact.getFixtureB().getBody().getUserData(), COLLISION_STATE.END, contact); + } + + public void preSolve(Contact contact, Manifold oldManifold) {} + public void postSolve(Contact contact, ContactImpulse impulse) {} + + public void determenCollision(Object targetA, Object targetB, COLLISION_STATE state, Contact contact){ + if(regulairCollision(targetA, targetB, state, contact)) + return; + ObjectCollision(targetA, targetB, state, contact); + } + + public boolean regulairCollision(Object targetA, Object targetB, COLLISION_STATE state, Contact contact){ + if(targetA instanceof Integer && targetB instanceof Colider){ + SceneManager.fireEvent(new CollisionEvent((int) targetA, (Colider) targetB, state, contact)); + return true; + } + return false; + } + + public void ObjectCollision(Object targetA, Object targetB, COLLISION_STATE state, Contact contact){ + if(targetA instanceof Colider && targetB instanceof Colider){ + SceneManager.fireEvent(new CollisionEvent((Colider) targetA, (Colider) targetB, state, contact)); + } + } +} \ No newline at end of file diff --git a/core/src/com/jan/Collision/CollisionEvent.java b/core/src/com/jan/Collision/CollisionEvent.java new file mode 100644 index 0000000..0b84519 --- /dev/null +++ b/core/src/com/jan/Collision/CollisionEvent.java @@ -0,0 +1,47 @@ +package com.jan.Collision; + +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.Contact; +import com.jan.scene.Entity; + + + +public class CollisionEvent { + public enum COLLISION_STATE {BEGIN, END}; + public enum COLLISION_TYPE {TERAIN, OBJECT}; + + private Colider entityA; + private Colider entityB; + + private COLLISION_TYPE type; + private COLLISION_STATE state; + + private Contact contact; + + public CollisionEvent(Colider entityA, Colider entityB, COLLISION_STATE state, Contact contact){ + this.entityA = entityA; + this.entityB = entityB; + this.state = state; + this.type = COLLISION_TYPE.OBJECT; + this.contact = contact; + } + + public CollisionEvent(int entityA, Colider entityB, COLLISION_STATE state, Contact contact){ + this.entityB = entityB; + this.state = state; + this.type = COLLISION_TYPE.TERAIN; + this.contact = contact; + } + + public Entity getEntityA(){ return entityA.getEntity(); } + public Body getBodyA(){ return entityA.getBody(); } + + public Entity getEntityB(){ return entityB.getEntity(); } + public Body getBodyB(){ return entityB.getBody(); } + + public COLLISION_TYPE getType(){ return type; } + public COLLISION_STATE getState(){ return state; } + + public Contact getContact(){ return contact; } + +} diff --git a/core/src/com/jan/entity/Actor.java b/core/src/com/jan/entity/Actor.java new file mode 100644 index 0000000..56068b3 --- /dev/null +++ b/core/src/com/jan/entity/Actor.java @@ -0,0 +1,22 @@ +package com.jan.entity; + +import com.badlogic.gdx.maps.MapObject; +import com.jan.Collision.Colider; +import com.jan.Collision.ColiderInterface; + +public class Actor extends Animator implements ColiderInterface{ + + private Colider colider; + + public Actor(MapObject mapObject) { + super(mapObject); + String bodyType = (String)loadProperty(Colider.BODY_PROPERTY); + String coliderType = (String)loadProperty(Colider.BODY_COLLIDER); + colider = new Colider(this, bodyType, coliderType); + } + + public Colider getColider(){ + return colider; + } +} + diff --git a/core/src/com/jan/entity/Animator.java b/core/src/com/jan/entity/Animator.java new file mode 100644 index 0000000..a0a0896 --- /dev/null +++ b/core/src/com/jan/entity/Animator.java @@ -0,0 +1,111 @@ +package com.jan.entity; + +import java.util.ArrayList; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Animation; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g2d.Animation.PlayMode; +import com.badlogic.gdx.maps.MapObject; +import com.badlogic.gdx.utils.Json; +import com.badlogic.gdx.utils.JsonValue; + +public class Animator extends Renderable { + public static final String ANIMATOR_PROPERTY = "Animator"; + + private ArrayList animations; + private AnimationClip currClip; + + private float stateTime; + + public Animator(MapObject mapObject) { + super(mapObject); + animations = new ArrayList<>(); + String fileLocation = "animations/"+(String)loadProperty(ANIMATOR_PROPERTY); + + Json json = new Json(); + + ArrayList list = json.fromJson(ArrayList.class, Gdx.files.internal(fileLocation)); + for (JsonValue v : list) + animations.add(new AnimationClip(json.readValue(AnimationData.class, v))); + currClip = animations.get(0); + stateTime = 0f; + } + + public void update(){//override + stateTime += Gdx.graphics.getDeltaTime(); + this.setTexture(currClip.getKeyFrame(stateTime)); + } + + public void doAnimation(String animation, PlayMode mode){ + doAnimation(animation); + setAnimationState(mode); + } + public void doAnimation(String animation){ + for(int i = 0; i < animations.size(); i++){ + if(animations.get(i).getName().equals(animation)) + currClip = animations.get(i); + } + } + + public void setAnimationState(PlayMode mode){ currClip.setPlayMode(mode); } + +} + +class AnimationClip extends AnimationData{ + private Texture animSheet; + private Animation animation; + + public AnimationClip(AnimationData data){ + this.name = data.name; + this.path = data.path; + this.rows = data.rows; + this.collumns = data.collumns; + this.speed = data.speed; + animSheet = new Texture(Gdx.files.internal("images/"+path)); + loadAnimation(); + animation.setPlayMode(PlayMode.LOOP); + } + private void loadAnimation(){ + TextureRegion[][] tmp = TextureRegion.split(animSheet, animSheet.getWidth() / collumns, animSheet.getHeight() / rows); + TextureRegion[] animationFrames = new TextureRegion[collumns * rows]; + int index = 0; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < collumns; j++) + animationFrames[index++] = tmp[i][j]; + } + animation = new Animation(speed, animationFrames); + } + + public void setPlayMode(PlayMode playMode){ animation.setPlayMode(playMode); } + + public TextureRegion getKeyFrame(float deltaTime){ return animation.getKeyFrame(deltaTime); } + +} + +class AnimationData{ + protected String name; + protected String path; + + protected int rows; + protected int collumns; + protected float speed; + + public AnimationData(String name, String path, int rows, int collumns, float speed){ + this.name = name; + this.path = path; + this.rows = rows; + this.collumns = collumns; + this.speed = speed; + } + public AnimationData(){} + + public String getName(){ return name; } + public String getPath(){ return path; } + + public int getRows(){ return rows; } + public int getCollumns(){ return collumns; } + + public float getSpeed(){ return speed; } +} \ No newline at end of file diff --git a/core/src/com/jan/entity/GameObject.java b/core/src/com/jan/entity/GameObject.java new file mode 100644 index 0000000..a5266e7 --- /dev/null +++ b/core/src/com/jan/entity/GameObject.java @@ -0,0 +1,33 @@ +package com.jan.entity; + +import com.badlogic.gdx.maps.MapObject; +import com.jan.scene.Entity; + +public class GameObject extends Entity { + private float x; + private float y; + private float width; + private float height; + + public GameObject(MapObject mapObject) { + super(mapObject); + loadProperties(); + } + + private void loadProperties() { + x = (float)loadProperty("x"); + y = (float)loadProperty("y"); + width = (float)loadProperty("width"); + height = (float)loadProperty("height"); + } + + public float getX(){ return x; } + public float getY(){ return y; } + public void setX(float x){ this.x = x; } + public void setY(float y){ this.y = y; } + + public float getWidth(){ return width; } + public float getHeight(){ return height; } + public void setWidth(float width){ this.width = width;} + public void setHeight(float height){ this.height = height; } +} diff --git a/core/src/com/jan/entity/Renderable.java b/core/src/com/jan/entity/Renderable.java new file mode 100644 index 0000000..699db4a --- /dev/null +++ b/core/src/com/jan/entity/Renderable.java @@ -0,0 +1,27 @@ +package com.jan.entity; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.maps.MapObject; +import com.badlogic.gdx.maps.objects.TextureMapObject; + +public class Renderable extends GameObject{ + + private TextureRegion texture; + + public Renderable(MapObject mapObject) { + super(mapObject); + if(mapObject instanceof TextureMapObject){ + TextureMapObject textureObj = (TextureMapObject)mapObject; + texture = textureObj.getTextureRegion(); + } + } + + public void setTexture(TextureRegion texture){ + this.texture = texture; + } + + public TextureRegion getTexture(){ + return texture; + } + +} diff --git a/core/src/com/jan/entity/Trigger.java b/core/src/com/jan/entity/Trigger.java new file mode 100644 index 0000000..4c636cb --- /dev/null +++ b/core/src/com/jan/entity/Trigger.java @@ -0,0 +1,22 @@ +package com.jan.entity; + +import com.badlogic.gdx.maps.MapObject; +import com.jan.Collision.Colider; +import com.jan.Collision.ColiderInterface; + +public class Trigger extends GameObject implements ColiderInterface{ + + private Colider colider; + public Trigger(MapObject mapObject) { + super(mapObject); + String bodyType = (String)loadProperty(Colider.BODY_PROPERTY); + String coliderType = (String)loadProperty(Colider.BODY_COLLIDER); + boolean isSolid = (boolean)loadProperty("Solid"); + colider = new Colider(this, bodyType, coliderType, isSolid); + } + + public Colider getColider(){ + return colider; + } + +} diff --git a/core/src/com/jan/game/Display.java b/core/src/com/jan/game/Display.java new file mode 100644 index 0000000..0dad0f2 --- /dev/null +++ b/core/src/com/jan/game/Display.java @@ -0,0 +1,46 @@ +package com.jan.game; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.badlogic.gdx.graphics.OrthographicCamera; + +public class Display { + private static boolean isInitialized = false; + + private static ScreenViewport viewPort; + private static OrthographicCamera mainCamera; + + public static int DEFAULT_RESOLUTION_WIDTH = 960; + public static int DEFAULT_RESOLUTION_HEIGHT = 640; + + private static float tileSize = 0; + + public static void initialize(){ + if(isInitialized == false){ + Gdx.graphics.setResizable(false); + viewPort = new ScreenViewport(); + viewPort.setUnitsPerPixel(0.03125f); + setResolution(DEFAULT_RESOLUTION_WIDTH, DEFAULT_RESOLUTION_HEIGHT); + isInitialized = true; + } + } + + public static void setResolution(int width, int height){ + Gdx.graphics.setWindowedMode(width, height); + viewPort.update(width, height); + useCamera((OrthographicCamera)viewPort.getCamera()); + } + public static void useCamera(OrthographicCamera camera){ + viewPort.setCamera(camera); + mainCamera = (OrthographicCamera) viewPort.getCamera(); + } + + public static void update(){ + mainCamera.update(); + } + + public static OrthographicCamera getCamera(){ return mainCamera; } + + public static void setScale(float scale){ tileSize = scale; } + public static float getScale(){ return tileSize; } +} diff --git a/core/src/com/jan/game/Game.java b/core/src/com/jan/game/Game.java new file mode 100644 index 0000000..c347016 --- /dev/null +++ b/core/src/com/jan/game/Game.java @@ -0,0 +1,34 @@ +package com.jan.game; + +import com.jan.Collision.CollisionEvent; +import com.jan.entity.Trigger; +import com.jan.scene.Scene; + +public abstract class Game { + protected Scene currScene; + + public void create(Scene scene){ + currScene = scene; + } + + public abstract void start(); + public abstract void update(); + + public void catchEvent(CollisionEvent event){ + switch(event.getType()){ + case OBJECT: findType(event);break; + case TERAIN: regulairCollision(event); break; + } + } + + private void findType(CollisionEvent event){ + if(event.getEntityA() instanceof Trigger){ + return; + } + objectCollision(event); + } + + public void regulairCollision(CollisionEvent event){} + public void objectCollision(CollisionEvent event){} + public void trigger(CollisionEvent event){} +} diff --git a/core/src/com/jan/game/Main.java b/core/src/com/jan/game/Main.java new file mode 100644 index 0000000..5513ab6 --- /dev/null +++ b/core/src/com/jan/game/Main.java @@ -0,0 +1,38 @@ +package com.jan.game; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; + +public class Main extends ApplicationAdapter { + private OrthographicCamera camera; + + @Override + public void create () { + SceneManager.initialize(); + + camera = new OrthographicCamera(30,20); + Display.setResolution(1920, 1080); + Display.setResolution(680, 420); + Display.useCamera(camera); + camera.translate(15, 10); + SceneManager.loadScene("maps/testLevel1.tmx"); + } + + @Override + public void render () { + Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + SceneManager.updateScene();; + Display.update(); + } + + @Override + public void dispose () { + + } +} + diff --git a/core/src/com/jan/game/SceneManager.java b/core/src/com/jan/game/SceneManager.java new file mode 100644 index 0000000..a684a62 --- /dev/null +++ b/core/src/com/jan/game/SceneManager.java @@ -0,0 +1,30 @@ +package com.jan.game; + +import com.badlogic.gdx.physics.box2d.Box2D; +import com.jan.Collision.CollisionEvent; +import com.jan.scene.Scene; + +public class SceneManager { + private static Scene currScene; + + public static void initialize(){ + Display.initialize(); + Box2D.init(); + } + + public static void loadScene(String scene){ + currScene = new Scene(scene); + } + + public static void fireEvent(CollisionEvent event){ + currScene.fireEvent(event); + } + + public static void updateScene(){ + currScene.render(); + } + + public static Scene getScene(){ + return currScene; + } +} diff --git a/core/src/com/jan/scene/Entity.java b/core/src/com/jan/scene/Entity.java new file mode 100644 index 0000000..02aa3fa --- /dev/null +++ b/core/src/com/jan/scene/Entity.java @@ -0,0 +1,40 @@ +package com.jan.scene; + +import java.util.Iterator; +import com.badlogic.gdx.maps.MapObject; + +public abstract class Entity { + private MapObject objectData; + + private String entityName; + private String entityType; + private int entityID; + + public Entity(MapObject mapObject){ + objectData = mapObject; + entityName = objectData.getName(); + entityType = (String)loadProperty("type"); + entityID = (int)loadProperty("id"); + } + + public void update(){} + + protected void verifyData(){ + if(isDataLoaded() == false) + System.out.println("het"); + } + private boolean isDataLoaded(){ + Iterator props = objectData.getProperties().getKeys(); + return !props.hasNext(); + } + + protected Object loadProperty(String property){ + Object newProperty = objectData.getProperties().get(property); + objectData.getProperties().remove(property); + return newProperty; + } + + public String getEntityClass(){ return entityType; } + public String getEntityName(){ return entityName; } + public int getEntityID() { return entityID; } +} \ No newline at end of file diff --git a/core/src/com/jan/scene/Scene.java b/core/src/com/jan/scene/Scene.java new file mode 100644 index 0000000..85cb6a6 --- /dev/null +++ b/core/src/com/jan/scene/Scene.java @@ -0,0 +1,92 @@ +package com.jan.scene; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.maps.tiled.TiledMap; +import com.badlogic.gdx.maps.tiled.TmxMapLoader; +import com.jan.Collision.Collision; +import com.jan.Collision.CollisionEvent; +import com.jan.entity.Renderable; +import com.jan.game.Display; +import com.jan.game.Game; + +public class Scene{ + private World map; + private Collision collision; + + private ArrayList entities; + private Game currState; + + private OrthographicCamera sceneCamera; + + public Scene(String mapData){ + super(); + entities = new ArrayList<>(); + TiledMap world = new TmxMapLoader().load(mapData); + this.map = new World(world); + sceneCamera = new OrthographicCamera((float)world.getProperties().get("TilesViewportWidth"), (float)world.getProperties().get("TilesViewportHeight")); + Display.useCamera(sceneCamera); + setScale((int)world.getProperties().get("tilewidth"), (int)world.getProperties().get("tileheight")); + this.collision = new Collision(world); + collision.loadColiders(map.getEntities()); + populate(); + currState = new GameLoader().loadState((String)world.getProperties().get("State")); + currState.create(this); + currState.start(); + + } + private void populate(){ + ArrayList renderables = map.getRenderables(); + for(int i = 0; i < renderables.size(); i++) + entities.add(renderables.get(i)); + } + private void setScale(int tilesWidth, int tileHeight){ + if(tilesWidth == tileHeight){ + Display.setScale(tileHeight); + return; + } + System.out.println("Tile Width & Height must be equal"); + } + + + public void render(){ + currState.update(); + collision.update(Gdx.graphics.getDeltaTime()); + map.render(); + } + + public Entity getEntity(String name){ + for(int i = 0; i < entities.size(); i++){ + if(entities.get(i).getEntityName().equals(name)) + return entities.get(i); + } + return null; + } + + public void fireEvent(CollisionEvent event){ currState.catchEvent(event); } +} + +class GameLoader{ + + public Game loadState(String stateClass){ + try { + Class gameClass = Class.forName(stateClass); + Class[] types = {}; + Constructor constructor = gameClass.getConstructor(types); + Object gamObject = constructor.newInstance(); + return (Game)gamObject; + } + catch (ClassNotFoundException e) { e.printStackTrace();} + catch (NoSuchMethodException e) { e.printStackTrace();} + catch (SecurityException e) { e.printStackTrace();} + catch (InstantiationException e) { e.printStackTrace();} + catch (IllegalAccessException e) { e.printStackTrace();} + catch (IllegalArgumentException e) { e.printStackTrace();} + catch (InvocationTargetException e) { e.printStackTrace();} + return null; + } +} diff --git a/core/src/com/jan/scene/World.java b/core/src/com/jan/scene/World.java new file mode 100644 index 0000000..335a0d8 --- /dev/null +++ b/core/src/com/jan/scene/World.java @@ -0,0 +1,193 @@ +package com.jan.scene; + +import java.util.ArrayList; + +import com.badlogic.gdx.maps.MapLayer; +import com.badlogic.gdx.maps.MapObject; +import com.badlogic.gdx.maps.tiled.TiledMapImageLayer; +import com.badlogic.gdx.maps.tiled.TiledMap; +import com.badlogic.gdx.maps.tiled.TiledMapTileLayer; +import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer; +import com.jan.entity.Actor; +import com.jan.entity.Animator; +import com.jan.entity.Renderable; +import com.jan.entity.Trigger; +import com.jan.game.Display; + +public class World { + private TiledMap tiledMap; + private WorldRenderer worldRenderer; + + private ArrayList layers; + + private ArrayList renderables; + private ArrayList nonRenderables; + + public World(TiledMap tiledMap){ + this.tiledMap = tiledMap; + WorldLoader loader = new WorldLoader(tiledMap); + layers = loader.getLayers(); + renderables = loader.getRenderables(); + nonRenderables = loader.getNonRenderables(); + worldRenderer = new WorldRenderer(tiledMap); + } + + public void render(){ + worldRenderer.render(layers); + } + + public Renderable getRenderable(String name){ + for(int i = 0; i < renderables.size(); i++){ + if(renderables.get(i).getEntityName() == name) + return renderables.get(i); + } + return null; + } + + public ArrayList getRenderables(){ return renderables; } + public ArrayList getNonRenderables(){ return nonRenderables; } + public ArrayList getEntities(){ + ArrayList entities = new ArrayList<>(); + for(int i = 0; i < renderables.size(); i++) + entities.add(renderables.get(i)); + for(int i = 0; i < nonRenderables.size(); i++) + entities.add(nonRenderables.get(i)); + return entities; + } + + public TiledMap getMap(){ return tiledMap; } + +} + +enum LAYER_TYPES{STATIC_IMAGE, TILES, OBJECTS} + +class WorldRenderer{ + private OrthogonalTiledMapRenderer tiledMapRenderer; + + public WorldRenderer(TiledMap tiledMap){ + tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap, 1/32f); + } + + public void render(ArrayList layers){ + tiledMapRenderer.setView(Display.getCamera()); + tiledMapRenderer.getBatch().begin(); + for(int i = 0; i < layers.size(); i++) + renderLayer(layers.get(i)); + + tiledMapRenderer.getBatch().end(); + } + + private void renderLayer(Layer curr){ + switch(curr.getType()){ + case OBJECTS: renderObjectLayer(curr.getObjectLayer());break; + case STATIC_IMAGE: tiledMapRenderer.renderImageLayer(curr.getImageLayer()); break; + case TILES: tiledMapRenderer.renderTileLayer(curr.getTileLayer()); break; + } + } + + private void renderObjectLayer(ArrayList objLayer){ + for(int i = 0; i < objLayer.size(); i++){ + Renderable obj = objLayer.get(i); + obj.update(); + tiledMapRenderer.getBatch().draw(obj.getTexture(), obj.getX() /32, obj.getY() /32 , obj.getWidth() /32, obj.getHeight() /32); + } + } +} + +class WorldLoader{ + private TiledMap worldMap; + private ArrayList worldLayers; + + public WorldLoader(TiledMap worldMap){ + this.worldMap = worldMap; + worldLayers = new ArrayList<>(); + populate(); + } + private void populate(){ + int count = worldMap.getLayers().getCount(); + for(int i = 0; i < count; i++) + determenType(worldMap.getLayers().get(i)); + } + + private void determenType(MapLayer curr){ + if(curr instanceof TiledMapImageLayer){ worldLayers.add(new Layer((TiledMapImageLayer)curr)); return; } + if(curr instanceof TiledMapTileLayer){ worldLayers.add(new Layer((TiledMapTileLayer)curr)); return; } + if(curr instanceof MapLayer){ worldLayers.add(new Layer(curr)); return; } + } + + public ArrayList getRenderables(){ + ArrayList renederables = new ArrayList<>(); + for(int i = 0; i < worldLayers.size(); i++){ + if(worldLayers.get(i).getType() == LAYER_TYPES.OBJECTS){ + ArrayList objLayer = worldLayers.get(i).getObjectLayer(); + for(int j = 0; j < objLayer.size(); j++) + renederables.add(objLayer.get(j)); + } + } + return renederables; + } + + public ArrayList getNonRenderables(){ + ArrayList nonRenderables = new ArrayList<>(); + for(int i = 0; i < worldLayers.size(); i++){ + if(worldLayers.get(i).getType() == LAYER_TYPES.OBJECTS){ + ArrayList objLayer = worldLayers.get(i).getNonRenderables(); + for(int j = 0; j < objLayer.size(); j++) + nonRenderables.add(objLayer.get(j)); + } + } + return nonRenderables; + } + + public ArrayList getLayers(){ + return worldLayers; + } +} + +class Layer{ + private TiledMapTileLayer tileLayer; + private TiledMapImageLayer imageLayer; + + private ArrayList objectLayer; + private ArrayList nonRenderables; + + private LAYER_TYPES type; + + public Layer(TiledMapTileLayer tileLayer){ + this.type = LAYER_TYPES.TILES; + this.tileLayer = tileLayer; + } + + public Layer(TiledMapImageLayer imageLayer){ + this.type = LAYER_TYPES.STATIC_IMAGE; + this.imageLayer = imageLayer; + } + + public Layer(MapLayer objLayer){ + this.type = LAYER_TYPES.OBJECTS; + objectLayer = new ArrayList<>(); + nonRenderables = new ArrayList<>(); + for(int i = 0; i < objLayer.getObjects().getCount(); i++){ + MapObject currObj = objLayer.getObjects().get(i); + String type = (String)objLayer.getObjects().get(i).getProperties().get("type"); + if(type == null){continue;}; + switch(type){ + case "Renderable": objectLayer.add(new Renderable(currObj)); break; + case "Animator": objectLayer.add(new Animator(currObj)); break; + case "Actor": objectLayer.add(new Actor(currObj)); break; + case "Trigger": nonRenderables.add(new Trigger(currObj)); + } + } + + } + + public TiledMapTileLayer getTileLayer(){ return tileLayer; } + public TiledMapImageLayer getImageLayer(){ return imageLayer; } + + public ArrayList getObjectLayer(){ return objectLayer; } + public ArrayList getNonRenderables() {return nonRenderables; } + + public LAYER_TYPES getType(){ + return type; + } +} \ No newline at end of file diff --git a/core/src/com/jan/state/Platformer.java b/core/src/com/jan/state/Platformer.java new file mode 100644 index 0000000..f66b685 --- /dev/null +++ b/core/src/com/jan/state/Platformer.java @@ -0,0 +1,96 @@ +package com.jan.state; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.jan.Collision.CollisionEvent; +import com.jan.entity.Actor; +import com.jan.game.Display; +import com.jan.game.Game; + +public class Platformer extends Game{ + + private Actor player; + private boolean isColiding; + + private float maxSpeed = 8; + private float accelRate = 50f; + private float jumpForce = 30f; + + private float coolDown = 0.3f; + private float currCooldown = 0; + + public Platformer(){ + super(); + } + + public void start() { + player = (Actor)this.currScene.getEntity("Player"); + } + + @Override + public void update() { + updateInput(); + updateSpeed(); + updateCamera(); + } + + private void updateInput(){ + if(Gdx.input.isKeyPressed(Input.Keys.NUMPAD_6)) + player.getColider().getBody().applyForceToCenter(new Vector2(accelRate, 0), true); + if(Gdx.input.isKeyPressed(Input.Keys.NUMPAD_4)) + player.getColider().getBody().applyForceToCenter(new Vector2(-accelRate, 0), true); + if(Gdx.input.isKeyPressed(Input.Keys.A) && isColiding == true && currCooldown <= 0){ + float playerSpeed = player.getColider().getBody().getLinearVelocity().x; + player.getColider().getBody().setLinearVelocity(playerSpeed, jumpForce); + } + } + + private void updateCamera(){ + if(player.getX() < 420){ + Display.getCamera().position.set(13.644001f ,8.388437f, 0); + return; + } + System.out.println(Display.getCamera().position); + float offsetHeight = (Display.getCamera().viewportHeight /2); + float offsetWidth = (Display.getCamera().viewportWidth /2); + Vector3 pos = new Vector3(player.getColider().getBody().getWorldCenter(), 0); + pos.add(offsetWidth, offsetHeight, 0); + pos.sub(Display.getCamera().viewportWidth /2, (player.getHeight() /32)*2.6f, 0) ; + Display.getCamera().position.set(pos); + } + + private void updateSpeed(){ + Vector2 speed = player.getColider().getBody().getLinearVelocity(); + speed = new Vector2(speed.x, speed.y); + if(player.getColider().getBody().getPosition().x <= 0){ + System.out.println("Fuck"); + float angle = player.getColider().getBody().getAngle(); + player.getColider().getBody().setTransform(87.0f /32, 128.22997f /32, angle); + } + if(speed.x > maxSpeed ) + player.getColider().getBody().setLinearVelocity(maxSpeed, speed.y); + if( speed.x < maxSpeed*-1) + player.getColider().getBody().setLinearVelocity(-maxSpeed, speed.y); + + if(currCooldown > 0) + currCooldown -= Gdx.graphics.getDeltaTime(); + + + } + + public void regulairCollision(CollisionEvent event){ + Vector2 distance = event.getBodyB().getPosition(); + distance.sub(event.getContact().getFixtureA().getBody().getPosition()); + if(distance.y < 1.4f){ + isColiding = false; + return; + } + switch(event.getState()){ + case BEGIN: isColiding = true; currCooldown = coolDown; break; + case END: isColiding = false; break; + } + } + +} diff --git a/desktop/build.gradle b/desktop/build.gradle new file mode 100644 index 0000000..1258106 --- /dev/null +++ b/desktop/build.gradle @@ -0,0 +1,49 @@ +sourceCompatibility = 1.8 +sourceSets.main.java.srcDirs = [ "src/" ] +sourceSets.main.resources.srcDirs = ["../assets"] + +project.ext.mainClassName = "com.jan.game.DesktopLauncher" +project.ext.assetsDir = new File("../assets") + +import org.gradle.internal.os.OperatingSystem + +tasks.register('run', JavaExec) { + dependsOn classes + mainClass = project.mainClassName + classpath = sourceSets.main.runtimeClasspath + standardInput = System.in + workingDir = project.assetsDir + ignoreExitValue = true + + if (OperatingSystem.current() == OperatingSystem.MAC_OS) { + // Required to run on macOS + jvmArgs += "-XstartOnFirstThread" + } +} + +tasks.register('debug', JavaExec) { + dependsOn classes + mainClass = project.mainClassName + classpath = sourceSets.main.runtimeClasspath + standardInput = System.in + workingDir = project.assetsDir + ignoreExitValue = true + debug = true +} + +tasks.register('dist', Jar) { + duplicatesStrategy(DuplicatesStrategy.EXCLUDE) + manifest { + attributes 'Main-Class': project.mainClassName + } + dependsOn configurations.runtimeClasspath + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } + with jar +} + + +dist.dependsOn classes + +eclipse.project.name = appName + "-desktop" diff --git a/desktop/src/com/jan/game/DesktopLauncher.java b/desktop/src/com/jan/game/DesktopLauncher.java new file mode 100644 index 0000000..f667641 --- /dev/null +++ b/desktop/src/com/jan/game/DesktopLauncher.java @@ -0,0 +1,14 @@ +package com.jan.game; + +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; + +// Please note that on macOS your application needs to be started with the -XstartOnFirstThread JVM argument +public class DesktopLauncher { + public static void main (String[] arg) { + Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); + config.setForegroundFPS(60); + config.setTitle("Jan"); + new Lwjgl3Application(new Main(), config); + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..ff329ac --- /dev/null +++ b/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.daemon=true +org.gradle.jvmargs=-Xms128m -Xmx1500m +org.gradle.configureondemand=false diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..249e583 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..ae04661 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..a69d9cb --- /dev/null +++ b/gradlew @@ -0,0 +1,240 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f127cfd --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,91 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..74fc652 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include 'desktop', 'core' \ No newline at end of file