Scale games on both axes and 2x text size

All 4 games (simon_says, tic_tac_toe, memory_match, 2048):
- Changed sizing to use min(width, height) instead of just width
- Grids now scale proportionally on both axes
- All UI text now uses text_scale=2 for better visibility
- Games fill more of the screen properly on portrait mode

Fixes:
- Simon Says buttons now square grid on any orientation
- Tic-Tac-Toe grid centered vertically using full screen height
- Memory Match cards use smallest dimension for square sizing
- 2048 tiles scale and center on both axes
- All text (scores, menus, game over) now 2x larger
This commit is contained in:
Adolfo Reyna
2026-02-12 21:23:34 -05:00
parent a274fb04a1
commit fa7d2fd32f
4 changed files with 59 additions and 53 deletions

View File

@@ -12,9 +12,10 @@ local GRID_SIZE = 4
-- Calculate tile size based on screen size -- Calculate tile size based on screen size
local function get_tile_size() local function get_tile_size()
-- Use available space with padding -- Use smallest dimension for square grid
local padding = math.floor(game.width() / 8) local min_dim = math.min(game.width(), game.height())
local available = game.width() - (padding * 2) local padding = math.floor(min_dim / 8)
local available = min_dim - (padding * 2)
local tile_size = math.floor(available / GRID_SIZE) local tile_size = math.floor(available / GRID_SIZE)
return tile_size return tile_size
end end
@@ -26,7 +27,9 @@ local function get_grid_start_x()
end end
local function get_grid_start_y() local function get_grid_start_y()
return 30 local tile_size = get_tile_size()
local grid_height = tile_size * GRID_SIZE
return math.floor((game.height() - grid_height) / 2)
end end
function init() function init()
@@ -119,8 +122,8 @@ function draw()
local start_y = get_grid_start_y() local start_y = get_grid_start_y()
if state == STATE_MENU then if state == STATE_MENU then
renderer.text(game.width() / 2 - 15, game.height() / 2 - 30, "2048", true) renderer.text(game.width() / 2 - 15, game.height() / 2 - 30, "2048", true, 2)
renderer.text(game.width() / 2 - 50, game.height() / 2, "Tap to Start", true) renderer.text(game.width() / 2 - 50, game.height() / 2, "Tap to Start", true, 2)
elseif state == STATE_PLAYING or state == STATE_WIN or state == STATE_GAME_OVER then elseif state == STATE_PLAYING or state == STATE_WIN or state == STATE_GAME_OVER then
-- Draw grid -- Draw grid
@@ -140,27 +143,27 @@ function draw()
-- Draw value (simplified) -- Draw value (simplified)
local text = tostring(value) local text = tostring(value)
if string.len(text) <= 2 then if string.len(text) <= 2 then
renderer.text(tile_x + 2, tile_y + 2, text, false) renderer.text(tile_x + 2, tile_y + 2, text, false, 2)
else else
renderer.text(tile_x + 1, tile_y + 2, text, false) renderer.text(tile_x + 1, tile_y + 2, text, false, 2)
end end
end end
end end
end end
-- Draw score -- Draw score
renderer.text(10, 10, "Score: " .. tostring(game.vars.score), true) renderer.text(10, 10, "Score: " .. tostring(game.vars.score), true, 2)
if state == STATE_WIN then if state == STATE_WIN then
renderer.text(game.width() / 2 - 30, game.height() / 2 - 20, "YOU WIN!", true) renderer.text(game.width() / 2 - 30, game.height() / 2 - 20, "YOU WIN!", true, 2)
renderer.text(game.width() / 2 - 60, game.height() / 2, "Tap up: Continue", true) renderer.text(game.width() / 2 - 60, game.height() / 2, "Tap up: Continue", true, 2)
renderer.text(game.width() / 2 - 50, game.height() / 2 + 15, "Tap down: Menu", true) renderer.text(game.width() / 2 - 50, game.height() / 2 + 15, "Tap down: Menu", true, 2)
end end
if state == STATE_GAME_OVER then if state == STATE_GAME_OVER then
renderer.text(game.width() / 2 - 40, game.height() / 2, "GAME OVER", true) renderer.text(game.width() / 2 - 40, game.height() / 2, "GAME OVER", true, 2)
renderer.text(game.width() / 2 - 30, game.height() / 2 + 15, "Score: " .. tostring(game.vars.score), true) renderer.text(game.width() / 2 - 30, game.height() / 2 + 15, "Score: " .. tostring(game.vars.score), true, 2)
renderer.text(game.width() / 2 - 60, game.height() / 2 + 30, "Tap to Menu", true) renderer.text(game.width() / 2 - 60, game.height() / 2 + 30, "Tap to Menu", true, 2)
end end
end end
end end

View File

