-- title: drop -- author: pixelbath -- desc: 99 balls / wallsmash -- script: lua t=0 dt=0 x=96 y=24 num_rows=10 num_cols=10 rows_start=4 balls={} lasers=0 blocks={} blockWidth = 24 blockHeight = 13 previewDotCount = 31 -- starting player stuff playerBalls = 1 playerLasers = 0 launchBalls = 0 xpos=120 ypos=130 angle=-90 initialAngleSpeed=1 angleMin = -170 angleMax = -10 ballVel = 2.5 laserJitter = 2 -- degrees -- launch control ballGapTime = 50 laserGapTime = 20 -- todo: random delay? launchMode = false launchBallTimer = 0 launchLaserTimer = 0 launchBalls = playerBalls launchLasers = playerLasers -- debug stuff freeze = false function generate_grid() for row=0,num_rows-1 do blocks[row] = {} for col=0,num_cols-1 do if row < 5 and math.random() > 0.5 then blocks[row][col] = 5 else blocks[row][col] = 0 end end end end function launch_ball() theta=math.pi * angle / 180 table.insert(balls, { x = xpos, y = ypos, vx = ballVel * math.cos(theta), vy = ballVel * math.sin(theta), }) launchBalls = launchBalls - 1 end function draw_preview() theta=math.pi * angle / 180 xtarget=xpos + (160 * math.cos(theta)) ytarget=ypos + (160 * math.sin(theta)) dotGapX = (xtarget - xpos) / previewDotCount dotGapY = (ytarget - ypos) / previewDotCount -- line(xpos, ypos, xtarget, ytarget, 8) dotx=xpos doty=ypos for i=0,previewDotCount do pix(dotx, doty, 5) dotx = dotx + dotGapX doty = doty + dotGapY end print(playerBalls, xpos-8, 130, 12, false, 1, true) print(playerLasers, xpos+5, 130, 10, false, 1, true) end function draw_balls_and_lasers() for k,ball in pairs(balls) do circ(ball.x, ball.y, 1, 12) ball.x = ball.x + ball.vx ball.y = ball.y + ball.vy check_ball_collisions(ball) -- wall bounce if ball.x <= 0 or ball.x >= 240 then ball.vx = ball.vx * -1 end if ball.y <= 0 then ball.vy = ball.vy * -1 end -- prune the fallen boyz if ball.y >= ypos + 2 then table.remove(balls, k) if #balls == 0 then end end end end function circleRect(cx, cy, radius, rx, ry, rw, rh) -- temporary variables to set edges for testing local testX = cx local testY = cy -- which edge is closest? if cx < rx then testX = rx -- test left edge elseif cx > rx+rw then testX = rx+rw end -- right edge if cy < ry then testY = ry -- top edge elseif cy > ry+rh then testY = ry+rh end -- bottom edge -- get distance from closest edges local distX = cx-testX local distY = cy-testY local distance = math.sqrt( (distX*distX) + (distY*distY) ) -- if the distance is less than the radius, collision! if distance <= radius then return true end return false end function check_ball_collisions(ball) for row=0,num_rows-1 do for col=0,num_cols-1 do blockVal = blocks[row][col] if blockVal > 0 then local blockX = col * blockWidth local blockY = row * blockHeight -- if ball.x >= blockX then -- end -- if ball.x >= col * blockWidth and ball.x <= col * blockWidth + blockWidth then -- if ball.y >= row * blockHeight and ball.y <= row * blockHeight + blockHeight then -- if row * blockHeight - ball.y <= 1 or row * blockHeight + blockHeight - ball.y <= 1 then -- ball.vy = ball.vy * -1 -- blocks[row][col] = blockVal - 1 -- freeze = true -- else -- ball.vx = ball.vx * -1 -- blocks[row][col] = blockVal - 1 -- freeze = true -- end -- end -- end if circleRect(ball.x, ball.y, 2, blockX, blockY, blockWidth, blockHeight) then -- bottom if ball.y <= blockY - (blockHeight/2) then -- ball.y = blockY+1 ball.vy = ball.vy * -1 return end -- top if ball.y >= blockY + (blockHeight/2) then -- ball.y = blockY-1 ball.vy = ball.vy * -1 return end -- left if ball.x < blockX - (blockWidth/2) then -- ball.x = blockX-1 ball.vx = ball.vx * -1 return end -- right if ball.x > blockX then -- ball.x = blockX+1 ball.vx = ball.vx * -1 return end freeze = true end end end end end function draw_blocks() for row=0,num_rows-1 do for col=0,num_cols-1 do blockVal = blocks[row][col] colorCursor = 1 printPos = col * blockWidth + 8 if blockVal > 0 then if blockVal < 18 then colorCursor = colorCursor + 1 end if blockVal < 14 then colorCursor = colorCursor + 1 end if blockVal < 9 then colorCursor = colorCursor + 1 printPos = col * blockWidth + 10 end rect(col * blockWidth, row * blockHeight, blockWidth, blockHeight, colorCursor) print(blockVal, printPos, row * blockHeight + 4, 0, false, 1, true) end end end end function draw_debug() print(angle, 2, 130, 5, false, 1, true) print(playerBalls, 18, 130, 5, false, 1, true) print(#balls, 24, 130, 5, false, 1, true) print(launchMode, 34, 130, 5, false, 1, true) print(launchBallTimer, 64, 130, 5, false, 1, true) end -- P1 starts at 0; for players up to P4 add 8 to the ID value -- U D L R, A B X Y -> 0 1 2 3, 4 5 6 7 function handle_input() -- move faster if btn(5) then angleSpeed=initialAngleSpeed + initialAngleSpeed * 0.5 else angleSpeed=initialAngleSpeed end -- move slower if btn(6) then angleSpeed=initialAngleSpeed * 0.3 else angleSpeed=initialAngleSpeed end if btnp(4) then launchMode = true end if btn(2) then angle=angle-angleSpeed end if btn(3) then angle=angle+angleSpeed end -- clamp angle values if angle < angleMin then angle=angleMin-angleSpeed end if angle > angleMax then angle=angleMax end end -- run this stuff for init generate_grid() function TIC() if not freeze then t=time() end cls(0) draw_blocks() if launchMode then if launchBalls > 0 then if launchBallTimer == 0 then launchBallTimer = ballGapTime launch_ball() end launchBallTimer = launchBallTimer - 1 end if launchLasers > 0 then if launchBallTimer == 0 then launchLaserTimer = ballGapTime launch_laser() end launchLaserTimer = launchLaserTimer - 1 end draw_balls_and_lasers() -- if we're outta balls, turn off launchMode if #balls == 0 then launchMode = false launchBallTimer = 0 launchLaserTimer = 0 -- temp launchBalls = playerBalls end else handle_input() draw_preview() end draw_debug() end -- -- 001:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -- 002:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -- 003:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -- 004:0000000000ccc0000ccccc000ccccc000ccccc0000ccc0000000000000000000 -- -- -- 000:00000000ffffffff00000000ffffffff -- 001:0123456789abcdeffedcba9876543210 -- 002:0123456789abcdef0123456789abcdef -- -- -- 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000 -- -- -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 --