SHOW:
|
|
- or go back to the newest paste.
| 1 | - | local gpu=require("component").gpu |
| 1 | + | local AGUI_VERSION = "0.6" |
| 2 | - | local event=require("event") |
| 2 | + | local component = require("component")
|
| 3 | - | |
| 3 | + | local success, gui |
| 4 | - | fieldWidth=20 |
| 4 | + | repeat |
| 5 | - | fieldHeight=26 |
| 5 | + | success, gui = pcall(require, "AGUI") |
| 6 | - | |
| 6 | + | if not success then |
| 7 | - | width=30 --width of mas NOT field |
| 7 | + | print(gui) |
| 8 | - | |
| 8 | + | io.write("For the application need a library AGUI (https://pastebin.com/s4UFSFwn).\n")
|
| 9 | - | mas={} |
| 9 | + | if not component.isAvailable("internet") then
|
| 10 | - | |
| 10 | + | os.exit() |
| 11 | - | StockBlocks = { { start_position = { x = 4, y = 1 }, |
| 11 | + | end |
| 12 | - | color = { 175, 175, 0 }, |
| 12 | + | io.write("Do you want to install?[Y/n] ")
|
| 13 | - | symbol = "T", |
| 13 | + | if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
|
| 14 | - | transformations = { { { x = -1, y = 0 }, |
| 14 | + | os.exit() |
| 15 | - | { x = 0, y = 0 }, |
| 15 | + | end |
| 16 | - | { x = 1, y = 0 }, |
| 16 | + | loadfile("/bin/wget.lua")("https://pastebin.com/raw/s4UFSFwn", "/lib/AGUI.lua", "-f")
|
| 17 | - | { x = 0, y = -1 } }, |
| 17 | + | end |
| 18 | - | { { x = 0, y = 0 }, |
| 18 | + | until success |
| 19 | - | { x = 0, y = -1 }, |
| 19 | + | |
| 20 | - | { x = 0, y = 1 }, |
| 20 | + | if gui.Version ~= AGUI_VERSION then |
| 21 | - | { x = 1, y = 0 } }, |
| 21 | + | io.write("Recommended version of AGUI library ("..AGUI_VERSION..") does not match installed ("..(gui.Version or "unknown")..")\n")
|
| 22 | - | { { x = -1, y = 0 }, |
| 22 | + | io.write("Do you want to continue?[Y/n] ")
|
| 23 | - | { x = 0, y = 0 }, |
| 23 | + | if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
|
| 24 | - | { x = 1, y = 0 }, |
| 24 | + | os.exit() |
| 25 | - | { x = 0, y = 1 } }, |
| 25 | + | end |
| 26 | - | { { x = 0, y = 0 }, |
| 26 | + | end |
| 27 | - | { x = 0, y = -1 }, |
| 27 | + | |
| 28 | - | { x = 0, y = 1 }, |
| 28 | + | local gpu = component.gpu |
| 29 | - | { x = -1, y = 0 } } } }, |
| 29 | + | local event = require("event")
|
| 30 | - | { start_position = { x = 4, y = 1 }, |
| 30 | + | |
| 31 | - | color = { 0, 255, 0 }, |
| 31 | + | ------SETTINGS------- |
| 32 | - | symbol = "Z", |
| 32 | + | local cfg = {}
|
| 33 | - | transformations = { { { x = -1, y = 0 }, |
| 33 | + | cfg.mapWidth = 10 |
| 34 | - | { x = 0, y = 0 }, |
| 34 | + | cfg.mapHeight = 20 |
| 35 | - | { x = 0, y = -1 }, |
| 35 | + | cfg.startX = gui.GetCenter(1, cfg.mapWidth, 1) - 1 |
| 36 | - | { x = 1, y = -1 } }, |
| 36 | + | cfg.drawShadow = true |
| 37 | - | { { x = 0, y = -1 }, |
| 37 | + | cfg.shadowColor = 0x222222 |
| 38 | - | { x = 0, y = 0 }, |
| 38 | + | cfg.tickDelay = 0.1 |
| 39 | - | { x = 1, y = 0 }, |
| 39 | + | cfg.fallTickCnt = 3 |
| 40 | - | { x = 1, y = 1 } } } }, |
| 40 | + | cfg.fallLinesDelay = 0.3 |
| 41 | - | { start_position = { x = 4, y = 1 }, |
| 41 | + | cfg.backColor = 0x000000 |
| 42 | - | color = { 100, 100, 175 }, |
| 42 | + | -- |
| 43 | - | symbol = "S", |
| 43 | + | function InRange(value, left, right) |
| 44 | - | transformations = { { { x = 1, y = 0 }, |
| 44 | + | return left <= value and value <= right |
| 45 | - | { x = 0, y = 0 }, |
| 45 | + | end |
| 46 | - | { x = 0, y = -1 }, |
| 46 | + | |
| 47 | - | { x = -1, y = -1 } }, |
| 47 | + | function ValidateConfig() |
| 48 | - | { { x = 0, y = 1 }, |
| 48 | + | local MaxScreenWidth, MaxScreenHeight |
| 49 | - | { x = 0, y = 0 }, |
| 49 | + | MaxScreenWidth, MaxScreenHeight = gpu.maxResolution() |
| 50 | - | { x = 1, y = 0 }, |
| 50 | + | |
| 51 | - | { x = 1, y = -1 } } } }, |
| 51 | + | if not InRange(cfg.mapWidth * 2 + 12, 22, MaxScreenWidth) then |
| 52 | - | { start_position = { x = 4, y = 0 }, |
| 52 | + | return "MapWidthError", "out of bounds" |
| 53 | - | color = { 255, 255, 100 }, |
| 53 | + | end |
| 54 | - | symbol = "J", |
| 54 | + | |
| 55 | - | transformations = { { { x = -1, y = 0 }, |
| 55 | + | if not InRange(cfg.mapHeight, 15, MaxScreenHeight) then |
| 56 | - | { x = 0, y = 0 }, |
| 56 | + | return "MapHeightError", "out of bounds" |
| 57 | - | { x = 1, y = 0 }, |
| 57 | + | end |
| 58 | - | { x = -1, y = 1 } }, |
| 58 | + | end |
| 59 | - | { { x = 0, y = -1 }, |
| 59 | + | |
| 60 | - | { x = 0, y = 0 }, |
| 60 | + | --UpdateScreenSettings() |
| 61 | - | { x = 0, y = 1 }, |
| 61 | + | local err, msg = ValidateConfig() |
| 62 | - | { x = 1, y = 1 } }, |
| 62 | + | if err ~= nil then |
| 63 | - | { { x = -1, y = 0 }, |
| 63 | + | print(err, msg) |
| 64 | - | { x = 0, y = 0 }, |
| 64 | + | os.exit() |
| 65 | - | { x = 1, y = 0 }, |
| 65 | + | end |
| 66 | - | { x = 1, y = -1 } }, |
| 66 | + | -- |
| 67 | - | { { x = 0, y = -1 }, |
| 67 | + | |
| 68 | - | { x = 0, y = 0 }, |
| 68 | + | linePoints = {[0] = 0, [1] = 10, [2] = 25, [3] = 50, [4] = 100}
|
| 69 | - | { x = 0, y = 1 }, |
| 69 | + | --------------------- |
| 70 | - | { x = -1, y = -1 } } } }, |
| 70 | + | -- function centerText(x,y,w,text) |
| 71 | - | { start_position = { x = 4, y = 0 }, |
| 71 | + | -- gpu.set(x+math.floor(w/2-string.len(text)/2),y,text) |
| 72 | - | color = { 255, 0, 255 }, |
| 72 | + | -- end |
| 73 | - | symbol = "L", |
| 73 | + | |
| 74 | - | transformations = { { { x = -1, y = 0 }, |
| 74 | + | -- function messageBox(title,text,color) |
| 75 | - | { x = 0, y = 0 }, |
| 75 | + | -- local x,y=cfg.mapWidth-9,math.floor(cfg.mapHeight/2)-3 |
| 76 | - | { x = 1, y = 0 }, |
| 76 | + | -- local len1,len2=string.len(title),string.len(text) |
| 77 | - | { x = 1, y = 1 } }, |
| 77 | + | -- local len3=math.max(len1,len2)+2 |
| 78 | - | { { x = 0, y = -1 }, |
| 78 | + | -- gpu.setBackground(0xffffff) |
| 79 | - | { x = 0, y = 0 }, |
| 79 | + | -- gpu.fill(x,y,len3,2+3," ") |
| 80 | - | { x = 0, y = 1 }, |
| 80 | + | -- gpu.setForeground(color or 0xFF0000) |
| 81 | - | { x = 1, y = -1 } }, |
| 81 | + | -- centerText(x,y+1,len3,title) |
| 82 | - | { { x = -1, y = 0 }, |
| 82 | + | -- gpu.setForeground(0x000000) |
| 83 | - | { x = 0, y = 0 }, |
| 83 | + | -- centerText(x,y+3,len3,text) |
| 84 | - | { x = 1, y = 0 }, |
| 84 | + | -- gpu.setBackground(color or 0xFF0000) |
| 85 | - | { x = -1, y = -1 } }, |
| 85 | + | -- gpu.setForeground(0xffffff) |
| 86 | - | { { x = 0, y = -1 }, |
| 86 | + | -- gpu.fill(x,y+5,len3,3," ") |
| 87 | - | { x = 0, y = 0 }, |
| 87 | + | -- centerText(x,y+6,len3,"OK!") |
| 88 | - | { x = 0, y = 1 }, |
| 88 | + | -- end |
| 89 | - | { x = -1, y = 1 } } } }, |
| 89 | + | ---------------------------------------------------------------- |
| 90 | - | { start_position = { x = 4, y = 0 }, |
| 90 | + | StockBlocks = { { start_position = { x = 1, y = 1 },
|
| 91 | - | color = { 255, 0, 0 }, |
| 91 | + | color = 0xFFFF00, |
| 92 | - | symbol = "I", |
| 92 | + | symbol = "T", |
| 93 | - | transformations = { { { x = -1, y = 0 }, |
| 93 | + | transformations = { { { x = -1, y = 0 },
|
| 94 | - | { x = 0, y = 0 }, |
| 94 | + | { x = 0, y = 0 },
|
| 95 | - | { x = 1, y = 0 }, |
| 95 | + | { x = 1, y = 0 },
|
| 96 | - | { x = 2, y = 0 } }, |
| 96 | + | { x = 0, y = -1 } },
|
| 97 | - | { { x = 0, y = -1 }, |
| 97 | + | { { x = 0, y = 0 },
|
| 98 | - | { x = 0, y = 0 }, |
| 98 | + | { x = 0, y = -1 },
|
| 99 | - | { x = 0, y = 1 }, |
| 99 | + | { x = 0, y = 1 },
|
| 100 | - | { x = 0, y = 2 } } } }, |
| 100 | + | { x = -1, y = 0 } },
|
| 101 | - | { start_position = { x = 4, y = 0 }, |
| 101 | + | { { x = -1, y = 0 },
|
| 102 | - | color = { 0, 0, 255 }, |
| 102 | + | { x = 0, y = 0 },
|
| 103 | - | symbol = "[]", |
| 103 | + | { x = 1, y = 0 },
|
| 104 | - | transformations = { { { x = 0, y = 0 }, |
| 104 | + | { x = 0, y = 1 } },
|
| 105 | - | { x = 0, y = 1 }, |
| 105 | + | { { x = 0, y = 0 },
|
| 106 | - | { x = 1, y = 0 }, |
| 106 | + | { x = 0, y = -1 },
|
| 107 | - | { x = 1, y = 1 } } } } |
| 107 | + | { x = 0, y = 1 },
|
| 108 | - | } |
| 108 | + | { x = 1, y = 0 } } } },
|
| 109 | - | |
| 109 | + | |
| 110 | - | function toXY(num,wid) |
| 110 | + | { start_position = { x = 1, y = 1 },
|
| 111 | - | wid=wid or width |
| 111 | + | color = 0x00FF00, |
| 112 | - | y=math.floor((num-1)/wid)+1 |
| 112 | + | symbol = "Z", |
| 113 | - | return num-(y-1)*width,y |
| 113 | + | transformations = { { { x = -1, y = 0 },
|
| 114 | - | end |
| 114 | + | { x = 0, y = 0 },
|
| 115 | - | function fromXY(x,y,wid) |
| 115 | + | { x = 0, y = -1 },
|
| 116 | - | wid=wid or width |
| 116 | + | { x = 1, y = -1 } },
|
| 117 | - | return (y-1)*wid+x |
| 117 | + | { { x = 0, y = -1 },
|
| 118 | - | end |
| 118 | + | { x = 0, y = 0 },
|
| 119 | - | |
| 119 | + | { x = 1, y = 0 },
|
| 120 | - | for i=-1000,2500 do |
| 120 | + | { x = 1, y = 1 } } } },
|
| 121 | - | mas[i]=0 |
| 121 | + | { start_position = { x = 1, y = 1 },
|
| 122 | - | end |
| 122 | + | color = 0x9999CC, |
| 123 | - | --print(StockBlocks[1].transformations[1][1].y) |
| 123 | + | symbol = "S", |
| 124 | - | --[[f=7 |
| 124 | + | transformations = { { { x = 1, y = 0 },
|
| 125 | - | tr=1 |
| 125 | + | { x = 0, y = 0 },
|
| 126 | - | for i=1,4 do |
| 126 | + | { x = 0, y = -1 },
|
| 127 | - | gpu.set(StockBlocks[f].transformations[tr][i].x+5,StockBlocks[f].transformations[tr][i].y+5,"!") |
| 127 | + | { x = -1, y = -1 } },
|
| 128 | - | end]]-- |
| 128 | + | { { x = 0, y = 1 },
|
| 129 | - | obj={ |
| 129 | + | { x = 0, y = 0 },
|
| 130 | - | id=-1, |
| 130 | + | { x = 1, y = 0 },
|
| 131 | - | x=-1, |
| 131 | + | { x = 1, y = -1 } } } },
|
| 132 | - | y=-1, |
| 132 | + | { start_position = { x = 1, y = 0 },
|
| 133 | - | dX=0, |
| 133 | + | color = 0xFFFF99, |
| 134 | - | dY=0, |
| 134 | + | symbol = "J", |
| 135 | - | dR=0, |
| 135 | + | transformations = { { { x = -1, y = 0 },
|
| 136 | - | rotate=-1, |
| 136 | + | { x = 0, y = 0 },
|
| 137 | - | } |
| 137 | + | { x = 1, y = 0 },
|
| 138 | - | function newTile(tile) |
| 138 | + | { x = -1, y = 1 } },
|
| 139 | - | tile=tile or (math.random(1,7)) |
| 139 | + | { { x = 0, y = -1 },
|
| 140 | - | obj.id=tile |
| 140 | + | { x = 0, y = 0 },
|
| 141 | - | obj.x,obj.y=StockBlocks[tile].start_position.x+5,StockBlocks[tile].start_position.y |
| 141 | + | { x = 0, y = 1 },
|
| 142 | - | obj.rotate=1 |
| 142 | + | { x = 1, y = 1 } },
|
| 143 | - | if test() then |
| 143 | + | { { x = -1, y = 0 },
|
| 144 | - | gpu.setForeground(0xff0000) |
| 144 | + | { x = 0, y = 0 },
|
| 145 | - | gpu.set(10,1,"GAME OVER") |
| 145 | + | { x = 1, y = 0 },
|
| 146 | - | os.sleep(0.5) |
| 146 | + | { x = 1, y = -1 } },
|
| 147 | - | gpu.setForeground(0xffffff) |
| 147 | + | { { x = 0, y = -1 },
|
| 148 | - | isRunning=false |
| 148 | + | { x = 0, y = 0 },
|
| 149 | - | else |
| 149 | + | { x = 0, y = 1 },
|
| 150 | - | clearLines() |
| 150 | + | { x = -1, y = -1 } } } },
|
| 151 | - | end |
| 151 | + | { start_position = { x = 1, y = 0 },
|
| 152 | - | -- print("!") |
| 152 | + | color = 0xFF00FF, |
| 153 | - | end |
| 153 | + | symbol = "L", |
| 154 | - | function drawBlock(x,y,color) |
| 154 | + | transformations = { { { x = -1, y = 0 },
|
| 155 | - | gpu.set((x-1)*2+1,y," ") |
| 155 | + | { x = 0, y = 0 },
|
| 156 | - | end |
| 156 | + | { x = 1, y = 0 },
|
| 157 | - | function drawTile(color) |
| 157 | + | { x = 1, y = 1 } },
|
| 158 | - | gpu.setBackground(color or 0x005500) |
| 158 | + | { { x = 0, y = -1 },
|
| 159 | - | -- print(obj.id,obj.rotate) |
| 159 | + | { x = 0, y = 0 },
|
| 160 | - | for i=1,4 do |
| 160 | + | { x = 0, y = 1 },
|
| 161 | - | drawBlock(StockBlocks[obj.id].transformations[obj.rotate][i].x+obj.x,StockBlocks[obj.id].transformations[obj.rotate][i].y+obj.y) |
| 161 | + | { x = 1, y = -1 } },
|
| 162 | - | end |
| 162 | + | { { x = -1, y = 0 },
|
| 163 | - | gpu.setBackground(0x000000) |
| 163 | + | { x = 0, y = 0 },
|
| 164 | - | end |
| 164 | + | { x = 1, y = 0 },
|
| 165 | - | function testLine(line) |
| 165 | + | { x = -1, y = -1 } },
|
| 166 | - | for x=1,fieldWidth-1 do |
| 166 | + | { { x = 0, y = -1 },
|
| 167 | - | if mas[fromXY(x,line)]==0 then |
| 167 | + | { x = 0, y = 0 },
|
| 168 | - | return false |
| 168 | + | { x = 0, y = 1 },
|
| 169 | - | end |
| 169 | + | { x = -1, y = 1 } } } },
|
| 170 | - | end |
| 170 | + | { start_position = { x = 1, y = 0 },
|
| 171 | - | return true |
| 171 | + | color = 0xFF0000, |
| 172 | - | end |
| 172 | + | symbol = "I", |
| 173 | - | function clearLines() |
| 173 | + | transformations = { { { x = -1, y = 0 },
|
| 174 | - | -- gpu.set(90,1,"!") |
| 174 | + | { x = 0, y = 0 },
|
| 175 | - | for i=1,fieldHeight do |
| 175 | + | { x = 1, y = 0 },
|
| 176 | - | if testLine(i) then |
| 176 | + | { x = 2, y = 0 } },
|
| 177 | - | downTiles(i) |
| 177 | + | { { x = 0, y = -1 },
|
| 178 | - | -- gpu.set(90,2,"!") |
| 178 | + | { x = 0, y = 0 },
|
| 179 | - | gpu.set(1,i,string.rep(" ",fieldWidth*2-2)) |
| 179 | + | { x = 0, y = 1 },
|
| 180 | - | os.sleep(0.5) |
| 180 | + | { x = 0, y = 2 } } } },
|
| 181 | - | gpu.copy(1,i-20,fieldWidth*2-1,20,0,1) |
| 181 | + | { start_position = { x = 1, y = 0 },
|
| 182 | - | end |
| 182 | + | color = 0x0000FF, |
| 183 | - | end |
| 183 | + | symbol = "[]", |
| 184 | - | end |
| 184 | + | transformations = { { { x = 0, y = 0 },
|
| 185 | - | function downTiles(line) |
| 185 | + | { x = 0, y = 1 },
|
| 186 | - | for i=line,1,-1 do |
| 186 | + | { x = 1, y = 0 },
|
| 187 | - | for j=1,fieldWidth+2 do |
| 187 | + | { x = 1, y = 1 } } } }
|
| 188 | - | mas[fromXY(j,i)]=mas[fromXY(j,i-1)] |
| 188 | + | } |
| 189 | - | end |
| 189 | + | |
| 190 | - | end |
| 190 | + | local width = cfg.mapWidth + 10 --width of map NOT field |
| 191 | - | end |
| 191 | + | local score -- = 0 |
| 192 | - | function test() |
| 192 | + | local map -- = {}
|
| 193 | - | for i=1,4 do |
| 193 | + | local control |
| 194 | - | local x,y=StockBlocks[obj.id].transformations[obj.rotate][i].x+obj.x,StockBlocks[obj.id].transformations[obj.rotate][i].y+obj.y |
| 194 | + | local tick |
| 195 | - | if (y==fieldHeight)or(mas[fromXY(x,y)]~=0)or(x>=fieldWidth)or(x<1) then |
| 195 | + | local isRunning = false |
| 196 | - | return true |
| 196 | + | local isInited = false |
| 197 | - | end |
| 197 | + | |
| 198 | - | end |
| 198 | + | function toXY(num,wid) |
| 199 | - | return false |
| 199 | + | wid=wid or width |
| 200 | - | end |
| 200 | + | y=math.floor((num-1)/wid)+1 |
| 201 | - | function putInMap() |
| 201 | + | return num-(y-1)*width,y |
| 202 | - | for j=1,4 do |
| 202 | + | end |
| 203 | - | mas[fromXY(StockBlocks[obj.id].transformations[obj.rotate][j].x+obj.x,StockBlocks[obj.id].transformations[obj.rotate][j].y+obj.y)]=1 |
| 203 | + | function fromXY(x,y,wid) |
| 204 | - | end |
| 204 | + | wid = wid or width |
| 205 | - | end |
| 205 | + | return (y-1)*wid+x |
| 206 | - | function mapUpdate() |
| 206 | + | end |
| 207 | - | drawTile(0x000000) |
| 207 | + | |
| 208 | - | if step2 then |
| 208 | + | -- TODO DELETE |
| 209 | - | obj.y=obj.y+1 |
| 209 | + | -- for i=-1000,2500 do |
| 210 | - | end |
| 210 | + | -- map[i]=0 |
| 211 | - | -- obj.x=obj.x+obj.dX |
| 211 | + | -- end |
| 212 | - | if (test())and(step2) then |
| 212 | + | --print(StockBlocks[1].transformations[1][1].y) |
| 213 | - | -- obj.x=obj.x-obj.dX |
| 213 | + | --[[f=7 |
| 214 | - | obj.y=obj.y-1 |
| 214 | + | tr=1 |
| 215 | - | drawTile() |
| 215 | + | for i=1,4 do |
| 216 | - | putInMap() |
| 216 | + | gpu.set(StockBlocks[f].transformations[tr][i].x+5,StockBlocks[f].transformations[tr][i].y+5,"!") |
| 217 | - | newTile() |
| 217 | + | end]]-- |
| 218 | - | else |
| 218 | + | local fObj, nextObj, sObj |
| 219 | - | if obj.dY==1 then |
| 219 | + | local gCanvas, pCanvas |
| 220 | - | drawTile(0x000000) |
| 220 | + | |
| 221 | - | obj.y=obj.y+1 |
| 221 | + | local scoreObj |
| 222 | - | if test() then |
| 222 | + | function GetScore() |
| 223 | - | obj.y=obj.y-1 |
| 223 | + | return tonumber(scoreObj.Text) |
| 224 | - | drawTile() |
| 224 | + | end |
| 225 | - | putInMap() |
| 225 | + | |
| 226 | - | newTile() |
| 226 | + | function SetScore(value) |
| 227 | - | end |
| 227 | + | scoreObj:Modify{Text = tostring(value)}:Paint()
|
| 228 | - | end |
| 228 | + | end |
| 229 | - | if obj.dX~=0 then |
| 229 | + | |
| 230 | - | drawTile(0x000000) |
| 230 | + | function IncreaseScore(amount) |
| 231 | - | obj.x=obj.x+obj.dX |
| 231 | + | SetScore(GetScore() + amount) |
| 232 | - | if test() then |
| 232 | + | end |
| 233 | - | obj.x=obj.x-obj.dX |
| 233 | + | |
| 234 | - | end |
| 234 | + | function randomID() |
| 235 | - | end |
| 235 | + | -- return 6 |
| 236 | - | if obj.dR~=0 then |
| 236 | + | return math.random(1, 7) |
| 237 | - | local tmp=obj.rotate |
| 237 | + | end |
| 238 | - | drawTile(0x000000) |
| 238 | + | |
| 239 | - | obj.rotate=(obj.rotate+#StockBlocks[obj.id].transformations)%(#StockBlocks[obj.id].transformations)+1 |
| 239 | + | function createObject(id, x, y) |
| 240 | - | if test() then |
| 240 | + | id = id or randomID() |
| 241 | - | obj.rotate=tmp |
| 241 | + | local obj = {}
|
| 242 | - | end |
| 242 | + | obj.id = id |
| 243 | - | -- obj.rotate=obj.rotate+1 |
| 243 | + | obj.x, obj.y = StockBlocks[id].start_position.x + (x or cfg.startX), StockBlocks[id].start_position.y + (y or 0) |
| 244 | - | end |
| 244 | + | obj.color = StockBlocks[id].color |
| 245 | - | end |
| 245 | + | obj.rotate = 1 |
| 246 | - | obj.dX=0 |
| 246 | + | return obj |
| 247 | - | obj.dY=0 |
| 247 | + | end |
| 248 | - | obj.dR=0 |
| 248 | + | |
| 249 | - | drawTile() |
| 249 | + | function cloneObject(obj, x, y, r) |
| 250 | - | end |
| 250 | + | local nObj = {}
|
| 251 | - | function onKey(ev,_,code1,code2,player) |
| 251 | + | for index, value in pairs(obj) do |
| 252 | - | if (code1==113)and(code2==16) then |
| 252 | + | nObj[index] = value |
| 253 | - | isRunning=false |
| 253 | + | end |
| 254 | - | elseif (code1==0) then |
| 254 | + | nObj.x = nObj.x + (x or 0) |
| 255 | - | if code2==203 then--left |
| 255 | + | nObj.y = nObj.y + (y or 0) |
| 256 | - | obj.dX=-1 |
| 256 | + | nObj.rotate = (nObj.rotate - 1 + (r or 0) + #StockBlocks[obj.id].transformations) % (#StockBlocks[obj.id].transformations) + 1 |
| 257 | - | elseif code2==200 then--up |
| 257 | + | return nObj |
| 258 | - | obj.dR=1 |
| 258 | + | end |
| 259 | - | elseif code2==205 then--right |
| 259 | + | |
| 260 | - | obj.dX=1 |
| 260 | + | function createShadow(obj) |
| 261 | - | elseif code2==208 then--down |
| 261 | + | local sObj = cloneObject(obj) |
| 262 | - | obj.dY=1 |
| 262 | + | while check(sObj) do |
| 263 | - | end |
| 263 | + | sObj.y = sObj.y + 1 |
| 264 | - | end |
| 264 | + | end |
| 265 | - | end |
| 265 | + | sObj.y = sObj.y - 1 |
| 266 | - | newTile() |
| 266 | + | return sObj |
| 267 | - | drawTile() |
| 267 | + | end |
| 268 | - | isRunning=true |
| 268 | + | |
| 269 | - | event.ignore("key_down",onKey) |
| 269 | + | function drawBlock(canvas, x, y, color) |
| 270 | - | event.listen("key_down",onKey) |
| 270 | + | canvas.set(x * 2 - 1, y, " ") |
| 271 | - | step2=false |
| 271 | + | end |
| 272 | - | gpu.setBackground(0x222222) |
| 272 | + | |
| 273 | - | require("term").clear() |
| 273 | + | function drawObject(canvas, obj, color) |
| 274 | - | gpu.setBackground(0x000000) |
| 274 | + | gpu.setBackground(color or obj.color) |
| 275 | - | gpu.fill(1,1,fieldWidth*2-2,fieldHeight-1," ") |
| 275 | + | for i = 1, 4 do |
| 276 | - | while isRunning do |
| 276 | + | drawBlock(canvas, StockBlocks[obj.id].transformations[obj.rotate][i].x + obj.x,StockBlocks[obj.id].transformations[obj.rotate][i].y + obj.y) |
| 277 | - | step2=not step2 |
| 277 | + | end |
| 278 | - | os.sleep(0.15) |
| 278 | + | gpu.setBackground(0x000000) |
| 279 | - | mapUpdate() |
| 279 | + | end |
| 280 | - | -- for i=1,fieldWidth do |
| 280 | + | |
| 281 | - | -- gpu.set(70+i,3,tostring(mas[fromXY(i,25)])) |
| 281 | + | function drawPredict(obj) |
| 282 | - | -- end |
| 282 | + | gpu.setBackground(cfg.backColor) |
| 283 | - | end |
| 283 | + | pCanvas.fill(1, 1, 8, 4, " ") |
| 284 | - | event.ignore("key_down",onKey) |
| 284 | + | drawObject(pCanvas, obj) |
| 285 | end | |
| 286 | ||
| 287 | function checkLine(line) | |
| 288 | for x = 1, cfg.mapWidth do | |
| 289 | if not map[fromXY(x, line)] then | |
| 290 | return false | |
| 291 | end | |
| 292 | end | |
| 293 | return true | |
| 294 | end | |
| 295 | ||
| 296 | function fallBlocks(line) | |
| 297 | for i = line, 1, -1 do | |
| 298 | for j = 1, cfg.mapWidth do | |
| 299 | map[fromXY(j,i)] = map[fromXY(j,i-1)] | |
| 300 | end | |
| 301 | end | |
| 302 | end | |
| 303 | ||
| 304 | function clearLines() | |
| 305 | local cnt, offset = 0, 0 | |
| 306 | -- for i = cfg.mapHeight, 1, -1 do | |
| 307 | -- if checkLine(i) then | |
| 308 | -- cnt = cnt + 1 | |
| 309 | -- offset = offset + 1 | |
| 310 | -- gpu.set(1, i - offset, string.rep(" ", cfg.mapWidth * 2))
| |
| 311 | -- os.sleep(cfg.fallLinesDelay) | |
| 312 | -- gpu.copy(1, i - cfg.mapHeight, cfg.mapWidth * 2, cfg.mapHeight, 0, 1) | |
| 313 | -- end | |
| 314 | -- if offset > 0 then | |
| 315 | -- for j = 1, cfg.mapWidth do | |
| 316 | -- map[fromXY(j, i - offset)] = map[fromXY(j, i)] | |
| 317 | -- end | |
| 318 | -- end | |
| 319 | -- end | |
| 320 | for i = 1, cfg.mapHeight do | |
| 321 | if checkLine(i) then | |
| 322 | cnt = cnt + 1 | |
| 323 | fallBlocks(i) -- ... TODO SPEEDUP | |
| 324 | gpu.set(1, i, string.rep(" ", cfg.mapWidth * 2))
| |
| 325 | os.sleep(cfg.fallLinesDelay) | |
| 326 | gpu.copy(1, i - cfg.mapHeight, cfg.mapWidth * 2, cfg.mapHeight, 0, 1) | |
| 327 | end | |
| 328 | end | |
| 329 | return cnt | |
| 330 | end | |
| 331 | ||
| 332 | function check(obj) | |
| 333 | for i = 1, 4 do | |
| 334 | local x, y = StockBlocks[obj.id].transformations[obj.rotate][i].x + obj.x, StockBlocks[obj.id].transformations[obj.rotate][i].y + obj.y | |
| 335 | if (y == cfg.mapHeight + 1) or (map[fromXY(x,y)]) or (x > cfg.mapWidth) or (x < 1) then | |
| 336 | return false | |
| 337 | end | |
| 338 | end | |
| 339 | return true | |
| 340 | end | |
| 341 | ||
| 342 | function putInMap(obj) | |
| 343 | for j = 1, 4 do | |
| 344 | map[fromXY(StockBlocks[obj.id].transformations[obj.rotate][j].x + obj.x, StockBlocks[obj.id].transformations[obj.rotate][j].y + obj.y)] = 1 | |
| 345 | end | |
| 346 | end | |
| 347 | ||
| 348 | function GameInit() | |
| 349 | map = {}
| |
| 350 | control = {}
| |
| 351 | SetScore(0) | |
| 352 | fObj = createObject() | |
| 353 | sObj = createShadow(fObj) | |
| 354 | nextObj = createObject(nil, 1, 2) | |
| 355 | tick = 0 | |
| 356 | end | |
| 357 | ||
| 358 | function DrawMap() | |
| 359 | -- gpu.setBackground(0x222222) | |
| 360 | -- require("term").clear()
| |
| 361 | gpu.setBackground(cfg.backColor) | |
| 362 | gCanvas:Paint() | |
| 363 | -- gpu.fill(1, 1, cfg.mapWidth * 2, cfg.mapHeight, " ") | |
| 364 | drawPredict(nextObj) | |
| 365 | if cfg.drawShadow then | |
| 366 | drawObject(gCanvas, sObj, cfg.shadowColor) | |
| 367 | end | |
| 368 | end | |
| 369 | ||
| 370 | function GameHandle() | |
| 371 | local dX = 0 | |
| 372 | local dY = 0 | |
| 373 | local dR = 0 | |
| 374 | if control.l then | |
| 375 | dX = dX - 1 | |
| 376 | end | |
| 377 | if control.r then | |
| 378 | dX = dX + 1 | |
| 379 | end | |
| 380 | if control.d then | |
| 381 | dY = 1 | |
| 382 | end | |
| 383 | if control.u then | |
| 384 | dR = -1 | |
| 385 | control.u = false | |
| 386 | end | |
| 387 | -- control = {}
| |
| 388 | ||
| 389 | tick = (tick + 1) % cfg.fallTickCnt | |
| 390 | ||
| 391 | local moved = false | |
| 392 | local shadowMoved = false | |
| 393 | local tObj = cloneObject(fObj) | |
| 394 | ||
| 395 | if dX ~= 0 then | |
| 396 | fObj.x = fObj.x + dX | |
| 397 | if not check(fObj) then | |
| 398 | fObj.x = fObj.x - dX | |
| 399 | else | |
| 400 | moved = true | |
| 401 | shadowMoved = true | |
| 402 | end | |
| 403 | end | |
| 404 | if dR ~= 0 then | |
| 405 | fObj.rotate = (fObj.rotate - 1 + dR + #StockBlocks[fObj.id].transformations) % (#StockBlocks[fObj.id].transformations) + 1 | |
| 406 | if not check(fObj) then | |
| 407 | fObj.rotate = (fObj.rotate - 1 - dR + #StockBlocks[fObj.id].transformations) % (#StockBlocks[fObj.id].transformations) + 1 | |
| 408 | else | |
| 409 | moved = true | |
| 410 | shadowMoved = true | |
| 411 | end | |
| 412 | end | |
| 413 | ||
| 414 | local freeze = false | |
| 415 | if dY ~= 0 then | |
| 416 | tick = 0 | |
| 417 | fObj.y = fObj.y + dY | |
| 418 | if not check(fObj) then | |
| 419 | freeze = true | |
| 420 | fObj.y = fObj.y - dY | |
| 421 | else | |
| 422 | moved = true | |
| 423 | end | |
| 424 | elseif tick == 0 then | |
| 425 | fObj.y = fObj.y + 1 | |
| 426 | if not check(fObj) then | |
| 427 | freeze = true | |
| 428 | fObj.y = fObj.y - 1 | |
| 429 | else | |
| 430 | moved = true | |
| 431 | end | |
| 432 | end | |
| 433 | ||
| 434 | if cfg.drawShadow and shadowMoved then | |
| 435 | drawObject(gCanvas, sObj, cfg.backColor) | |
| 436 | sObj = createShadow(fObj) | |
| 437 | drawObject(gCanvas, sObj, cfg.shadowColor) | |
| 438 | end | |
| 439 | if moved then | |
| 440 | drawObject(gCanvas, tObj, cfg.backColor) | |
| 441 | drawObject(gCanvas, fObj) | |
| 442 | end | |
| 443 | if freeze then | |
| 444 | putInMap(fObj) | |
| 445 | IncreaseScore(linePoints[clearLines()]) | |
| 446 | fObj = nextObj | |
| 447 | fObj.x, fObj.y = StockBlocks[fObj.id].start_position.x + cfg.startX, StockBlocks[fObj.id].start_position.y | |
| 448 | if not check(fObj) then | |
| 449 | gui.backend.MessageBox:Create("GAME OVER", "Your score: "..GetScore()):Modify{ScreenWidth = cfg.mapWidth * 2, ScreenHeight = cfg.mapHeight}:Init():Paint()
| |
| 450 | -- messageBox("GAME OVER","Your score: "..GetScore())
| |
| 451 | -- gpu.setForeground(0xffffff) | |
| 452 | isRunning = false | |
| 453 | else | |
| 454 | clearLines() | |
| 455 | end | |
| 456 | if cfg.drawShadow then | |
| 457 | sObj = createShadow(fObj) | |
| 458 | drawObject(gCanvas, sObj, cfg.shadowColor) | |
| 459 | end | |
| 460 | drawObject(gCanvas, fObj) | |
| 461 | nextObj = createObject(nil, 1, 2) | |
| 462 | drawPredict(nextObj) | |
| 463 | end | |
| 464 | ||
| 465 | os.sleep(cfg.tickDelay) | |
| 466 | end | |
| 467 | ||
| 468 | function onKeyDown(ev, _, code1, code2, player) | |
| 469 | if (code1==113)and(code2==16) then | |
| 470 | isRunning = false -- TODO REMOVE | |
| 471 | elseif (code1==0) then | |
| 472 | if code2 == 203 then--left | |
| 473 | control.l = true | |
| 474 | elseif code2==200 then--up | |
| 475 | control.u = true | |
| 476 | elseif code2==205 then--right | |
| 477 | control.r = true | |
| 478 | elseif code2==208 then--down | |
| 479 | control.d = true | |
| 480 | end | |
| 481 | end | |
| 482 | end | |
| 483 | ||
| 484 | function onKeyUp(ev, _, code1, code2, player) | |
| 485 | if code2 == 203 then--left | |
| 486 | control.l = false | |
| 487 | elseif code2==200 then--up | |
| 488 | -- control.u = false | |
| 489 | elseif code2==205 then--right | |
| 490 | control.r = false | |
| 491 | elseif code2==208 then--down | |
| 492 | control.d = false | |
| 493 | end | |
| 494 | end | |
| 495 | -------------------- GUI -------------------- | |
| 496 | local quit = false | |
| 497 | gui.Init() | |
| 498 | ||
| 499 | GameForm = gui.backend.Form:Create(cfg.mapWidth * 2 + 12, cfg.mapHeight, | |
| 500 | {
| |
| 501 | canvas = gui.backend.Canvas:Create(1, 1, cfg.mapWidth * 2, cfg.mapHeight), | |
| 502 | panel = gui.CreateGroup( | |
| 503 | {
| |
| 504 | OnPaint = function(self) | |
| 505 | gpu.setBackground(0x222222) | |
| 506 | gpu.fill(self.X, 1, self.Width, cfg.mapHeight, " ") | |
| 507 | end | |
| 508 | }, | |
| 509 | {
| |
| 510 | canvas = gui.backend.Canvas:Create(3, 1, 8, 4), | |
| 511 | gui.backend.Text:Create(1, 6, 12, "Score:"):Modify{BackColor = 0x222222},
| |
| 512 | score = gui.backend.Text:Create(1, 7, 12, "0"):Modify{BackColor = 0x222222},
| |
| 513 | -- gui.backend.CheckBox:Create(1, 9, 12, "Shadow", true):Modify{BackColor = 0x222222},
| |
| 514 | gui.backend.Button:Create(1, 9, 12, 1, "New Game", function(self) | |
| 515 | -- if isRunning then | |
| 516 | -- self.Text = "Start" | |
| 517 | -- else | |
| 518 | -- self.Text = "Restart" | |
| 519 | -- end | |
| 520 | -- self:Paint() | |
| 521 | -- gpu.set(1, 1, self.Parent.Elements["pause"].X .. " " .. self.Parent.Elements["pause"].Y)os.sleep(1) | |
| 522 | self.Parent.Elements["pause"]:Modify{Text = "Pause"}:Paint()
| |
| 523 | GameInit() | |
| 524 | DrawMap() | |
| 525 | isInited = true | |
| 526 | isRunning = true | |
| 527 | end), | |
| 528 | pause = gui.backend.Button:Create(1, 11, 12, 1, "Pause", function(self) | |
| 529 | if not isInited then | |
| 530 | return | |
| 531 | end | |
| 532 | if isRunning then | |
| 533 | self.Text = "Resume" | |
| 534 | else | |
| 535 | self.Text = "Pause" | |
| 536 | end | |
| 537 | -- isRunning = false | |
| 538 | isRunning = not isRunning | |
| 539 | self:Paint() | |
| 540 | end), | |
| 541 | gui.backend.Button:Create(1, 13, 12, 1, "Settings", function(self) | |
| 542 | -- self.Parent.Elements["pause"]:OnElementClick() | |
| 543 | isRunning = false | |
| 544 | isInited = false | |
| 545 | self.Parent.Elements["pause"].Text = "Pause" | |
| 546 | GameForm:Disable(true) | |
| 547 | SettingsForm:Enable():Paint() | |
| 548 | end), | |
| 549 | gui.backend.Button:Create(1, 15, 12, 1, "Exit", function() quit = true end), | |
| 550 | }, cfg.mapWidth * 2 + 1, gui.GetCenter(1, cfg.mapHeight, 15), 12, cfg.mapHeight), | |
| 551 | } | |
| 552 | ):Init() | |
| 553 | ||
| 554 | SettingsForm = gui.backend.Form:Create(20, 13, | |
| 555 | {
| |
| 556 | gui.backend.Text:Create(1, 1, 20, "Settings"), | |
| 557 | ||
| 558 | gui.backend.Text:Create(1, 3, nil, "Width"), | |
| 559 | MapWidth = gui.backend.TextBox:Create(1, 4, 20, cfg.mapWidth .. "", "0123456789"), | |
| 560 | MapWidthError = gui.backend.Text:Create(1, 5, nil, ""):Modify{TextColor = 0xff0000},
| |
| 561 | ||
| 562 | gui.backend.Text:Create(1, 6, nil, "Height"), | |
| 563 | MapHeight = gui.backend.TextBox:Create(1, 7, 20, cfg.mapHeight .. "", "0123456789"), | |
| 564 | MapHeightError = gui.backend.Text:Create(1, 8, nil, ""):Modify{TextColor = 0xff0000},
| |
| 565 | ||
| 566 | DrawShadow = gui.backend.CheckBox:Create(1, 9, 0, "Draw Shadow", cfg.drawShadow), | |
| 567 | ||
| 568 | gui.backend.Button:Create(1, 11, 20, 3, "Back", function() | |
| 569 | cfg.mapWidth = SettingsForm.Elements["MapWidth"].Text + 0 | |
| 570 | cfg.startX = gui.GetCenter(1, cfg.mapWidth, 1) - 1 | |
| 571 | width = cfg.mapWidth + 10 | |
| 572 | cfg.mapHeight = SettingsForm.Elements["MapHeight"].Text + 0 | |
| 573 | cfg.drawShadow = SettingsForm.Elements["DrawShadow"].Checked | |
| 574 | SettingsForm.Elements["MapWidthError"]:Modify{Text = ""}:Paint()
| |
| 575 | SettingsForm.Elements["MapWidth"]:Modify{TextColor = 0xffffff}:Paint()
| |
| 576 | SettingsForm.Elements["MapHeightError"]:Modify{Text = ""}:Paint()
| |
| 577 | SettingsForm.Elements["MapHeight"]:Modify{TextColor = 0xffffff}:Paint()
| |
| 578 | ||
| 579 | local err, msg = ValidateConfig() | |
| 580 | if err ~= nil then | |
| 581 | SettingsForm.Elements[err]:Modify{Text = msg}:Paint()
| |
| 582 | SettingsForm.Elements[unicode.sub(err, 1, -6)]:Modify{TextColor = 0xff0000}:Paint()
| |
| 583 | return false | |
| 584 | end | |
| 585 | ||
| 586 | GameForm.Width = cfg.mapWidth * 2 + 12 | |
| 587 | local offsetX = cfg.mapWidth * 2 + 1 - GameForm.Elements["panel"].X | |
| 588 | local offsetY = gui.GetCenter(1, cfg.mapHeight, 15) - GameForm.Elements["panel"].Y | |
| 589 | -- GameForm.Elements["panel"].X = cfg.mapWidth * 2 + 1 | |
| 590 | for index, element in pairs(GameForm.Elements["panel"].Elements) do | |
| 591 | element.X = element.X + offsetX | |
| 592 | element.Y = element.Y + offsetY | |
| 593 | end | |
| 594 | GameForm.Elements["panel"].Elements["canvas"]:Init() -- kostil need fix | |
| 595 | GameForm.Elements["panel"].X = GameForm.Elements["panel"].X + offsetX | |
| 596 | GameForm.Elements["panel"].Y = GameForm.Elements["panel"].Y + offsetY | |
| 597 | GameForm.Height = cfg.mapHeight | |
| 598 | SettingsForm:Disable(true) | |
| 599 | GameForm:Enable():Paint() | |
| 600 | end), | |
| 601 | } | |
| 602 | ):Init() | |
| 603 | ||
| 604 | GameForm:Enable():Paint() | |
| 605 | ||
| 606 | gCanvas = GameForm.Elements["canvas"] | |
| 607 | pCanvas = GameForm.Elements["panel"].Elements["canvas"] | |
| 608 | scoreObj = GameForm.Elements["panel"].Elements["score"] | |
| 609 | ||
| 610 | ||
| 611 | -- GameInit() | |
| 612 | -- DrawMap() | |
| 613 | event.ignore("key_down", onKeyDown)
| |
| 614 | event.listen("key_down", onKeyDown)
| |
| 615 | event.ignore("key_up", onKeyUp)
| |
| 616 | event.listen("key_up", onKeyUp)
| |
| 617 | ||
| 618 | local suc, err = pcall(function() | |
| 619 | while not quit do | |
| 620 | if isRunning then | |
| 621 | GameHandle() | |
| 622 | else | |
| 623 | event.pull() | |
| 624 | end | |
| 625 | end | |
| 626 | end) | |
| 627 | ||
| 628 | if not suc then | |
| 629 | print(err) | |
| 630 | os.sleep(3) | |
| 631 | end | |
| 632 | ||
| 633 | gui.Destroy() | |
| 634 | event.ignore("key_down", onKeyDown)
| |
| 635 | event.ignore("key_up", onKeyUp)
| |
| 636 | gpu.setBackground(0x000000) | |
| 637 | gpu.setForeground(0xffffff) |