- Notifications
You must be signed in to change notification settings - Fork14
Open
Description
Summary
Tighten gameplay feel and make builds frictionless. This issue bundles small, safe improvements:
- Smooth, frame-rate-independent movement viadelta-time.
- No-stutter SFX withaudio clip pooling.
- Progressivedifficulty curve + spawn scheduler.
- Hitbox tuning + player i-frames after hit.
- Remove local JavaFX SDK path by usingjavafx-maven-plugin.
- AddCI (build + test) andpackaging (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
newAnimationTimer() {privatelonglastNs =0L;@Overridepublicvoidhandle(longnow) {if (lastNs ==0L) {lastNs =now;return; }doubledt =Math.min((now -lastNs) /1_000_000_000.0,0.033);// ~30 ms caplastNs =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/MediaPlayerfor repeated SFX (shoot/hit/power-up). - Volume & rate configurable via constants.
Sketch
classSfxPool {privatefinalList<AudioClip>shots;privateinti =0;SfxPool(URLwavUrl,intsize) {shots =IntStream.range(0,size) .mapToObj(n ->newAudioClip(wavUrl.toString())) .collect(Collectors.toList()); }voidplayShot() {AudioClipc =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
doubledifficulty =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
booleancollides(Nodea,Nodeb) {BoundsA =a.getBoundsInParent();BoundsB =b.getBoundsInParent();doublepad =6;// shrink by 6pxreturnA.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.
- AddPause (P) andMute (M).
6) Build: remove SDK path; add packaging
- Switch to
org.openjfx:javafx-maven-pluginso no local SDK path is needed. - Add
jpackageprofile to produce platform installers. - Embed assets in
src/main/resourcesand load viagetResource.
POM snippet
<plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>com.yourgame.SpaceShooter</mainClass> <launcher>SpaceShooter</launcher> <stripNativeCommands>true</stripNativeCommands> <jlinkZip>true</jlinkZip> <modules> <module>javafx.controls</module> <module>javafx.media</module> </modules> </configuration></plugin>
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:runworkswithout 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.