Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hometask 1 #39

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,26 @@ version '1.0-SNAPSHOT'
application {
mainClassName = 'ru.mipt.bit.platformer.GameDesktopLauncher'
if (Os.isFamily(Os.FAMILY_MAC)) {
applicationDefaultJvmArgs = ['-XstartOnFirstThread']
applicationDefaultJvmArgs = [
'-XstartOnFirstThread',
"-Djava.library.path=$projectDir/libs"
]

}
}

repositories {
mavenCentral()
}

java {
sourceSets.main.runtimeClasspath += files("$projectDir/libs/")
}


dependencies {
implementation deps.gdx.gdx
implementation deps.gdx.backend_lwjgl3
implementation deps.gdx.platform_desktop

}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
144 changes: 24 additions & 120 deletions src/main/java/ru/mipt/bit/platformer/GameDesktopLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,175 +4,79 @@
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.MapRenderer;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Rectangle;
import ru.mipt.bit.platformer.abstractions.Field;
import ru.mipt.bit.platformer.abstractions.Tree;
import ru.mipt.bit.platformer.abstractions.Tank;
import ru.mipt.bit.platformer.util.TileMovement;

import static com.badlogic.gdx.Input.Keys.*;
import static com.badlogic.gdx.graphics.GL20.GL_COLOR_BUFFER_BIT;
import static com.badlogic.gdx.math.MathUtils.isEqual;
import static ru.mipt.bit.platformer.util.GdxGameUtils.*;

public class GameDesktopLauncher implements ApplicationListener {

private static final float MOVEMENT_SPEED = 0.4f;

private Batch batch;

private TiledMap level;
private MapRenderer levelRenderer;
private Field field;
private Tank tank;
private Tree tree;
private TileMovement tileMovement;

private Texture blueTankTexture;
private TextureRegion playerGraphics;
private Rectangle playerRectangle;
// player current position coordinates on level 10x8 grid (e.g. x=0, y=1)
private GridPoint2 playerCoordinates;
// which tile the player want to go next
private GridPoint2 playerDestinationCoordinates;
private float playerMovementProgress = 1f;
private float playerRotation;

private Texture greenTreeTexture;
private TextureRegion treeObstacleGraphics;
private GridPoint2 treeObstacleCoordinates = new GridPoint2();
private Rectangle treeObstacleRectangle = new Rectangle();

@Override
public void create() {
batch = new SpriteBatch();
field = new Field("level.tmx", batch);

// load level tiles
level = new TmxMapLoader().load("level.tmx");
levelRenderer = createSingleLayerMapRenderer(level, batch);
TiledMapTileLayer groundLayer = getSingleLayer(level);
TiledMapTileLayer groundLayer = field.getLayer();
tileMovement = new TileMovement(groundLayer, Interpolation.smooth);

// Texture decodes an image file and loads it into GPU memory, it represents a native resource
blueTankTexture = new Texture("images/tank_blue.png");
// TextureRegion represents Texture portion, there may be many TextureRegion instances of the same Texture
playerGraphics = new TextureRegion(blueTankTexture);
playerRectangle = createBoundingRectangle(playerGraphics);
// set player initial position
playerDestinationCoordinates = new GridPoint2(1, 1);
playerCoordinates = new GridPoint2(playerDestinationCoordinates);
playerRotation = 0f;

greenTreeTexture = new Texture("images/greenTree.png");
treeObstacleGraphics = new TextureRegion(greenTreeTexture);
treeObstacleCoordinates = new GridPoint2(1, 3);
treeObstacleRectangle = createBoundingRectangle(treeObstacleGraphics);
moveRectangleAtTileCenter(groundLayer, treeObstacleRectangle, treeObstacleCoordinates);
tank = new Tank("images/tank_blue.png", new GridPoint2(1, 1), 0.4f);
tree = new Tree("images/greenTree.png", new GridPoint2(1, 3), groundLayer);
}

@Override
public void render() {
// clear the screen
Gdx.gl.glClearColor(0f, 0f, 0.2f, 1f);
Gdx.gl.glClear(GL_COLOR_BUFFER_BIT);

// get time passed since the last render
float deltaTime = Gdx.graphics.getDeltaTime();

if (Gdx.input.isKeyPressed(UP) || Gdx.input.isKeyPressed(W)) {
if (isEqual(playerMovementProgress, 1f)) {
// check potential player destination for collision with obstacles
if (!treeObstacleCoordinates.equals(incrementedY(playerCoordinates))) {
playerDestinationCoordinates.y++;
playerMovementProgress = 0f;
}
playerRotation = 90f;
}
}
if (Gdx.input.isKeyPressed(LEFT) || Gdx.input.isKeyPressed(A)) {
if (isEqual(playerMovementProgress, 1f)) {
if (!treeObstacleCoordinates.equals(decrementedX(playerCoordinates))) {
playerDestinationCoordinates.x--;
playerMovementProgress = 0f;
}
playerRotation = -180f;
}
}
if (Gdx.input.isKeyPressed(DOWN) || Gdx.input.isKeyPressed(S)) {
if (isEqual(playerMovementProgress, 1f)) {
if (!treeObstacleCoordinates.equals(decrementedY(playerCoordinates))) {
playerDestinationCoordinates.y--;
playerMovementProgress = 0f;
}
playerRotation = -90f;
}
}
if (Gdx.input.isKeyPressed(RIGHT) || Gdx.input.isKeyPressed(D)) {
if (isEqual(playerMovementProgress, 1f)) {
if (!treeObstacleCoordinates.equals(incrementedX(playerCoordinates))) {
playerDestinationCoordinates.x++;
playerMovementProgress = 0f;
}
playerRotation = 0f;
}
}

// calculate interpolated player screen coordinates
tileMovement.moveRectangleBetweenTileCenters(playerRectangle, playerCoordinates, playerDestinationCoordinates, playerMovementProgress);

playerMovementProgress = continueProgress(playerMovementProgress, deltaTime, MOVEMENT_SPEED);
if (isEqual(playerMovementProgress, 1f)) {
// record that the player has reached his/her destination
playerCoordinates.set(playerDestinationCoordinates);
tank.handleInput();
if (!tree.collidesWith(tank.getDestination())) {
tank.updatePosition(tileMovement, deltaTime);
}
field.render();

// render each tile of the level
levelRenderer.render();

// start recording all drawing commands
batch.begin();

// render player
drawTextureRegionUnscaled(batch, playerGraphics, playerRectangle, playerRotation);

// render tree obstacle
drawTextureRegionUnscaled(batch, treeObstacleGraphics, treeObstacleRectangle, 0f);

// submit all drawing requests
tank.render(batch);
tree.render(batch);
batch.end();
}

@Override
public void resize(int width, int height) {
// do not react to window resizing
public void dispose() {
batch.dispose();
field.dispose();
tank.dispose();
tree.dispose();
}

@Override
public void pause() {
// game doesn't get paused
public void resize(int width, int height) {
}

@Override
public void resume() {
// game doesn't get paused
public void pause() {
}

@Override
public void dispose() {
// dispose of all the native resources (classes which implement com.badlogic.gdx.utils.Disposable)
greenTreeTexture.dispose();
blueTankTexture.dispose();
level.dispose();
batch.dispose();
public void resume() {
}

public static void main(String[] args) {
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
// level width: 10 tiles x 128px, height: 8 tiles x 128px
config.setWindowedMode(1280, 1024);
new Lwjgl3Application(new GameDesktopLauncher(), config);
}
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/ru/mipt/bit/platformer/abstractions/Direction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ru.mipt.bit.platformer.abstractions;

import com.badlogic.gdx.math.GridPoint2;

public enum Direction {
UP(90), DOWN(-90), LEFT(-180), RIGHT(0);

private final float rotation;

Direction(float rotation) {
this.rotation = rotation;
}

public float getRotation() {
return rotation;
}

public GridPoint2 move(GridPoint2 currentPosition) {
switch (this) {
case UP:
return new GridPoint2(currentPosition.x, currentPosition.y + 1);
case DOWN:
return new GridPoint2(currentPosition.x, currentPosition.y - 1);
case LEFT:
return new GridPoint2(currentPosition.x - 1, currentPosition.y);
case RIGHT:
return new GridPoint2(currentPosition.x + 1, currentPosition.y);
default:
throw new IllegalArgumentException("Unknown direction");
}
}
}
32 changes: 32 additions & 0 deletions src/main/java/ru/mipt/bit/platformer/abstractions/Field.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ru.mipt.bit.platformer.abstractions;

import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.maps.MapRenderer;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;

import static ru.mipt.bit.platformer.util.GdxGameUtils.createSingleLayerMapRenderer;
import static ru.mipt.bit.platformer.util.GdxGameUtils.getSingleLayer;

public class Field {
private TiledMap map;
private MapRenderer renderer;

public Field(String mapPath, Batch batch) {
this.map = new TmxMapLoader().load(mapPath);
this.renderer = createSingleLayerMapRenderer(map, batch);
}

public void render() {
renderer.render();
}

public TiledMapTileLayer getLayer() {
return getSingleLayer(map);
}

public void dispose() {
map.dispose();
}
}
81 changes: 81 additions & 0 deletions src/main/java/ru/mipt/bit/platformer/abstractions/Tank.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package ru.mipt.bit.platformer.abstractions;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Rectangle;
import ru.mipt.bit.platformer.util.TileMovement;
import static com.badlogic.gdx.Input.Keys.*;
import static com.badlogic.gdx.math.MathUtils.isEqual;
import static ru.mipt.bit.platformer.util.GdxGameUtils.*;

public class Tank {

private final Texture tankTexture;
private final TextureRegion tankGraphics;
private final Rectangle tankRectangle;
private final float movementSpeed;

private GridPoint2 currentCoordinates;
private GridPoint2 destinationCoordinates;
private float movementProgress = 1f;
private float rotation;

public Tank(String texturePath, GridPoint2 initialCoordinates, float movementSpeed) {
this.tankTexture = new Texture(texturePath);
this.tankGraphics = new TextureRegion(tankTexture);
this.tankRectangle = createBoundingRectangle(tankGraphics);
this.currentCoordinates = new GridPoint2(initialCoordinates);
this.destinationCoordinates = new GridPoint2(initialCoordinates);
this.movementSpeed = movementSpeed;
this.rotation = 0f;
}

public void handleInput() {
if (isEqual(movementProgress, 1f)) {
if (Gdx.input.isKeyPressed(UP) || Gdx.input.isKeyPressed(W)) {
destinationCoordinates.y++;
rotation = 90f;
movementProgress = 0f;
}
if (Gdx.input.isKeyPressed(LEFT) || Gdx.input.isKeyPressed(A)) {
destinationCoordinates.x--;
rotation = -180f;
movementProgress = 0f;
}
if (Gdx.input.isKeyPressed(DOWN) || Gdx.input.isKeyPressed(S)) {
destinationCoordinates.y--;
rotation = -90f;
movementProgress = 0f;
}
if (Gdx.input.isKeyPressed(RIGHT) || Gdx.input.isKeyPressed(D)) {
destinationCoordinates.x++;
rotation = 0f;
movementProgress = 0f;
}
}
}

public void updatePosition(TileMovement tileMovement, float deltaTime) {
tileMovement.moveRectangleBetweenTileCenters(tankRectangle, currentCoordinates, destinationCoordinates, movementProgress);

movementProgress = continueProgress(movementProgress, deltaTime, movementSpeed);
if (isEqual(movementProgress, 1f)) {
currentCoordinates.set(destinationCoordinates);
}
}

public void render(Batch batch) {
drawTextureRegionUnscaled(batch, tankGraphics, tankRectangle, rotation);
}

public void dispose() {
tankTexture.dispose();
}

public GridPoint2 getDestination() {
return new GridPoint2(destinationCoordinates);
}
}
Loading