Редактирование: Тетрис

Перейти к: навигация, поиск

Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
==Описание==
 
 
Реализация копьютерной игры тетрис на языке программирования JavaScript
 
 
Исполнитель: [[Бакута Артём|Бакута Артём]]
 
 
Группа 13632/1 Кафедра Теоретической механики
 
 
Файл:[[https://csspbstu-my.sharepoint.com/:w:/g/personal/bakuta_ad_edu_spbstu_ru/EUhgTweJoiRGkRsNAJYFuPEB3PDm0ceEIPsR2nG1jQYF-g?e=lI4tSY]]
 
 
==Визуализация==
 
 
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Bakuta_AD/tetris.html |width=800 |height=650 |border=0 }}
 
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Bakuta_AD/tetris.html |width=800 |height=650 |border=0 }}
 
==Код программы==
 
<div class="mw-collapsible mw-collapsed">
 
'''Код программы на языке JavaScript:''' <div class="mw-collapsible-content">
 
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 
// indicates the table in the page, this table is the main panel that will display the game
 
var tbl;
 
// Game state 0: not started; 1 run; 2 abort;
 
var status = 0;
 
// timer, the timer will do moveDown operation
 
var timer;
 
//fraction
 
var score = 0;
 
//True if this is the first piece
 
// Needed to generate the next piece
 
var ff;
 
//area is an 18*10 array that also corresponds to the table's table. Initially 0, if occupied, 1
 
// Counter for droped lines
 
var DropedLines = 0;
 
//Speed of the game from 1 to 0.3
 
var speed = 1;
 
//Level of current game
 
var level = 1;
 
// Incresing the score if lines are dropping in a raw
 
var factor = 0;
 
 
var isDown = true;
 
var area = new Array(18);
 
for(var i=0;i<18;i++)
 
{
 
area[i] = new Array(10);
 
}
 
for(var i=0;i<18;i++)
 
{
 
for(var j=0; j<10; j++)
 
{
 
area[i][j] = 0;
 
}
 
}
 
 
// The currently active square, which can be moved left and right, variant. When it bottoms out, the area will be updated;
 
var activeBlock;
 
var nextBlock;
 
// Produce a square shape with 7 basic shapes.
 
function generateBlock()
 
{
 
activeBlock = null;
 
document.getElementById("speed").innerText = " " + speed;
 
if (ff == false)
 
{
 
activeBlock = nextBlock;
 
eraseNext();
 
}
 
else
 
{
 
activeBlock = gen();
 
}
 
nextBlock = gen();
 
 
//Check if the four small squares just produced can be placed in the initialized position.
 
for(var i=0; i<4; i++)
 
{
 
if(!isCellValid(activeBlock[i].x, activeBlock[i].y))
 
{
 
return false;
 
}
 
}
 
ff = false;
 
return true;
 
}
 
 
// Randomly generate 0-6 array, representing 7 forms.
 
function gen()
 
{
 
var block = new Array(4);
 
var t = (Math.floor(Math.random()*20)+1)%19;
 
// The repetition prevents an appearance the same blocks many times in a raw
 
switch(t)
 
{
 
case 0:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:0, y:5};
 
block[3] = {x:1, y:5};
 
break;
 
}
 
case 1:
 
{
 
block[0] = {x:0, y:3};
 
block[1] = {x:0, y:4};
 
block[2] = {x:0, y:5};
 
block[3] = {x:0, y:6};
 
break;
 
}
 
case 2:
 
{
 
block[0] = {x:0, y:5};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:2, y:4};
 
break;
 
}
 
case 3:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:2, y:5};
 
break;
 
}
 
case 4:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:1, y:6};
 
break;
 
}
 
case 5:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:2, y:4};
 
block[3] = {x:2, y:5};
 
break;
 
}
 
case 6:
 
{
 
block[0] = {x:0, y:5};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:1, y:6};
 
break;
 
}
 
case 7:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:0, y:5};
 
