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) |