Split off STATE-LOOP into an engine package (⚙)
… while making generic state-function-creators for both dialogues and overworld maps. This should make game-specific code more pretty-like!
This commit is contained in:
parent
e21d16069b
commit
4d4b65da9c
|
@ -20,7 +20,7 @@
|
||||||
(defpackage :flora-search-aurora.dialogue
|
(defpackage :flora-search-aurora.dialogue
|
||||||
(:nicknames :fsa.dia :dialogue :💬)
|
(:nicknames :fsa.dia :dialogue :💬)
|
||||||
(:use :cl)
|
(:use :cl)
|
||||||
(:export #:dialogue-state
|
(:export #:dialogue-state #:make-dialogue-state
|
||||||
#:start-dialogue #:face #:say #:mumble #:move
|
#:start-dialogue #:face #:say #:mumble #:move
|
||||||
:normal-face :talking-face))
|
:normal-face :talking-face))
|
||||||
|
|
||||||
|
@ -330,5 +330,12 @@ A state-function for use with STATE-LOOP."
|
||||||
(dialogue-state-update map dialogue))
|
(dialogue-state-update map dialogue))
|
||||||
|
|
||||||
|
|
||||||
|
(defun make-dialogue-state (map dialogue-list)
|
||||||
|
"Return a state-function for a section of dialogue, for use with STATE-LOOP."
|
||||||
|
(lambda (matrix &key (map map) (dialogue dialogue-list))
|
||||||
|
(🌍:overworld-state-draw matrix map)
|
||||||
|
(dialogue-state matrix :map map :dialogue dialogue-list)))
|
||||||
|
|
||||||
|
|
||||||
;; Split a banana in two, bisection-fruit,
|
;; Split a banana in two, bisection-fruit,
|
||||||
;; Yummy-yummy, toot-toot~ 🎵
|
;; Yummy-yummy, toot-toot~ 🎵
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
;;;; Copyright © 2023, Jaidyn Ann <jadedctrl@posteo.at>
|
||||||
|
;;;;
|
||||||
|
;;;; This program is free software: you can redistribute it and/or
|
||||||
|
;;;; modify it under the terms of the GNU General Public License as
|
||||||
|
;;;; published by the Free Software Foundation, either version 3 of
|
||||||
|
;;;; the License, or (at your option) any later version.
|
||||||
|
;;;;
|
||||||
|
;;;; This program is distributed in the hope that it will be useful,
|
||||||
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;;;; GNU General Public License for more details.
|
||||||
|
;;;;
|
||||||
|
;;;; You should have received a copy of the GNU General Public License
|
||||||
|
;;;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;;; FLORA-SEARCH-AURORA.ENGINE
|
||||||
|
;;;; The core of the game’s engine, the loop. Not much to see here other
|
||||||
|
;;;; than a loop. Honest!
|
||||||
|
|
||||||
|
|
||||||
|
(defpackage :flora-search-aurora.engine
|
||||||
|
(:nicknames :fsa.eng :engine :⚙)
|
||||||
|
(:export #:state-loop #:main)
|
||||||
|
(:use :cl))
|
||||||
|
|
||||||
|
(in-package :flora-search-aurora.engine)
|
||||||
|
|
||||||
|
|
||||||
|
(defun state-loop
|
||||||
|
(states &key (last-matrix (✎:make-screen-matrix)) (matrix (✎:make-screen-matrix)) (state-params nil))
|
||||||
|
"Begin the game’s loop, which executes (henceforthly called) state-functions over and over again
|
||||||
|
until Hell freezes over and a new king reigns supreme.
|
||||||
|
Given a list of state-functions, STATES, it will execute the first function.
|
||||||
|
Each state-function must take at least a single parameter, a matrix of characters. A state-function
|
||||||
|
should edit this matrix in-place, replacing its elements with characters that will later be printed
|
||||||
|
to the terminal.
|
||||||
|
What the state-function returns is pretty important, having different repercussions:
|
||||||
|
* NIL — The function is removed from STATES, and so the next function in STATES will start
|
||||||
|
getting executed instead.
|
||||||
|
* NIL; List — The function is popped off STATES and the list is used as the new parameters for
|
||||||
|
the next function in STATES.
|
||||||
|
* Function — The function is pushed to the front of STATES, and so is executed instead of the
|
||||||
|
current function.
|
||||||
|
* List — The current function (front of STATES) continues to be executed with the given
|
||||||
|
list as a parameters list.
|
||||||
|
Make note to add a delay w SLEEP to your state functions, or… well, y’know. Your computer will
|
||||||
|
overheat, or something ¯\_(ツ)_/¯"
|
||||||
|
(when states
|
||||||
|
(multiple-value-bind (state-result new-state-params)
|
||||||
|
(apply (car states) (cons matrix state-params)) ;; Run the latest-added update/draw loop
|
||||||
|
(✎:print-screen-matrix (✎:matrix-delta last-matrix matrix)) ;; Print its results.
|
||||||
|
(force-output)
|
||||||
|
(state-loop
|
||||||
|
(cond ((functionp state-result)
|
||||||
|
(cons state-result states))
|
||||||
|
((not state-result)
|
||||||
|
(cdr states))
|
||||||
|
('t states))
|
||||||
|
:last-matrix matrix
|
||||||
|
:state-params
|
||||||
|
(cond ((not state-result)
|
||||||
|
new-state-params)
|
||||||
|
((listp state-result)
|
||||||
|
state-result))))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun main (states)
|
||||||
|
"A toplevel-worthy function that configures rendering and kicks off the
|
||||||
|
game’s loop. Let’s get started!"
|
||||||
|
(cl-charms:with-curses ()
|
||||||
|
(cl-charms:enable-raw-input :interpret-control-characters 't)
|
||||||
|
(✎:hide-cursor)
|
||||||
|
(✎:clear-screen)
|
||||||
|
(state-loop states)))
|
|
@ -27,6 +27,7 @@
|
||||||
(load "overworld.tiled.lisp")
|
(load "overworld.tiled.lisp")
|
||||||
(load "overworld.lisp")
|
(load "overworld.lisp")
|
||||||
(load "dialogue.lisp")
|
(load "dialogue.lisp")
|
||||||
|
(load "engine.lisp")
|
||||||
|
|
||||||
(defpackage :flora-search-aurora
|
(defpackage :flora-search-aurora
|
||||||
(:nicknames :fsa :✿)
|
(:nicknames :fsa :✿)
|
||||||
|
@ -39,72 +40,19 @@
|
||||||
(in-package :flora-search-aurora)
|
(in-package :flora-search-aurora)
|
||||||
|
|
||||||
|
|
||||||
(defun literary-girl-dialogue-2 (map)
|
(defparameter *literary-girl-dialogue*
|
||||||
(print "OWO"))
|
(💬:start-dialogue
|
||||||
|
(💬:mumble "literary-girl" :en "...")
|
||||||
|
(💬:say "player" :eo "Kielas apud la mar'?"
|
||||||
|
:en "How's the view?")
|
||||||
|
(💬:face "player" "<.<")
|
||||||
|
(💬:say "literary-girl" :eo "Kielas apud la ruinoj de via viv'?"
|
||||||
|
:en "How's your trainwreck of a life?")
|
||||||
|
(💬:face "player" '💬:normal-face)))
|
||||||
|
|
||||||
|
|
||||||
(defun literary-girl-dialogue (map)
|
(defun literary-girl-dialogue (map)
|
||||||
(let
|
(make-dialogue-state map *literary-girl-dialogue*))
|
||||||
((dialogue
|
|
||||||
(💬:start-dialogue
|
|
||||||
(💬:mumble "literary-girl" :en "...")
|
|
||||||
(💬:say "player" :eo "Kielas apud la mar'?"
|
|
||||||
:en "How's the view?")
|
|
||||||
(💬:face "player" "<.<")
|
|
||||||
(💬:say "literary-girl" :eo "Kielas apud la ruinoj de via viv'?"
|
|
||||||
:en "How's your trainwreck of a life?")
|
|
||||||
(💬:face "player" '💬:normal-face))))
|
|
||||||
(lambda (matrix &key (map map) (dialogue dialogue))
|
|
||||||
(🌍:overworld-state-draw matrix map)
|
|
||||||
(💬:dialogue-state matrix :map map :dialogue dialogue))))
|
|
||||||
|
|
||||||
|
|
||||||
(defun state-loop
|
|
||||||
(states &key (last-matrix (make-screen-matrix)) (matrix (make-screen-matrix)) (state-params nil))
|
|
||||||
"Begin the game’s loop, which executes (henceforthly called) state-functions over and over again
|
|
||||||
until Hell freezes over and a new king reigns supreme.
|
|
||||||
Given a list of state-functions, STATES, it will execute the first function.
|
|
||||||
Each state-function must take at least a single parameter, a matrix of characters. A state-function
|
|
||||||
should edit this matrix in-place, replacing its elements with characters that will later be printed
|
|
||||||
to the terminal.
|
|
||||||
What the state-function returns is pretty important, having different repercussions:
|
|
||||||
* NIL — The function is removed from STATES, and so the next function in STATES will start
|
|
||||||
getting executed instead.
|
|
||||||
* NIL; List — The function is popped off STATES and the list is used as the new parameters for
|
|
||||||
the next function in STATES.
|
|
||||||
* Function — The function is pushed to the front of STATES, and so is executed instead of the
|
|
||||||
current function.
|
|
||||||
* List — The current function (front of STATES) continues to be executed with the given
|
|
||||||
list as a parameters list.
|
|
||||||
Make note to add a delay w SLEEP to your state functions, or… well, y’know. Your computer will
|
|
||||||
overheat, or something ¯\_(ツ)_/¯"
|
|
||||||
(when states
|
|
||||||
(multiple-value-bind (state-result new-state-params)
|
|
||||||
(apply (car states) (cons matrix state-params)) ;; Run the latest-added update/draw loop
|
|
||||||
(✎:print-screen-matrix (✎:matrix-delta last-matrix matrix)) ;; Print its results.
|
|
||||||
(force-output)
|
|
||||||
(state-loop
|
|
||||||
(cond ((functionp state-result)
|
|
||||||
(cons state-result states))
|
|
||||||
((not state-result)
|
|
||||||
(cdr states))
|
|
||||||
('t states))
|
|
||||||
:last-matrix matrix
|
|
||||||
:state-params
|
|
||||||
(cond ((not state-result)
|
|
||||||
new-state-params)
|
|
||||||
((listp state-result)
|
|
||||||
state-result))))))
|
|
||||||
|
|
||||||
|
|
||||||
(defun make-main-overworld-state ()
|
|
||||||
"Return a state-function for the game’s overworld (the majority of the game), for use
|
|
||||||
with STATE-LOOP."
|
|
||||||
(lambda (matrix &rest args)
|
|
||||||
(apply #'🌍:overworld-state
|
|
||||||
(append (list matrix)
|
|
||||||
'(:map-path #p"/home/jaidyn/.local/src/games/flora search aurora/res/map.tmx")
|
|
||||||
args))))
|
|
||||||
|
|
||||||
|
|
||||||
(defparameter *submenu* `(((LABEL :en "IDK") (selection . 100) (selected t))
|
(defparameter *submenu* `(((LABEL :en "IDK") (selection . 100) (selected t))
|
||||||
|
@ -113,7 +61,8 @@ with STATE-LOOP."
|
||||||
|
|
||||||
(defparameter *main-menu* `(((LABEL :en "PLAY" :eo "EKLUDI")
|
(defparameter *main-menu* `(((LABEL :en "PLAY" :eo "EKLUDI")
|
||||||
(selection . 100) (selected . t)
|
(selection . 100) (selected . t)
|
||||||
(return . ,(make-main-overworld-state)))
|
(return . ,(🌍:make-overworld-state
|
||||||
|
(format nil "~Ares/map.tmx" (uiop:getcwd)))))
|
||||||
((LABEL :en "SUBMENU" :eo "SUBMENUO")
|
((LABEL :en "SUBMENU" :eo "SUBMENUO")
|
||||||
(return . ,(📋:make-menu-state *submenu*)))
|
(return . ,(📋:make-menu-state *submenu*)))
|
||||||
((LABEL :en "QUIT" :eo "REZIGNI")
|
((LABEL :en "QUIT" :eo "REZIGNI")
|
||||||
|
@ -121,12 +70,10 @@ with STATE-LOOP."
|
||||||
|
|
||||||
|
|
||||||
(defun main ()
|
(defun main ()
|
||||||
"A pathetic fascimile of a main loop. What does it do? WHAST DOES TI DODOO?"
|
"A pathetic fascimile of a main loop. What does it do? WHAST DOES TI DODOO?
|
||||||
(cl-charms:with-curses ()
|
What a mysteryyy! You’ll have to check out the engine to uncover it.
|
||||||
(cl-charms:enable-raw-input :interpret-control-characters 't)
|
engine.lisp, that is. Cheers! :D"
|
||||||
(✎:hide-cursor)
|
(⚙:main (list (📋:make-menu-state *main-menu*))))
|
||||||
(✎:clear-screen)
|
|
||||||
(state-loop (list (📋:make-menu-state *main-menu*)))))
|
|
||||||
|
|
||||||
|
|
||||||
(main) ;; — Knock-knock
|
(main) ;; — Knock-knock
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
(:nicknames :fsa.o :overworld :🌍)
|
(:nicknames :fsa.o :overworld :🌍)
|
||||||
(:use :cl
|
(:use :cl
|
||||||
:flora-search-aurora.overworld.tiled :flora-search-aurora.overworld.util)
|
:flora-search-aurora.overworld.tiled :flora-search-aurora.overworld.util)
|
||||||
(:export #:overworld-state #:overworld-state-draw
|
(:export #:overworld-state #:make-overworld-state #:overworld-state-draw
|
||||||
#:world-coords->screen-coords
|
#:world-coords->screen-coords
|
||||||
#:getf-entity #:getf-entity-data
|
#:getf-entity #:getf-entity-data
|
||||||
#:move-entity-to #:move-entity
|
#:move-entity-to #:move-entity
|
||||||
|
@ -250,3 +250,11 @@ A state-function for use with STATE-LOOP."
|
||||||
(sleep .02)
|
(sleep .02)
|
||||||
(overworld-state-draw matrix map)
|
(overworld-state-draw matrix map)
|
||||||
(overworld-state-update map))
|
(overworld-state-update map))
|
||||||
|
|
||||||
|
|
||||||
|
(defun make-overworld-state (map-path)
|
||||||
|
"Return a state-function for a a map, for use with STATE-LOOP."
|
||||||
|
(lambda (matrix &rest args)
|
||||||
|
(apply #'🌍:overworld-state
|
||||||
|
(append (list matrix :map-path map-path)
|
||||||
|
args))))
|
||||||
|
|
Ŝarĝante…
Reference in New Issue