hoangsonww / hoangsonww/Space-Invader-Game-JavaFX
Gameplay Polish & Performance: delta-time loop, audio pooling, difficulty curve, CI + packaging
- Dominant language
- Java
- Stars
- 14
- Forks
- 6
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
Tighten gameplay feel and make builds frictionless. This issue bundles small, safe improvements:
* Smooth, frame-rate-independent movement via **delta-time**.
* No-stutter SFX with **audio clip pooling**.
* Progressive **difficulty curve** + spawn scheduler.
* **Hitbox tuning** + player i-frames after hit.
* Remove local JavaFX SDK path by using **javafx-maven-plugin**.
* Add **CI** (build + test) and **packaging** (jpackage) for one-click runs.
---
## Scope & Tasks
### 1) Frame-rate independence
* [ ] Replace fixed per-frame movement with delta time in `AnimationTimer`.
* [ ] Cap `dt` (e.g., 0.033s) to avoid tunneling after GC pauses.
**Sketch**
```java
new AnimationTimer() {
private long lastNs = 0L;
@Override public void handle(long now) {
if (lastNs == 0L) { lastNs = now; return; }
double dt = Math.min((now - lastNs) / 1_000_000_000.0, 0.033); // ~30 ms cap
lastNs = now;
player.update(dt);
enemies.forEach(e -> e.update(dt));
bullets.forEach(b -> b.update(dt));
physics.update(dt);
ui.render();
}
}.start();
```
### 2) Audio stutter fix (pooling)
* [ ] Pool `AudioClip`/`MediaPlayer` for repeated SFX (shoot/hit/power-up).
* [ ] Volume & rate configurable via constants.
**Sketch**
```java
class SfxPool {
private final List shots;
private int i = 0;
SfxPool(URL wavUrl, int size) {
shots = IntStream.range(0, size)
.mapToObj(n -> new AudioClip(wavUrl.toString()))
.collect(Collectors.toList());
}
void playShot() {
AudioClip c = shots.get(i++ % shots.size());
c.stop(); c.play();
}
}
```
### 3) Difficulty curve & spawns
* [ ] Spawn rate & enemy speed scale with score/time.
* [ ] Boss every N points with telegraphed warning.
* [ ] Power-up weighting increases when player is low on lives.
**Sketch**
```java
double difficulty = 1.0 + (score / 250.0) + elapsedMinutes * 0.25;
spawner.setSpawnIntervalSeconds(Math.max(0.25, 1.5 / difficulty));
enemyBaseSpeed = 120 * difficulty;
```
### 4) Hitboxes & i-frames
* [ ] Slightly shrink collision bounds (feel > math).
* [ ] Add 1.0s invulnerability after hit (blink sprite).
**Sketch**
```java
boolean collides(Node a, Node b) {
Bounds A = a.getBoundsInParent(); Bounds B = b.getBoundsInParent();
double pad = 6; // shrink by 6px
return A.getMaxX()-pad > B.getMinX()+pad &&
A.getMinX()+pad < B.getMaxX()-pad &&
A.getMaxY()-pad > B.getMinY()+pad &&
A.getMinY()+pad < B.getMaxY()-pad;
}
```
### 5) Input polish
* [ ] Key repeat & “diagonal feels right”: normalize vector, clamp speed.
* [ ] Add **Pause (P)** and **Mute (M)**.
### 6) Build: remove SDK path; add packaging
* [ ] Switch to `org.openjfx:javafx-maven-plugin` so no local SDK path is needed.
* [ ] Add `jpackage` profile to produce platform installers.
* [ ] Embed assets in `src/main/resources` and load via `getResource`.
**POM snippet**
```xml
org.openjfx
javafx-maven-plugin
0.0.8
com.yourgame.SpaceShooter
SpaceShooter
true
true
javafx.controls
javafx.media
```
### 7) CI & Tests
* [ ] GitHub Actions: `mvn -B -ntp -DskipTests=false verify`.
* [ ] Headless smoke tests (logic only; no Stage) for spawn math & collisions.
* [ ] Optional: TestFX stage tests behind `-Dtestfx.headless=true`.
---
## Acceptance Criteria
* ✅ Player speed & projectile speed are consistent at 60fps and 120fps (simulate by throttling) with <5% variance.
* ✅ No audible stutter on rapid fire (≥8 shots/sec).
* ✅ Spawn rate & enemy speed visibly scale with score/time; boss appears on schedule.
* ✅ Post-hit i-frames prevent immediate double damage; player sprite blinks.
* ✅ `mvn javafx:run` works **without** editing a local JavaFX SDK path.
* ✅ CI workflow passes on Ubuntu runner; a packaged artifact is produced via `mvn -Ppackage`.
---
## Nice-to-have (future)
* Quadtree for broad-phase collision when entities > 400.
* Screen-space shaders (flash on boss entry).
* Save best score (Preferences API) + simple settings modal.
---
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.