View difference between Paste ID: M9wVcNi3 and Aw5jNfmG
SHOW: | | - or go back to the newest paste.
1
--ComputerCraft
2
--Tetris v 1.0
3
--© dzanis 12.07.12
4
5
6
local w,h = term.getSize()
7
local sX = w / 2 - 10/2 -- X позиция стакана
8
local sY = 1 -- Y позиция стакана
9
local iX = 2 -- X позиция инфы
10
local iY = 2 -- Y позиция инфы
11
12
local matrix = {} -- стакан 10x20
13
for p = 1 ,200 do -- инициализирую 200 ячеек
14
matrix[p] = 0 
15
end
16
17
 local figurePosX = 4 -- позиция фигуры в стакане
18
 local figurePosY = 1 --позиция фигуры в стакане
19
 local figureNum = 1 -- номер  фигуры
20
 local figureNextNum = math.random(1,7) -- случайный выбор  фигуры 
21
 local figureRotateNumber = 1 --номер положения фигуры
22
23
 --координаты квадратиков фигур по осям (x,y)
24
   local figure = {
25
        {{0,0,1,0,0,1,1,1}},--фигура квадрат
26
        {{0,1,1,1,2,1,1,2},{1,0,0,1,1,1,1,2},{1,0,0,1,1,1,2,1},{1,0,1,1,2,1,1,2}},--фигура по форме буквы "Т"
27
        {{1,0,1,1,1,2,2,2},{0,1,1,1,2,1,0,2},{0,0,1,0,1,1,1,2},{2,0,0,1,1,1,2,1}},--фигура по форме буквы "L"
28
        {{1,0,1,1,1,2,0,2},{0,0,0,1,1,1,2,1},{1,0,2,0,1,1,1,2},{0,1,1,1,2,1,2,2}},--фигура по форме буквы "L" зеркально
29
        {{0,1,1,1,1,2,2,2},{1,0,0,1,1,1,0,2}},--фигура по форме буквы "Z"
30
        {{1,1,2,1,0,2,1,2},{0,0,0,1,1,1,1,2}},--фигура по форме буквы "Z" зеркально
31
        {{0,2,1,2,2,2,3,2},{1,0,1,1,1,2,1,3}} --фигура по форме буквы "I"
32
    }
33
	
34
local run = true
35
local FIRST = 1
36
local PAUSE = 2
37
local GAME_OVER = 3
38
local GAME = 4
39
local gameState = FIRST -- выключатель режимов 1 начало,2 пауза , 3 проигрыш
40
local speed = 1.0 -- скорость игры	
41
local SCORE = 0 --очки
42
local LINES = 0 --счётчик линий
43
local LEVEL = 0 --уровень игры 
44
45
	
46
--прорисовка инфы
47
local function paintInfa()
48
	
49
50
	y = iY
51
	
52
	--прорисовка информации
53
	term.setCursorPos(iX,y)
54
	term.write("Score : " .. SCORE)
55
	y = y + 1
56
	term.setCursorPos(iX,y)
57
	term.write("Lines : " .. LINES)
58
	y = y + 1
59
	term.setCursorPos(iX,y)
60
	term.write("Level : " .. LEVEL)
61
	term.setCursorPos(iX,h - 2)
62
	term.write("")
63-
	term.write("ComputerCraft")
63+
64
	term.write("")
65
	term.setCursorPos(iX,h)
66
	term.write("Tetris")
67-
	term.write("dzanis 12.07.12")
67+
68
--прорисовка следуюшей фигуры
69
70
        for i = 1,8,2 do 
71
            term.setCursorPos(sX - 5 + figure[figureNextNum][1][i], iY + figure[figureNextNum][1][i + 1])
72
			term.write("0")
73
        end
74
75
76
 return	
77
end
78
79
local helpText = {	"",
80
					"------HELP-----", 
81
					"",
82
					"Right:  -> or D",
83
					"---------------",
84
					"Left: <- or A",
85
					"---------------",
86
					"Rotate:",
87
					" space or enter",
88
					"---------------",
89
					"Pause: P",
90
					"---------------",
91
					"Exit game:",
92
					"     back space",
93
					"",
94
					"---------------",
95
					}
96
97
--прорисовка хелпа управления
98
local function paintText()
99
	
100
	y = 1
101
	x = sX + 14
102
	
103
	--прорисовка информации
104
	while #helpText > y - 1 do
105
	term.setCursorPos(x,y)
106
	term.write(helpText[y])
107
	y = y + 1
108
	end
109
 return
110
end
111
112
113
	
