Skip to content

Instantly share code, notes, and snippets.

@AlecTroemel
Created Jun 13, 2021
Embed
What would you like to do?
GMTK Jam 2021
 D @ D @D DD @D DD DD À Ì Ì À ÀÌ ÌÌ ÌÌ ÀÌ D @ D  @ D D @D D @D D @D DD @D ÌÌ ÌÌ ÌÌ ÌÌ ÌÌ ÀÌ Ì À @ @D D @ @ D @ D DD DD D @D D @ D @ Ì À À Ì À Ì À Ì @D @D @ D @    D ÀÌÌ ÌÌ"Ì"" " À Ì ÀÌ ÌÌ Ì ÀÌÌÀÌ,"Ì, Ì ,  ÀÌ À, Ì , À À À À À À, Ì Ì À, À À "" "" """ " """ """ " "" """""""""""""""" " "" """""""""""" ```f`\efÀUffPeffPfff`fff`fff f`ffffffffffffffffff ```f`fff`fff`ffÆ`ffÌ`fÆ\`fÌU f`ÆUf\Uf\efUffefffff ```f`fff`fff`fff`fff`fff`fff f`ffffffffffffffffff  "" !" " !  " " "   """""" !"" "" !" " ! """ "" "" " "   !"""""" !"" "" !" " ! """"" "" " "   `fffpfff fff fff gff pff wf wfffffffff fff ffv ff fw w `Æ\epÌUf Uef Uff gff pff wf wfffffffff fff ffv ff fw w `fffpfff fff fff gff pff wV wffÆffUfVU fUe ÆUv \e Uw w UUUÌUUÅ UUÅÀUUÅÀUUÅÀUUÅÀUÌÌÀÅ ÀÌUUU \UU \UU \UU \UU \UU ÌÌU \ " "" "!"""" !"  " "" "" !   @ @ D@ D@@D@@D@@D@   D D D@D@D@ ```f`ffv`fv`v ` ` `  f`gffpgf pg ` ` ` ÿ ÿÿ ÿÿ ðÿ ÿ ÿ  ÿ  ÿÿÿÿÿÿÿÿ ÿÿÿ ÿÿÿÿ ÿ ÿ ÿÿ ÿÿ ÿ ðÿ ÿ ÿ ÌÌÌ ÌÌÌÅÀÌÌU ÌÌUÅÀÌUU ÌUUÅ UUUÌÌÌÌÀÌÌÌÀÌÌ \ÌÌÀUÌ \UÌÀUU \UUÌUUU! " ! " ! " !  "  "  "   @D@@D@0D@ D@ 3@ @ 0 D@D@D0D 3   ` pf f f gf pff wf w ` f f f fv ff fw w ÿ ð ÿ ðÿ ÿÿ ÿÿ ÿ ÿ ðÿÿ ÿÿÿÿ ÿÿÿ  ÿÿÿÿÿÿÿÿ ÿ ðÿ ÿ ÿÿ ÿÿ ÿ "    " ! " !    "   DD D3 @4 @ @ D @@4 0@ DDD 33D @4 D @4 DDD33C D  ™ ™™‰ ™ˆ ‰ ™ ‰™ ™ ˜™™ ˆ™ ˜ ™  ˜  € €™  ÿðððÿ îïÝÍîîÝÜ ÌÌÌÜÌÌÌÌ ÝÝîîÝîíî ð ÿÿð "" !    "" !  "" !    "" !  @DD033 @ 4 @@ 4 D@DD4033 @4 D @4 D 4  ™  ˜  € €™ ˆ ™ ™™ ˆˆ™ ˆ ™ ‰™ˆ  ™ ™™ ™ˆˆ ˆ ÿððÿ ÿÞÍÌîîÝÌ ÜÜîïÌÝîþ ÿ  ÿîÝðïïÍ ÌíÿÌÝþ ÀÀ ÀÌÀÌÌìÀÌìÀì À À À Ì À ÎÌÌ àÎÌ àÎ À À À ÌÌÌ Ìîî Î àÌ Î àÌ Î ÌÌÌ îîÌ Àì Ì Àì Ì ì ÀÌ ÌÌ ÀìÎÌÌ ÀÌ Ì Àì ÌÀ ì ÌÀì Ì Àì ÌÜÜîÌÜííÌ Ü Ý í î ï þþÿðð ðððïÿï îÍÍÌÞÞÍÌ Ì Í Ý Þ î þ ð  ÿ þ ï î Ý Ü À àÌ Ì Ì ÎÌ àÌÌ îÌ î À Ì Ì Ì Ìì ÌÌ Ìî î À Ì Àì Ì Àì Ì ÌÌÌ îîî Ì Î àÌ Î àÌ ÌÌÌ îîî àÌì ÎÌÀ ÌÌÌÀ ÌÌÌÀìÌ ÌÎÌì àî Ì ì  Ì Ì î ÿ ÿ ð  ð ÿ ÿ  ð  Ì Ì Ý í þ ÿ ð ð  ð ÿ ÿ  ð  ÿ ÿ  ÿ ï Þ Ý Ì Ì ï î í Ý Ü Ì ÌÜííÌÜÜî þÿððþ ÿïðððï þ î Þ Ý Í ÌÞÞÍÌîÍÍÌÍ Ý î þ ï ÿ ð ‘ UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUEDTUUEDUU5DUU5DUU5DUUCDUUDDUEDDUUUUTUUÅDUÌ @ÌÌÀ@UÌ DUUÅ TUE @U5\UUUÌUUU ÌUUÌÀÌ\ ÌUUÌUUULUUU@UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUwU%"r""""UUUUUUUUfUUUwVUUuWUUfwwUww'"""""UUUUUUUUUUUUUUUUUUUUUUUURUUU"UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUU3UUUUUUUUUUUUUUUUUUUUUCDD3DDD33DD3333UE UE UE U•  T5DDD%DDD$33S5 @UE @UE TU5 UUE@UUU@UUU@UUU@UUU@UUU@UUU@UUU@UUUUUU%UUU"UU%ÂUU%ÂUU%"UU""UU""UU""ÂÌ""ÌÌ"",""Ì,""Ì"""""""Â"""""""""""""""""Ì"""Ì""""""Â""",""""""""RUU"RUU""RU""RU""RU""U""U""UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU©ªª•ªª©•ªªª•ªªš•ªªª•ªªª•ªªª•©ªªªYUEªYUEªYUIªš™ ©ªª
š™™ ªZ•IªªUE@UUU@UUU@TUU TUU TUU TUU@TUU UUUUU""UU""UU%"UU%"UU%"UUU"UUU"UUU%""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""U""U""QU""QU"QU"QU"UUUUUUUUUUUUUUUUUUU%UUU"UU%"UU%"UU%"UU%"%"""""""""""""""ÂÂ""",""ÂÂ"""UUU"""U""Ì"""ÌÌ"""Ì""""""""""""UUUUUUUUUUUU"UUU"UUU"RUU"RUU""UU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU•©ªª•©ªª•©ªª™ªªª™ªªª™™™™U™™™UUUUªªUEªªZEªªZEªªZEªªª5©ªª5™UU%UUU50UUU@UUU@UUU0UUU@UUU@UUU UUU#UUUUUU%UUUUUUUUUUUUUUUUUUUUUUUUUUUU""""""""%"""U"UU"UUU!UU""UU""U"""""QUU%RUU%QUU%"UU%"QUUUUUQUUUUUUUUUUUUUUURUUURUUUUU'"UU'"UU"Uf"ev"uwvWwUU""""""""""""""""""""""""!""""""""""""""""""""""""""""UU""UU""UU"UU"U"U"" UUUUUUUUUUUUUUUUUUffUUffUUfwUUf UUUUUUUUUUUUUUUUffffffffwwww wpUUUUUUUUUUUUUUUUffffffffwwww pwUUUUUUUUUUUUUUUUffUUffUUwfUU fUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUfpUUfpUUf UUfpUUfpUUf UUfpUUfp pçí ÎÌÍÀ
ÞÜ çí pw w wwÞ àÌìw× ÜwçÍí Þww wwp pfUUpfUU fUUpfUUpfUU fUUpfUUpfUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUf UUfpUUfpUUf UUfpUUfpUUf UUfp wp pw wp pw wp p pww wwp pww wwp pww w fUUpfUUpfUU fUUpfUUpfUU fUUpfUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUÅÌUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUffUUffUUwwUUUUUUUfUUUfUUUfUUUUffffffffwwwwfUUUgUUUfUUUfUUUUUUUffffffffwwwwUUUfUUUvUUUfUUUfUUUUffUUffUUwwUUUUUUfUUUfUUUfUUUUUUUUUUUUfffUfffUfw UfwpUf pUfw UfffÌÌ\Uffffffff wp pw wpffffUUUUffffffff pgw gwp` pgffffUUUUVUUUVUUUVefVVefVVUfVffgVvwwW UUUUUUUUUUUUUUUUUUUUU©ZUU©©UU©ZUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU¥UUUšUUUUUUUUUUUUUUUUU¥UU¥ššUš šU šUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU U© ©U©ÀU© U©À U© U©  U© ªU© ZUUUUZUUU©UUU ZU¥ªUUªZU¥ªUUªšU¥ª UUUªUUU¥UUUUZUUUªUUUªZUU©ªUUªZU šU
šUª šU¥ªZUUªYUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU U©ªUU¥ZUUUUUUUU¥UUUªUU¥ªUUªšU¥ª UªšÞ¥ªéͪšÞ̪ Í š Í ÞÌ àÍ Þí©ªUÜžªZÌí©ªÀܐªÀÜ ©Ìí Ü í UUUUUUUUUUUUZUUUªUUUªZUU©ªUUªZUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU U¥ªªU¥ªªU•™™UUUUUUUUUUUUUUUUUUUUªªªªªªªª™™™™UUªUUUªUUU©UUªªUUªªUªªªªªªªª™™™™UªUUUªUUUšUUUªZUUªZUªªZUªªZU™™YUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUµUUUµU¥ªºU¥ªªU•™©UUUUUUUÌUUÌ [ÅÌÌ[ÌÌÌ«ªªªªªªªš™™™UUUUÌUUUÀÌUUÌÌ\µÌÌ̵ª¬ªºÊ̪ªÉÌ™©UUUUUUUUUUUU[UUU[UUU«ªZUªªZUš™YU ÀÌ ÌÌ ÌÌ ÈÌ €ÌÌ ÌÌ ÈÌ ÀÌ ÀÌ ÀÌ ÌÌ ÌŒ ÀÌ Ì Ì ÌÌ ÈÌ ÀÌ Ì À Ì ÀÀÌ ÀÀÌ À€Ì Ì ˆ Ì ÀÌ Ì  ÌÌÌ Ì ÌÌÌ À À Ì Ì Ì Ì Ì Ì Ì ÌÌ ÌÌÌ ÌÌ ÀÌÌ À̈ ÌŒ Ì Ì Ì Ì ÌÌÌ ÌÌÌ ˆˆˆ Ì À Ì Ì Ì Ì Ì Ì Ì Ì Ì €Ì ÌÌ ÈÌ ÀÌ €Ì Ì È À ÀÌ ÌÌ ÌŒ ÌÌ ÌÌ ÌÌ ÌŒ Ì €Ì ÌÌ ÈÌ ÈÌÌ €ÌÌ ÌÌ ÈÌ ÀÌÀÌÌÌÌ ÌÌŒ ÌÌ ÌÌ ÌÌ ÌŒ Ì Ì ÌÌÌ ˆˆÌ ÀŒ Ì Ì ÀŒ ÌÌÌ ÌÌÌÀÌÌÌÀŒ ÌÀ ÌÀ ÌÀ ÌÀ ÌÀÌÌÌ€ÌÌÌÀÌÌÌÀ̈ÌÀŒ ˆÀ À À À À À̈ÌÀŒ ÌÀ ÌÀ ÌÀ ÌÀÌ ÌÀÌÌÌ€ÌÌÌ Ì Ì Ì Ì Ì Ì Ì ÀÌ ÌÌÌ ÌÌÌ ˆˆÌ È È È Ì ÌÀÌ ÌÌÌ ÌŒÈ Ì€Ì Ì Ì Ì ÀÌÌ ÌÌÌ ÌˆÈ Ì À Ì À Ì À Ì À ÌÌÌ ÌÌÌ ÌÌÌ ÌˆÈ Ì À Ì À Ì À Ì À ÌÌÌ ÌÌÌ ÌÌÌÌÌŒÈÌÌ€ÌÌ ÌÌ ÌÌ ÌÌ Ì € ˆ €ˆ  ˆ ÌÌÌÌ ˆˆˆ ÌÌÌÌ ˆˆˆ ÌÌÌÌÿÿÿÿ€ ÌÌÌÌÿÿÿÿ ˆˆˆ ÌÌÌÌÿÿÿÿ Àˆ €ÀÌ Ì À À À ÌÌ ÿÏ À ˆ ÌÌ  À Ì Ì À À À À Ì ˆ ÈÌÌ €ˆˆ ÌÌÌ̈ˆ Ì Ì Ì Ì Ì Ì Ì Ìˆ ˆ ÀÌÌÌüÿÿÿ ÎÌÌÌàîîî ÌÌÌÌÿÿÿÿ ÌÌÌÌîîîî ÿÿÿÿ ÌÌÌÌîîîî ÿÿÿÿ ÌÌÌÌîîîî ÌÌÌÌîîîî ÌÌÌÌîîîî ÌÌÌÌîîîî ÌÌ îÎ àÌ ÎÌ àî À Ì Àì ÌÌ îî Ì Ì Ì Ì ˆ© Ð ÀÁ° ´µ³ °±²³Âà àá ÐÑ ÒÓ ðñ ¡¢£¤ àá âã ðñ  ¡¢£¤ òó ÀÁ °±²³ ´µ ´µ ÂÂà ÀÐÑ ÒÒÓ Ð Å Õ ä ô Å Õ ä Å ô Õ àá âã ðñ  ¡¢£¤¥  ¡¢£¤¥ òó m                                                                ’ “ “ ” ” ” • • – – — — ˜ ˜ ™ ™ ™ ™ š š › › › › › › œ œ                                 \ W S P P R S S S S S S S S S S SS SS SðSàSðS S T T T T T  K I D @ A C C C C C C C C C C C C C C C C C C C C C C C C C                                 P P P P P P P P Q R U W X Y Z [ [ \ \ \ \ \ \ \ ] ] ] ] ] ]  ö ö ù ü ý þ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ & @@CIJKLMNOOOOO@ @ C I J L M N O O O O O O O O 5 ððònón÷mùjûgüUüSüBü üý ýàþÐþÐþàþðþþþðþÐþÐþ þ0þ þàþðþÿr à 
å %
ã 3

 Û  ;
   € €€€€€€ €€€  ‘ ¡ ¡ ² Â Â Ó Ô ä õ ö   - ?O_ P U \ _ _ P U \ _ _ P U [ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ T ÿþþþ þ ýüú
ø õ ó ó ð
óõ÷ûüüýýýýþþþþþÿÿ P PpP PPPrPƒPPsPP…PPvPP‡PPxPP‰P
PzP P‹P R}VY\^_ ÿ ÿ ÿ ÿ þ þ ý ý ý ý ü ü ü û û ú ú ù ù ø ø ÷ ÷ ö õ õ ô ô ó ÿ s
° ÿÿÿÿ ÿÿÿÿ2Tv˜ºÜþïÍ«‰gE#2Tv˜ºÜþ2Tv˜ºÜþ èÏ˽yšgUvW3#SE"ƒ' …ÛþÿÎ' …ÛþÿÎ "3DUfw "3DUfwÌÌÌ5333 ˜º»«ªš‰xgfUU4CTv¡“’ ––P·F6€%· D  K I N D K 9 M D K I N D K I G    @ G } « ô¡ §  k D¡ g ­ û @ 6¡TD¡  @ — ] 4¡ V ®aLa G I G La G I B  @ G La G I G La G I G K  T › ¶ þa ´ › V ž  ´ û @¶ @ ža A T @ › ¶ ù –ôB  °  P     ôB 𰠐 0   ®" ð   B  ð °  0    ôB 𰠐 @   þ"  ü" ð    @   ü" ð    @   ÷A   ü" ð    @   ü" ð    @   þ! 𠦃  @ƒ @d `ƒ
Fƒ @e   ` ` @ @«ƒ ƒ Dƒ @e  @ ` ¤ƒ Pe  ` 0    ƒ fƒ §ƒ ƒ Gƒ @c Pe  p P      `
c Ec
c `  ƒ Pe € @    @ ` Gƒfƒ”ƒ®c¤ƒ Pe € ` P 0    ¤cð   c  c  C  C  B   «c   c c
c c c  c  c b   §ƒ   c  c  ¡   ö& b =b ö& b =b ö& b =b ö& ö& =b ö& b ô& b ö& b ]b ö& b ]b ö& b ]b ö& ö& ýb ö& ­b ô& ûbùb                                                   @… … …
…B¥ ¥ ¥
¥AÅ
¥ ¥ ¥@¥
… … …A… … …
…B¥ ¥ ¥
¥AÅ
¥ ¥ ¥@¥
… … …A… … …
…B¥ ¥ ¥
¥AÅ
¥ ¥ ¥@¥
… … …A… … …
…B¥ ¥ ¥
¥AÅ
¥ ¥ ¥@¥
… … …þ žb >b þ žb >b þ žb >b þ þ >b þ žb ô&
b þ žb >b þ žb >b þ žb >b þ þ >b þ žb ô&
b  ƒ  Fƒ 
@ƒ Pe  `ƒ    ƒ    ƒ ƒ ƒ ƒ ƒ Pe °  ` P   øƒ ƒ 
ƒ  £ Pe   ð °  P   fC CyC CC c¦c c»c
cƃ ƒÙƒ ƒíƒ £ù£ @g  `£ £ £ £
ƒ ô& ”b 4b ô& ”b 4b ô& ”b 4b ô& ô& 4b ô& ”b ô&  b ô& ”b 4b ô& ”b 4b ô& ”b 4b ô& ô& 4b ô& ”b ô&  b ƒ F£  @ƒ ƒ   Pe °  P 0   ` C&C8CIC[Cdcvcˆc™c«c´ƒÆƒØƒéƒûƒ £ ƒ
ƒ Fƒ  ƒ  Pe `ƒ  ƒ  Fƒ
@c Pe  +Ac ö& ö&  ‚  &     ‚   ‚   ‚  &  &  &    ‚   ‚  ‚ ýF ýF  ýF     a   
  ¡  Á  ¡ 
   a  F  F  F   „   „ „  „
„  †  †  †    a 
a    ¡ 
¡ 
¡  ¡   
a  a  †  †  †    f  f  f    a
a   ¡
¡
¡  ¡ 
a  a  †  †  †    c Ic Iƒ @c  †  †  †   a  
 ¡  Á ¡
   a † † †   c Fƒ  @ƒ Fƒ
@ƒŠ P a Pa P$ º Ê ¦ TeWeTeWeT…W•ZµWŝ÷÷UV 0 ,]']±>Sï}WÿÍu§ðp8·d%qy)6o;]ÉA¦ösï÷ôôô”°ÂVl†3<W"‰ ;; title: Wizard Graph
;; author: Alec Troemel
;; desc: GMTK 2021
;; script: fennel
;; +---------------------+
;; | Function Shorthands |
;; +---------------------+
(global abs math.abs)
(global rnd math.random)
(global min math.min)
(global max math.max)
(global sin math.sin)
(global cos math.cos)
(global flr math.floor)
(global sqrt math.sqrt)
(global sub string.sub)
(global srt table.sort)
(global rmv table.remove)
(global add table.insert)
(global button-mapping {:UP 0
:DOWN 1
:LEFT 2
:RIGHT 3
:A 4
:B 5
:X 6
:Y 7})
(global level 1)
(fn printc [s x y c bc sc sel]
(let [w (print s 0 -8)
wx (/ w (/ 2 sc))]
(when sel
(line (- x wx 7) (+ y 2) (- x wx 2) (+ y 2) c)
(line (+ x wx 8) (+ y 2) (+ x wx 4) (+ y 2) c))
(print s (- x wx) (+ y 1) bc true sc)
(print s (- x wx) y c true sc)))
;; +--------------------+
;; | ECS |
;; +--------------------+
(fn ent [t]
(var cmpt {})
(var t (or t {}))
(setmetatable t
{:__index cmpt
:__add (fn [self cmp]
(assert cmp._cn)
(tset self cmp._cn cmp) self)
:__sub (fn [self cn]
(tset self cn nil) self)})
t)
(fn cmp [cn t]
(var t (or t {}))
(set t._cn cn)
t)
(fn sys [cns f]
(fn [wld ...]
(each [i e (ipairs wld)]
(var matches true)
(each [j cns (ipairs cns)]
(when (not (. e cns))
(set matches false)))
(when matches
(f e i wld ...)))))
;; +--------------------+
;; | Position |
;; +--------------------+
(fn pos [x y locked] (cmp :pos {: x : y : locked}))
(fn des-pos [x y speed] (cmp :des-pos {: x : y : speed}))
(var des-pos-tic
(sys ["pos" "des-pos"]
(fn [e]
(let [{: x : y} e.pos
{:x dx :y dy : speed} e.des-pos]
(tset e.pos :x (+ x (/ (- dx x) speed)))
(tset e.pos :y (+ y (/ (- dy y) speed)))))))
;; +--------------------+
;; | Animation (ECS) |
;; +--------------------+
(fn anim [current states paused]
(cmp :anim
{: paused
:tick 0
:frame 0
: current
: states}))
(var anim-tic
(sys ["anim" "pos"]
(fn [e]
(let [{: anim : pos} e
{: x : y} pos
{: frames
: speed
: flip
: rotate
: width
: height
: colorkey
: scale} (. anim.states anim.current)]
(when (not anim.paused)
;; Update
(tset anim :tick (% (+ anim.tick 1) speed))
(when (= anim.tick 0)
(tset anim :frame (% (+ anim.frame 1) (# frames))))
(when (> anim.frame (# frames))
(tset anim :frame 0))
;; Draw
(spr (. frames (+ anim.frame 1))
x y colorkey scale flip rotate width height))))))
;; +--------------------+
;; | Timers (ECS) |
;; +--------------------+
(fn timer-create [wld t i cb fin]
(add wld (+ (ent)
(cmp :timer {:c 0 ;; internal counter
: t ;; times to run
: i ;; interval
: cb ;; interval callback
: fin})))) ;; finished cb
(var timer-tic
(sys ["timer"]
(fn [e ei wld]
(tset e.timer :c (+ e.timer.c 1))
(when (= e.timer.c e.timer.i)
(: e.timer :cb)
(tset e.timer :t (- e.timer.t 1))
(tset e.timer :c 0))
(when (= e.timer.t 0)
(when e.timer.fin (: e.timer :fin))
(rmv wld ei)))))
;; +--------------------+
;; | Screen Shake (ECS) |
;; +--------------------+
(fn shake-it [wld d p]
(add wld (+ (ent)
(cmp :shaker {: d : p}))))
(var shake-tic
(sys ["shaker"]
(fn [e ei wld]
(let [{: d : p} e.shaker]
;; time to shake
(when (> d 0)
(poke 0x3FF9 (rnd (- p) p))
(poke 0x3FFA (rnd (- p) p))
(tset e.shaker :d (- d 1)))
;; shake all done
(when (= d 0)
(memset 0x3FF9 0 2)
(rmv wld ei))))))
;; +--------------------+
;; | Game State Manager |
;; +--------------------+
(global STATE {:current nil})
(fn state-add [name init tic]
(tset STATE name {: init : tic}))
(fn state-goto [name]
(tset STATE :current name)
(: (. STATE name) :init))
(fn state-tic [t]
(let [current (. STATE STATE.current)]
(: current :tic t)))
;; +---------------------+
;; | In Bounds |
;; +---------------------+
(fn bounds [x y w h]
(cmp :bounds
{:min-x x
:min-y y
:max-x (+ x w)
:max-y (+ y h)}))
(var bounds-tic
(sys ["bounds" "pos"]
(fn [e]
(let [{: min-x : min-y : max-x : max-y} e.bounds
{: x : y} e.pos]
(tset e.pos :x (max min-x (min max-x x)))
(tset e.pos :y (max min-y (min max-y y)))))))
;; +---------------------+
;; | Verlet |
;; +---------------------+
(fn spring [a b len stiffness active]
(+ (ent)
(cmp :spring {: a : b
: len
: stiffness
: active})))
(var spring-tic
(sys ["spring"]
(fn spring-tic [e]
(let [{: a : b : len : stiffness} e.spring
{:pos apos :node anode} a
{:pos bpos :node bnode} b
graph (match anode.graph
:wizard wizard-graph
:monster monster-graph)
[eca ecb] edge-cursor.edge-cursor.at
active (or (and (= turn-man.turn-man.current :setup)
(= turn-man.turn-man.phase 2)
(~= nil bnode)
(= anode.i eca)
(= bnode.i ecb))
(and (~= nil bnode)
(~= nil (. graph.edges anode.i))
(= (. graph.edges anode.i bnode.i) 1)))
dx (- bpos.x apos.x)
dy (- bpos.y apos.y)
d2 (sqrt (+ (* dx dx) (* dy dy)))
d3 (/ (- d2 len) d2)
d3 (if (~= d3 d3) 0 d3)
]
;; Update
(when (not apos.locked)
(tset apos :x (+ apos.x (* 0.5 dx d3 stiffness)))
(tset apos :y (+ apos.y (* 0.5 dy d3 stiffness))))
(when (not bpos.locked)
(tset bpos :x (- bpos.x (* 0.5 dx d3 stiffness)))
(tset bpos :y (- bpos.y (* 0.5 dy d3 stiffness))))
;; Draw
(when active
(let [ax (+ apos.x 8)
ay (+ apos.y 8)
bx (+ bpos.x 8)
by (+ bpos.y 8)
ratio 0.3
ratio (if (> d2 50) 0.25 ratio)
ratio (if (> d2 70) 0.15 ratio)
sx (+ ax (* (- bx ax) ratio))
sy (+ ay (* (- by ay) ratio))
ex (- bx (* (- bx ax) ratio))
ey (- by (* (- by ay) ratio))
l (/ 10 d2)
angle 0.785
x2 (+ ex (* l (+ (* (- sx ex) (cos angle))
(* (- sy ey) (sin angle)))))
y2 (+ ey (* l (- (* (- sy ey) (cos angle))
(* (- sx ex) (sin angle)))))
x3 (+ ex (* l (- (* (- sx ex) (cos angle))
(* (- sy ey) (sin angle)))))
y3 (+ ey (* l (+ (* (- sy ey) (cos angle))
(* (- sx ex) (sin angle)))))
col (match turn-man.turn-man.current
:battle
(if (= anode.i graph.active) 12 14)
:setup
(if (and (= anode.i eca)
(= bnode.i ecb))
12 14))
]
(line sx sy ex ey col)
(tri ex ey x2 y2 x3 y3 col)))
))))
;; +---------------------+
;; | Action Graph |
;; +---------------------+
(fn node-create [graph type i aframes iframes]
(+ (ent)
(cmp :node {: graph : type : i})
(pos (rnd 0 240) (rnd 0 136))
(anim (if selected :active :idle)
{:active {:speed 8 :flip 0 :rotate 0
:width 2 :height 2
:colorkey 0 :scale 1
:frames aframes}
:idle {:speed 32 :flip 0 :rotate 0
:width 2 :height 2
:colorkey 0 :scale 1
:frames iframes}}
false)))
(var node-tic
(sys ["pos" "node"]
(fn [e]
;; Update
;; Draw
(let [{: x : y} e.pos
{: type : graph : i} e.node
graph (match graph
:wizard wizard-graph
:monster monster-graph)
selected (= i graph.active)]
(when selected
(circb (+ x 7) (+ y 9) 12 14)
(circb (+ x 7) (+ y 8) 12 12))))))
(fn action-graph-init [wld graph center]
;; add nodes to world
(each [i n (ipairs graph.nodes)]
(add wld n)
(add wld (spring n center 40 0.5)))
;; add spring for edges
(each [i ends (ipairs graph.edges)]
(each [j active (ipairs ends)]
(when (~= i j)
(add wld (spring (. graph.nodes i)
(. graph.nodes j)
60 0.1 active))))))
;; +---------------------+
;; | Shadow |
;; +---------------------+
(fn shadow [] (cmp :shadow {}))
(var shadow-tic
(sys ["shadow" "pos"]
(fn [e]
(spr 128 e.pos.x (+ e.pos.y 24) 0 1 false 0 4 2))))
;; +---------------------+
;; | Stats |
;; +---------------------+
(fn stats-health-up [self v]
(tset self :health (min self.max-health
(+ self.health v))))
(fn stats-health-down [self v]
(tset self :health (max 0 (- self.health v))))
(fn stats-defense-up [self]
(tset self :defense 1))
(fn stats-defense-reset [self v]
(tset self :defense 0))
(fn stats [max-health attack]
(cmp :stats
{;fields
:health max-health
: max-health
:defense 0
: attack
; Methods
:health-up stats-health-up
:health-down stats-health-down
:defense-up stats-defense-up
:defense-reset stats-defense-reset }))
(var stats-tic
(sys ["pos" "stats"]
(fn [e]
(let [{ : x : y} e.pos
{ : health : max-health} e.stats
h-ratio (/ health max-health)
col 6
col (if (< h-ratio 0.55) 4 col)
col (if (< h-ratio 0.26) 2 col)]
(print (.. health "/" max-health)
(+ x 8) (- y 8) col)))))
;; +---------------------+
;; | Attacks |
;; +---------------------+
(fn attacks-init [wld]
(var noop-anim {:speed 100 :flip 0 :rotate 0
:width 1 :height 1
:colorkey 0 :scale 1
:frames [0]})
(global action-electricity
(+ (ent {:trigger (fn [s wld]
(tset s.anim :current :atk)
(timer-create wld 1 (* 4 7)
(fn []
(tset s.anim :current :idle)))
(sfx 18 nil -1 3)
(shake-it wld 10 2)
(: monster.stats :health-down
(- wizard.stats.attack
monster.stats.defense)))})
(pos 155 0)
(cmp :attack {})
(anim :idle
{:idle noop-anim
:atk {:speed 4 :flip 0 :rotate 0
:width 1 :height 3
:colorkey 0 :scale 3
:frames [1 2 0 3 3 4 4]}})))
(global action-heal
(+ (ent {:trigger (fn [s wld]
(tset s.anim :current :atk)
(timer-create wld 1 (* 8 5)
(fn []
(tset s.anim :current :idle)))
(sfx 20 nil -1 3)
(: wizard.stats :health-up 1))})
(pos 58 8)
(cmp :attack {})
(anim :idle
{:idle noop-anim
:atk {:speed 8 :flip 0 :rotate 0
:width 2 :height 2
:colorkey 0 :scale 1
:frames [80 82 84 84 84]}})))
(global action-shield
(+ (ent {:trigger (fn [s wld]
(tset s.anim :current :atk)
(timer-create wld 1 (* 10 5)
(fn []
(tset s.anim :current :idle)))
(sfx 19 nil -1 3)
(: wizard.stats :defense-up 1))})
(pos 58 8)
(cmp :attack {})
(anim :idle
{:idle noop-anim
:atk {:speed 10 :flip 0 :rotate 0
:width 2 :height 2
:colorkey 0 :scale 1
:frames [86 86 88 90 90]}})))
(global action-m-attack
(+ (ent {:trigger (fn [s wld]
(tset s.anim :current :atk)
(timer-create wld 1 (- (* 12 3) 4)
(fn []
(tset s.anim :current :idle)))
(sfx 22 nil -1 3)
(shake-it wld 10 2)
(: wizard.stats :health-down
(- monster.stats.attack
wizard.stats.defense)))})
(pos 50 34)
(cmp :attack {})
(anim :idle
{:idle noop-anim
:atk {:speed 12 :flip 0 :rotate 0
:width 2 :height 2
:colorkey 0 :scale 2
:frames [48 50 52]}})))
(global action-m-defend
(+ (ent {:trigger (fn [s wld]
(tset s.anim :current :atk)
(timer-create wld 1 (* 10 5)
(fn []
(tset s.anim :current :idle)))
(sfx 19 nil -1 3)
(: monster.stats :defense-up 1))})
(pos 158 8)
(cmp :attack {})
(anim :idle
{:idle noop-anim
:atk {:speed 10 :flip 0 :rotate 0
:width 2 :height 2
:colorkey 0 :scale 1
:frames [86 86 88 90 90]}})))
(add wld action-electricity)
(add wld action-heal)
(add wld action-shield)
(add wld action-m-attack)
(add wld action-m-defend)
)
(fn wizard-play-move [wld]
(let [{: nodes : edges : active} wizard-graph
node (. nodes active)
{: type} node.node]
(match type
:heal (: action-heal :trigger wld)
:thunderbolt (: action-electricity :trigger wld)
:shield (: action-shield :trigger wld)
_ (sfx 21 nil -1 3))))
(fn monster-play-move [wld]
(let [{: nodes : edges : active} monster-graph
node (. nodes active)
{: type} node.node]
(match type
:attack (: action-m-attack :trigger wld)
:defend (: action-m-defend :trigger wld)
_ (sfx 21 nil -1 3))))
;; +---------------------+
;; | Turn Manager |
;; +---------------------+
(fn turn-man-resolve []
(let [{: current : phase : states} turn-man.turn-man
state (. states current)
phase (. state phase)
[wg w m mg] (. phase :offsets)]
;; Update Textbox
(tset tb.textbox :text (. phase :desc))
(when (= phase.title "Player Move")
(tset tb.textbox :text
(..
"Casting "
(. wizard-graph :nodes wizard-graph.active :node :type))))
(when (= phase.title "Enemy Move")
(let [ma monster-graph.active
ntype (. monster-graph :nodes ma :node :type)]
(tset tb.textbox :text
(match ntype
:attack "Monster attacks!"
:wait "They do nothing.."
:defend "Monster raises defenses!"))))
;; update des-pos for relevent entities
(tset wizard-graph-center.des-pos :x wg)
(tset wizard.des-pos :x w)
(tset monster.des-pos :x m)
(tset monster-graph-center.des-pos :x mg)))
(fn turn-man-progress []
(let [{: current : phase : states} turn-man.turn-man
state (. states current)]
(tset turn-man.turn-man :phase (% (+ 1 phase)
(+ 1 (# state))))
(when (= turn-man.turn-man.phase 0)
(tset turn-man.turn-man :phase 1)))
(turn-man-resolve)
(tset turn-man.turn-man :working false))
(fn turn-man-init [wld]
(global turn-man
(+ (ent)
(cmp :turn-man
{:working false
:current :battle
:phase 1
:states {:battle [{:title "Player Pick"
:desc "Pick you action."
:offsets [50 105 180 300]}
{:title "Player Move"
:desc "Casting spell!"
:offsets [-70 50 150 300]}
{:title "Enemy Pick"
:desc "Monster is responding."
:offsets [-70 25 105 150]}
{:title "Enemy Move"
:desc "Monster attacks!"
:offsets [-70 50 150 300]}]
:setup [{:title "Remove Edge"
:desc "You must remove an edge."
:offsets [105 300 300 300]}
{:title "Add Edge"
:desc "You get to add an edge."
:offsets [105 300 300 300]}
{:title "Add Node"
:desc "New action introduced!"
:offsets [105 300 300 300]}]
}})))
(turn-man-resolve)
(add wld turn-man))
;; +---------------------+
;; | monster Manager |
;; +---------------------+
(fn monster-pick-move []
(let [{: nodes : edges : active} monster-graph
edges (. edges active)]
(var new-at active)
(while (or (= new-at active)
(and (~= new-at active)
(~= 1 (. edges new-at))))
(set new-at (% (+ 1 new-at) (+ 1 (# nodes))))
(when (= new-at 0) (set new-at 1)))
(tset monster-graph :active new-at)))
(fn monster-defend-node [i]
(node-create :monster :defend i [183] [183]))
(fn monster-wait-node [i]
(node-create :monster :wait i [185] [185]))
(fn monster-attack-node [i]
(node-create :monster :attack i [187] [187]))
(fn monster-generic-init [wld h a idle dead nodes edges]
(global monster
(+ (ent)
(cmp :monster {})
(pos 150 35)
(des-pos 150 35 4)
(stats h a)
(shadow)
(anim :idle
{:idle {:speed 32 :flip 0 :rotate 0
:width 4 :height 4
:colorkey 5 :scale 1
:frames idle}
:dead {:speed 32 :flip 0 :rotate 0
:width 4 :height 4
:colorkey 5 :scale 1
:frames dead}})))
(global monster-graph
{:active 1 : nodes : edges})
(global monster-graph-center
(+ (ent)
(pos 300 40 true)
(des-pos 300 40 4)))
(add wld monster)
(add wld monster-graph-center)
(action-graph-init wld
monster-graph
monster-graph-center))
(fn monster-tomato-init [wld]
(monster-generic-init wld
(match level
1 1
2 1
3 2
4 2
5 2
6 2
_ 3)
(match level
1 1
2 1
3 1
4 1
5 2
6 2
_ 2)
[260] [264]
[(monster-wait-node 1)
(monster-attack-node 2)]
[[0 1]
[1 0]]))
(fn monster-greenboi-init [wld]
(monster-generic-init wld
(match level
1 2
2 2
3 3
4 3
5 3
6 3
7 4
8 4
9 4
_ 4)
(match level _ 1)
[324] [328]
[(monster-attack-node 1)
(monster-defend-node 2)
(monster-wait-node 3)
(monster-defend-node 4)]
[[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
[1 0 0 0]]))
(fn monster-triangle-init [wld]
(monster-generic-init wld
(match level
1 1
2 1
3 1
4 1
5 1
6 2
7 2
8 2
9 2
_ 2)
(match level
1 2
2 2
3 2
4 2
5 2
6 3
7 3
8 3
9 4
_ 4)
[388] [392]
[(monster-attack-node 1)
(monster-wait-node 2)
(monster-attack-node 3)]
[[0 1 0]
[0 0 1]
[1 0 0]]))
(fn monster-init-random [wld]
(match (rnd 1 10)
1 (monster-tomato-init wld)
2 (monster-tomato-init wld)
3 (monster-tomato-init wld)
4 (monster-tomato-init wld)
5 (monster-tomato-init wld)
6 (monster-greenboi-init wld)
7 (monster-greenboi-init wld)
8 (monster-greenboi-init wld)
9 (monster-triangle-init wld)
10 (monster-triangle-init wld)))
(var turn-man-tic
(sys ["turn-man"]
(fn [e ei wld]
(let [{: working
: current
: phase
: states} e.turn-man
state (. states current)
phase (. state phase)]
(when (not working)
(match phase.title
"Player Pick"
(: wizard.stats :defense-reset)
"Player Move"
(do
(tset e.turn-man :working true)
(timer-create wld 1 30
(fn []
(wizard-play-move wld)
(if (~= monster.stats.health 0)
(timer-create wld 1 100
(fn [] (turn-man-progress)))))))
"Enemy Pick"
(when (~= monster.stats.health 0)
(tset e.turn-man :working true)
(: monster.stats :defense-reset)
(timer-create wld 1 40
monster-pick-move
(fn []
(sfx 16 nil -1 3)
(timer-create wld 1 50
(fn [] (turn-man-progress))))
))
"Enemy Move"
(do
(tset e.turn-man :working true)
(timer-create wld 1 80
(fn []
(monster-play-move wld)
(timer-create wld 1 80
(fn [] (turn-man-progress))))))
"Remove Edge"
(when (btnp (. button-mapping :A))
(sfx 17 nil -1 3)
(tset e.turn-man :working true)
(let [[a b] edge-cursor.edge-cursor.at]
(tset (. wizard-graph.edges a) b 0))
(monster-init-random wld)
(timer-create wld 1 40
(fn []
(tset e.turn-man :working false)
(tset e.turn-man :current :battle)
(tset e.turn-man :phase 1)
(turn-man-resolve))))
"Add Edge"
(when (btnp (. button-mapping :A))
(sfx 16 nil -1 3)
(tset e.turn-man :working true)
(let [[a b] edge-cursor.edge-cursor.at]
(tset (. wizard-graph.edges a) b 1))
(monster-init-random wld)
(timer-create wld 1 40
(fn []
(tset e.turn-man :current :battle)
(tset e.turn-man :phase 1)
(turn-man-resolve))))
"Add Node"
(let [ai (rnd 1 (# action-list))
node-i (+ (# wizard-graph.nodes) 1)
node ((. action-list ai) node-i)]
(sfx 23 nil -1 3)
(tset e.turn-man :working true)
;; add node to world
(add wld node)
(add wld (spring node wizard-graph-center 40 0.5))
;; add to nodes list in graph
(tset wizard-graph.nodes node-i node)
;; add on to existing edges map
(each [_ edge (pairs wizard-graph.edges)]
(tset edge node-i 0))
;; insert new edges map
(var n-edges [])
(for [i 1 (# wizard-graph.nodes)]
(add n-edges 0))
(tset n-edges (rnd 1 (# wizard-graph.nodes)) 1)
(tset wizard-graph.edges node-i n-edges)
;; attach springs to all existing nodes
(each [i ends (ipairs wizard-graph.edges)]
(each [j active (ipairs ends)]
(when (and (~= i j)
(or (= i node-i)
(= j node-i)))
(add wld (spring (. wizard-graph.nodes i)
(. wizard-graph.nodes j)
60 0.1 active)))))
(monster-init-random wld)
(timer-create wld 1 100
(fn []
(tset e.turn-man :current :battle)
(tset e.turn-man :phase 1)
(turn-man-resolve))))
_ nil))
))))
;; +---------------------+
;; | Node Cursor |
;; +---------------------+
(fn cursor-create []
(+ (ent)
(pos 0 0)
(cmp :cursor {:at 1})))
(fn cursor-cycle [e d]
(let [{: at} e.cursor
{: active : nodes : edges} wizard-graph
edges (. edges active)]
(var new-at at)
(while (or (= new-at at)
(and (~= new-at active)
(~= 1 (. edges new-at))))
(set new-at (% (+ d new-at) (+ 1 (# nodes))))
(when (and (= new-at 0) (> d 0))
(set new-at 1))
(when (and (= new-at 0) (< d 0))
(set new-at (# nodes))))
(tset e.cursor :at new-at)))
(var cursor-tic
(sys ["cursor" "pos"]
(fn [e ei wld]
(let [{: x : y} e.pos
{: nodes} wizard-graph
{: current } turn-man.turn-man]
(when (= current :battle)
;; Update
;; cycle through possible options
(when (btnp (. button-mapping :RIGHT))
(sfx 16 nil -1 3)
(cursor-cycle e 1))
(when (btnp (. button-mapping :LEFT))
(sfx 16 nil -1 3)
(cursor-cycle e (- 1)))
(when (and (btnp (. button-mapping :A))
(~= e.cursor.at wizard-graph.active))
(sfx 17 nil -1 3)
(tset wizard-graph :active e.cursor.at)
(timer-create wld 1 20
(fn [] (turn-man-progress))))
;; move towards target
(let [node (. nodes e.cursor.at)]
(tset e.pos :x (+ x (/ (- node.pos.x x) 4)))
(tset e.pos :y (+ y (/ (- node.pos.y y) 4)))
; Draw
(if (< e.pos.y 32)
(spr 117
e.pos.x
(+ (sin (/ t 5)) (+ e.pos.y 12))
5 1 false 2 2 2)
(spr 117
e.pos.x
(+ (sin (/ t 5)) (- e.pos.y 12))
5 1 false 0 2 2))
))))))
;; +---------------------+
;; | Edge Cursor |
;; +---------------------+
(fn edge-cursor-init [wld]
(global edge-cursor (+ (ent)
(pos 0 0)
(cmp :edge-cursor {:at [1 2]})))
(add wld edge-cursor))
(fn active-edge-count [edge]
(var c 0)
(for [i 1 (# edge)]
(set c (+ c (. edge i))))
c)
(fn edge-cursor-cycle-remove [e d]
(let [{: at} e.edge-cursor
[a b] at
{: active : nodes : edges} wizard-graph]
;; Cycle 1
(var new-a a)
(var new-b b)
(set new-b (% (+ new-b d) (+ (# (. edges new-a)) 1)))
(when (= new-b 0)
(set new-b (if (> d 0) 1 (# (. edges new-a))))
(set new-a (% (+ new-a d) (+ (# edges) 1)))
(when (= new-a 0)
(set new-a (if (> d 0) 1 (# edges)))))
;; Cycles 2+
(while (or (~= 1 (. edges new-a new-b))
(< (active-edge-count (. edges new-a)) 2))
(set new-b (% (+ new-b d) (+ (# (. edges new-a)) 1)))
(when (= new-b 0)
(set new-b (if (> d 0) 1 (# (. edges new-a))))
(set new-a (% (+ new-a d) (+ (# edges) 1)))
(when (= new-a 0)
(set new-a (if (> d 0) 1 (# edges))))))
;; All done
(tset e.edge-cursor :at [new-a new-b])))
(fn edge-cursor-cycle-add [e d]
(let [{: at} e.edge-cursor
[a b] at
{: active : nodes : edges} wizard-graph]
;; Cycle 1
(var new-a a)
(var new-b b)
(set new-b (% (+ new-b d) (+ (# (. edges new-a)) 1)))
(when (= new-b 0)
(set new-b (if (> d 0) 1 (# (. edges new-a))))
(set new-a (% (+ new-a d) (+ (# edges) 1)))
(when (= new-a 0)
(set new-a (if (> d 0) 1 (# edges)))))
;; Cycles 2+
(while (or (= new-a new-b)
(= 1 (. edges new-b new-a))
(~= 0 (. edges new-a new-b)))
(set new-b (% (+ new-b d) (+ (# (. edges new-a)) 1)))
(when (= new-b 0)
(set new-b (if (> d 0) 1 (# (. edges new-a))))
(set new-a (% (+ new-a d) (+ (# edges) 1)))
(when (= new-a 0)
(set new-a (if (> d 0) 1 (# edges))))))
;; All done
(tset e.edge-cursor :at [new-a new-b])))
(fn edge-cursor-cycle [e d]
(match turn-man.turn-man.phase
1 (edge-cursor-cycle-remove e d)
2 (edge-cursor-cycle-add e d)))
(var edge-cursor-tic
(sys ["edge-cursor" "pos"]
(fn [e ei wld]
(let [{: x : y} e.pos
{: nodes : edges} wizard-graph
{: current } turn-man.turn-man]
(when (= current :setup)
(when (btnp (. button-mapping :RIGHT))
(sfx 16 nil nil 3)
(edge-cursor-cycle e 1))
(when (btnp (. button-mapping :LEFT))
(sfx 16 nil nil 3)
(edge-cursor-cycle e (- 1)))
(let [{: at} e.edge-cursor
[a b] at
node-a (. nodes a)
node-b (. nodes b)
{:x ax :y ay} node-a.pos
{:x bx :y by} node-b.pos
dx (+ ax (* (- bx ax) 0.5))
dy (+ ay (* (- by ay) 0.5))]
(tset e.pos :x (+ x (/ (- dx x) 4)))
(tset e.pos :y (+ y (/ (- dy y) 4)))
; Draw
(spr 117
e.pos.x
(+ (sin (/ t 5)) (- e.pos.y 8))
5 1 false 0 2 2)
)
)))))
;; +---------------------+
;; | Game over |
;; +---------------------+
(fn game-over-transition []
(cmp :game-over-trans {:r 0}))
(var game-over-tic
(sys ["game-over-trans"]
(fn [e ei wld]
;; update
(shake-it wld 2 4)
(tset e.game-over-trans :r (+ e.game-over-trans.r 3))
(when (> e.game-over-trans.r 200)
(sfx -1)
(state-goto :over))
;; draw
(circ 120 (/ 136 2) e.game-over-trans.r 2)
)))
;; +---------------------+
;; | Wizard |
;; +---------------------+
(global action-list
[(fn [i] (node-create :wizard :thunderbolt i [153] [153]))
(fn [i] (node-create :wizard :wait i [185] [185]))
(fn [i] (node-create :wizard :heal i [119] [119]))
(fn [i] (node-create :wizard :shield i [123] [123]))])
(fn wizard-init [wld]
(global wizard
(+ (ent)
(cmp :wizard {})
(pos 0 35)
(des-pos 50 35 4)
(stats 3 1)
(shadow)
(anim :idle
{:idle {:speed 32 :flip 0 :rotate 0
:width 4 :height 4
:colorkey 5 :scale 1
:frames [256]}})))
(var nodes [])
(for [i 1 3]
(add nodes ((. action-list i) i)))
(global wizard-graph
{:active 3
:nodes nodes
:edges [[0 1 0]
[0 0 1]
[1 0 0]]})
(global wizard-graph-center
(+ (ent)
(pos -60 40 true)
(des-pos -60 40 4)))
(add wld wizard)
(add wld wizard-graph-center)
(action-graph-init wld
wizard-graph
wizard-graph-center))
(var wizard-tic
(sys ["wizard" "stats"]
(fn [e ei wld]
(when (= e.stats.health 0)
(tset e.stats :health -1)
(sfx 24 nil -1 3)
(add wld (+ (ent)
(game-over-transition)))))))
;; +---------------------+
;; | Monsters |
;; +---------------------+
(global next-setup 3)
(var monster-tic
(sys ["monster" "stats" "anim"]
(fn [e ei wld]
(when (and (~= e.anim.current :dead)
(= turn-man.turn-man.current :battle)
(= e.stats.health 0))
;; Level stuff
(when (> level 3)
(tset wizard.stats :max-health 4))
(when (> level 5)
(tset wizard.stats :attack 2))
(when (> level 7)
(tset wizard.stats :max-health 5))
(: wizard.stats :health-up 1)
(global level (+ 1 level))
(tset e.anim :current :dead)
(timer-create wld 1 40
(fn []
(tset turn-man.turn-man :current :setup)
(tset turn-man.turn-man :phase next-setup)
(tset turn-man.turn-man :working false)
(edge-cursor-cycle edge-cursor 1)
(global next-setup
(match next-setup
1 (if (< (# wizard-graph.nodes) 8) 3 2)
2 1
3 2))
(turn-man-resolve)))
))))
;; +---------------------+
;; | Textbox |
;; +---------------------+
(fn textbox-init [wld]
(global tb
(+ (ent)
(cmp :textbox {:text "Test text here."})))
(add wld tb))
(var textbox-tic
(sys ["textbox"]
(fn [e]
(map 0 1 19 5 46 102)
(printc e.textbox.text 120 115 12 14 1))))
;; +---------------------+
;; | State Main |
;; +---------------------+
(state-add :main
(fn [s]
(music 2 0 0 true)
(global level 1)
(var world [])
(wizard-init world)
(monster-tomato-init world)
(attacks-init world)
(textbox-init world)
(turn-man-init world)
(edge-cursor-init world)
(add world (cursor-create))
(tset s :world world))
(fn [s t]
(cls 0)
(let [{: world} s]
(des-pos-tic world)
(timer-tic world)
(shake-tic world)
(spring-tic world)
(bounds-tic world)
(node-tic world)
(shadow-tic world)
(anim-tic world)
(cursor-tic world)
(edge-cursor-tic world)
(textbox-tic world)
(turn-man-tic world)
(stats-tic world)
(wizard-tic world)
(monster-tic world)
(game-over-tic world)
(map 22 0 8 3 190 -14)
(print (.. "LVL: " level) 200 1 14)
(print (.. "LVL: " level) 200 0 12)
)))
;; +---------------------+
;; | State Menu |
;; +---------------------+
(state-add :menu
(fn [s]
(music 0 0 0 true)
(tset s :selected 1))
(fn [s t]
(cls 0)
(spr 448 8 (+ (* 2 (sin (/ t 30))) 10) -1 2 0 0 14 4)
(printc "Enter the Crypt"
(/ 240 2) 94
(if (= s.selected 1) 12 13)
(if (= s.selected 1) 14 8)
1
(= s.selected 1))
(printc "Tutorial"
(/ 240 2) 110
(if (= s.selected 2) 12 13)
(if (= s.selected 2) 14 8)
1
(= s.selected 2))
(when (btnp (. button-mapping :DOWN))
(sfx 16 nil -1 3)
(tset s :selected (% (+ s.selected 1) 3)))
(when (btnp (. button-mapping :UP))
(sfx 16 nil -1 3)
(tset s :selected (% (- s.selected 1) 3)))
(when (= s.selected 0) (tset s :selected 1))
(when (or (btnp (. button-mapping :X))
(btnp (. button-mapping :Y))
(btnp (. button-mapping :A))
(btnp (. button-mapping :B)))
(sfx 17 nil -1 3)
(state-goto (match s.selected
1 :main
2 :tutorial)))
))
;; +---------------------+
;; | State Over |
;; +---------------------+
(state-add :over
(fn [s] (music 1))
(fn [s t]
(cls 2)
(printc (.. "You reached level " level)
(/ 240 2) (/ 136 3)
0 -1
1 false)
(printc "Game Over, press any button."
(/ 240 2) (/ 136 2)
0 -1
1 false)
(when (or (btnp (. button-mapping :X))
(btnp (. button-mapping :Y))
(btnp (. button-mapping :A))
(btnp (. button-mapping :B)))
(sfx 17 nil -1 3)
(state-goto :menu))
))
;; +---------------------+
;; | State tutorial |
;; +---------------------+
(state-add :tutorial
(fn [s] nil)
(fn [s t]
(cls 0)
(map 0 9 25 24 20 4)
;; 1)
(printc
"1) Select actions connected"
(- (/ 240 2) 10) 20 12 15 1 false)
(printc
"to last played move."
(- (/ 240 2) 10) 30 12 15 1 false)
(printc
"-Left/Right to cycle actions"
(/ 240 2) 40 13 15 1 false)
(printc
"-X to select"
76 50 13 15 1 false)
(printc "2) Choose carefully" 90 70 12 15 1 false)
(printc "3) Survive" 63 100 12 15 1 false)
(when (or (btnp (. button-mapping :X))
(btnp (. button-mapping :Y))
(btnp (. button-mapping :A))
(btnp (. button-mapping :B)))
(state-goto :menu))
))
;; +---------------------+
;; | Main |
;; +---------------------+
(state-goto :menu)
(global t 0)
(global TIC
(fn tic []
(state-tic t)
(global t (+ t 1))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment