diff --git a/gfx/button-table-114-32.png b/gfx/button-table-114-32.png new file mode 100644 index 0000000..b63139e Binary files /dev/null and b/gfx/button-table-114-32.png differ diff --git a/gfx/cart.png b/gfx/cart.png new file mode 100644 index 0000000..76d23fe Binary files /dev/null and b/gfx/cart.png differ diff --git a/gfx/comic.png b/gfx/comic.png new file mode 100644 index 0000000..fb1c95c Binary files /dev/null and b/gfx/comic.png differ diff --git a/gfx/enemy-table-30-48.png b/gfx/enemy-table-30-48.png new file mode 100644 index 0000000..25461e4 Binary files /dev/null and b/gfx/enemy-table-30-48.png differ diff --git a/gfx/floor.png b/gfx/floor.png new file mode 100644 index 0000000..89313bb Binary files /dev/null and b/gfx/floor.png differ diff --git a/gfx/font.fnt b/gfx/font.fnt new file mode 100644 index 0000000..3d09942 --- /dev/null +++ b/gfx/font.fnt @@ -0,0 +1,21 @@ +--metrics={"baseline":-2,"xHeight":8,"capHeight":2,"pairs":{},"left":[],"right":[]} +datalen=1552 +data=iVBORw0KGgoAAAANSUhEUgAAAGAAAABICAYAAAAJZ/BjAAAEUklEQVR4Xu1d23LrMAg8+f+PPu24sUciQssiUJwMeWkT2UhiYbnIaR//nq//v6/z99nPx+/Lcp12jTZPlly5DnYeq17OeVj5lzKtE7ETSAUUAL1GHlIhmoFLB2GB0OY55bLyNM+NXv+5buT4Xv0UAIBPtwFwIjxAslsia7HIw1h5GqVp62+4+fiVnY+gZpf8ywMKgLErfA0AEuDBe1d2hYK6pBDWA1DGtyp/mwcUAGMotwEwyMddnIks0hojvFlXtPwCgEVUXJ9GQdmUERUDkP5WFWTtFHj3o3pAAdBDi7KhAkChhtU6QHpAdKX9tR4Q3fpAFfFyK0Iiq1XEq3l0FCdbu62TApOqO7ZRUONy3R69HBedtlmDrkY9zecFgKc3s9vyrYB7DfQlBnyqByDO91r+xwMw6dV0lfCgUjZRhFXxUfI1QG7rAQXA3IfSD2RQ+jYI0sdH1l7NXeQvp6Eya9AUw3LpXRQkY1s0wG4ArL0OVvGs3GyO3iXfCuylT1ZR7ASogJkENVcQRlkLa0js+ln9vMQAtAF2AnYDrIJYA2LlZ6+/AAAWtw0AdCjv7QHtCsIoicgOwl755hOxAsAUkujHXrYDINO1qCCMngvKzoLCKuHoNrTWfo4K9rvkG9Z7XMIyxds8gM2mNAVkny+w87JZVgGATFsZR55nNbC3AbDK/TL/t8YAq2KQ5cusi6We634Dki5u26UgtH5v8L0tACzHTTi626O3mWWtM7zyJRAIcNbDaAoqAP6+yhV12K8eSU5c8BiyIq1ZaFS6iywyiqtlS8Kb979QotWFG04vAAYeYDVIFYBJVtIFYS8FoWzPa1GoDkDjaF3WZKIAeH57VqaDtwcApVtey5SWo6WDqwpC96Nx5AFZ3H8xSQEwh+BrAECVqtfTsrMgJN/L/ds9oAAYe5p6yrDKnVoMiH6+XqOIQQXbfWS13Cg9qFnm7hhQAPQahx6gZS8oexhYYOpfY5GeMKlrbGeLTwGaXKsHIT0VAEBD2wDIsiBUD0R5GLK0rPFVgLb9vaBsgLMUjOQuA7Ari2h6SMM9RfXrkcKixlGB1ux3GnO2PZ5eACh1AKr0pOJkswtZVLZ8NH/0eDRjwBOxAqCHcBsAZ567Wgmi+9F4tAV75Vk5XzNYLSbMvil/BI9VBaH70bhXYdH3FQDRGjXKQ5TTxMRDonzf1EHdjCfDlAcAIN4GgFzXXfv1RkN2XyYpEgnSPEB6AvSAAuBPA9sAkNFbAuCtVJELa/NEdRuRxaJx6/qtli+zodtUwpqLIgVlj28DIOvIsFHs9DzAG2OyAdDWrx0sscyRXgkXAL3dSWpNT0ORhX5KIYY8QasHJOe/JDdIAWgcKRiNZ8tH87PjqCJmn5pOpyC5YG3Dd48BA27vuIVV/OUZ2e3iAmD+L1+2paEoa/DWGSyFRF+vGZi1jikAFhFZBsCaJqJoru3DSkFe+Yv6e/vt6U9FFABzjH8AeebksrVI2isAAAAASUVORK5CYII= +width=24 +height=24 + +tracking=1 + +0 22 +1 12 +2 12 +3 12 +4 12 +5 12 +6 12 +7 12 +8 12 +9 12 +space 22 +� 20 + diff --git a/gfx/logo.png b/gfx/logo.png new file mode 100644 index 0000000..b3c2678 Binary files /dev/null and b/gfx/logo.png differ diff --git a/gfx/player-table-34-42.png b/gfx/player-table-34-42.png new file mode 100644 index 0000000..6ae9aa8 Binary files /dev/null and b/gfx/player-table-34-42.png differ diff --git a/gfx/security.png b/gfx/security.png new file mode 100644 index 0000000..b82e3bc Binary files /dev/null and b/gfx/security.png differ diff --git a/gfx/square-table-22-22.png b/gfx/square-table-22-22.png new file mode 100644 index 0000000..312eafe Binary files /dev/null and b/gfx/square-table-22-22.png differ diff --git a/launcher/card.png b/launcher/card.png new file mode 100644 index 0000000..7247449 Binary files /dev/null and b/launcher/card.png differ diff --git a/main.lua b/main.lua new file mode 100644 index 0000000..2b173c9 --- /dev/null +++ b/main.lua @@ -0,0 +1,346 @@ +-- PossiblyAxolotl +-- June 24th, 2022 to June 27th, 2022 +-- Shopping spree + +-- I am well aware that if you are touching an enemy and item at the same time no collision is counted +-- I am simply lazy and there's not enough jam time left to fix it + +-- IMPORTS +import "CoreLibs/ui" +import "CoreLibs/animation" +import "CoreLibs/sprites" +import "CoreLibs/math" +import "CoreLibs/graphics" + +local gfx = playdate.graphics + +-- sprites +local tSquare = gfx.imagetable.new("gfx/square") +local tPlayer = gfx.imagetable.new("gfx/player") +local tEnemy = gfx.imagetable.new("gfx/enemy") +local tButton = gfx.imagetable.new("gfx/button") +local imgCart = gfx.image.new("gfx/cart") +local imgLogo = gfx.image.new("gfx/logo") +local imgTile = gfx.image.new("gfx/floor") +local imgSecurity = gfx.image.new("gfx/security") +local imgComic = gfx.image.new("gfx/comic") +assert(tSquare) +assert(tPlayer) +assert(tEnemy) +assert(tButton) +assert(imgCart) +assert(imgLogo) +assert(imgTile) +assert(imgSecurity) +assert(imgComic) + +local animPlayer = gfx.animation.loop.new(150,tPlayer) +local animEnemy = gfx.animation.loop.new(200,tEnemy) +local animButton = gfx.animation.loop.new(300,tButton) + +local sprSquare = gfx.sprite.new(tSquare[1]) +local sprPlayer = gfx.sprite.new() +local sprEnemies = gfx.sprite.new() +sprSquare:setCollideRect(0,0,18,18) +sprPlayer:setCollideRect(6,2,22,34) +sprPlayer:setZIndex(2) +sprEnemies:setCollideRect(11,18,10,10) +sprSquare:add() +sprSquare:moveTo(50,50) +sprPlayer:add() +sprEnemies:add() + +-- sfx +local sfxCollect = playdate.sound.sampleplayer.new("sfx/collect") +local sfxLose = playdate.sound.sampleplayer.new("sfx/lose") +local sfxPlay = playdate.sound.sampleplayer.new("sfx/play") + +local mus = playdate.sound.fileplayer.new("sfx/tree") + +mus:play(0) + +-- enemy vars +local enemies = {} +local rechargeTime = 80 +local recharge = 80 +local enemySpeed = 1 +local enemyAmount = 1 + +-- title vars +local titleY = 400 -- -100 +local titleLerpY = 0 + +-- other vars +local mode = "comic" + +local yOffset = 240 + +local score = 0 + +local particles = {} +local shake = 0 + +local font = gfx.font.new("gfx/font") + +-- OTHER STUFF +gfx.setLineWidth(2) +gfx.setFont(font) + + +playdate.graphics.sprite.setBackgroundDrawingCallback(function() + gfx.setDrawOffset(0,yOffset) + imgTile:drawTiled(0,0,400,240) +end) + +local menu = playdate.getSystemMenu() +menu:addMenuItem("restart", function() die() end) +menu:addCheckmarkMenuItem("night mode", function(value) playdate.display.setInverted(value) end) + +math.randomseed(playdate.getSecondsSinceEpoch()) + +playdate.ui.crankIndicator:start() + +--local cubePos = math.rad(math.random(1,359)) +local cubePos = math.pi +local cubeCirc = 0 + +function playdate.update() + gfx.setDrawOffset(0,0) + if mode == "game" then + updateGame() + elseif mode == "comic" then -- too lazy to move to a different function. screw you. + titleY = playdate.math.lerp(titleY,titleLerpY,0.1) + imgComic:draw(0,titleY) + + local change = playdate.getCrankChange() + titleLerpY -= change + if titleLerpY > 0 then titleLerpY = 0 end + if titleLerpY < -453 then titleLerpY = -453 end + + if playdate.buttonJustPressed(playdate.kButtonA) then + titleLerpY = 0 + titleY = -100 + mode = "title" + sfxCollect:play() + end + elseif mode == "title" then + updateTitle() + end + + processParticles() + + if playdate.isCrankDocked() then + playdate.ui.crankIndicator:update() + end +end + +function collectCube(pos) + shake = 5 + sfxCollect:play() + + sprSquare:setImage(tSquare[math.random(1,#tSquare)]) + + spawnParts(sprSquare.x,sprSquare.y) + + score += 1 + + local option = score % 3 + if option == 0 and rechargeTime > 20 then + rechargeTime -= .5 + elseif option == 1 and enemySpeed < 10 then + enemySpeed += .3 + elseif option == 2 and enemyAmount < 6 then + enemyAmount += .3 + end + + cubeCirc = 0 + cubePos = pos + math.rad(math.random(-45,45) + 180) +end + +function updateTitle() + gfx.clear() + imgLogo:draw(31,imgLogo.height/2+titleY - 40) + titleY = playdate.math.lerp(titleY,titleLerpY,0.1) + + if titleLerpY+1 >= titleY then + if titleLerpY == -170 then + mode = "game" + else + animButton:draw(143, 200) + + if playdate.buttonJustPressed(playdate.kButtonA) then + titleLerpY = -170 + rechargeTime = 80 + recharge = 80 + enemySpeed = 1 + enemyAmount = 1 + + sfxPlay:play() + + cubePos = math.rad(playdate.getCrankPosition() + 180) + + spawnParts(143 + 57,210) + end + end + end +end + +function updateGame() + -- UPDATE + + -- set important vars + local pos = playdate.getCrankPosition() + local change = playdate.getCrankChange() + pos = math.rad(pos) + + -- if player is overlapping a square, move it + if #sprSquare:overlappingSprites() > 0 then + local spr = sprSquare:overlappingSprites()[1] + if spr.width == 34 and spr.height == 42 then + collectCube(pos) + end + end + + -- set shake var. yeah + if shake > 0 then shake -= .2 elseif shake < 0 then shake = 0 end + + -- spawn enemies + recharge -= 1 + + if recharge <= 0 then + for amnt = 1, math.floor(enemyAmount), 1 do + local enemy = { + x=180, + y=100, + dir = math.random(0,359), + speed = enemySpeed + } + enemies[#enemies+1] = enemy + end + + recharge = rechargeTime + end + + -- DRAW + gfx.clear() + + -- smooth transition in + drawing with shake + yOffset = playdate.math.lerp(yOffset,0,0.1) + + gfx.setDrawOffset(math.random(-1,1) * shake, math.random(-1,1) * shake + yOffset) + + -- animate + if change == 0 then + animPlayer.frame = 0 + end + + sprPlayer:setImage(animPlayer:image()) + + -- move sprites + local nX, nY = 200 + (math.sin(pos) * 120), 120 - (math.cos(pos) * 70) + sprPlayer:moveTo(nX, nY) + + sprSquare:moveTo(200 + (math.sin(cubePos) * 120), 120 - (math.cos(cubePos) * 70)) + + -- yeah + gfx.sprite.update() + + -- enemy processing and drawing + for enemyNo = 1, #enemies, 1 do + local enemy = enemies[enemyNo] + enemy.x += math.sin(enemy.dir) * enemy.speed + enemy.y -= math.cos(enemy.dir) * enemy.speed + + local flipped = playdate.graphics.kImageUnflipped + --print(math.sin(enemy.dir)) + if math.sin(enemy.dir)< -0.01 then + flipped = playdate.graphics.kImageFlippedX + end + + animEnemy:draw(enemy.x-2,enemy.y, flipped) + sprEnemies:moveTo(enemy.x-2,enemy.y) + + -- death + if #sprEnemies:overlappingSprites() > 0 and #sprSquare:overlappingSprites() == 0 then + die() + break + end + end + + -- despawn enemies out of camera + for enemyNo = 1, #enemies do + local enemy = enemies[enemyNo] + if enemy.x > 400 or enemy.x < -34 or enemy.y > 240 or enemy.y < -44 then + table.remove(enemies,enemyNo) + break + end + end + + -- draw the circle around items when they spawn + if cubeCirc < 32 then + cubeCirc += 1 + gfx.setColor(gfx.kColorXOR) + gfx.fillCircleAtPoint(sprSquare.x,sprSquare.y,math.sin(cubeCirc/10) * 19) + end + + imgSecurity:draw(200-44,120-40) + + -- overlay + gfx.setDrawOffset(0,0) + imgCart:draw(2,2) + gfx.drawText(score,30,5) +end + +function die() + -- vars + titleLerpY = 0 + mode = "title" + yOffset = 240 + score = 0 + + sfxLose:play() + + -- spawn particles on each enemy + other objects + for enemy = 1, #enemies do + spawnParts(enemies[enemy].x,enemies[enemy].y) + end + enemies = {} + + spawnParts(sprPlayer.x,sprPlayer.y) + spawnParts(sprSquare.x,sprSquare.y) +end + +-- particle functions +function spawnParts(_x,_y) + for i = 1, 10, 1 do + local part = { + x = _x, + y = _y, + dir = math.random(0,359), + size = math.random(10,15), + speed = math.random(1,3) + } + particles[#particles+1] = part + end +end + +function processParticles() + gfx.setColor(gfx.kColorBlack) + for part = 1, #particles do + local particle = particles[part] + + particle.x += math.sin(particle.dir) * particle.speed + particle.y -= math.cos(particle.dir) * particle.speed + gfx.fillCircleAtPoint(particle.x,particle.y,particle.size) + particles[part].size -= .3 + + if particles[part].size < 0 then particles[part].size = 0 end + end + + for part = 1, #particles do + if particles[part].size <= 0.1 then + table.remove(particles, part) + break + end + end +end \ No newline at end of file diff --git a/pdxinfo b/pdxinfo new file mode 100644 index 0000000..1aadbf8 --- /dev/null +++ b/pdxinfo @@ -0,0 +1,8 @@ +name=Shopping Spree +author=PossiblyAxolotl +description=I can't remember exactly what I was looking for, I'm sure if I grab everything one of them will be it! +bundleID=com.PossiblyAxolotl.shoppingspree +version=1.1 +buildNumber=1 +imagePath=launcher +contentWarning=This game contains mild amounts of screen shaking and particle effects. \ No newline at end of file diff --git a/sfx/collect.wav b/sfx/collect.wav new file mode 100644 index 0000000..4e92136 Binary files /dev/null and b/sfx/collect.wav differ diff --git a/sfx/lose.wav b/sfx/lose.wav new file mode 100644 index 0000000..aeb79c0 Binary files /dev/null and b/sfx/lose.wav differ diff --git a/sfx/play.wav b/sfx/play.wav new file mode 100644 index 0000000..ec61299 Binary files /dev/null and b/sfx/play.wav differ diff --git a/sfx/tree.wav b/sfx/tree.wav new file mode 100644 index 0000000..9d67602 Binary files /dev/null and b/sfx/tree.wav differ