block[3] = {x:1, y:5};
 
break;
 
}
 
case 8:
 
{
 
block[0] = {x:0, y:3};
 
block[1] = {x:0, y:4};
 
block[2] = {x:0, y:5};
 
block[3] = {x:0, y:6};
 
break;
 
}
 
case 9:
 
{
 
block[0] = {x:0, y:5};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:2, y:4};
 
break;
 
}
 
case 10:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:2, y:5};
 
break;
 
}
 
case 11:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:1, y:6};
 
break;
 
}
 
case 12:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:2, y:4};
 
block[3] = {x:2, y:5};
 
break;
 
}
 
case 13:
 
{
 
block[0] = {x:0, y:5};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:1, y:6};
 
break;
 
}
 
case 14:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:0, y:5};
 
block[3] = {x:1, y:5};
 
break;
 
}
 
case 15:
 
{
 
block[0] = {x:0, y:3};
 
block[1] = {x:0, y:4};
 
block[2] = {x:0, y:5};
 
block[3] = {x:0, y:6};
 
break;
 
}
 
case 16:
 
{
 
block[0] = {x:0, y:5};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:2, y:4};
 
break;
 
}
 
case 17:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:2, y:5};
 
break;
 
}
 
case 18:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:1, y:5};
 
block[3] = {x:1, y:6};
 
break;
 
}
 
case 19:
 
{
 
block[0] = {x:0, y:4};
 
block[1] = {x:1, y:4};
 
block[2] = {x:2, y:4};
 
block[3] = {x:2, y:5};
 
break;
 
}
 
}
 
return block;
 
}
 
//Move Downward
 
function moveDown()
 
{
 
// Check the bottom boundary.
 
if(checkBottomBorder())
 
{
 
//No bottoming, erase the current graphic,
 
erase();
 
// Update the current drawing coordinates
 
for(var i=0; i<4; i++)
 
{
 
activeBlock[i].x = activeBlock[i].x + 1;
 
}
 
// Repaint the current graphics
 
paint();
 
}
 
// bottoming out,
 
else
 
{
 
// Stop the current timer, that is, stop automatically moving down.
 
clearInterval(timer);
 
// Update the area array.
 
updatearea();
 
// Consumer
 
var lines = deleteLine();
 
//if there is a break, then
 
if(lines!=0){
 
DropedLines++;
 
factor++;
 
// Update the score
 
score = score + lines*10*factor;
 
for (var i = 1; i < 10; i++)
 
{
 
if (score - i*50 >= 0) { level = i+1; }
 
}
 
updatescore();
 
// Wipe the entire panel
 
erasearea();
 
//Redraw panel
 
paintarea();
 
}
 
else { factor = 0 }
 
 
if (level > 1)
 
{
 
speed = 1-0.1*level;
 
}
 
 
//Generate a new graphic and determine if it can be placed in the original position.
 
if(!generateBlock())
 
{
 
alert("Game over!");
 
status = 2;
 
return;
 
}
 
paint();
 
//timer, execute moveDown every second
 
timer = setInterval(moveDown, 1000*speed)
 
}
 
}
 
 
function straightDown()
 
{
 
var currentBlock = activeBlock;
 
for(var i = 0; i < 18; i++)
 
{
 
if (currentBlock == activeBlock)
 
{
 
moveDown();
 
}
 
else
 
{
 
break;
 
}
 
}
 
 
 
}
 
 
//Left move
 
function moveLeft()
 
{
 
if(checkLeftBorder())
 
{
 
erase();
 
for(var i=0; i<4; i++)
 
{
 
activeBlock[i].y = activeBlock[i].y - 1;
 
}
 
paint();
 
}
 
}
 
//Right move
 
function moveRight()
 
{
 
if(checkRightBorder())
 
{
 
erase();
 
for(var i=0; i<4; i++)
 
{
 
activeBlock[i].y = activeBlock[i].y + 1;
 
}
 
paint();
 
}
 
}
 
