From ce3dcebbb49c9a5478118829729813190bc89516 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann <10477760+JadedCtrl@users.noreply.github.com> Date: Thu, 1 Jun 2023 23:18:15 -0500 Subject: [PATCH] On screen refresh, only draw changed characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous method — clearing the screen and completely redrawing every frame — caused severe screen-flickering. This is better, calculating the changed characters per-frame and printing only those. --- flora-search-aurora.lisp | 91 ++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 21 deletions(-) diff --git a/flora-search-aurora.lisp b/flora-search-aurora.lisp index 7c59165..0646f8e 100644 --- a/flora-search-aurora.lisp +++ b/flora-search-aurora.lisp @@ -19,12 +19,7 @@ ;; https://jamgaroo.xyz/jams/2 ;; 72x20 -(ql:quickload :cl-tiled) - - -(defun main () - (clear-screen) - (draw-map "/home/jaidyn/.local/src/games/flower/res/map.tmx")) +(ql:quickload '(alexandria cl-tiled str)) (defun move-cursor (row column &key (stream *standard-output*)) @@ -40,24 +35,79 @@ Borrowed from https://github.com/gorozhin/chlorophyll/ (format stream "~C[J" #\Esc)) -(defun draw-map (map-path) - "Draw a Tiled-format tilemap to the screen." - (mapcar #'draw-tile-layer - (cl-tiled:map-layers (cl-tiled:load-map map-path)))) +(defun matrix-delta (a b) + "Given two 2D matrices, return a listcontaining on the cells that change between a→b in the following +format: +only the cells that change between a→b — all others are nil." + (let* ((dimensions (array-dimensions a)) + (delta (make-array dimensions :initial-element nil)) + (max-i (car dimensions)) + (max-j (cadr dimensions)) + (i 0) (j 0)) + (loop + (cond + ((< i max-i) + (cond + ((< j max-j) + (if (not (eq (aref a i j) + (aref b i j))) + (setf (aref delta i j) + (aref b i j))) + (incf j)) + ((eq j max-j) + (setf j 0) + (incf i)))) + ((eq i max-i) + (return)))) + delta)) -(defun draw-tile-layer (tile-layer) - "Draw a Tiled tile-layer to the screen." - (mapcar #'draw-cell - (cl-tiled:layer-cells tile-layer))) +(defun print-screen-matrix (array) + "Given a matrix of characters, print each element to standard output." + (let* ((dimensions (array-dimensions array)) + (max-i (car dimensions)) + (max-j (cadr dimensions)) + (i 0) (j 0)) + (loop + (cond + ((< i max-i) + (cond + ((< j max-j) + (if (characterp (aref array i j)) + (progn + (move-cursor i j) + (write-char (aref array i j)))) + (incf j)) + ((eq j max-j) + (setf j 0) + (incf i)))) + ((eq i max-i) + (return)))))) -(defun draw-cell (cell) - "Draw a specific cell of a tile-layer to the screen." - (move-cursor (+ (cl-tiled:cell-row cell) 1) - (+ (cl-tiled:cell-column cell) 1)) - (write-char (tile-character - (cl-tiled:cell-tile cell)))) +(defun screen-matrix-set-map (array map-path) + "Draw a Tiled-format tilemap to the 2D array." + (mapcar (lambda (layer) (screen-matrix-set-map-layer array layer)) + (cl-tiled:map-layers (cl-tiled:load-map map-path))) + array) + + +(defun screen-matrix-set-map-layer (array tile-layer) + "Set an array's elements to those corresponding the given Tiled +tile-layer's cells. a Tiled tile-layer to the screen." + (mapcar (lambda (cell) (screen-matrix-set-char-cell array cell)) + (cl-tiled:layer-cells tile-layer)) + array) + + +(defun screen-matrix-set-char-cell (array cell) + "Set a 2D array's element corresponding to a Tiled cell's +character-value, using it's column and row." + (setf (aref array + (cl-tiled:cell-row cell) + (cl-tiled:cell-column cell)) + (tile-character + (cl-tiled:cell-tile cell)))) (defun tile-character (tile) @@ -69,5 +119,4 @@ with 15 characters-per-line." (cl-tiled:tile-column tile) 32))) - (main)