diff --git a/frontend/android/build.gradle b/frontend/android/build.gradle index fb0d06bc0d5a8cd8476ce06f29c59d7d19656186..1450f1075d9ac5a729415025b28af1e0d392c322 100644 --- a/frontend/android/build.gradle +++ b/frontend/android/build.gradle @@ -85,4 +85,5 @@ task run(type: Exec) { commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.game.tankwars/com.game.tankwars.AndroidLauncher' } + eclipse.project.name = appName + "-android" diff --git a/frontend/build.gradle b/frontend/build.gradle index f2b240ad6c1498d7024f7ca54415dcb281531638..df072c8f6f8609d86179e4af82c732f7c964fc48 100644 --- a/frontend/build.gradle +++ b/frontend/build.gradle @@ -51,7 +51,11 @@ project(":desktop") { implementation "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" api "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" api "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" - + + implementation "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" + + + } } @@ -68,12 +72,17 @@ project(":android") { natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86" natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64" + implementation "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" + natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi-v7a" + natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-arm64-v8a" + natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86" + natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86_64" + implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a" natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a" natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86" natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86_64" - } } @@ -83,6 +92,9 @@ project(":core") { dependencies { api "com.badlogicgames.gdx:gdx:$gdxVersion" + + implementation "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" + } } diff --git a/frontend/core/build.gradle b/frontend/core/build.gradle index d192d041d2164132cd2ec37cc81105151b1b9126..178f3c50e88bf8d82a8f0408114d067e8d5ccb54 100644 --- a/frontend/core/build.gradle +++ b/frontend/core/build.gradle @@ -4,3 +4,5 @@ sourceCompatibility = 1.7 sourceSets.main.java.srcDirs = [ "src/" ] eclipse.project.name = appName + "-core" + + diff --git a/frontend/core/src/com/game/tankwars/TankWarsGame.java b/frontend/core/src/com/game/tankwars/TankWarsGame.java index 5bf7b2d21b93790124d7e1dcfd615f6c7b0eb44e..c80fa99d1426fec5ce3a370a0a0167da6280bb3e 100644 --- a/frontend/core/src/com/game/tankwars/TankWarsGame.java +++ b/frontend/core/src/com/game/tankwars/TankWarsGame.java @@ -7,26 +7,40 @@ import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Game; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer; +import com.badlogic.gdx.physics.box2d.World; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ScreenUtils; +import com.game.tankwars.model.Box2dWorld; +import com.game.tankwars.model.Bullet; import com.game.tankwars.model.Tank; import com.game.tankwars.view.MainMenuScreen; public class TankWarsGame extends Game { - private SpriteBatch batch; + public static int VIEWPORT_WIDTH = 80; + public static int VIEWPORT_HEIGHT = 50; + private BitmapFont font; + private SpriteBatch batch; private OrthographicCamera camera; @Override public void create() { - - batch = new SpriteBatch(); // Font from https://www.fontspace.com/roll-accurate-font-f32330 font = generateFontFromTTFFile("RollAccurate-mvrx.ttf"); // Camera size set to main menu dimensions: portrait mode diff --git a/frontend/core/src/com/game/tankwars/model/Box2dWorld.java b/frontend/core/src/com/game/tankwars/model/Box2dWorld.java new file mode 100644 index 0000000000000000000000000000000000000000..b012dc18b9ea6ae6852873b37c6a8e7ee1b7a887 --- /dev/null +++ b/frontend/core/src/com/game/tankwars/model/Box2dWorld.java @@ -0,0 +1,19 @@ +package com.game.tankwars.model; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.World; + +public class Box2dWorld { + + private static final World world = new World(new Vector2(0, -10), true); + + public void logicStep(float dt) { + world.step(dt, 3, 3); + } + + public static World getWorld() { + return world; + } + + +} diff --git a/frontend/core/src/com/game/tankwars/model/Bullet.java b/frontend/core/src/com/game/tankwars/model/Bullet.java new file mode 100644 index 0000000000000000000000000000000000000000..034b9ecb4bacb8fc036af008f4aaeb309d52c201 --- /dev/null +++ b/frontend/core/src/com/game/tankwars/model/Bullet.java @@ -0,0 +1,47 @@ +package com.game.tankwars.model; + +import com.badlogic.gdx.Gdx; +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.CircleShape; +import com.badlogic.gdx.physics.box2d.FixtureDef; +import com.badlogic.gdx.physics.box2d.World; + +public class Bullet { + + BodyDef bodyDef = new BodyDef(); + FixtureDef fixtureDef = new FixtureDef(); + + World world; + Body body; + Tank tank; + Vector2 position; + + public Bullet(Tank tank) { + this.position = tank.getPosition(); + position.y += 0.5; + this.tank = tank; + world = Box2dWorld.getWorld(); + bodyDef.type = BodyDef.BodyType.DynamicBody; + bodyDef.position.set(this.position); + body = world.createBody(bodyDef); + + CircleShape shape = new CircleShape(); + shape.setRadius(0.1f); + fixtureDef.shape = shape; + fixtureDef.density = 0.5f; + fixtureDef.restitution = 0.6f; + fixtureDef.friction = 0.4f; + body.createFixture(fixtureDef); + + shape.dispose(); + + } + + public void shoot() { + body.applyLinearImpulse(0.4f, 0.3f, position.x-1, position.y-2, true); + System.out.println(this.position); + } + +} diff --git a/frontend/core/src/com/game/tankwars/model/Tank.java b/frontend/core/src/com/game/tankwars/model/Tank.java index 36293af2784e8dda33e6030bee35fe35ef197d98..4d5ae33716908b20dd29608dc860bc9838fd61de 100644 --- a/frontend/core/src/com/game/tankwars/model/Tank.java +++ b/frontend/core/src/com/game/tankwars/model/Tank.java @@ -2,25 +2,52 @@ package com.game.tankwars.model; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Sprite; 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.FixtureDef; +import com.badlogic.gdx.physics.box2d.PolygonShape; +import com.badlogic.gdx.physics.box2d.World; +import com.badlogic.gdx.utils.Array; +import com.game.tankwars.TankWarsGame; public class Tank { - public static final int TANK_MOVESPEED = 2; - public static final int TANK_WIDTH = 50; - public static final int TANK_HEIGHT = 50; + public static final int TANK_MOVESPEED = 10; + public static final int TANK_WIDTH = 2; + public static final int TANK_HEIGHT = 1; private Vector2 position; private Rectangle bounds; private Texture texture; + private Sprite sprite; + World world; + Body body; + BodyDef bodyDef = new BodyDef(); + FixtureDef fixtureDef = new FixtureDef(); public Tank(Vector2 position, Texture texture) { this.position = position; this.bounds = new Rectangle(position.x, position.y, TANK_WIDTH, TANK_HEIGHT); this.texture = texture; + sprite = new Sprite(texture); + sprite.setPosition(TankWarsGame.VIEWPORT_WIDTH/2, TankWarsGame.VIEWPORT_HEIGHT/2 + TANK_HEIGHT); + + world = Box2dWorld.getWorld(); + bodyDef.type = BodyDef.BodyType.KinematicBody; + bodyDef.position.set(sprite.getX(), sprite.getY()); + body = world.createBody(bodyDef); + body.setUserData(sprite); + + PolygonShape shape = new PolygonShape(); + shape.setAsBox(TANK_WIDTH, TANK_HEIGHT); + fixtureDef.shape = shape; + body.createFixture(fixtureDef); + shape.dispose(); } public Vector2 getPosition() { @@ -35,6 +62,8 @@ public class Tank { return texture; } + public Sprite getSprite() {return sprite;} + public void setPosition(Vector2 position) { this.position = position; } @@ -49,19 +78,24 @@ public class Tank { public void moveRight() { - position.x += TANK_MOVESPEED; + body.setLinearVelocity(TANK_MOVESPEED, 0); + position = body.getPosition(); } public void moveLeft() { - position.x -= TANK_MOVESPEED; + body.setLinearVelocity(- TANK_MOVESPEED, 0); + position = body.getPosition(); } + public void stop() {body.setLinearVelocity(0, 0);} + public boolean detectCollisionLeft() { return position.x < 0; } public boolean detectCollisionRight() { - return Gdx.graphics.getWidth() / 2.0f - bounds.getWidth() / 2.0f - 50 < position.x; + return TankWarsGame.VIEWPORT_WIDTH - TANK_WIDTH < position.x; } + } diff --git a/frontend/core/src/com/game/tankwars/view/GameScreen.java b/frontend/core/src/com/game/tankwars/view/GameScreen.java index d92f2fba1f6c6dbc2bd3f64281d257f84e8e5aeb..7247d8ddbafa77224753cadf34d393258b117ab0 100644 --- a/frontend/core/src/com/game/tankwars/view/GameScreen.java +++ b/frontend/core/src/com/game/tankwars/view/GameScreen.java @@ -3,39 +3,89 @@ package com.game.tankwars.view; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer; +import com.badlogic.gdx.physics.box2d.World; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ScreenUtils; import com.game.tankwars.TankWarsGame; +import com.game.tankwars.model.Box2dWorld; +import com.game.tankwars.model.Bullet; import com.game.tankwars.model.Tank; public class GameScreen implements Screen { final TankWarsGame tankWarsGame; - OrthographicCamera camera; - SpriteBatch batch; - Tank tank; + public static int VIEWPORT_WIDTH = 80; + public static int VIEWPORT_HEIGHT = 50; + + int horizontalScaling; + int verticalScaling; + private SpriteBatch batch; + + private Tank tank; + private Box2dWorld model; + private World world; + + private OrthographicCamera cam; + private Box2DDebugRenderer debugRenderer; + + private Bullet bullet; public GameScreen(final TankWarsGame tankWarsGame){ this.tankWarsGame = tankWarsGame; - camera = new OrthographicCamera(); - batch = new SpriteBatch(); - tank = new Tank(new Vector2(50, 50), new Texture("tank-khaki.png")); + model = new Box2dWorld(); + world = Box2dWorld.getWorld(); + cam = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); + cam.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0); + cam.update(); + debugRenderer = new Box2DDebugRenderer(true, true, true, true, true, true); + Vector2 tankPos = new Vector2(0, cam.position.y/2); + tank = new Tank(tankPos, new Texture("tank-khaki.png")); + horizontalScaling = Gdx.graphics.getWidth() / VIEWPORT_WIDTH; + verticalScaling = Gdx.graphics.getHeight() / VIEWPORT_HEIGHT; } @Override public void render(float delta) { - if(Gdx.input.isKeyPressed(Input.Keys.D)) { + model.logicStep(Gdx.graphics.getDeltaTime()); + Gdx.gl.glClearColor(0f, 0f, 0f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + debugRenderer.render(world, cam.combined); + + if(Gdx.input.isKeyPressed(Input.Keys.D) && !tank.detectCollisionRight()) { tank.moveRight(); } - if(Gdx.input.isKeyPressed(Input.Keys.A)) { + else if(Gdx.input.isKeyPressed(Input.Keys.A) && !tank.detectCollisionLeft()) { tank.moveLeft(); + } else { + tank.stop(); + } + if(Gdx.input.justTouched()) { + bullet = new Bullet(tank); + System.out.println(tank.getPosition()); + bullet.shoot(); + } + + Array<Body> bodies = new Array<Body>(); + world.getBodies(bodies); + + for (Body b : bodies) { + Sprite s = (Sprite) b.getUserData(); + + if (s != null) { + s.setPosition(b.getPosition().x * (float) horizontalScaling, b.getPosition().y * (float) verticalScaling); + } } - ScreenUtils.clear(0, 0, 0, 1); batch.begin(); - batch.draw(tank.getTexture(), tank.getPosition().x, tank.getPosition().y, Tank.TANK_WIDTH, Tank.TANK_HEIGHT); + tank.getSprite().draw(batch); batch.end(); } diff --git a/frontend/desktop/build.gradle b/frontend/desktop/build.gradle index 6a6e12b4bda59b0855db384ce041fe003d939b71..882823e0ef66997cfc7db0df642b9abe11f0dcf4 100644 --- a/frontend/desktop/build.gradle +++ b/frontend/desktop/build.gradle @@ -7,6 +7,8 @@ project.ext.assetsDir = new File("../assets") import org.gradle.internal.os.OperatingSystem + + task run(dependsOn: classes, type: JavaExec) { main = project.mainClassName classpath = sourceSets.main.runtimeClasspath