//rotate, because there may be squares over the existing squares after the rotation.
 
// First use a tmpBlock, copy the contents of activeBlock to tmpBlock,
 
// Try to rotate tmpBlock, if the detection after rotation found no squares conflict, then
 
// Give the value of the rotated tmpBlock to activeBlock.
 
function rotate()
 
{
 
var tmpBlock = new Array(4);
 
for(var i=0; i<4; i++)
 
{
 
tmpBlock[i] = {x:0, y:0};
 
}
 
for(var i=0; i<4; i++)
 
{
 
tmpBlock[i].x = activeBlock[i].x;
 
tmpBlock[i].y = activeBlock[i].y;
 
}
 
// Calculate the center point of the four points first, then the four points are rotated 90 degrees around the center.
 
var cx = Math.round((tmpBlock[0].x + tmpBlock[1].x + tmpBlock[2].x + tmpBlock[3].x)/4);
 
var cy = Math.round((tmpBlock[0].y + tmpBlock[1].y + tmpBlock[2].y + tmpBlock[3].y)/4);
 
// The main algorithm of rotation. Can be broken down to understand.
 
// First assume that the rotation around the source point. Then add the coordinates of the center point.
 
 
for(var i=0; i<4; i++)
 
{
 
tmpBlock[i].x = cx+cy-activeBlock[i].y;
 
tmpBlock[i].y = cy-cx+activeBlock[i].x;
 
}
 
// Check whether the rotation of the rear grid is legal.
 
for(var i=0; i<4; i++)
 
{
 
if(!isCellValid(tmpBlock[i].x,tmpBlock[i].y))
 
{
 
return;
 
}
 
}
 
//if it is legal, erase
 
erase();
 
// Reassign the activeBlock.
 
for(var i=0; i<4; i++)
 
{
 
activeBlock[i].x = tmpBlock[i].x;
 
activeBlock[i].y = tmpBlock[i].y;
 
}
 
//Redraw.
 
paint();
 
}
 
//Check the left border and try to move one to the left to see if it is legal.
 
function checkLeftBorder()
 
{
 
for(var i=0; i<activeBlock.length; i++)
 
{
 
if(activeBlock[i].y==0)
 
{
 
return false;
 
}
 
if(!isCellValid(activeBlock[i].x, activeBlock[i].y-1))
 
{
 
return false;
 
}
 
}
 
return true;
 
}
 
//Check the right border and try to move one to the right to see if it is legal.
 
function checkRightBorder()
 
{
 
for(var i=0; i<activeBlock.length; i++)
 
{
 
if(activeBlock[i].y==9)
 
{
 
return false;
 
}
 
if(!isCellValid(activeBlock[i].x, activeBlock[i].y+1))
 
{
 
return false;
 
}
 
}
 
return true;
 
}
 
//Check the bottom boundary and try to move one down to see if it is legal.
 
function checkBottomBorder()
 
{
 
for(var i=0; i<activeBlock.length; i++)
 
{
 
if(activeBlock[i].x==17)
 
{
 
return false;
 
}
 
if(!isCellValid(activeBlock[i].x+1, activeBlock[i].y)){
 
return false;
 
}
 
}
 
return true;
 
}
 
//Check if the coordinates of (x,y) already exist in the area, and the existence indicates that the square is illegal.
 
function isCellValid(x, y)
 
{
 
if(x>17||x<0||y>9||y<0)
 
{
 
return false;
 
}
 
if(area[x][y]==1)
 
{
 
return false;
 
}
 
return true;
 
}
 
//erase
 
function erase()
 
{
 
for(var i=0; i<4; i++)
 
{
 
tbl.rows[activeBlock[i].x].cells[activeBlock[i].y].style.backgroundColor="white";
 
}
 
}
 
 
function eraseNext()
 
{
 
for(var i=0; i<4; i++)
 
{
 
tbl2.rows[nextBlock[i].x].cells[nextBlock[i].y-3].style.backgroundColor="#EBEBEB";
 
}
 
}
 
 
// paint activity graphics
 
