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) {