(module world * (import scheme (chicken base) (only srfi-1 fold filter) defstruct tilemap entity) ;; Scene = current level: tilemap (layers, objects) + list of entities. ;; Returns tile-id if the cell at (col, row) in this layer is non-zero, #f otherwise. (define (layer-tile-at layer col row) (let ((rows (layer-map layer))) (and (< row (length rows)) (let ((row-data (list-ref rows row))) (and (< col (length row-data)) (let ((tile-id (list-ref row-data col))) (and (not (zero? tile-id)) tile-id))))))) (define (tilemap-tile-at tilemap col row) "Get the tile ID at grid position (col, row). Returns 0 if out of bounds or if all layers have 0 at that cell." (let ((width (tilemap-width tilemap)) (height (tilemap-height tilemap))) (if (or (< col 0) (>= col width) (< row 0) (>= row height)) 0 (let loop ((layers (tilemap-layers tilemap))) (if (null? layers) 0 (or (layer-tile-at (car layers) col row) (loop (cdr layers)))))))) (defstruct camera x y) (defstruct scene entities tilemap camera tileset-texture) (define (scene-add-entity scene entity) (scene-entities-set! scene (append (scene-entities scene) (list entity))) scene) (define (scene-update-entities scene . procs) "Apply each proc in sequence to the scene's entities; each proc maps over all entities. The scene's entity list is replaced once with the final result." (scene-entities-set! scene (fold (lambda (proc es) (map proc es)) (scene-entities scene) procs)) scene) (define (scene-filter-entities scene pred) "Remove all entities from scene that do not satisfy pred." (scene-entities-set! scene (filter pred (scene-entities scene))) scene) )