function paint()
 
{
 
for(var i=0; i<4; i++)
 
{
 
tbl.rows[activeBlock[i].x].cells[activeBlock[i].y].style.backgroundColor="#CC3333";
 
}
 
for(var i = 0; i < 4; i++)
 
{
 
tbl2.rows[nextBlock[i].x].cells[nextBlock[i].y-3].style.backgroundColor="#CC3333";
 
}
 
}
 
// Update the area array
 
function updatearea()
 
{
 
for(var i=0; i<4; i++)
 
{
 
area[activeBlock[i].x][activeBlock[i].y]=1;
 
}
 
}
 
// Consumer
 
function deleteLine()
 
{
 
var lines = 0;
 
for(var i=0; i<18; i++)
 
{
 
var j=0;
 
for(; j<10; j++)
 
{
 
if(area[i][j]==0)
 
{
 
break;
 
}
 
}
 
if(j==10)
 
{
 
lines++;
 
if(i!=0)
 
{
 
for(var k=i-1; k>=0; k--)
 
{
 
area[k+1] = area[k];
 
}
 
}
 
area[0] = generateBlankLine();
 
}
 
}
 
return lines;
 
}
 
// Wipe the entire panel
 
function erasearea()
 
{
 
for(var i=0; i<18; i++)
 
{
 
for(var j=0; j<10; j++)
 
{
 
tbl.rows[i].cells[j].style.backgroundColor = "white";
 
}
 
}
 
}
 
// Redraw the entire panel
 
function paintarea()
 
{
 
for(var i=0;i<18;i++)
 
{
 
for(var j=0; j<10; j++)
 
{
 
if(area[i][j]==1)
 
{
 
tbl.rows[i].cells[j].style.backgroundColor = "#CC3333";
 
}
 
}
 
}
 
}
 
//Generate a blank line.
 
function generateBlankLine()
 
{
 
var line = new Array(10);
 
for(var i=0; i<10; i++)
 
{
 
line[i] = 0;
 
}
 
return line;
 
}
 
// Update the score
 
function updatescore()
 
{
 
document.getElementById("score").innerText = " " + score;
 
document.getElementById("lines").innerText = " " + DropedLines;
 
document.getElementById("level").innerText = " " + level;
 
}
 
// keyboard control
 
function keyControl()
 
{
 
if(status !=1 )
 
{
 
return;
 
}
 
var code = event.keyCode;
 
switch(code)
 
{
 
case 32:
 
{
 
straightDown();
 
break;
 
}
 
 
case 37:
 
{
 
moveLeft();
 
break;
 
}
 
case 38:
 
{
 
rotate();
 
break;
 
}
 
case 39:
 
{
 
moveRight();
 
break;
 
}
 
case 40:
 
{
 
moveDown();
 
break;
 
}
 
}
 
}
 
 
 
//Start
 
function begin(e)
 
{
 
e.disabled = true;
 
ff = true;
 
status = 1;
 
tbl = document.getElementById("area");
 
tbl2 = document.getElementById("NextPiece");
 
if(!generateBlock())
 
{
 
alert("Game over!");
 
status = 2;
 
return;
 
}
 
paint();
 
timer = setInterval(moveDown,1000*speed);
 
}
 
document.onkeydown=keyControl;
 
 
</syntaxhighlight>
 
</div>
 
Вам запрещено изменять защиту статьи. Edit Создать редактором

Обратите внимание, что все добавления и изменения текста статьи рассматриваются как выпущенные на условиях лицензии Public Domain (см. Department of Theoretical and Applied Mechanics:Авторские права). Если вы не хотите, чтобы ваши тексты свободно распространялись и редактировались любым желающим, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого.
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ МАТЕРИАЛЫ, ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Отменить | Справка по редактированию  (в новом окне)
Источник — «http://tm.spbstu.ru/Тетрис»