diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ba3dc50 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,53 @@ +name: Java CI to create and upload release on pull request + +permissions: + contents: write + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + build-number: ${GITHUB_RUN_NUMBER} + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: 'maven' + + - name: Install Maven + uses: stCarolas/setup-maven@v4 + with: + maven-version: '3.9.4' + + - run: mvn clean package -DskipTests + + - name: Prepare Artifacts + run: | + mkdir -p staging + mv target/platformer-java-1.0-SNAPSHOT.jar target/platformer-java-${{ env.build-number }}.jar + cp target/*.jar staging + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: Package + path: staging/ + retention-days: 1 + + - uses: marvinpinto/action-automatic-releases@latest + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: "${{ github.run_number }}" + title: "Automated Build ${{ github.run_number }}" + prerelease: true + files: staging/*.jar \ No newline at end of file diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml new file mode 100644 index 0000000..7daa65f --- /dev/null +++ b/dependency-reduced-pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + com.drewm + platformer-java + 1.0-SNAPSHOT + + + + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + com.drewm.main.Main + + + + + + + + + + 17 + 17 + UTF-8 + + diff --git a/pom.xml b/pom.xml index 2ea8ad2..b7e1e16 100644 --- a/pom.xml +++ b/pom.xml @@ -21,5 +21,30 @@ 2.15.2 + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + com.drewm.main.Main + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/drewm/entities/Player.java b/src/main/java/com/drewm/entities/Player.java index 50c2661..2c30f6e 100644 --- a/src/main/java/com/drewm/entities/Player.java +++ b/src/main/java/com/drewm/entities/Player.java @@ -23,6 +23,11 @@ public class Player extends Entity { private int health = maxHealth; private float speed = Constants.PLAYER_STARTING_SPEED; + private int healthUpgradeLvl = 1; + private int speedUpgradeLvl = 1; + private int jumpUpgradeLvl = 1; + private int timeUpgradeLvl = 1; + public boolean invincible = false; private long invincibilityStartTime = 0; private final int INVINCIBILITY_DURATION = 500; @@ -203,24 +208,61 @@ public void takeDamage(int amount) { } } + public int getHealthUpgradeCost() { + return 50*this.healthUpgradeLvl; + } + + public int getSpeedUpgradeCost() { + return (int) Math.pow(2, this.speedUpgradeLvl); + } + + public int getJumpUpgradeCost() { + return (int) Math.pow(3, this.jumpUpgradeLvl); + } + + public int getTimeUpgradeCost() { + return 10*this.timeUpgradeLvl; + } + + public int getCoinMultiplierUpgradeCost() { + return 20*this.coinMultiplier; + } + + public int getAmmoUpgradeCost() { + return 30*this.pistol.getMaxBullets(); + } + public void upgradeHealth() { - if (spendCoins(5)) { + if (spendCoins(getHealthUpgradeCost())) { maxHealth += 1; health = maxHealth; this.healthBar = updateHudText("Health: ", health); + this.healthUpgradeLvl++; } } + /** + * speed: 1, 2, 5, 8, 10, 20, 60, 400, 800, 1000 + * jump: 3, 10, 15, 20, 25, 50, 75, 100, 150, 200 + * double jump: 600exp + * time: 10, 15(8sec), 20(14sec), 25(20sec), 30(26sec), 35(32sec), 40, 45(44sec), 50(50sec), 60(56sec), 70(62sec), 80(68sec), 90(74sec), 100(80sec), 120(86sec), 140(92sec), 160(98sec), 180(104sec) + * health: 50, 150, 200, 300 + * multi: 20, 30, 40, 60, 80, 100, 150, 200, 250, 300 + * ammo: 20, 40, 70, 100, 150, 200, 250, 300, 400 + */ + public void upgradeSpeed() { - if (spendCoins(5)) { + if (spendCoins(getSpeedUpgradeCost())) { speed += 0.5f; + this.speedUpgradeLvl++; } } public void upgradeJumpPower() { - if (spendCoins(5)) { - jumpPower += 0.75f; + if (spendCoins(getJumpUpgradeCost())) { + jumpPower += 2.0f; + this.jumpUpgradeLvl++; } } @@ -231,16 +273,17 @@ public void buyPistol() { } public void buyAmmo() { - if (ownsPistol && this.spendCoins(1)) { + if (ownsPistol && this.spendCoins(getAmmoUpgradeCost())) { this.pistol.setMaxBullets(pistol.getMaxBullets()+1); this.pistol.setBulletsRemaining(pistol.getBulletsRemaining()+1); } } public void buyTimeUpgrade() { - if (spendCoins(10)) { + if (spendCoins(getTimeUpgradeCost())) { this.maxTimeLimitSeconds += 10; this.currentTimeLeft = this.maxTimeLimitSeconds; + this.timeUpgradeLvl++; } } @@ -259,7 +302,7 @@ public void earnCoins(int amount) { } public void buyCoinMultiplier() { - if (spendCoins(20)) this.coinMultiplier++; + if (spendCoins(getCoinMultiplierUpgradeCost())) this.coinMultiplier++; } public int getCoinMultiplier() { diff --git a/src/main/java/com/drewm/gamestates/Menu.java b/src/main/java/com/drewm/gamestates/Menu.java index 89755f3..76025cf 100644 --- a/src/main/java/com/drewm/gamestates/Menu.java +++ b/src/main/java/com/drewm/gamestates/Menu.java @@ -31,9 +31,9 @@ private BufferedImage createTitleText(String text) { } private void loadBtns() { - btns[0] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, this.titleText.getHeight(), Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, "Play", () -> { Gamestate.state = Gamestate.PLAYING; }); - btns[1] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, this.titleText.getHeight() + Constants.BTN_HEIGHT_SCALED + 10, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, "Options", () -> { Gamestate.state = Gamestate.OPTIONS; }); - btns[2] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, this.titleText.getHeight() + (Constants.BTN_HEIGHT_SCALED + 10) * 2, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, "Quit", () -> { Gamestate.state = Gamestate.QUIT; }); + btns[0] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, this.titleText.getHeight(), Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, () -> "Play", () -> { Gamestate.state = Gamestate.PLAYING; }); + btns[1] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, this.titleText.getHeight() + Constants.BTN_HEIGHT_SCALED + 10, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, () -> "Options", () -> { Gamestate.state = Gamestate.OPTIONS; }); + btns[2] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, this.titleText.getHeight() + (Constants.BTN_HEIGHT_SCALED + 10) * 2, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, () -> "Quit", () -> { Gamestate.state = Gamestate.QUIT; }); } @Override public void update() { diff --git a/src/main/java/com/drewm/gamestates/Options.java b/src/main/java/com/drewm/gamestates/Options.java index dba3577..e23b5b2 100644 --- a/src/main/java/com/drewm/gamestates/Options.java +++ b/src/main/java/com/drewm/gamestates/Options.java @@ -34,11 +34,11 @@ private BufferedImage createTitleText(String text) { } private void loadBtns() { - btns[0] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.BTN_HEIGHT_SCALED, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, window.getIsFullscreen() ? "Disable Fullscreen" : "Enable Fullscreen", () -> { + btns[0] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.BTN_HEIGHT_SCALED, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, () -> window.getIsFullscreen() ? "Disable Fullscreen" : "Enable Fullscreen", () -> { window.setIsFullscreen(!window.getIsFullscreen()); loadBtns(); }); - btns[1] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.BTN_HEIGHT_SCALED * 2 + 10, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, "Back", () -> { Gamestate.state = Gamestate.MENU; }); + btns[1] = new Button((Constants.SCREEN_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.BTN_HEIGHT_SCALED * 2 + 10, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, () -> "Back", () -> { Gamestate.state = Gamestate.MENU; }); } @Override public void update() { diff --git a/src/main/java/com/drewm/gamestates/Playing.java b/src/main/java/com/drewm/gamestates/Playing.java index acefe23..823d142 100644 --- a/src/main/java/com/drewm/gamestates/Playing.java +++ b/src/main/java/com/drewm/gamestates/Playing.java @@ -29,40 +29,40 @@ public class Playing implements Statemethods { public Door currentDoor = null; private final Modal pauseMenu = new Modal("Game Paused", new Button[]{ - new Button(Constants.MODAL_BG_X + (Constants.MODAL_BG_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.MODAL_BG_Y + Constants.BTN_HEIGHT_SCALED, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, "Resume", () -> { + new Button(Constants.MODAL_BG_X + (Constants.MODAL_BG_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.MODAL_BG_Y + Constants.BTN_HEIGHT_SCALED, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, () -> "Resume", () -> { isPaused = false; }), - new Button(Constants.MODAL_BG_X + (Constants.MODAL_BG_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.MODAL_BG_Y + Constants.BTN_HEIGHT_SCALED * 2, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, "Main Menu", () -> { + new Button(Constants.MODAL_BG_X + (Constants.MODAL_BG_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.MODAL_BG_Y + Constants.BTN_HEIGHT_SCALED * 2, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, () -> "Main Menu", () -> { Gamestate.state = Gamestate.MENU; resetLevel(); }) }); private final Modal buyMenu = new Modal("Buy Menu", new Button[]{ - new Button(1, "Health Upgrade [5 coins]", () -> { + new Button(1, () -> "Health Upgrade [" + player.getHealthUpgradeCost() + "coins]", () -> { player.upgradeHealth(); - }, () -> player.getCoins() >= 5), - new Button(2, "Speed Upgrade [5 coins]", () -> { + }, () -> player.getCoins() >= player.getHealthUpgradeCost()), + new Button(2, () -> "Speed Upgrade [" + player.getSpeedUpgradeCost() + "coins]", () -> { player.upgradeSpeed(); - }, () -> player.getCoins() >= 5), - new Button(3, "Jump Power Upgrade [5 coins]", () -> { + }, () -> player.getCoins() >= player.getSpeedUpgradeCost()), + new Button(3, () -> "Jump Power Upgrade [" + player.getJumpUpgradeCost() + "coins]", () -> { player.upgradeJumpPower(); - }, () -> player.getCoins() >= 5), - new Button(4, "Buy Pistol [5 coins]", () -> { + }, () -> player.getCoins() >= player.getJumpUpgradeCost()), + new Button(4, () -> "Buy Pistol [" + 5 + "coins]", () -> { player.buyPistol(); }, () -> player.getCoins() >= 5), - new Button(5, "Buy Ammo [1 coin]", () -> { + new Button(5, () -> "Buy Ammo [" + player.getAmmoUpgradeCost() + "coin]", () -> { player.buyAmmo(); - }, () -> player.ownsPistol && player.getCoins() >= 1), - new Button(6, "Time upgrade [10 coins]", () -> { + }, () -> player.ownsPistol && player.getCoins() >= player.getAmmoUpgradeCost()), + new Button(6, () -> "Time upgrade [" + player.getTimeUpgradeCost() + " coins]", () -> { player.buyTimeUpgrade(); - }, () -> player.getCoins() >= 10), - new Button(7, "Coin multiplier upgrade [20 coins]", () -> { + }, () -> player.getCoins() >= player.getTimeUpgradeCost()), + new Button(7, () -> "Coin multiplier upgrade [" + player.getCoinMultiplierUpgradeCost() + " coins]", () -> { player.buyCoinMultiplier(); - }, () -> player.getCoins() >= 20) + }, () -> player.getCoins() >= player.getCoinMultiplierUpgradeCost()) }); private final Modal winScreen = new Modal("You Win!", new Button[]{ - new Button(Constants.MODAL_BG_X + (Constants.MODAL_BG_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.MODAL_BG_Y + 30 + Constants.BTN_HEIGHT_SCALED, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, "Restart", this::resetLevel), - new Button(Constants.MODAL_BG_X + (Constants.MODAL_BG_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.MODAL_BG_Y + 40 + Constants.BTN_HEIGHT_SCALED * 2, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, "Main Menu", () -> { + new Button(Constants.MODAL_BG_X + (Constants.MODAL_BG_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.MODAL_BG_Y + 30 + Constants.BTN_HEIGHT_SCALED, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, () -> "Restart", this::resetLevel), + new Button(Constants.MODAL_BG_X + (Constants.MODAL_BG_WIDTH - Constants.BTN_WIDTH_SCALED) / 2, Constants.MODAL_BG_Y + 40 + Constants.BTN_HEIGHT_SCALED * 2, Constants.BTN_WIDTH_SCALED, Constants.BTN_HEIGHT_SCALED, () -> "Main Menu", () -> { Gamestate.state = Gamestate.MENU; resetLevel(); }) diff --git a/src/main/java/com/drewm/objects/FloatingMine.java b/src/main/java/com/drewm/objects/FloatingMine.java index 31a7b03..6e2bc4c 100644 --- a/src/main/java/com/drewm/objects/FloatingMine.java +++ b/src/main/java/com/drewm/objects/FloatingMine.java @@ -20,6 +20,7 @@ public class FloatingMine { private int spriteCounter = 0; private int spriteNum = 0; private float speed = 1f; + private final boolean showHitbox = false; public FloatingMine(float startX, float startY, float endX, float endY, Playing playing) { this.playing = playing; @@ -89,7 +90,7 @@ public void draw(Graphics2D g2) { screenY + Constants.TILE_SIZE * 2 > 0 && screenY < Constants.SCREEN_HEIGHT) { g2.drawImage(spriteFrames[spriteNum], (int) screenX, (int) screenY, spriteFrames[0].getWidth() * Constants.SCALE, spriteFrames[0].getHeight() * Constants.SCALE, null); - g2.drawRect((int) screenX, (int) screenY, spriteFrames[0].getWidth() * Constants.SCALE, spriteFrames[0].getHeight() * Constants.SCALE); + if (showHitbox) g2.drawRect((int) screenX, (int) screenY, spriteFrames[0].getWidth() * Constants.SCALE, spriteFrames[0].getHeight() * Constants.SCALE); } } diff --git a/src/main/java/com/drewm/ui/Button.java b/src/main/java/com/drewm/ui/Button.java index 4943484..f3b5678 100644 --- a/src/main/java/com/drewm/ui/Button.java +++ b/src/main/java/com/drewm/ui/Button.java @@ -8,46 +8,52 @@ public class Button { public int x, y, width, height, index; + private Supplier labelSupplier; private Supplier enabledSupplier; public Runnable onClick; public boolean mouseOver, mousePressed; public Rectangle bounds; private BufferedImage[] imgs; + private String lastRenderedLabel = ""; - public Button(int x, int y, int width, int height, String label, Runnable onClick) { - this(x, y, width, height, label, onClick, () -> true); + public Button(int x, int y, int width, int height, Supplier labelSupplier, Runnable onClick) { + this(x, y, width, height, labelSupplier, onClick, () -> true); } - public Button(int idx, String label, Runnable onClick, Supplier enabledSupplier) { + public Button(int idx, Supplier labelSupplier, Runnable onClick, Supplier enabledSupplier) { this( (Constants.SCREEN_WIDTH - (int) (Constants.SCREEN_WIDTH * 0.5f)) / 2, Constants.MODAL_BG_Y + Constants.BTN_HEIGHT_SCALED * idx, (int) (Constants.SCREEN_WIDTH * 0.5f), Constants.BTN_HEIGHT_SCALED, - label, + labelSupplier, onClick, enabledSupplier ); } - public Button(int x, int y, int width, int height, String label, Runnable onClick, Supplier enabledSupplier) { + public Button(int x, int y, int width, int height, Supplier labelSupplier, Runnable onClick, Supplier enabledSupplier) { this.x = x; this.y = y; this.width = width; this.height = height; this.onClick = onClick; - loadImgs(label); this.bounds = new Rectangle(x, y, width, height); + this.labelSupplier = labelSupplier; this.enabledSupplier = enabledSupplier; + updateLabelGraphics(); } - private void loadImgs(String label) { - imgs = new BufferedImage[3]; - - imgs[0] = createBtnImg(label, width, height, Color.DARK_GRAY, Color.WHITE); - imgs[1] = createBtnImg(label, width, height, Color.GRAY, Color.YELLOW); - imgs[2] = createBtnImg(label, width, height, Color.BLACK, Color.RED); + private void updateLabelGraphics() { + String currentLabel = labelSupplier.get(); + if (!currentLabel.equals(lastRenderedLabel)) { + lastRenderedLabel = currentLabel; + imgs = new BufferedImage[3]; + imgs[0] = createBtnImg(currentLabel, width, height, Color.DARK_GRAY, Color.WHITE); + imgs[1] = createBtnImg(currentLabel, width, height, Color.GRAY, Color.YELLOW); + imgs[2] = createBtnImg(currentLabel, width, height, Color.BLACK, Color.RED); + } } private BufferedImage createBtnImg(String label, int width, int height, Color bgColor, Color textColor) { @@ -86,6 +92,7 @@ public void update() { index = 0; if (mouseOver) index = 1; if (mousePressed) index = 2; + updateLabelGraphics(); } public void draw(Graphics g) {