sizescape

q*ball pico1k 2025

Sep 23rd, 2025
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.09 KB | Gaming | 0 0
  1. -- Q*BALL for Pico1k
  2. -- Submission code is this file, passed through Shrinko8, set to reducing compressed bytes:
  3. --  https://thisismypassport.github.io/shrinko8/
  4. -- Copyright (c) 2025 by Sizescape
  5.  
  6. score = 0
  7. ballc = 0
  8. directions = {{0,1}, {0,-1}, {-1,-1}, {1,1}, {0,0}}
  9.  
  10. -- Setup half of the cube sprite.
  11. for i=0,127 do y=i\8 x=i%8 if x-2*y<2 and x+2*y<32 do sset(x,y,x+2*y<14 and 3 or 2)end end
  12.  
  13. lb=50
  14. wto="\^w\^t\^o"
  15. function _init()
  16.     if lb < 16 then
  17.         print(wto.."1ffgame over",28,56,7)
  18.         print("\^o1ffscore: "..score,43,70,7)
  19.         flip()
  20.         _init()
  21.     end
  22.     lb=0
  23.     timer = 100
  24.     ballc += 1
  25.     map = {}
  26.     for y=0,9 do
  27.         -- Offset, color, drop
  28.         map[y] = {}
  29.         for x=0,y+1 do
  30.             map[y][x] = y > 0 and y < 9 and x > 0 and x<=y and {0,11,0} or {500,9,1}
  31.         end
  32.     end
  33.  
  34.     -- x, y, xd, yd, offset. Player is 1st, rest are qballs.
  35.     mobs = {{2,4,0,0,0}}
  36.     for i=1,ballc do
  37.         y=rnd(7)\1+1
  38.         x=rnd(y)\1+1
  39.         add(mobs, {x,y,0,0,0})
  40.     end
  41. end
  42.  
  43. function _draw()
  44.     cls()
  45.  
  46.     -- Update and draw map blocks based on state.
  47.     for y=1,8 do
  48.         for x=1,y do
  49.             map[y][x][1] += map[y][x][3]
  50.             if map[y][x][2] == 9 and map[y][x][3] == 0 do ox,oy=rnd(2),rnd(2) else ox,oy=0,0 end
  51.             pal({0, 2, map[y][x][2]})
  52.             spr(0, 48+x*16-y*8+ox, y*13+map[y][x][1]+oy,1,2,true)
  53.             pal({0, 8, map[y][x][2]})
  54.             spr(0, 48+x*16-y*8+8+ox, y*13+map[y][x][1]+oy,1,2,false)
  55.             pal()
  56.         end
  57.     end
  58.  
  59.     function check_line(l)
  60.         start=1
  61.         good=1
  62.         for i=1,#l do
  63.             m=map[l[i][1]][l[i][2]]
  64.             if m[2]~=11 do
  65.                 if i-start>1 do
  66.                    if map[l[start][1]][l[start][2]][3]+m[3]+good==3 do
  67.                         for j=start,i do
  68.                             map[l[j][1]][l[j][2]][2]=9
  69.                         end
  70.                     elseif m[3]==1 do
  71.                         start = i
  72.                         good = 1
  73.                     end
  74.                 end
  75.             else
  76.                 good = 0
  77.             end
  78.         end
  79.     end
  80.  
  81.     -- Look to see if player has formed a line of marked blocks.
  82.     for i=0,9 do
  83.         p={} for y=i,9 do add(p,{y,i+1}) end check_line(p) -- diagonal
  84.         p={} for j=0,9-i do add(p,{i+j,j}) end check_line(p) -- anti-diagonal
  85.         p={} for j=0,i+1 do add(p,{i,j}) end check_line(p) -- horizontal
  86.        -- If a square is marked for dropping (color=9), and the main character has left the row/col, drop it
  87.        for x=1,i do
  88.             if map[i][x][2] == 9 and map[i][x][3] == 0 and not (mobs[1][1] == x and mobs[1][2] == i) do
  89.                 map[i][x][3] = 1
  90.                 score += 1
  91.                 lb+=1
  92.            end
  93.        end
  94.    end
  95.  
  96.     -- Update and draw mobs based on their state.
  97.     for b=#mobs,1,-1 do
  98.         if mobs[b][3] == 0 and mobs[b][4] == 0 do
  99.             d = rnd(4)\1
  100.             -- b==1 is player character, get dir from gamepad
  101.             if b==1 do
  102.                 d=4
  103.                 for t=0,3 do
  104.                     if btnp(t) do
  105.                         d = t
  106.                     end
  107.                 end
  108.             end
  109.             mobs[b][3] = directions[d+1][1]
  110.             mobs[b][4] = directions[d+1][2]
  111.  
  112.             -- Check if movement is valid.
  113.             if map[mobs[b][2]+mobs[b][4]][mobs[b][1] + mobs[b][3]][3] == 1 do
  114.                 mobs[b][3] = 0
  115.                 mobs[b][4] = 0
  116.             end
  117.         else
  118.             -- Update offset. If we've moved 8 pixels, update position, reset direction, and color map.
  119.             mobs[b][5] += 1
  120.             if mobs[b][5] > 8 do
  121.                 mobs[b] = {mobs[b][1]+mobs[b][3], mobs[b][2]+mobs[b][4], 0, 0, 0}
  122.                 map[mobs[b][2]][mobs[b][1]][2] = b==1 and 10 or 11
  123.             end
  124.         end
  125.  
  126.         -- Draw player and balls.
  127.         bx = 52+mobs[b][1]*16-mobs[b][2]*8+(2*mobs[b][3]-mobs[b][4])*mobs[b][5]+4
  128.         by = mobs[b][2]*13+mobs[b][4]*mobs[b][5]+mobs[b][5]*(mobs[b][5]-9)/2
  129.         if b==1 then -- Player
  130.             print(wto.."181웃",bx-7,by-6,14)
  131.             print('"',bx-2,by-4,1)
  132.         else -- Balls
  133.             circfill(bx, by, 5, 1)
  134.             circfill(bx-1, by-1, 4, 12)
  135.         end
  136.     end
  137.  
  138.    -- dfs to find if a mob can be reached from a block. If not, set it to drop to let them decay.
  139.    visited={}
  140.    function search(x,y)
  141.         for m in all(mobs) do if m[1]==x and m[2]==y do return true end end
  142.         if visited[y*10+x] or map[y][x][3] == 1 do return end
  143.         visited[y*10+x] = true
  144.         for d in all(directions) do if search(x+d[1],y+d[2]) do return true end end
  145.    end
  146.    y = rnd(9)\1
  147.    x = rnd(y+1)\1
  148.    if not search(x,y) do
  149.         map[y][x][2] = 9
  150.    end
  151.  
  152.   -- Draw timer
  153.   line(0, 120, 0, 20+100-timer, 11)
  154.   -- Draw score
  155.   print(score, 0, 0, 7)
  156.   line(127, 0, 127, lb*6, lb < 16 and 8 or 11)
  157.  
  158.    -- Check for level complete. Speed up the timer if player holds X since I'm impatient.
  159.    timer -= btn(5) and 1 or .1
  160.    if timer <= 0 do
  161.        _init()
  162.    end
  163. end
  164.  
Tags: #pico8
Advertisement
Add Comment
Please, Sign In to add comment