diff --git a/game.js b/game.js
index 49f2da6..47780a6 100644
--- a/game.js
+++ b/game.js
@@ -67,6 +67,7 @@ window.addEventListener("load", async () => {
getContext: (elem, type) => elem.getContext(type),
setGlobalAlpha: (ctx, alpha) => ctx.globalAlpha = alpha,
setFillColor: (ctx, color) => ctx.fillStyle = color,
+ setStrokeColor: (ctx, color) => ctx.strokeStyle = color,
setFont: (ctx, font) => ctx.font = font,
setTextAlign: (ctx, align) => ctx.textAlign = align,
clearRect: (ctx, x, y, w, h) => ctx.clearRect(x, y, w, h),
diff --git a/game.scm b/game.scm
index 1fbaba7..493aa18 100644
--- a/game.scm
+++ b/game.scm
@@ -61,7 +61,8 @@
(local-storage)
(math)
(math rect)
- (math vector))
+ (math vector)
+ (scheme base))
(define game-width 320.0)
(define game-height 240.0)
@@ -105,7 +106,20 @@
(define audio:bg-music (load-music "cirkoban"))
;; Game state
-(define *state* #f)
+(define *state* '(initial))
+
+(define (push-game-state! state)
+ (set! *state* (cons state *state*)))
+(define (pop-game-state!)
+ (when (pair? *state*)
+ (set! *state* (cdr *state*))))
+(define (replace-game-state! state)
+ (match *state*
+ ((_ . rest)
+ (set! *state* (cons state rest)))))
+(define (current-game-state)
+ (match *state*
+ ((state . _) state)))
(define *actormap* (make-whactormap))
(define (call-with-goblins thunk)
@@ -132,6 +146,8 @@
load-catboss-2
load-catboss-3))
(define *level-idx* #f)
+;; Last level for restoring after visiting credits via the menu
+(define *level-last* #f)
(define *gems* #f)
(define *level* #f)
;; Latest representation of all actors in level
@@ -201,8 +217,8 @@
(define (collected-gem? idx)
(memq idx *gems*))
-(define (load-level! idx)
- (set! *state* 'play)
+(define (set-level! idx)
+ (replace-game-state! 'play)
(set! *actormap* (make-whactormap))
(clear-snapshots!)
(with-goblins
@@ -210,7 +226,7 @@
(update-objects!)))
(define (load-credits!)
- (set! *state* 'win)
+ (replace-game-state! 'credits)
(set! *actormap* (make-whactormap))
(set-vec2-y! *credits-scroll* 0.0)
(clear-snapshots!)
@@ -218,8 +234,7 @@
(set! *level* (load-credits #f))
(update-objects!)))
-(define (next-level!)
- (let ((idx (+ *level-idx* 1)))
+(define (load-level! idx)
;; TODO: Maybe show a little achievement popup when all gems
;; are collected?
(when (with-goblins ($ (level-actor *level*) 'gem-collected?))
@@ -228,17 +243,17 @@
(begin
(run-script
(lambda ()
- (set! *state* 'interstitial)
+ (replace-game-state! 'interstitial)
(yield
(lambda (k)
(show-effect! (make-fade-out+in-effect 1.0 k))))
(set! *level-idx* idx)
(save-game!)
- (load-level! idx))))
+ (set-level! idx))))
(begin
(run-script
(lambda ()
- (set! *state* 'interstitial)
+ (replace-game-state! 'interstitial)
(yield
(lambda (k)
(show-effect! (make-fade-out+in-effect 2.0 k))))
@@ -248,7 +263,10 @@
;; text from showing up when resetting the game, set
;; level idx to non-zero during the credits.
(set! *level-idx* -1)
- (load-credits!)))))))
+ (load-credits!))))))
+
+(define (next-level!)
+ (load-level! (+ *level-idx* 1)))
;; Auto-save/load to local storage.
(define (save-game!)
@@ -266,18 +284,127 @@
((idx gems)
(set! *level-idx* idx)
(set! *gems* gems)
- (load-level! *level-idx*)
+ (set-level! *level-idx*)
(media-play audio:bg-music)))))
+;; Menu types
+
+(define-record-type