114
--прорисовка фигур в стакане
115
local function paintMatrix()
116
117
118
-- прорисовка фона стакана
119
for y = 0,17 do
120
term.setCursorPos(sX,sY + y)
121
term.write("|..........|")
122
end
123
124
local pos = 21 --начинаю прорисовывать с 21-го (эфект вылезания фигур из потолка)
125
126
--прорисовка стакана с кубиками
127
	for y = sY,18 do
128
			for x = 1 + sX , 10 + sX do
129
				if matrix[pos] ~= 0 then --если не пусто 
130
				term.setCursorPos(x,y)
131
				term.write("0")	
132
				end
133
				if  matrix[pos] == -1 then matrix[pos] = 0 end -- обнуление ячейки падаюшей фигуры				
134
				
135
				
136
			pos = pos + 1
137
		end
138
139
	end
140
	
141
142
end
143
144
145
--даём добро на передвижение-поворот фигуры если:
146
    --1.фигура не выходит за пределы стакана
147
    --2.фигуре не мешают кубики
148
    --так же используется для проверки на упор фигуры в дно стакана или в замороженные кубики
149
local function canMove()
150
151
  for i = 1,8,2 do 
152
            x = figurePosX + figure[figureNum][figureRotateNumber][i];
153
            y = figurePosY + (figure[figureNum][figureRotateNumber][i+1] * 10);
154
            if x < 0 or x > 9 or x+y > 200 or x+y < 1 then --не выходит ли фигура за пределы стакана
155
                return false
156
            end
157
			
158
            if matrix[x+y] == 1 then --не мешают ли фигуре кубики
159
                return false;
160
				end
161
        end
162
		
163
      return true
164
end
165
166
local function newFigure()
167
	 
168
	figurePosX = 4 -- позиция фигуры в стакане
169
	figurePosY = 1 --позиция фигуры в стакане
170
	figureRotateNumber = 1 --номер положения фигуры	
171
 
172
	figureNum = figureNextNum
173
	figureNextNum = math.random(1,7) -- случайный выбор следуюшей фигуры
174
175
return 
176
end
177
178
179
--записываю фигуру в массив поля
180
    --(kube = 1)- замороженная фигура(достигшая дна), (kube = -1) - падающая фигура
181
 local function    insertFigureToMatrix() 
182
      local kube,pos, linesCount, count,len = 0
183
      if canMove() then  
184
		kube = -1
185
		else --если фигура уперается то замораживаю её
186
            figurePosY = figurePosY - 10 --позицию возврашяю для исключения выхода за пределы массива или наложения фигуры на замороженные кубики
187
            kube = 1;
188
       end
189
		
190
        --записываю фигуру в массив поля
191
        for i = 1,8,2 do  
192
		
193
		  pos = figurePosX + figure[figureNum][figureRotateNumber][i] + figurePosY + (figure[figureNum][figureRotateNumber][i+1] * 10)
194
            matrix[pos] = kube
195
			--print(pos)
196
        end
197
        
198
		
199
		pos = 21 --начинаю проверять с 21-й ячейки
200
		linesCount = 0 -- счётчик удалённых линий
201
		--проверка есть ли полные горизонтальные линии
202
	for y = 1,18 do
203
			count = 0 -- счётчик замороженных ячеек
204
			
205
		for x = 1 , 10  do
206
		
207
				if(matrix[pos] == 1) then --если ячейка заморожена то увеличиваем счётчик
208
                        count = count + 1
209
				end
210
				
211
				
212
			if y == 1  and count > 0 then --если есть замороженая ячейка в самой верхней линии то игра закончена
213
						gameState = GAME_OVER
214
					end
215
   
216
   
217
						if count == 10 then  --если в линии 10-ть замороженных ячеек то она  заполнена и её надо удалить
218
							linesCount = linesCount + 1 
219
							--удаление линии из стакана путём перезаписывания ячеек верхней линии в нижнию
220
							len = pos
221
							while len > 31 do
222
								for i = len,len - 10,-1 do  matrix[i] = matrix[i - 10] end
223
								len = len - 10								
224
							end	
225
								--перерисовываю стакан с задержкой							
226
								paintMatrix()
227
								sleep(0.1)
228
						end
229
		pos = pos + 1
230
			
231
		end	
232
			
233
		
234
	end
235
		
236
		
237
			
238
			
239
        -- если были стёрты линии обновляем инфу
240
		if linesCount > 0 then 
241
			LINES = LINES + linesCount --увеличиваем счётчик линий
242
			LEVEL = math.floor (LINES / 10) --уровень игры зависит от количества стёртых линий  ,10 линий 1 уровень ,20 линий 2й уровень и т.д.
243
			--присуждаем очки за количество удалённых линий,и уровня
244
			--очки за количество удалённых линий за раз,за одну 10,за две 50 и т.д
245
				local bonus = {10,50,100,200}
246
				SCORE = SCORE + bonus[linesCount]
