Помогите пожалуйста с оптимизацией тетриса
Помогите пожалуйста оптимизировать тетрис. Исходник написан каряво и на двухядерном проце 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, время: 16:34. |