drop.lua 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. -- title: drop
  2. -- author: pixelbath
  3. -- desc: 99 balls / wallsmash
  4. -- script: lua
  5. t=0
  6. dt=0
  7. x=96
  8. y=24
  9. num_rows=10
  10. num_cols=10
  11. rows_start=4
  12. balls={}
  13. lasers=0
  14. blocks={}
  15. blockWidth = 24
  16. blockHeight = 13
  17. previewDotCount = 31
  18. -- starting player stuff
  19. playerBalls = 1
  20. playerLasers = 0
  21. launchBalls = 0
  22. xpos=120
  23. ypos=130
  24. angle=-90
  25. initialAngleSpeed=1
  26. angleMin = -170
  27. angleMax = -10
  28. ballVel = 2.5
  29. laserJitter = 2 -- degrees
  30. -- launch control
  31. ballGapTime = 50
  32. laserGapTime = 20 -- todo: random delay?
  33. launchMode = false
  34. launchBallTimer = 0
  35. launchLaserTimer = 0
  36. launchBalls = playerBalls
  37. launchLasers = playerLasers
  38. -- debug stuff
  39. freeze = false
  40. function generate_grid()
  41. for row=0,num_rows-1 do
  42. blocks[row] = {}
  43. for col=0,num_cols-1 do
  44. if row < 5 and math.random() > 0.5 then
  45. blocks[row][col] = 5
  46. else
  47. blocks[row][col] = 0
  48. end
  49. end
  50. end
  51. end
  52. function launch_ball()
  53. theta=math.pi * angle / 180
  54. table.insert(balls, {
  55. x = xpos,
  56. y = ypos,
  57. vx = ballVel * math.cos(theta),
  58. vy = ballVel * math.sin(theta),
  59. })
  60. launchBalls = launchBalls - 1
  61. end
  62. function draw_preview()
  63. theta=math.pi * angle / 180
  64. xtarget=xpos + (160 * math.cos(theta))
  65. ytarget=ypos + (160 * math.sin(theta))
  66. dotGapX = (xtarget - xpos) / previewDotCount
  67. dotGapY = (ytarget - ypos) / previewDotCount
  68. -- line(xpos, ypos, xtarget, ytarget, 8)
  69. dotx=xpos
  70. doty=ypos
  71. for i=0,previewDotCount do
  72. pix(dotx, doty, 5)
  73. dotx = dotx + dotGapX
  74. doty = doty + dotGapY
  75. end
  76. print(playerBalls, xpos-8, 130, 12, false, 1, true)
  77. print(playerLasers, xpos+5, 130, 10, false, 1, true)
  78. end
  79. function draw_balls_and_lasers()
  80. for k,ball in pairs(balls) do
  81. circ(ball.x, ball.y, 1, 12)
  82. ball.x = ball.x + ball.vx
  83. ball.y = ball.y + ball.vy
  84. check_ball_collisions(ball)
  85. -- wall bounce
  86. if ball.x <= 0 or ball.x >= 240 then
  87. ball.vx = ball.vx * -1
  88. end
  89. if ball.y <= 0 then
  90. ball.vy = ball.vy * -1
  91. end
  92. -- prune the fallen boyz
  93. if ball.y >= ypos + 2 then
  94. table.remove(balls, k)
  95. if #balls == 0 then
  96. end
  97. end
  98. end
  99. end
  100. function circleRect(cx, cy, radius, rx, ry, rw, rh)
  101. -- temporary variables to set edges for testing
  102. local testX = cx
  103. local testY = cy
  104. -- which edge is closest?
  105. if cx < rx then testX = rx -- test left edge
  106. elseif cx > rx+rw then testX = rx+rw end -- right edge
  107. if cy < ry then testY = ry -- top edge
  108. elseif cy > ry+rh then testY = ry+rh end -- bottom edge
  109. -- get distance from closest edges
  110. local distX = cx-testX
  111. local distY = cy-testY
  112. local distance = math.sqrt( (distX*distX) + (distY*distY) )
  113. -- if the distance is less than the radius, collision!
  114. if distance <= radius then
  115. return true
  116. end
  117. return false
  118. end
  119. function check_ball_collisions(ball)
  120. for row=0,num_rows-1 do
  121. for col=0,num_cols-1 do
  122. blockVal = blocks[row][col]
  123. if blockVal > 0 then
  124. local blockX = col * blockWidth
  125. local blockY = row * blockHeight
  126. -- if ball.x >= blockX then
  127. -- end
  128. -- if ball.x >= col * blockWidth and ball.x <= col * blockWidth + blockWidth then
  129. -- if ball.y >= row * blockHeight and ball.y <= row * blockHeight + blockHeight then
  130. -- if row * blockHeight - ball.y <= 1 or row * blockHeight + blockHeight - ball.y <= 1 then
  131. -- ball.vy = ball.vy * -1
  132. -- blocks[row][col] = blockVal - 1
  133. -- freeze = true
  134. -- else
  135. -- ball.vx = ball.vx * -1
  136. -- blocks[row][col] = blockVal - 1
  137. -- freeze = true
  138. -- end
  139. -- end
  140. -- end
  141. if circleRect(ball.x, ball.y, 2, blockX, blockY, blockWidth, blockHeight) then
  142. -- bottom
  143. if ball.y <= blockY - (blockHeight/2) then
  144. -- ball.y = blockY+1
  145. ball.vy = ball.vy * -1
  146. return
  147. end
  148. -- top
  149. if ball.y >= blockY + (blockHeight/2) then
  150. -- ball.y = blockY-1
  151. ball.vy = ball.vy * -1
  152. return
  153. end
  154. -- left
  155. if ball.x < blockX - (blockWidth/2) then
  156. -- ball.x = blockX-1
  157. ball.vx = ball.vx * -1
  158. return
  159. end
  160. -- right
  161. if ball.x > blockX then
  162. -- ball.x = blockX+1
  163. ball.vx = ball.vx * -1
  164. return
  165. end
  166. freeze = true
  167. end
  168. end
  169. end
  170. end
  171. end
  172. function draw_blocks()
  173. for row=0,num_rows-1 do
  174. for col=0,num_cols-1 do
  175. blockVal = blocks[row][col]
  176. colorCursor = 1
  177. printPos = col * blockWidth + 8
  178. if blockVal > 0 then
  179. if blockVal < 18 then
  180. colorCursor = colorCursor + 1
  181. end
  182. if blockVal < 14 then
  183. colorCursor = colorCursor + 1
  184. end
  185. if blockVal < 9 then
  186. colorCursor = colorCursor + 1
  187. printPos = col * blockWidth + 10
  188. end
  189. rect(col * blockWidth, row * blockHeight, blockWidth, blockHeight, colorCursor)
  190. print(blockVal, printPos, row * blockHeight + 4, 0, false, 1, true)
  191. end
  192. end
  193. end
  194. end
  195. function draw_debug()
  196. print(angle, 2, 130, 5, false, 1, true)
  197. print(playerBalls, 18, 130, 5, false, 1, true)
  198. print(#balls, 24, 130, 5, false, 1, true)
  199. print(launchMode, 34, 130, 5, false, 1, true)
  200. print(launchBallTimer, 64, 130, 5, false, 1, true)
  201. end
  202. -- P1 starts at 0; for players up to P4 add 8 to the ID value
  203. -- U D L R, A B X Y -> 0 1 2 3, 4 5 6 7
  204. function handle_input()
  205. -- move faster
  206. if btn(5) then
  207. angleSpeed=initialAngleSpeed + initialAngleSpeed * 0.5
  208. else
  209. angleSpeed=initialAngleSpeed
  210. end
  211. -- move slower
  212. if btn(6) then
  213. angleSpeed=initialAngleSpeed * 0.3
  214. else
  215. angleSpeed=initialAngleSpeed
  216. end
  217. if btnp(4) then
  218. launchMode = true
  219. end
  220. if btn(2) then
  221. angle=angle-angleSpeed
  222. end
  223. if btn(3) then
  224. angle=angle+angleSpeed
  225. end
  226. -- clamp angle values
  227. if angle < angleMin then
  228. angle=angleMin-angleSpeed
  229. end
  230. if angle > angleMax then
  231. angle=angleMax
  232. end
  233. end
  234. -- run this stuff for init
  235. generate_grid()
  236. function TIC()
  237. if not freeze then
  238. t=time()
  239. end
  240. cls(0)
  241. draw_blocks()
  242. if launchMode then
  243. if launchBalls > 0 then
  244. if launchBallTimer == 0 then
  245. launchBallTimer = ballGapTime
  246. launch_ball()
  247. end
  248. launchBallTimer = launchBallTimer - 1
  249. end
  250. if launchLasers > 0 then
  251. if launchBallTimer == 0 then
  252. launchLaserTimer = ballGapTime
  253. launch_laser()
  254. end
  255. launchLaserTimer = launchLaserTimer - 1
  256. end
  257. draw_balls_and_lasers()
  258. -- if we're outta balls, turn off launchMode
  259. if #balls == 0 then
  260. launchMode = false
  261. launchBallTimer = 0
  262. launchLaserTimer = 0
  263. -- temp
  264. launchBalls = playerBalls
  265. end
  266. else
  267. handle_input()
  268. draw_preview()
  269. end
  270. draw_debug()
  271. end
  272. -- <TILES>
  273. -- 001:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  274. -- 002:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  275. -- 003:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  276. -- 004:0000000000ccc0000ccccc000ccccc000ccccc0000ccc0000000000000000000
  277. -- </TILES>
  278. -- <WAVES>
  279. -- 000:00000000ffffffff00000000ffffffff
  280. -- 001:0123456789abcdeffedcba9876543210
  281. -- 002:0123456789abcdef0123456789abcdef
  282. -- </WAVES>
  283. -- <SFX>
  284. -- 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000
  285. -- </SFX>
  286. -- <PALETTE>
  287. -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
  288. -- </PALETTE>