@@ -13,14 +13,15 @@ local FLIP_DURATION = 15 -- Frames to show flip animation
-- Calculate card size based on screen size -- Calculate card size based on screen size
local function get_card_size() local function get_card_size()
-- Use available space with padding -- Use available space with padding, based on smallest dimension
local padding = math.floor(game.width() / 8) local min_dim = math.min(game.width(), game.height())
local available_width = game.width() - (padding * 2) local padding = math.floor(min_dim / 8)
local available_height = game.height() - 80 -- Leave room for text local available_w = game.width() - (padding * 2)
local available_h = game.height() - 80 -- Leave room for text
-- Calculate based on grid -- Calculate based on grid
local card_width = math.floor(available_width / GRID_COLS) local card_width = math.floor(available_w / GRID_COLS)
local card_height = math.floor(available_height / GRID_ROWS) local card_height = math.floor(available_h / GRID_ROWS)
-- Use the smaller dimension for square cards -- Use the smaller dimension for square cards
return math.min(card_width, card_height) return math.min(card_width, card_height)
@@ -33,7 +34,7 @@ local function get_grid_start_x()
end end
local function get_grid_start_y() local function get_grid_start_y()
return 40 return 60
end end
function init() function init()
@@ -133,9 +134,9 @@ function draw()
local start_y = get_grid_start_y() local start_y = get_grid_start_y()
if state == STATE_MENU then if state == STATE_MENU then
renderer.text(game.width() / 2 - 40, game.height() / 2 - 40, "MEMORY MATCH", true) renderer.text(game.width() / 2 - 40, game.height() / 2 - 40, "MEMORY MATCH", true, 2)
renderer.text(game.width() / 2 - 50, game.height() / 2 - 10, "Find all pairs", true) renderer.text(game.width() / 2 - 50, game.height() / 2 - 10, "Find all pairs", true, 2)
renderer.text(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true) renderer.text(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true, 2)
elseif state == STATE_PLAYING or state == STATE_GAME_OVER then elseif state == STATE_PLAYING or state == STATE_GAME_OVER then
-- Draw grid -- Draw grid
@@ -150,7 +151,7 @@ function draw()
-- Show card value -- Show card value
renderer.rect(x, y, card_size, card_size, true, true) renderer.rect(x, y, card_size, card_size, true, true)
local text = tostring(card.id) local text = tostring(card.id)
renderer.text(x + math.floor(card_size / 2 - 2), y + math.floor(card_size / 2 - 2), text, false) renderer.text(x + math.floor(card_size / 2 - 2), y + math.floor(card_size / 2 - 2), text, false, 2)
else else
-- Face down (outline) -- Face down (outline)
renderer.rect(x, y, card_size, card_size, true, false) renderer.rect(x, y, card_size, card_size, true, false)
@@ -159,12 +160,12 @@ function draw()
end end
-- Draw stats -- Draw stats
renderer.text(10, 10, "Pairs: " .. tostring(game.vars.score) .. "/" .. tostring((GRID_COLS * GRID_ROWS) / 2), true) renderer.text(10, 10, "Pairs: " .. tostring(game.vars.score) .. "/" .. tostring((GRID_COLS * GRID_ROWS) / 2), true, 2)
renderer.text(10, 20, "Moves: " .. tostring(game.vars.moves), true) renderer.text(10, 25, "Moves: " .. tostring(game.vars.moves), true, 2)
if state == STATE_GAME_OVER then if state == STATE_GAME_OVER then
renderer.text(game.width() / 2 - 40, 5, "YOU WIN!", true) renderer.text(game.width() / 2 - 40, 5, "YOU WIN!", true, 2)
renderer.text(game.width() / 2 - 50, game.height() - 20, "Tap to Menu", true) renderer.text(game.width() / 2 - 50, game.height() - 20, "Tap to Menu", true, 2)
end end
end end
end end

View File

