Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 27.04.2011, 20:20
Новичок на форуме
Отправить личное сообщение для klerik113 Посмотреть профиль Найти все сообщения от klerik113
 
Регистрация: 27.04.2011
Сообщений: 6

Помогите пожалуйста с оптимизацией тетриса
Помогите пожалуйста оптимизировать тетрис. Исходник написан каряво и на двухядерном проце 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+=">&nbsp;</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;}

Последний раз редактировалось klerik113, 27.04.2011 в 20:24.
Ответить с цитированием
  #2 (permalink)  
Старый 27.04.2011, 20:57
Аватар для B@rmaley.e><e
⊞ Развернуть
Отправить личное сообщение для B@rmaley.e><e Посмотреть профиль Найти все сообщения от B@rmaley.e><e
 
Регистрация: 11.01.2010
Сообщений: 1,810

Сообщение от klerik113
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+=">&nbsp;</td>";
	            }
	            res+="</tr>";
	        }
	        res+="</table>";
	        return res;
	    });
	      
	}, 50);
Зачем Вы каждые 50 миллисекунд создаете таблицу заново? Не проще работать с существующей таблицей, изменяя только изменившиеся ячейки?
Ответить с цитированием
  #3 (permalink)  
Старый 27.04.2011, 23:49
Новичок на форуме
Отправить личное сообщение для klerik113 Посмотреть профиль Найти все сообщения от klerik113
 
Регистрация: 27.04.2011
Сообщений: 6

Над этим я уже думал но не знаю как сделать. У меня функция вставки и все остальное изменяет большой массив container и потом я его вывожу переписывая полностью таблицу. Как сделать иначе подскажите плз.
Ответить с цитированием
  #4 (permalink)  
Старый 28.04.2011, 00:25
Аватар для B@rmaley.e><e
⊞ Развернуть
Отправить личное сообщение для B@rmaley.e><e Посмотреть профиль Найти все сообщения от B@rmaley.e><e
 
Регистрация: 11.01.2010
Сообщений: 1,810

Менять существующую таблицу.
Почитайте о работе с DOM'ом.
Ответить с цитированием
  #5 (permalink)  
Старый 28.04.2011, 00:46
Новичок на форуме
Отправить личное сообщение для klerik113 Посмотреть профиль Найти все сообщения от klerik113
 
Регистрация: 27.04.2011
Сообщений: 6

Тоесть перебрать массив и если какой-то элемент изменился то заменить ячейку таблици?
Ответить с цитированием
  #6 (permalink)  
Старый 28.04.2011, 01:04
Аватар для B@rmaley.e><e
⊞ Развернуть
Отправить личное сообщение для B@rmaley.e><e Посмотреть профиль Найти все сообщения от B@rmaley.e><e
 
Регистрация: 11.01.2010
Сообщений: 1,810

Можно просто пройтись по всем ячейкам таблицы, поставив или убрав для них класс videmii (пользоваться транслитом нехорошо - используйте английский язык). Повторное задание того же класса не скажется на производительности, но сделает обновление таблицы удобнее.
Ответить с цитированием
  #7 (permalink)  
Старый 28.04.2011, 01:39
Новичок на форуме
Отправить личное сообщение для klerik113 Посмотреть профиль Найти все сообщения от klerik113
 
Регистрация: 27.04.2011
Сообщений: 6

Спасибо вроде понял. Пробовал убрать вывод таблици $(body).append, без него задействуется 5 - 10% проца. А с выводом 40 -50%
Ответить с цитированием
  #8 (permalink)  
Старый 28.04.2011, 02:39
Новичок на форуме
Отправить личное сообщение для klerik113 Посмотреть профиль Найти все сообщения от klerik113
 
Регистрация: 27.04.2011
Сообщений: 6

заменил
$("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+=">&nbsp;</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%. Что-то у меня руки карявые
Ответить с цитированием
  #9 (permalink)  
Старый 28.04.2011, 03:19
Аватар для poorking
prodigy
Отправить личное сообщение для poorking Посмотреть профиль Найти все сообщения от poorking
 
Регистрация: 01.11.2010
Сообщений: 503

Вы в setInterval делаете выборки, получите ссылку на таблицу заранее, а не выбирайте ее каждые 50миллисекунд, далее вы как то странно выбираете ячейки, сначала делаете выборку tr = $("table tr")[m];
, то есть получаете одного дитя выборки, а потом снова при выборе td заворачиваете td = $(tr).children("td")[n] и тут же берете снова одного дитя, потом $(td).addClass("videmii");
снова заворачиваете... Я jquery не знаю, но по-моему так там и работает и чтобы взять из выборки объект jquery к нему надо обращаться не selection[i] а selection.eq(i) кажется. (или наоборот )
Выберите таблицу ДО setInterval, а потом перемещайтесь по ней методами jquery, а не делайте выборки каждый раз
UPD
И кстати к ячейкам таблицы удобно обращаться table.rows[r].cells[c].className = "videmii"
table.rows[r].cells[c].className = ""
Это если обращаться не к библиотечным объектам а к голым узлам, ну там то уж точно что нибудь для этого есть
__________________
readOnly

Последний раз редактировалось poorking, 28.04.2011 в 03:58.
Ответить с цитированием
  #10 (permalink)  
Старый 28.04.2011, 14:37
Новичок на форуме
Отправить личное сообщение для klerik113 Посмотреть профиль Найти все сообщения от klerik113
 
Регистрация: 27.04.2011
Сообщений: 6

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);
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите пожалуйста девушке разобраться Feni4ka jQuery 10 26.04.2011 19:25
Помогите , пожалуйста, вытащить текст из тега liana1979 Общие вопросы Javascript 2 15.02.2011 14:55
Пожалуйста, помогите с созданием скрипта! Елизавета Общие вопросы Javascript 10 08.06.2010 13:20
помогите пожалуйста с скриптиком Len4ik Javascript под браузер 2 30.04.2010 20:10
помогите пожалуйста с кодом, который отмечает область на картинке 500rublei Общие вопросы Javascript 1 04.04.2010 13:04