I made my own minigame app called Fynk with chatGPT

Fynk game

– Fynk - Mini-Game Party
– Standalone Codea Lua Script

– Game state
currentGame = nil
buttons = {}

– Tap Battle
player1Score = 0
player2Score = 0
winner = nil

– Reaction Test
reactionActive = false
reactionStart = 0
reactionTime = nil
reactionMessage = “Tap Start”

– Color Match
colorOptions = {“Red”,“Green”,“Blue”,“Yellow”}
targetColor = “Red”
scoreColorMatch = 0

– Dodge the Blocks
playerX = WIDTH/2
playerSize = 50
blocks = {}
blockSpeed = 5
scoreDodge = 0

– Number Memory
sequence = {}
playerInput = {}
showSequence = true
seqIndex = 1
scoreMemory = 0

– ---------------- Setup ----------------
function setup()
resetTapBattle()
resetReactionTest()
resetColorMatch()
resetDodgeBlocks()
resetNumberMemory()
end

function draw()
background(30,30,40)
buttons = {} – reset buttons each frame

if not currentGame then
    drawMainMenu()
elseif currentGame == "tap" then
    drawTapBattle()
elseif currentGame == "reaction" then
    drawReactionTest()
elseif currentGame == "color" then
    drawColorMatch()
elseif currentGame == "dodge" then
    drawDodgeBlocks()
elseif currentGame == "memory" then
    drawNumberMemory()
end

end

– ---------------- Main Menu ----------------
function drawMainMenu()
fill(255)
fontSize(50)
text(“:video_game: Fynk”, WIDTH/2, HEIGHT - 100)

drawButton(WIDTH/2, HEIGHT/2 + 140, 300, 60, "Tap Battle", function() resetTapBattle(); currentGame="tap" end)
drawButton(WIDTH/2, HEIGHT/2 + 70, 300, 60, "Reaction Test", function() resetReactionTest(); currentGame="reaction" end)
drawButton(WIDTH/2, HEIGHT/2, 300, 60, "Color Match", function() resetColorMatch(); currentGame="color" end)
drawButton(WIDTH/2, HEIGHT/2 - 70, 300, 60, "Dodge the Blocks", function() resetDodgeBlocks(); currentGame="dodge" end)
drawButton(WIDTH/2, HEIGHT/2 - 140, 300, 60, "Number Memory", function() resetNumberMemory(); currentGame="memory" end)

end

– ---------------- Tap Battle ----------------
function drawTapBattle()
fill(255,0,0) rect(0,0,WIDTH/2,HEIGHT)
fill(0,0,255) rect(WIDTH/2,0,WIDTH/2,HEIGHT)
fill(255) fontSize(60)
text(player1Score, WIDTH/4, HEIGHT/2)
text(player2Score, 3*WIDTH/4, HEIGHT/2)
if winner then
fill(0,0,0,180) rect(0, HEIGHT/2-100, WIDTH, 200)
fill(255,255,0) fontSize(60)
text(winner.." Wins!", WIDTH/2, HEIGHT/2)
drawButton(WIDTH/2, HEIGHT/2-120, 250,60,“Play Again”,function() resetTapBattle() end)
end
drawButton(WIDTH/2,80,200,50,“Back”,function() currentGame=nil end)
end

function resetTapBattle()
player1Score=0 player2Score=0 winner=nil
end

– ---------------- Reaction Test ----------------
function drawReactionTest()
fill(255) fontSize(40)
text(“:high_voltage: Reaction Test :high_voltage:”, WIDTH/2, HEIGHT-100)
text(reactionMessage, WIDTH/2, HEIGHT/2 +50)
if reactionTime then
text(string.format(“:stopwatch: %.3f sec”, reactionTime), WIDTH/2, HEIGHT/2-50)
drawButton(WIDTH/2,100,250,60,“Try Again”,function() resetReactionTest() end)
else drawButton(WIDTH/2,100,250,60,“Start”,function() startReactionTest() end)
end
drawButton(WIDTH/2,40,200,50,“Back”,function() currentGame=nil end)
end

function resetReactionTest() reactionActive=false reactionTime=nil reactionMessage=“Tap Start” end
function startReactionTest()
reactionMessage=“Wait for it…” reactionActive=false
local delay=math.random(1500,3500)/1000
timer.delay(function() reactionMessage=“TAP NOW!” reactionActive=true reactionStart=ElapsedTime end, delay)
end

– ---------------- Color Match ----------------
function drawColorMatch()
fill(255) fontSize(40)
text(“:artist_palette: Color Match”, WIDTH/2, HEIGHT-100)
text(“Tap “..targetColor..”!”, WIDTH/2, HEIGHT/2 +100)
local cols = {“Red”,“Green”,“Blue”,“Yellow”}
for i=1,4 do
local x=WIDTH/5*i
local y=HEIGHT/2
fill(cols[i]==“Red” and 255 or 0, cols[i]==“Green” and 255 or 0, cols[i]==“Blue” and 255 or 0)
rect(x-50,y-50,100,100)
drawButton(x,y,100,100,cols[i],function() checkColor(cols[i]) end)
end
text("Score: "..scoreColorMatch, WIDTH/2, 80)
drawButton(WIDTH/2,40,200,50,“Back”,function() currentGame=nil end)
end

function resetColorMatch() scoreColorMatch=0 targetColor=colorOptions[math.random(4)] end
function checkColor(c)
if c==targetColor then scoreColorMatch=scoreColorMatch+1 end
targetColor=colorOptions[math.random(4)]
end