@@ -13,8 +13,9 @@ local WAIT_DURATION = 20 -- Frames between shows
-- Button positions (calculated dynamically based on screen size) -- Button positions (calculated dynamically based on screen size)
local function get_buttons() local function get_buttons()
local padding = math.floor(game.width() / 10) local padding = math.floor(math.min(game.width(), game.height()) / 10)
local button_size = math.floor((game.width() - padding * 3) / 2) local available = math.min(game.width(), game.height()) - (padding * 3)
local button_size = math.floor(available / 2)
local spacing = padding local spacing = padding
return { return {
@@ -147,9 +148,9 @@ function draw()
local buttons = get_buttons() local buttons = get_buttons()
if state == STATE_MENU then if state == STATE_MENU then
renderer.text(game.width() / 2 - 40, game.height() / 2 - 40, "SIMON SAYS", true) renderer.text(game.width() / 2 - 40, game.height() / 2 - 40, "SIMON SAYS", true, 2)
renderer.text(game.width() / 2 - 50, game.height() / 2 - 10, "Repeat the sequence", true) renderer.text(game.width() / 2 - 50, game.height() / 2 - 10, "Repeat the sequence", true, 2)
renderer.text(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true) renderer.text(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true, 2)
else else
-- Draw buttons with highlight -- Draw buttons with highlight
@@ -160,16 +161,16 @@ function draw()
end end
-- Draw score -- Draw score
renderer.text(10, 10, "Level: " .. tostring(game.vars.score + 1), true) renderer.text(10, 10, "Level: " .. tostring(game.vars.score + 1), true, 2)
if state == STATE_PLAYING and game.vars.waiting_for_input then if state == STATE_PLAYING and game.vars.waiting_for_input then
renderer.text(game.width() / 2 - 40, game.height() - 20, "Your turn!", true) renderer.text(game.width() / 2 - 40, game.height() - 20, "Your turn!", true, 2)
end end
if state == STATE_GAME_OVER then if state == STATE_GAME_OVER then
renderer.text(game.width() / 2 - 40, game.height() / 2 - 20, "GAME OVER", true) renderer.text(game.width() / 2 - 40, game.height() / 2 - 20, "GAME OVER", true, 2)
renderer.text(game.width() / 2 - 30, game.height() / 2, "Level: " .. tostring(game.vars.score + 1), true) renderer.text(game.width() / 2 - 30, game.height() / 2, "Level: " .. tostring(game.vars.score + 1), true, 2)
renderer.text(game.width() / 2 - 60, game.height() / 2 + 20, "Tap to Restart", true) renderer.text(game.width() / 2 - 60, game.height() / 2 + 20, "Tap to Restart", true, 2)
end end
end end
end end

View File

@@ -11,24 +11,25 @@ local GRID_SIZE = 3
-- Calculate cell size based on screen size -- Calculate cell size based on screen size
local function get_cell_size() local function get_cell_size()
-- Use available space minus padding -- Use smallest dimension to maintain square grid
local padding = math.floor(game.width() / 8) local min_dim = math.min(game.width(), game.height())
local available = game.width() - (padding * 2) local padding = math.floor(min_dim / 8)
local available = min_dim - (padding * 2)
local cell_size = math.floor(available / GRID_SIZE) local cell_size = math.floor(available / GRID_SIZE)
return cell_size return cell_size
end end
local function get_grid_start_y() local function get_grid_start_y()
-- Center grid vertically with some top margin -- Center grid vertically
local cell_size = get_cell_size() local cell_size = get_cell_size()
local grid_height = cell_size * GRID_SIZE + 2 * 2 -- spacing local grid_height = cell_size * GRID_SIZE
return math.floor((game.height() - grid_height) / 2) return math.floor((game.height() - grid_height) / 2)
end end
local function get_grid_start_x() local function get_grid_start_x()
-- Center grid horizontally -- Center grid horizontally
local cell_size = get_cell_size() local cell_size = get_cell_size()
local grid_width = cell_size * GRID_SIZE + 2 * 2 -- spacing local grid_width = cell_size * GRID_SIZE
return math.floor((game.width() - grid_width) / 2) return math.floor((game.width() - grid_width) / 2)
end end
@@ -127,9 +128,9 @@ function draw()
local cell_spacing = 2 local cell_spacing = 2
if state == STATE_MENU then if state == STATE_MENU then
renderer.text(game.width() / 2 - 50, game.height() / 2 - 30, "TIC-TAC-TOE", true) renderer.text(game.width() / 2 - 50, game.height() / 2 - 30, "TIC-TAC-TOE", true, 2)
renderer.text(game.width() / 2 - 50, game.height() / 2, "Play vs AI", true) renderer.text(game.width() / 2 - 50, game.height() / 2, "Play vs AI", true, 2)
renderer.text(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true) renderer.text(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true, 2)
elseif state == STATE_PLAYING or state == STATE_GAME_OVER then elseif state == STATE_PLAYING or state == STATE_GAME_OVER then
-- Draw grid -- Draw grid
@@ -157,14 +158,14 @@ function draw()
if state == STATE_GAME_OVER then if state == STATE_GAME_OVER then
if game.vars.winner == 1 then if game.vars.winner == 1 then
renderer.text(game.width() / 2 - 30, 10, "YOU WIN!", true) renderer.text(game.width() / 2 - 30, 10, "YOU WIN!", true, 2)
elseif game.vars.winner == 2 then elseif game.vars.winner == 2 then
renderer.text(game.width() / 2 - 30, 10, "AI WINS!", true) renderer.text(game.width() / 2 - 30, 10, "AI WINS!", true, 2)
else else
renderer.text(game.width() / 2 - 20, 10, "DRAW!", true) renderer.text(game.width() / 2 - 20, 10, "DRAW!", true, 2)
end end
renderer.text(game.width() / 2 - 60, game.height() - 15, "Tap to Menu", true) renderer.text(game.width() / 2 - 60, game.height() - 15, "Tap to Menu", true, 2)
end end
end end
end end