game.cmn 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. # Flying Ball
  2. #
  3. # Simple clone of the famous game with a flying bird. This game is written in
  4. # the comun programming language and can be run with the saf_comun.h native
  5. # SAF program.
  6. #
  7. # by drummyfish, released under CC0 1.0, public domain
  8. ~gameState # 0: playing, 1: waiting for start, > 1: game over
  9. ~playerHeight
  10. ~score
  11. ~lastPressFrame
  12. ~lastPressHeight
  13. ~startFrame
  14. ~pointer:0
  15. ~columns:16 # format: col1Type, col1Pos, col2Type, col2Pos, ...
  16. ~nextSpawnIn
  17. MAX_COLUMNS: 8 .
  18. JUMP_HEIGHT: 16 .
  19. COLUMN_WIDTH: 8 .
  20. POSITION_X: 10 .
  21. BALL_RADIUS: 4 .
  22. restart:
  23. 1 $:gameState
  24. 0 $:nextSpawnIn
  25. 0 $:score
  26. SAF_frame $:startFrame
  27. SAF_frame $:lastPressFrame
  28. SAF_SCREEN_HEIGHT 2 / $0 $:playerHeight $:lastPressHeight
  29. $columns>pointer
  30. MAX_COLUMNS 2 / # set all columns to type 0 (empty)
  31. @'
  32. 0 $:pointer
  33. $>pointer
  34. $>pointer
  35. --
  36. .
  37. ^
  38. .
  39. # checks if player collides with a column
  40. playerCollides:
  41. $columns>pointer
  42. MAX_COLUMNS 2 /
  43. @'
  44. $pointer
  45. ?
  46. $pointer
  47. $>pointer
  48. $pointer
  49. columnHeights
  50. SAF_SCREEN_HEIGHT $playerHeight - >> # vertical1
  51. ><
  52. $playerHeight >> # vertical2
  53. | # vertical1 1 OR vertical2 = A
  54. POSITION_X BALL_RADIUS - $pointer > # horizontal1
  55. POSITION_X BALL_RADIUS + $pointer COLUMN_WIDTH - < # horiuontal2
  56. | 0 = # NOT (horizontal1 | horiuontal2) = B
  57. & # A AND B
  58. ?
  59. ^ 1
  60. !.
  61. .
  62. $<pointer
  63. .
  64. $>pointer
  65. $>pointer
  66. --
  67. .
  68. ^
  69. 0
  70. .
  71. draw:
  72. 147 SAF_clearScreen
  73. $playerHeight SAF_SCREEN_HEIGHT << ?
  74. # draw ball:
  75. POSITION_X $playerHeight BALL_RADIUS SAF_COLOR_GRAY 1 SAF_drawCircle
  76. # draw the direction line:
  77. POSITION_X $playerHeight
  78. $gameState 1 = ? BALL_RADIUS 0 ; computeDirection .
  79. >< POSITION_X + >< $playerHeight +
  80. SAF_COLOR_GRAY_DARK SAF_drawLine
  81. POSITION_X $playerHeight BALL_RADIUS SAF_COLOR_GRAY_DARK 0 SAF_drawCircle
  82. .
  83. # draw columns:
  84. $columns>pointer
  85. MAX_COLUMNS 2 /
  86. @'
  87. $pointer
  88. $>pointer
  89. ?
  90. $pointer $<pointer $pointer $>pointer ><
  91. columnHeights
  92. $pointer
  93. # stack top: h1 h2 x
  94. $0 COLUMN_WIDTH - -1 COLUMN_WIDTH $5 SAF_COLOR_BROWN 1 SAF_drawRect
  95. $0 COLUMN_WIDTH - SAF_SCREEN_HEIGHT $3 - COLUMN_WIDTH $4 SAF_COLOR_BROWN 1 SAF_drawRect
  96. ^ ^ ^
  97. .
  98. $>pointer
  99. --
  100. .
  101. ^
  102. $gameState 1 = ?
  103. 0 "HISCORE:" 2 2 SAF_COLOR_BLACK 1 SAF_drawText
  104. getHighScore SAF_intToStr 4 9 SAF_COLOR_BLACK 2 SAF_drawText
  105. ;
  106. $score SAF_intToStr 1 59 SAF_COLOR_BLUE 1 SAF_drawText
  107. .
  108. .
  109. updateColumns:
  110. $columns>pointer
  111. MAX_COLUMNS 2 /
  112. @'
  113. $pointer
  114. $>pointer
  115. ?
  116. $pointer
  117. -- $:pointer'
  118. 0 <<= ?
  119. # remove column:
  120. $<pointer
  121. 0 $:pointer
  122. $>pointer
  123. .
  124. .
  125. $>pointer
  126. --
  127. .
  128. ^
  129. $nextSpawnIn ?'
  130. -- $:nextSpawnIn
  131. ;
  132. spawnColumn
  133. ^ SAF_random 32 % 34 difficulty 2 * - + $:nextSpawnIn
  134. .
  135. .
  136. # given two values, type and position, returns two values, upper and lower height
  137. # of a column
  138. columnHeights:
  139. # ordered from easiest to hardest
  140. $1 1 = ?
  141. ^ ^ 12 16 !.
  142. .
  143. $1 2 = ?
  144. ^ ^ 5 30 !.
  145. .
  146. $1 3 = ?
  147. ^ ^ 25 7 !.
  148. .
  149. $1 4 = ?
  150. ^ ^ 20 18 !.
  151. .
  152. $1 5 = ?
  153. ^ ^ 6 35 !.
  154. .
  155. $1 6 = ?
  156. ^ ^ 34 4 !.
  157. .
  158. $1 7 = ?
  159. # squeezing columns
  160. >< ^ 4 / $0 20 >< - >< 20 >< - !.
  161. .
  162. # vertically moving column
  163. >< ^ 4 * SAF_sin 8 / $0 15 + >< 15 >< -
  164. .
  165. # returns current difficulty as a number 3 to 8
  166. difficulty:
  167. 3 $score 8 / +
  168. $0 8 > ?
  169. ^ 8
  170. .
  171. .
  172. spawnColumn:
  173. $columns>pointer
  174. MAX_COLUMNS 2 / # find first empty slot and create new column there
  175. @'
  176. $pointer 0 =
  177. ?
  178. SAF_random 5 * SAF_random 7 / + # this makes it "more random"
  179. difficulty % ++ # allow more difficult columns with greater difficulty
  180. $:pointer
  181. $>pointer
  182. SAF_SCREEN_WIDTH COLUMN_WIDTH + $:pointer
  183. !@
  184. .
  185. $>pointer
  186. $>pointer
  187. --
  188. .
  189. ^
  190. .
  191. jump:
  192. $playerHeight
  193. SAF_frame $:lastPressFrame
  194. $:lastPressHeight
  195. SAF_SOUND_BUMP SAF_playSound
  196. .
  197. computeHeight:
  198. SAF_frame $lastPressFrame - JUMP_HEIGHT - $0 * 16 /
  199. $lastPressHeight JUMP_HEIGHT JUMP_HEIGHT * 16 / - +
  200. .
  201. # pushes player's direction offset vector with length of ball radius
  202. computeDirection:
  203. SAF_frame $lastPressFrame - JUMP_HEIGHT - # d = derivative times 8
  204. $0 $0 * 64 + SAF_sqrt # L = len(vec(8,d))
  205. $0 8 BALL_RADIUS * >< // # (8 * r) / L
  206. $2 BALL_RADIUS * $2 // # (d * r) / L
  207. $:2 $:2
  208. .
  209. buttonPressed:
  210. SAF_BUTTON_UP SAF_buttonJustPressed
  211. SAF_BUTTON_A SAF_buttonJustPressed
  212. SAF_BUTTON_B SAF_buttonJustPressed
  213. | |
  214. .
  215. setHighScore:
  216. $0 256 % 0 >< SAF_save 256 / 1 >< SAF_save
  217. .
  218. getHighScore:
  219. 0 SAF_load 1 SAF_load 256 * +
  220. .
  221. SAF_loop:
  222. draw
  223. $gameState 0 = ?
  224. updateColumns
  225. buttonPressed ?
  226. jump
  227. .
  228. computeHeight $:playerHeight
  229. SAF_frame $startFrame - 32 % 0 = ?
  230. $score ++ $:score
  231. .
  232. playerCollides ?
  233. $score getHighScore > ?
  234. $score setHighScore
  235. .
  236. SAF_SOUND_BOOM SAF_playSound
  237. 50 $:gameState
  238. .
  239. ;
  240. $gameState 1 = ?
  241. buttonPressed ?
  242. restart
  243. 0 $:gameState
  244. .
  245. ; # gameState > 1
  246. computeHeight $:playerHeight
  247. $gameState -- $:gameState
  248. $gameState 1 = ?
  249. restart
  250. .
  251. .
  252. .
  253. .
  254. restart