– ---------------- Dodge the Blocks ----------------
function drawDodgeBlocks()
fill(255) fontSize(40)
text(“:black_large_square: Dodge the Blocks”, WIDTH/2, HEIGHT-100)
fill(0,255,0) rect(playerX,50,playerSize,playerSize)
for i=#blocks,1,-1 do
local b=blocks[i]
fill(255,0,0) rect(b.x,b.y,50,50)
b.y=b.y-blockSpeed
if b.y<50 and math.abs(b.x-playerX)<50 then
scoreDodge=0 blocks={} return
elseif b.y<0 then table.remove(blocks,i) scoreDodge=scoreDodge+1 end
end
if math.random()<0.02 then table.insert(blocks,{x=math.random(50,WIDTH-50),y=HEIGHT}) end
text("Score: "..scoreDodge, WIDTH/2, 80)
drawButton(WIDTH/2,40,200,50,“Back”,function() currentGame=nil resetDodgeBlocks() end)
end

function resetDodgeBlocks() playerX=WIDTH/2 blocks={} scoreDodge=0 end

– ---------------- Number Memory ----------------
function drawNumberMemory()
fill(255) fontSize(40)
text(“:1234: Number Memory”, WIDTH/2, HEIGHT-100)
if showSequence then
for i,n in ipairs(sequence) do
text(n, WIDTH/2, HEIGHT-200 - i50)
end
drawButton(WIDTH/2,100,250,60,“Next”,function() showSequence=false playerInput={} seqIndex=1 end)
else
for i,n in ipairs(playerInput) do
text(n, WIDTH/2, HEIGHT-200 - i
50)
end
for i=1,9 do drawButton(50*i,100,40,40,tostring(i),function() addNumber(i) end) end
end
text("Score: "..scoreMemory, WIDTH/2,50)
drawButton(WIDTH/2,20,200,50,“Back”,function() currentGame=nil resetNumberMemory() end)
end

function resetNumberMemory()
sequence={} for i=1,3 do table.insert(sequence,math.random(1,9)) end
playerInput={} showSequence=true seqIndex=1 scoreMemory=0
end

function addNumber(n)
table.insert(playerInput,n)
if n~=sequence[seqIndex] then resetNumberMemory() return end
seqIndex=seqIndex+1
if seqIndex>#sequence then
scoreMemory=scoreMemory+1
table.insert(sequence,math.random(1,9))
showSequence=true
end
end

– ---------------- Touch Handling ----------------
function touched(t)
if t.state~=BEGAN then return end
if currentGame==“tap” then
if winner==nil then
if t.x<WIDTH/2 then player1Score=player1Score+1 else player2Score=player2Score+1 end
if player1Score>=15 then winner=“Player 1” end
if player2Score>=15 then winner=“Player 2” end
end
elseif currentGame==“reaction” then
if reactionActive then reactionTime=ElapsedTime-reactionStart reactionActive=false reactionMessage=“Nice reflexes!” end
end
for i=#buttons,1,-1 do
local b=buttons[i]
if t.x>=b.x-b.w/2 and t.x<=b.x+b.w/2 and t.y>=b.y-b.h/2 and t.y<=b.y+b.h/2 then
b.action()
end
end
end

– ---------------- UI Helper ----------------
function drawButton(x,y,w,h,label,action)
fill(100,200,250)
rect(x-w/2,y-h/2,w,h,12)
fill(255)
fontSize(30)
text(label,x,y)
table.insert(buttons,{x=x,y=y,w=w,h=h,action=action})
end

2 Likes

This is really cool.

It doesn’t work, but it’s still really cool.

Thank you for posting your code, I love running other people’s code to see how it works.

Three of the games were not playable and two fully crashed your app.

I had ChatGPT help me fix the errors in your code. Here’s the project (I also made your attached image the icon for the project):

Fynk.zip (163.1 KB)

There are still quite a few visual problems where text is wider than the screen or text overlaps but you should have GPT help you fix those.

Also I really like that you gave us your full code but you need to learn how to paste code properly otherwise a lot of formatting errors make it hard to run. I had the patience to fix these manually but most won’t.

To format code you have to put three tildes before and after it—a tilde is the “~” symbol. Here is the word “Code” formatted that way:

Code

This makes it easy for people to copy and paste it all at once.

Personally I think the whole project would look cooler with rounded buttons. Here’s some rounded rectangle code that the makers of Codea wrote in one of the demo projects:

function drawRoundedRect(x, y, w, h, r, fillCol, strokeCol)
    pushStyle()
    
    -- CENTER → CORNER
    local cx, cy = x - w/2, y - h/2
    
    -- choose colors
    local fc = fillCol or color(255)
    local sc = strokeCol or fillCol or color(255)
    
    fill(fc)
    stroke(sc)
    
    rectMode(CORNER)
    noSmooth()
    
    local insetPos  = vec2(cx + r, cy + r)
    local insetSize = vec2(w - 2*r, h - 2*r)
    rect(insetPos.x, insetPos.y, insetSize.x, insetSize.y)
    
    if r > 0 then
        smooth()
        lineCapMode(ROUND)
        strokeWidth(r * 2)
        
        -- top
        line(insetPos.x, insetPos.y,
        insetPos.x + insetSize.x, insetPos.y)
        -- bottom
        line(insetPos.x, insetPos.y + insetSize.y,
        insetPos.x + insetSize.x, insetPos.y + insetSize.y)
        -- left
        line(insetPos.x, insetPos.y,
        insetPos.x, insetPos.y + insetSize.y)
        -- right
        line(insetPos.x + insetSize.x, insetPos.y,
        insetPos.x + insetSize.x, insetPos.y + insetSize.y)
    end
    
    popStyle()
end

…if you would like rounded buttons, give GPT this code and ask it to apply it to all your buttons.

1 Like