247
		end
248
         
249
        if kube == 1 then --если фигура зоморожена создаю новую
250
				newFigure()
251
			end
252
			
253
        return
254
    end
255
256
257
	
258
259
local timer = os.startTimer(0)
260
local event, p1, p2 = nil
261
262
local function game()
263
264
 --временно сохраняю текущую позицию фигуры
265
         previosfigureRotateNumber = figureRotateNumber;
266
         previosfigurePosX = figurePosX;
267
         previosfigurePosY = figurePosY;
268
269
	
270
	
271
		if event == "key" then -- если нажата какая либо кнопка
272
			local key = p1
273
	
274
			if key == 83 or key == 263 then -- движение фигуры влево
275
				figurePosX = figurePosX - 1
276
		
277
			elseif key == 68 or key == 262 then --движение фигуры вправо
278
			figurePosX = figurePosX + 1
279
		
280
			--end	
281
			elseif key == 32 or key == 257 then -- поворот фигуры
282
			figureRotateNumber =  ((#figure[figureNum] > figureRotateNumber  ) and figureRotateNumber + 1) or 1 -- если массив фигур больше figureRotateNumber,то увеличеваем его на 1,если нет то сбрасываем на 1
283
			elseif key == 87 or key == 265 then  -- вниз 
284
			figurePosY = figurePosY + 10
285
			end
286
			
287
			
288
				
289
				
290
		end
291
		
292
	
293
	
294
	
295
			if canMove() ~= true then -- если двигать крутить нельзя то возврашяю прежнию позицию фигуры
296
				figureRotateNumber = previosfigureRotateNumber 
297
				figurePosX = previosfigurePosX
298
				figurePosY = previosfigurePosY
299
			end
300
		
301
		
302
			-- 1 уровень speed = 1.0    2  speed = 0.9   чем меньше тем быстрее фигуры падают,и недаю скорости уменьшится меньше 0.3 
303
			speed =  ((speed > 0.1) and 1.0 - LEVEL/10) or 0.1
304
			
305
	
306
		if event == "timer" and p1 == timer then -- здесь задаётся скорость падения фигур в зависимости от уровня
307
			timer = os.startTimer(speed)
308
			 figurePosY = figurePosY + 10 			
309
		end		
310
	
311
		
312
	
313
	return
314
end
315
316
317
 -- новая игра
318
local function newGame()
319
	SCORE = 0 
320
	LINES = 0 
321
	LEVEL = 0
322
	for p = 1 ,200 do matrix[p] = 0  end -- очистка 
323
	newFigure()
324
	return
325
end
326
327
-- диалог предлагаюший продолжить 
328
flashing = true
329
local function paintDialog()
330
	local text = {	
331
				{" WELKOME TETRIS",
332
				 "   P A U S E",
333
				"G A M E  O V E R",
334
				 "  PLAY TETRIS" },	
335
				 
336
				{"   to start",
337
				 "   to rezume",
338
				 "   to start",
339
				 "" },	 
340
				
341
			}
342
				
343
	term.setCursorPos(iX,h/2)
344
	term.write(text[1][gameState])
345
346
	if flashing and gameState ~= GAME  then
347
	term.setCursorPos(iX,h/2 + 2)
348
	term.write(" Press any key")
349
	term.setCursorPos(iX,h/2 + 3)
350
	term.write(text[2][gameState])
351
	end
352
	if event == "timer" and p1 == timer then -- здесь задаётся скорость моргалки
353
			timer = os.startTimer(0.5)
354
			 flashing = flashing ~= true				
355
		end	
356
	
357
	return
358
	end
359
360
	
361
-- здесь начинается игра
362
newGame()
363
364
while run do
365
366
367
	event, p1, p2 = os.pullEvent()
368
	
369
	
370
	if event == "key" then -- если нажата какая либо кнопка
371
			local key = p1		
372
	if  key == 80 then -- кнопка P
373
		gameState = PAUSE
374
	elseif  key == 259 then -- кнопка back space
375
		run = false	
376
	elseif key > 1 and gameState ~= GAME then -- если нажата любая кнопка  кроме Escape
377
				if gameState == GAME_OVER then newGame()  end 
378
				gameState = GAME 
379
				timer = os.startTimer(0)	
380
		end
381
	end
382
	
383
	if gameState == GAME then  	
384
		game()
385
	end
386
387
	insertFigureToMatrix() 
388
	term.clear() --очистка терминала
389
	paintMatrix()
390
	paintInfa()
391
	paintText()	
392
	paintDialog() 
393
	
394
	
395
	
396
	
397
		
398
399
end
400
401
term.clear() --очистка терминала
402
term.setCursorPos(1,1)
403
404
405
406
407
408
409
410
411
412
413