Помогите пожалуйста с оптимизацией тетриса
Помогите пожалуйста оптимизировать тетрис. Исходник написан каряво и на двухядерном проце 1.8 одно ядро забито полностью.
index.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>Tetris</title> <link media="all" rel="stylesheet" type="text/css" href="css/all.css" /> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/tetris.js"></script> </head> <body> </body> </html> tetris.js
Array.prototype.null = function()
{
for (indexMass = 0; indexMass < this.length; indexMass++)
{
this[indexMass] = 0;
}
};
var container = new Array();
containerHeight = 23;
containerWidth = 16;
for (i = 0; i < containerHeight; i++)
{
container[i] = new Array(containerWidth);
container[i].null();
}
for (i = 0; i<containerHeight; i++)
{
container[i][0] = 1;
container[i][1] = 1;
if (i == containerHeight-1 || i == containerHeight-2)
{
for (j = 0; j<containerWidth; j++)
{
container[i][j] = 1;
}
}
container[i][containerWidth-1] = 1;
container[i][containerWidth-2] = 1;
}
typeFigure=[
[ [0, 0, 1, 0], [0, 0, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0] ], //J+
[ [0, 0, 0, 0], [1, 1, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0] ],
[ [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 0, 0], [0, 1, 0, 0] ],
[ [0, 0, 0, 0], [0, 1, 0, 0], [0, 1, 1, 1], [0, 0, 0, 0] ],
[ [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0] ], //L+
[ [0, 0, 0, 0], [0, 0, 1, 0], [1, 1, 1, 0], [0, 0, 0, 0] ],
[ [0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0] ],
[ [0, 0, 0, 0], [0, 1, 1, 1], [0, 1, 0, 0], [0, 0, 0, 0] ],
[ [0, 0, 0, 0], [0, 1, 1, 0], [1, 1, 0, 0], [0, 0, 0, 0] ], //S
[ [0, 0, 0, 0], [0, 1, 0, 0], [0, 1, 1, 0], [0, 0, 1, 0] ],
[ [0, 0, 0, 0], [0, 0, 1, 1], [0, 1, 1, 0], [0, 0, 0, 0] ],
[ [0, 1, 0, 0], [0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0] ],
[ [0, 0, 0, 0], [1, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0] ], //Z
[ [0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 1, 0], [0, 1, 0, 0] ],
[ [0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 1, 1], [0, 0, 0, 0] ],
[ [0, 0, 1, 0], [0, 1, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0] ],
[ [0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0] ], //O+
[ [0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0] ],
[ [0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0] ],
[ [0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0] ],
[ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1] ], //I+
[ [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0] ],
[ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1] ],
[ [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0] ],
[ [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 0], [0, 1, 0, 0] ], //T+
[ [0, 0, 0, 0], [0, 1, 0, 0], [0, 1, 1, 0], [0, 1, 0, 0] ],
[ [0, 0, 0, 0], [0, 1, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0] ],
[ [0, 0, 0, 0], [0, 1, 0, 0], [1, 1, 0, 0], [0, 1, 0, 0] ],
];
function Figure (index)
{
this.x = null;
this.y = null;
this.index = index || (Math.floor(Math.random() * 7) * 4);
this.type = typeFigure[this.index];
if (this.type == null || undefined)
alert("type of figure is not defined");
}
Figure.prototype.validityAppend = function(x, y)
{
result = new Array(4);
for (k = 0; k < 4; k++)
{
result[k] = new Array(4);
figureSlice = this.type[k];
containerSlice = container [y + k] .slice (x, x + 4);
for (j = 0; j < 4; j++)
{
result[k][j] = figureSlice [j] + containerSlice [j];
if (result[k][j] == 2)
return false;
}
}
return true;
};
Figure.prototype.figureAppend = function(x, y)
{
if(!x && !y)
return false;
this.x = x;
this.y = y;
result = this.validityAppend(x, y);
if (result!=false)
{
for(i = 0; i < 4; i++)
{
container[y + i].splice(x, 4,
this.type[i][0] + container[y + i][x],
this.type[i][1] + container[y + i][x + 1],
this.type[i][2] + container[y + i][x + 2],
this.type[i][3] + container[y + i][x + 3]);
}
return true;
}
return false;
}
Figure.prototype.searchFigure = function()
{
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if (this.type[i][j] == 1)
{
if (container[this.y + i][this.x + j] != 1)
return false;
}
}
}
return true;
}
Figure.prototype.deleteFigure = function()
{
if (this.searchFigure() == true)
{
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if (this.type[i][j] == 1)
{
container[this.y + i][this.x + j] = 0;
}
}
}
}
}
Figure.prototype.overturnFigure = function()
{
this.deleteFigure();
reserv = this.index;
indexx = this.index;
if (this.index >= 3)
indexx = this.index % 4;
if (indexx == 3)
this.index = this.index - 3;
else
this.index++;
this.type = typeFigure[this.index];
if(this.figureAppend(this.x, this.y))
return true;
else
{
this.index = reserv;
this.type = typeFigure[this.index];
this.figureAppend(this.x, this.y);
return false;
}
}
Figure.prototype.left = function()
{
if(this.x > 0)
{
this.deleteFigure();
if(this.figureAppend(this.x - 1, this.y))
{
this.xl = this.x;
this.yl = this.y;
return true;
}
else
{
this.figureAppend(this.x + 1, this.y);
return false;
}
}
}
Figure.prototype.right = function()
{
if(this.x < containerWidth)
{
this.deleteFigure();
if(this.figureAppend(this.x + 1, this.y))
{
this.xr = this.x;
this.yr = this.y;
return true;
}
else
{
this.figureAppend(this.x - 1, this.y);
return false;
}
}
}
Figure.prototype.down = function()
{
if(this.y <= containerHeight)
{
this.deleteFigure();
if (this.figureAppend(this.x, this.y + 1))
{
this.xd = this.x;
this.yd = this.y;
return true;
}
else
{
this.figureAppend(this.x, this.y - 1);
return false;
}
}
}
Figure.prototype.completeSeries = function (mas)
{
for (i = 0; i < containerWidth; i++)
{
if (mas[i] == 0)
return false;
}
return true;
}
Figure.prototype.completeSeriesDelete = function ()
{
for (k = 2; k < containerHeight - 2; k++)
{
if (figure1.completeSeries(container[k]))
{
container.splice(k, 1);
container.unshift([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]);
}
}
}
$(document).ready(function()
{
time = new Date();
time = time.getTime();
$(document).keypress(function(e)
{
keypressTime = new Date();
if ( !(time + 50 > keypressTime.getTime()) )
{
switch(e.keyCode)
{
case 37:
figure1.left();
time = keypressTime.getTime();
break;
case 39:
figure1.right();
time = keypressTime.getTime();
break;
case 38:
figure1.overturnFigure();
time = keypressTime.getTime();
break;
case 40:
if(!figure1.down())
{
figure1 = new Figure();
figure1.completeSeriesDelete();
if (!figure1.figureAppend(6, 0))
exit();
}
time = keypressTime.getTime();
break;
}
}
});
});
function exit()
{
alert('exit');
}
$(document).ready(function(){
var count = 0;
figure1= new Figure();
figure1.figureAppend(6, 0);
setInterval(function(){
$("body").html(function(){
res="<table>";
for(i=0; i<containerHeight; i++)
{
res+="<tr>";
for(j=0; j<containerWidth; j++)
{
res+="<td";
if(container[i][j]==1)
res+=" class='videmii'";
res+="> </td>";
}
res+="</tr>";
}
res+="</table>";
return res;
});
}, 50);
setInterval(function(){
if(!figure1.down())
{
figure1= new Figure();
figure1.completeSeriesDelete();
if (!figure1.figureAppend(6, 0))
exit();
}
}, 1000);
});
all.css
body{margin: 0; padding: 0;}
table{font-size: 5px;}
td{width: 15px; height: 15px; border: 1px solid;}
.videmii{background: black;}
|
Цитата:
|
Над этим я уже думал но не знаю как сделать. У меня функция вставки и все остальное изменяет большой массив container и потом я его вывожу переписывая полностью таблицу. Как сделать иначе подскажите плз.
|
Менять существующую таблицу.
Почитайте о работе с DOM'ом. |
Тоесть перебрать массив и если какой-то элемент изменился то заменить ячейку таблици?
|
Можно просто пройтись по всем ячейкам таблицы, поставив или убрав для них класс videmii (пользоваться транслитом нехорошо - используйте английский язык). Повторное задание того же класса не скажется на производительности, но сделает обновление таблицы удобнее.
|
Спасибо вроде понял. Пробовал убрать вывод таблици $(body).append, без него задействуется 5 - 10% проца. А с выводом 40 -50%
|
заменил
$("body").html(function(){
res="<table>";
for(i=0; i<containerHeight; i++)
{
res+="<tr>";
for(j=0; j<containerWidth; j++)
{
res+="<td";
if(container[i][j]==1)
res+=" class='videmii'";
res+="> </td>";
}
res+="</tr>";
}
res+="</table>";
return res;
});
setInterval(function(){
for(m=0; m<containerHeight - 2; m++)
{
tr = $("table tr")[m];
for(n=2; n<containerWidth - 2; n++)
{
td = $(tr).children("td")[n];
if (container[m][n]==1)
$(td).addClass("videmii");
else
$(td).removeClass("videmii");
}
}
}, 50);
Загрузка проца пошла на 60%. Что-то у меня руки карявые |
Вы в setInterval делаете выборки, получите ссылку на таблицу заранее, а не выбирайте ее каждые 50миллисекунд, далее вы как то странно выбираете ячейки, сначала делаете выборку tr = $("table tr")[m];
, то есть получаете одного дитя выборки, а потом снова при выборе td заворачиваете td = $(tr).children("td")[n] и тут же берете снова одного дитя, потом $(td).addClass("videmii"); снова заворачиваете... Я jquery не знаю, но по-моему так там и работает и чтобы взять из выборки объект jquery к нему надо обращаться не selection[i] а selection.eq(i) кажется. (или наоборот :D :D) Выберите таблицу ДО setInterval, а потом перемещайтесь по ней методами jquery, а не делайте выборки каждый раз UPD И кстати к ячейкам таблицы удобно обращаться table.rows[r].cells[c].className = "videmii" table.rows[r].cells[c].className = "" Это если обращаться не к библиотечным объектам а к голым узлам, ну там то уж точно что нибудь для этого есть |
poorking,
Спасибо. Написал без jQuery. Работает отлично)). Правда при нажатии клавиши вниз всеравно чуть подвисает((. Теперь понял что в таких случаях надо оптимизировать и переходить аж на Ассемблер))
table = $("table")[0];
setInterval(function(){
for(m=0; m<23; m++)
{
//tr = $("table tr")[m];
for(n=0; n<16; n++)
{
td = table.rows[m].cells[n];//$(tr).children("td")[n];
if (container[m][n]==1)
td.className = "videmii";
else
td.className = "";
}
}
}, 50);
|
Цитата:
В остальных же случаях вопрос лишь в правильном использовании того, что имеется. |
| Часовой пояс GMT +3, время: 01:07. |