Game is playable and editable

This commit is contained in:
Jeremy Penner 2022-04-24 22:45:30 -04:00
parent 370d5ebc7e
commit 760815c865
3 changed files with 85 additions and 6 deletions

56
edtris.txt Normal file
View file

@ -0,0 +1,56 @@
Welcome to Edtris, the Editable Tetris!
This game has a text editor built into it! You are looking at an editor
called "lite", which is written in Lua and has been ported to run inside
the love2d game engine.
Edtris is written in Fennel, which is a language in the Lisp family
that compiles to Lua.
To your right is a file called "state.fnl" - this contains a snapshot of
all of the information that can change while the game is running. This
includes the next piece (represented by the letters O, I, J, L, S, Z, and T),
the current piece and its position in the well, the time left before the
current piece drops down one level, and the current speed of automatic
dropping.
You can edit state.fnl and, with a simple keystroke, make your changes
live in the game! Try the following:
1. Change the line reading
:next-piece "O"
(or instead of "O", whatever letter represents the next piece)
to say
:next-piece "I"
2. Hit Ctrl-S to save the file
3. Hit Alt-R to "reload" the file. If everything is alright, you will see
a message pop up at the bottom of the screen saying "Hotswapping game.state".
If an error message pops up instead, hit Ctrl-Z repeatedly to undo all of
your changes and try again!
4. Hit F1 to go back to the game. Now your next piece will be a long "I"-beam!
At any time, you can press "E" to come back to this editor and try new things.
Feel free to experiment!
* What happens if you make the well bigger?
* What happens if you remove the walls of the well?
* Can you draw a picture in the well?
If you like, you can also run the game and the editor at the same time!
If you press Ctrl-Shift-P, type "game" and press enter, a new tab will
open with the game running inside.
If you're feeling adventurous, you can edit the source code for this game while
it's running, too! That's how I made it! Most of the interesting rules are
defined in game/rules.fnl. You can find this file in the directory tree to the left,
or press Ctrl-P, type "rules.fnl", and press enter to jump right to it.
* Can you add a new piece to the game?
* Can you make the up arrow make the piece levitate upwards, instead of rotating?
This game was made for the Glorious Trainwrecks 15th Anniversary Klik Jam!
https://www.glorioustrainwrecks.com/node/12219
Happy 15th birthday, Glorious Trainwrecks!
-- Jeremy Penner

View file

@ -74,17 +74,16 @@
" #"]]}) " #"]]})
(fn Rules.choose-random-tetromino [] (fn Rules.choose-random-tetromino []
(let [possible-values (icollect [k (pairs state.tetrominoes)] k) (let [possible-values (icollect [k (pairs tetrominoes)] k)
ivalue (love.math.random (length possible-values))] ivalue (love.math.random (length possible-values))]
(. possible-values ivalue))) (. possible-values ivalue)))
(fn Rules.tetromino [k irotation] (fn Rules.tetromino [k irotation]
(let [rotations (or (. state.tetrominoes k) []) (let [rotations (or (. tetrominoes k) [])
irotation (+ (% (- irotation 1) (length rotations)) 1)] irotation (+ (% (- irotation 1) (length rotations)) 1)]
(. rotations irotation))) (. rotations irotation)))
(fn Rules.reset-game [] (fn Rules.reset-game []
(set state.tetrominoes tetrominoes)
(set state.well (map.new-tilemap 12 21)) (set state.well (map.new-tilemap 12 21))
(for [y 0 19] (for [y 0 19]
(map.set-itile-at 0 y state.well "X") (map.set-itile-at 0 y state.well "X")
@ -95,6 +94,7 @@
(Rules.play-next-piece)) (Rules.play-next-piece))
(fn Rules.play-next-piece [] (fn Rules.play-next-piece []
(Rules.clear-lines)
(let [piece (or state.next-piece (Rules.choose-random-tetromino)) (let [piece (or state.next-piece (Rules.choose-random-tetromino))
x (math.floor (/ (- (length (. state.well 1)) 2) 2))] x (math.floor (/ (- (length (. state.well 1)) 2) 2))]
(set state.current {: piece : x :y 0 :irotation 1}) (set state.current {: piece : x :y 0 :irotation 1})
@ -151,10 +151,32 @@
(set state.current.x x) (set state.current.x x)
(set state.current.irotation irotation))))))) (set state.current.irotation irotation)))))))
(fn Rules.clear-lines []
(let [rows (icollect [irow row (ipairs state.well)] (when (not (row:match "^X%#+X$")) row))
first-row (. state.well 1)
empty-row (.. :X (string.rep " " (- (length first-row) 2)) :X)
cleared-rows (math.max 0 (- (length state.well) (length rows)))]
(when (> cleared-rows 0)
(for [i 1 cleared-rows]
(print i cleared-rows (length state.well))
(table.insert rows 1 empty-row))
(set state.well rows))))
(fn Rules.edit-game []
(let [modes (require :editor.lovemode)
core (require :core)
filename "game/state.fnl"
f (io.open filename :w)]
(f:write (fv state))
(f:close)
(modes:cycle)
(core.root_view:open_doc (core.open_doc filename))))
(set Rules.commands (set Rules.commands
{:move Rules.try-move-piece {:move Rules.try-move-piece
:rotate Rules.rotate :rotate Rules.rotate
:reset Rules.reset-game}) :reset Rules.reset-game
:edit Rules.edit-game})
(set Rules.keymap (set Rules.keymap
{:left [:move -1 0] {:left [:move -1 0]
@ -163,7 +185,8 @@
:up [:rotate 1] :up [:rotate 1]
:z [:rotate -1] :z [:rotate -1]
:x [:rotate 1] :x [:rotate 1]
:r [:reset]}) :r [:reset]
:e [:edit]})
(fn Rules.run-command [cmd] (fn Rules.run-command [cmd]
(when cmd (when cmd

View file

@ -41,7 +41,7 @@
tile (tile-at tx ty tilemap tileset) tile (tile-at tx ty tilemap tileset)
xt (+ x (* tx dim.tilesize) (/ dim.tilesize 2)) xt (+ x (* tx dim.tilesize) (/ dim.tilesize 2))
yt (+ y (* ty dim.tilesize) (/ dim.tilesize 2))] yt (+ y (* ty dim.tilesize) (/ dim.tilesize 2))]
(drawtile tile xt yt))))) (when tile (drawtile tile xt yt))))))
(fn world-to-tile [vec] (fn world-to-tile [vec]
(-> vec (-> vec