Files
basic1/games/lua_examples/ball.lua
Adolfo Reyna b22170b62c Fix Lua game float-to-int conversion errors for renderer.circle()
All games had the same issue: renderer.circle() requires integer arguments,
but float calculations produced non-integer coordinates.

Fixed in all games using math.floor(x + 0.5) for proper rounding:
- pong.lua: Ball position
- air_hockey.lua: Puck position
- asteroids.lua: Asteroid positions
- ball.lua: Ball and trail positions, velocity line
- breakout.lua: Ball position
- flappy_bird.lua: Bird Y position
- counter.lua: Last touch marker position
- snake.lua: Food position (center calculation)
- tic_tac_toe.lua: O circle center position

Also fixed floating-point coordinate calculations in ball and line
drawing to ensure all coordinates are integers.
2026-02-12 20:51:26 -05:00

85 lines
3.0 KiB
Lua

-- NAME: Bouncing Ball
-- DESC: Physics demo with state management
-- States
local STATE_PAUSED = 0
local STATE_RUNNING = 1
function init()
game.vars.state = STATE_PAUSED
game.vars.ball_x = game.width() / 2
game.vars.ball_y = game.height() / 2
game.vars.vel_x = 3
game.vars.vel_y = 2
game.vars.radius = 10
game.vars.frame_count = 0
-- Enable continuous frame updates for smooth animation
game.set_frame_updates(true)
print("Bouncing Ball initialized")
end
function update(event)
-- Toggle pause on tap
if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.BUTTON_0 or event.type == INPUT.BUTTON_1 then
if game.vars.state == STATE_PAUSED then
game.vars.state = STATE_RUNNING
else
game.vars.state = STATE_PAUSED
end
return true
end
-- Update physics if running (on any frame tick)
if event.type == INPUT.FRAME_TICK and game.vars.state == STATE_RUNNING then
-- Move ball
game.vars.ball_x = game.vars.ball_x + game.vars.vel_x
game.vars.ball_y = game.vars.ball_y + game.vars.vel_y
-- Bounce off walls
if game.vars.ball_x - game.vars.radius < 0 or game.vars.ball_x + game.vars.radius > game.width() then
game.vars.vel_x = -game.vars.vel_x
game.vars.ball_x = math.max(game.vars.radius, math.min(game.width() - game.vars.radius, game.vars.ball_x))
end
if game.vars.ball_y - game.vars.radius < 0 or game.vars.ball_y + game.vars.radius > game.height() then
game.vars.vel_y = -game.vars.vel_y
game.vars.ball_y = math.max(game.vars.radius, math.min(game.height() - game.vars.radius, game.vars.ball_y))
end
game.vars.frame_count = game.vars.frame_count + 1
return true -- Always redraw when running
end
return false
end
function draw()
renderer.clear(false)
-- Draw ball (convert to integers)
renderer.circle(math.floor(game.vars.ball_x + 0.5), math.floor(game.vars.ball_y + 0.5), game.vars.radius, true, true)
-- Draw trail (previous positions)
local trail_radius = game.vars.radius - 2
if trail_radius > 2 then
renderer.circle(math.floor(game.vars.ball_x - game.vars.vel_x + 0.5),
math.floor(game.vars.ball_y - game.vars.vel_y + 0.5),
trail_radius, true, false)
end
-- Draw status
if game.vars.state == STATE_PAUSED then
renderer.text(10, 10, "PAUSED - Tap to start", true)
else
renderer.text(10, 10, "Frames: " .. tostring(game.vars.frame_count), true)
renderer.text(10, 25, "Tap to pause", true)
end
-- Draw velocity vector
local arrow_x = game.vars.ball_x + game.vars.vel_x * 3
local arrow_y = game.vars.ball_y + game.vars.vel_y * 3
renderer.line(math.floor(game.vars.ball_x + 0.5), math.floor(game.vars.ball_y + 0.5), math.floor(arrow_x + 0.5), math.floor(arrow_y + 0.5), true, 2)
end