Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   змейка на javascript (https://javascript.ru/forum/project/14322-zmejjka-na-javascript.html)

Shaci 11.01.2011 11:58

змейка на javascript
 
Вложений: 1
попробовал написать змейку
в firefox чуть-чуть лагает,
в IE вроде всё нормально работает

Vulkan 11.01.2011 12:18

Ну у меня в опере чуть лагает, иногда остаются после змейки красные квадратики, а потом исчезают, а так вроде норм, а почему бы
<td> с помощью document.write(); в цикле не сформировать?

Shaci 11.01.2011 12:20

вот в IE у меня этих красных квадратиков не остается, а в firefox есть

Vulkan 11.01.2011 12:41

а по второму вопросу?)

Shaci 11.01.2011 12:44

да, надо будет сформировать динамически таблицу.

ksa 11.01.2011 13:13

Цитата:

Сообщение от Shaci
надо будет сформировать динамически таблицу

Зачем таблицу-то?
Можно и просто некий массив (как квадратики) гонять в некоем прямоугольнике...

Vulkan 11.01.2011 13:16

да кстати, например canvas использовать подойдёт в самый раз

ksa 11.01.2011 13:17

Обычные дивы запросто подойдут...

Vulkan 11.01.2011 13:37

Да, но на canvas думаю будет удобнее, просто рисовать и стирать прямоугольники.

Kolyaj 11.01.2011 13:49

Удобнее дивы передвигать, чем прямоугольники рисовать-стирать.

Vulkan 11.01.2011 14:07

Цитата:

Сообщение от Kolyaj (Сообщение 87366)
Удобнее дивы передвигать, чем прямоугольники рисовать-стирать.

Кому как

ksa 11.01.2011 14:07

Kolyaj, отож... :yes:

B~Vladi 11.01.2011 14:17

Почему бы код
//выход за пределы поля
if (snakeArray[lastI].x > 19) {
  alert("You LOSE" + " POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
} else if (snakeArray[lastI].y > 19){
  alert("You LOSE" + " POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
} else if (snakeArray[lastI].y < 0) {
  alert("You LOSE" + " POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
} else if (snakeArray[lastI].x < 0) {
  alert("You LOSE"  + " POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
}

не записать так:
if (snakeArray[lastI].x > 19 || snakeArray[lastI].y > 19 || snakeArray[lastI].y < 0 || snakeArray[lastI].x < 0) {
  alert("You LOSE POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
}


В фф у меня тоже остаются квадратики.

И ещё. Код в блоках if else вроде одинаковый? (строки с 189 по 240). Тогда нет смысла вообще проверять направление.

Shaci 11.01.2011 14:26

Цитата:

Сообщение от B~Vladi (Сообщение 87369)
Почему бы код
//выход за пределы поля
if (snakeArray[lastI].x > 19) {
  alert("You LOSE" + " POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
} else if (snakeArray[lastI].y > 19){
  alert("You LOSE" + " POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
} else if (snakeArray[lastI].y < 0) {
  alert("You LOSE" + " POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
} else if (snakeArray[lastI].x < 0) {
  alert("You LOSE"  + " POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
}

не записать так:
if (snakeArray[lastI].x > 19 || snakeArray[lastI].y > 19 || snakeArray[lastI].y < 0 || snakeArray[lastI].x < 0) {
  alert("You LOSE POINTS: " + POINTS);
  clearInterval(idInterval)
  return;
}

да ,конечно
я просто не оптимизировал код

Цитата:

И ещё. Код в блоках if else вроде одинаковый? (строки с 189 по 240). Тогда нет смысла вообще проверять направление.
там 2 строчки разные в зависимости от направления
которые nextX и nextY вычисляют

B~Vladi 11.01.2011 18:44

Цитата:

Сообщение от Shaci
там 2 строчки разные в зависимости от направления

Как это я не заметил =)
Ну в общем есть ещё над чем поработать =)

Matre 11.01.2011 22:07

Shaci
слиш а как вы это написали
там через сервер?или mvc?

кстати в lynx неработает игра

Shaci 11.01.2011 22:09

Цитата:

Сообщение от B~Vladi (Сообщение 87448)
Как это я не заметил =)
Ну в общем есть ещё над чем поработать =)

над вёрсткой надо мне работать))

Matre 11.01.2011 22:13

игра неваша-рас вы неможете сказать,через сервер там или mvc
это мерско,отвратительно,унизи тельно,дерско,пошло,оскорб тнльно и подло!!
кто сказал,может вы у меня ее и стырили

Shaci 11.01.2011 22:20

Цитата:

Сообщение от Matre (Сообщение 87491)
Shaci
слиш а как вы это написали
там через сервер?или mvc?

кстати в lynx неработает игра

конечно же через сервер, координаты храню в базе данных,
каждую секунду идет запрос на БД, берутся координаты, меняются и записываются опять в БД
и mvc используется тоже

x-yuri 12.01.2011 03:08

Цитата:

Сообщение от Shaci
там 2 строчки разные в зависимости от направления

а зачем в эти if'ы остальной код пихать? Да и... "Правило представления: Храните знания в данных так, чтобы логика программы была тупой и надёжной." (ссылка)
var inc = {};
inc[RIGHT] = {'x': 1, 'y': 0};
inc[DOWN] = {'x': 0, 'y': 1};
inc[LEFT] = {'x': -1, 'y': 0};
inc[UP] = {'x': 0, 'y': -1};

nextX = snakeArray[firstI].x + inc[DIRECTION]['x'];
nextY = snakeArray[firstI].y + inc[DIRECTION]['y'];
if (nextX == eat.x && nextY == eat.y) {
	growth();
	eat.id = "";
	POINTS++;
	createEat();
} else
	move();


2) что ты хотел сказать, называя переменные и константы в верхнем регистре?

3) можно было бы написать более понятный код, и ошибок, скорее всего, не было б

Цитата:

Сообщение от Shaci
я просто не оптимизировал код

это не оптимизация, это избавление от ненужного копипаста...

Shaci 12.01.2011 12:31

Цитата:

Сообщение от x-yuri (Сообщение 87553)
а зачем в эти if'ы остальной код пихать? Да и... "Правило представления: Храните знания в данных так, чтобы логика программы была тупой и надёжной." (ссылка)
var inc = {};
inc[RIGHT] = {'x': 1, 'y': 0};
inc[DOWN] = {'x': 0, 'y': 1};
inc[LEFT] = {'x': -1, 'y': 0};
inc[UP] = {'x': 0, 'y': -1};

nextX = snakeArray[firstI].x + inc[DIRECTION]['x'];
nextY = snakeArray[firstI].y + inc[DIRECTION]['y'];
if (nextX == eat.x && nextY == eat.y) {
	growth();
	eat.id = "";
	POINTS++;
	createEat();
} else
	move();

угу, так будет лучше намного
Цитата:

2) что ты хотел сказать, называя переменные и константы в верхнем регистре?

нельзя так было делать, переменную надо было в нижнем регистре
Цитата:


3) можно было бы написать более понятный код, и ошибок, скорее всего, не было б


это не оптимизация, это избавление от ненужного копипаста...
так а ошибок вроде и нет, я просто написал и как только она заработала и выложил сюда, надо конечно было код переделать

Aetae 13.01.2011 06:14

Дело было... ночью, но делать всё равно было нечего, забацал свою змейку).
Код сыроват, но вродь работает)
Пример: старая версия в опере не пашет
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<style type="text/css">
	.snakeTable {height:100px;width:600px;border:2px solid #ddf;table-layout:fixed;}
	.snakeTable * {margin:0;padding:0}
	.snakeTable td,.snakeTable tr {border:0;}
	.snakeTable td {background-color:#ddf}
	.snakeTable caption {border:2px solid #ddf;text-align:center;border-bottom:0;color: #99a;padding:2px;font:bold 12pt sans-serif;}
	.snakeTable a {color: #99a;text-decoration:none}	
	.snakeTable a:hover {color: #9a9;}	
	.snakeTable .snakeFood {background-color:#0f0}
	.snakeTable .snakeBody {background-color:#f00}
	.snakeTable table{border-collapse:collapse;width:100%;table-layout:fixed;}
	</style>
	<script type="text/javascript">
	window.onload=function(){
		(function(set){

			function addEvent(e,t,h){e.addEventListener?e.addEventListener(t,h,false):e.attachEvent("on"+t,h)}
			addEvent(document,'keydown',function(e){
				switch (e.keyCode!=way[2]&&e.keyCode){
					case false:
					break;
					case 37: //left
					way=[1,-1,39]
					break;
					case 38: //up
					way=[0,-1,40]
					break;
					case 39: //right
					way=[1,1,37]
					break;
					case 40: //down
					way=[0,1,38]
					break;
				}
			})

			var vars={
				way:[1,1,37], //направление движения
				zmey:[[0,0]], //,[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12]] //сама змейка
				points:0,  //очки
				elem:document.body, //в какой нод помещать змейку
				rows:20, //клеток y
				cells:20, //клеток х
				speed:100, //скорость
				css:'snakeTable' //класс базовой таблицы
			}

			if(set)for(var i in set)if (set.hasOwnProperty(i))vars[i]=set[i]; //меняем умолчания на заданные значения

			var lng={
				points:'POINTS: ',
				fail:'YOU FAIL!',
				speed:'SPEED',
				play:'PLAY',
				stop:'PAUSE',
				start:'START!',
				restart:'RESTART!'
			} //языковой объект)

			var d=document,way,zmey,points,time,timer;
			var e=function(h,w){ //отрисовка
				var t=d.createElement('table'),c=d.createElement('caption'),tr,i,a;
				t.className=vars.css;
				while(h--) {
					tr=t.insertRow(-1);i=w;
					while(i--)tr.insertCell(-1)
				}
				i=c.appendChild(d.createElement('table')).insertRow(-1);
				w=d.createElement('a');
				w.href='#';
				w.onclick=start;
				w.appendChild(d.createTextNode(lng.start))
				t.appendChild(c);
				return {
				caption:c,
				points:i.insertCell(-1).appendChild(d.createTextNode(lng.points+'0')),
				center:i.insertCell(-1).appendChild(w),
				time:i.insertCell(-1).appendChild(d.createTextNode('00:00')),
				table:vars.elem.appendChild(t)
				}
			}(vars.rows,vars.cells) 
			
			function start() {
				way=vars.way.slice();zmey=vars.zmey.slice();points=vars.points;time=new Date();//возвршаем умолчания
				var i=zmey.length;
				while(i--)e.table.rows[zmey[i][0]].cells[zmey[i][1]].className='snakeBody'; //первоначальная отрисовка
				makeFood();
				move();
				e.center.onclick=toggle;
				e.center.firstChild.data=lng.stop;
			}

			function restart() {
				var i=zmey.push(food)&&zmey.length;
				while(i--)e.table.rows[zmey[i][0]].cells[zmey[i][1]].className=''; //чистим поле от трупика
				start()
			}

			function toggle() {
				var txt=this.firstChild;
				if(txt.data==lng.stop){timer&&clearTimeout(timer);txt.data=lng.play}
				else{move();txt.data=lng.stop}
			}
			
			function makeFood() {
				(function(){
					var i=zmey.length;
					food=[Math.floor(Math.random()*vars.rows),Math.floor(Math.random()*vars.cells)];
					while(i--)if(food[0]==zmey[i][0]&&food[1]==zmey[i][1]){arguments.callee();break}
				})()
				e.table.rows[food[0]].cells[food[1]].className="snakeFood";
			}
			
			function move() {
				var i=zmey.length,good=true,tail;
				var head=zmey[i-1].slice(); //голова змейки
				head[way[0]]+=way[1]; //намечаем сдвиг согласно выбранному направлению
				while(i)if(zmey[--i].join()==head.join()){good=false;break} //если сдвинутая голова попадает на тело - плохо)
				if(~head[0]&&~head[1]&&head[0]<vars.rows&&head[1]<vars.cells&&good){ //проверяем не выходит ли за область и не пожирает ли себя
					zmey.push(head);
					e.table.rows[head[0]].cells[head[1]].className='snakeBody'; //добавляем в массив и отмечаем на экране
					if(food.join()==head.join()){ //если попадает на еду
						e.points.data=lng.points + ++points; //добавляем очки
						makeFood() //создаём новую еду
					}
					else{
						tail=zmey.shift(); //отрезаем хвост
						e.table.rows[tail[0]].cells[tail[1]].className='';
					}
					e.time.data=new Date(new Date()-time).toLocaleTimeString().slice(2);
					timer=setTimeout(move,vars.speed)
				}
				else{
					e.center.firstChild.data=lng.restart;
					e.center.onclick=restart
				}
				
			}
		})({cells:60,rows:10})
	}
	</script>
</head>
<body>
</body>
</html>

ksa 13.01.2011 10:48

Цитата:

Сообщение от Aetae
ночью, но делать всё равно было нечего

Прискорбно... :(

Matre 13.01.2011 11:19

Aetae
у меня доходит досередины и пишет проигрыш (pause меняеться на restart)
при нажатии restart-надпись меняеться на pause и ничего непроисходит,управление неработает
opera 11

Aetae 13.01.2011 14:51

Эх, так и знал. Писал на ноуте - а тут оперы нема чтоб проверить. ff\ie работает)
Теерь до следующей ночи, когда делать бут нефига.

P.S. Всегда ненавидел оперу.=\

monolithed 13.01.2011 18:03

Цитата:

Сообщение от Aetae
Дело было... ночью

да тут и утром попахивает :) :D
в целом, вполне неплохо, ждем в следующем релизе прохождение через стены :)
Цитата:

Сообщение от Aetae
P.S. Всегда ненавидел оперу.=\

я почему-то последнее время того же мнения о этом недобраузере

x-yuri 13.01.2011 18:51

а мне с каждой новой версией все больше нравиться. Имхо, лучший браузер под windows :)

Aetae 13.01.2011 19:45

Частично пофиксил(всё ещё недоумеваю чем опере противны побитовые операции), но что делать с кривым отображением таблицы я хз, имхо явный глюк оперы.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<style type="text/css">
	.snakeTable {height:100px;width:600px;border:2px solid #ddf;table-layout:fixed;}
	.snakeTable * {margin:0;padding:0}
	.snakeTable td,.snakeTable tr {border:0;}
	.snakeTable td {background-color:#ddf}
	.snakeTable caption {border:2px solid #ddf;text-align:center;border-bottom:0;color: #99a;padding:2px;font:bold 12pt sans-serif;}
	.snakeTable a {color: #99a;text-decoration:none}	
	.snakeTable a:hover {color: #9a9;}	
	.snakeTable .snakeFood {background-color:#0f0}
	.snakeTable .snakeBody {background-color:#f00}
	.snakeTable table{border-collapse:collapse;width:100%;table-layout:fixed;}
	</style>
	<script type="text/javascript">
	window.onload=function(){
		(function(set){

			function addEvent(e,t,h){e.addEventListener?e.addEventListener(t,h,false):e.attachEvent("on"+t,h)}
			addEvent(document,'keydown',function(e){
				switch (e.keyCode!=way[2]&&e.keyCode){
					case false:
					break;
					case 37: //left
					way=[1,-1,39]
					break;
					case 38: //up
					way=[0,-1,40]
					break;
					case 39: //right
					way=[1,1,37]
					break;
					case 40: //down
					way=[0,1,38]
					break;
				}
			})

			var vars={
				way:[1,1,37], //направление движения
				zmey:[[0,0]], //,[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12]] //сама змейка
				points:0,  //очки
				elem:document.body, //в какой нод помещать змейку
				rows:20, //клеток y
				cells:20, //клеток х
				speed:100, //скорость
				css:'snakeTable' //класс базовой таблицы
			}

			if(set)for(var i in set)if (set.hasOwnProperty(i))vars[i]=set[i]; //меняем умолчания на заданные значения

			var lng={
				points:'POINTS: ',
				fail:'YOU FAIL!',
				speed:'SPEED',
				play:'PLAY',
				stop:'PAUSE',
				start:'START!',
				restart:'RESTART!'
			} //языковой объект)

			var d=document,way,zmey,points,time,timer;
			var e=function(h,w){ //отрисовка
				var t=d.createElement('table'),c=d.createElement('caption'),tr,i,a;
				t.className=vars.css;
				while(h--) {
					tr=t.insertRow(-1);i=w;
					while(i--)tr.insertCell(-1)
				}
				i=c.appendChild(d.createElement('table')).insertRow(-1);
				w=d.createElement('a');
				w.href='#';
				w.onclick=start;
				w.appendChild(d.createTextNode(lng.start))
				t.appendChild(c);
				return {
				caption:c,
				points:i.insertCell(-1).appendChild(d.createTextNode(lng.points+'0')),
				center:i.insertCell(-1).appendChild(w),
				time:i.insertCell(-1).appendChild(d.createTextNode('00:00')),
				table:vars.elem.appendChild(t)
				}
			}(vars.rows,vars.cells) 
			
			function start() {
				way=vars.way.slice();zmey=vars.zmey.slice();points=vars.points;time=new Date();//возвршаем умолчания
				var i=zmey.length;
				while(i--)e.table.rows[zmey[i][0]].cells[zmey[i][1]].className='snakeBody'; //первоначальная отрисовка
				makeFood();
				move();
				e.center.onclick=toggle;
				e.center.firstChild.data=lng.stop;
			}

			function restart() {
				var i=zmey.push(food)&&zmey.length;
				while(i--)e.table.rows[zmey[i][0]].cells[zmey[i][1]].className=''; //чистим поле от трупика
				start()
			}

			function toggle() {
				var txt=this.firstChild;
				if(txt.data==lng.stop){txt.data=lng.play;timer&&clearTimeout(timer)}
				else{txt.data=lng.stop;move()}
			}
			
			function makeFood() {
				(function(){
					var i=zmey.length;
					food=[Math.floor(Math.random()*vars.rows),Math.floor(Math.random()*vars.cells)];
					while(i--)if(food[0]==zmey[i][0]&&food[1]==zmey[i][1]){arguments.callee();break}
				})()
				e.table.rows[food[0]].cells[food[1]].className="snakeFood";
			}
			
			function move() {
				var i=zmey.length,good=true,tail;
				var head=zmey[i-1].slice(); //голова змейки
				head[way[0]]+=way[1]; //намечаем сдвиг согласно выбранному направлению
				while(i)if(zmey[--i].join()==head.join()){good=false;break} //если сдвинутая голова попадает на тело - плохо)
			*!*	/* старая версия if(~head[0]&&~head[1]&&head[0]<vars.rows&&head[1]<vars.cells&&good){ кто мне скажет почему опера кладёт х*й на побитовые операции?*/ */!*
				if(head[0]>-1&&head[1]>-1&&head[0]<vars.rows&&head[1]<vars.cells&&good){
					zmey.push(head);
					e.table.rows[head[0]].cells[head[1]].className='snakeBody'; //добавляем в массив и отмечаем на экране
					if(food.join()==head.join()){ //если попадает на еду
						e.points.data=lng.points + ++points; //добавляем очки
						makeFood() //создаём новую еду
					}
					else{
						tail=zmey.shift(); //отрезаем хвост
						e.table.rows[tail[0]].cells[tail[1]].className='';
					}
					e.time.data=new Date(new Date()-time).toLocaleTimeString().slice(2);
					timer=setTimeout(move,vars.speed)
				}
				else{
					e.center.firstChild.data=lng.restart;
					e.center.onclick=restart
				}
				
			}
		})({cells:60,rows:10})
	}
	</script>
</head>
<body>
</body>
</html>

x-yuri 13.01.2011 20:01

Цитата:

Сообщение от Aetae
но что делать с кривым отображением таблицы я хз

задать высоту ячеек, а не таблицы

Aetae 13.01.2011 20:13

Цитата:

Сообщение от x-yuri (Сообщение 87883)
задать высоту ячеек, а не таблицы

А вот те хрен.) Да - таблица становится ровнее, но цвет нижней половины всё равно отказывается меняться. Ни через style ни через className не хочет.
И вообще по уму табица должна сама равнять ячейки, это как-бэ и есть смысл таблицы.

Нет можно конечно заюзать грязный хак вызывающий принудительный репеинт - тогда да всё работает, но что за нах?
Именно за это я ненавижу оперу.
Пример: спешал фор опера: ни единого скрпта без хака
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<style type="text/css">
	.snakeTable {border:2px solid #ddf;table-layout:fixed;}
	.snakeTable * {margin:0;padding:0}
	.snakeTable td,.snakeTable tr {border:0;}
	*!*.snakeTable td {background-color:#ddf;height:6px;width:6px;} /*из-за оперы вам придётся вычислять размер ячеек вручную под нужный вам размер*/  */!*
	.snakeTable caption {border:2px solid #ddf;text-align:center;border-bottom:0;color: #99a;padding:2px;font:bold 12pt sans-serif;}
	.snakeTable a {color: #99a;text-decoration:none}	
	.snakeTable a:hover {color: #9a9;}	
	.snakeTable .snakeFood {background-color:#0f0}
	.snakeTable .snakeBody {background-color:#f00}
	.snakeTable table{border-collapse:collapse;width:100%;table-layout:fixed;}
	</style>
	<script type="text/javascript">
	window.onload=function(){
		(function(set){

			function addEvent(e,t,h){e.addEventListener?e.addEventListener(t,h,false):e.attachEvent("on"+t,h)}
			addEvent(document,'keydown',function(e){
				switch (e.keyCode!=way[2]&&e.keyCode){
					case false:
					break;
					case 37: //left
					way=[1,-1,39]
					break;
					case 38: //up
					way=[0,-1,40]
					break;
					case 39: //right
					way=[1,1,37]
					break;
					case 40: //down
					way=[0,1,38]
					break;
				}
			})

			var vars={
				way:[1,1,37], //направление движения
				zmey:[[0,0]], //,[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12]] //сама змейка
				points:0,  //очки
				elem:document.body, //в какой нод помещать змейку
				rows:20, //клеток y
				cells:20, //клеток х
				speed:100, //скорость
				css:'snakeTable' //класс базовой таблицы
			}

			if(set)for(var i in set)if (set.hasOwnProperty(i))vars[i]=set[i]; //меняем умолчания на заданные значения

			var lng={
				points:'POINTS: ',
				fail:'YOU FAIL!',
				speed:'SPEED',
				play:'PLAY',
				stop:'PAUSE',
				start:'START!',
				restart:'RESTART!'
			} //языковой объект)

			var d=document,way,zmey,points,time,timer;
			var e=function(h,w){ //отрисовка
				var t=d.createElement('table'),c=d.createElement('caption'),tr,i,a;
				t.className=vars.css;
				while(h--) {
					tr=t.insertRow(-1);i=w;
					while(i--)tr.insertCell(-1);
				}
				i=c.appendChild(d.createElement('table')).insertRow(-1);
				w=d.createElement('a');
				w.href='#';
				w.onclick=start;
				w.appendChild(d.createTextNode(lng.start))
				t.appendChild(c);
				return {
				caption:c,
				points:i.insertCell(-1).appendChild(d.createTextNode(lng.points+'0')),
				center:i.insertCell(-1).appendChild(w),
				time:i.insertCell(-1).appendChild(d.createTextNode('00:00')),
				table:vars.elem.appendChild(t)
				}
			}(vars.rows,vars.cells) 
			
			function start() {
				way=vars.way.slice();zmey=vars.zmey.slice();points=vars.points;time=new Date();//возвршаем умолчания
				var i=zmey.length;
				while(i--)e.table.rows[zmey[i][0]].cells[zmey[i][1]].className='snakeBody'; //первоначальная отрисовка
				makeFood();
				move();
				e.center.onclick=toggle;
				e.center.firstChild.data=lng.stop;
			}

			function restart() {
				var i=zmey.push(food)&&zmey.length;
				while(i--)e.table.rows[zmey[i][0]].cells[zmey[i][1]].className=''; //чистим поле от трупика
				start()
			}

			function toggle() {
				var txt=this.firstChild;
				if(txt.data==lng.stop){txt.data=lng.play;timer&&clearTimeout(timer)}
				else{txt.data=lng.stop;move();}
			}
			
			function makeFood() {
				(function(){
					var i=zmey.length;
					food=[Math.floor(Math.random()*vars.rows),Math.floor(Math.random()*vars.cells)];
					while(i--)if(food[0]==zmey[i][0]&&food[1]==zmey[i][1]){arguments.callee();break}
				})()
				e.table.rows[food[0]].cells[food[1]].className="snakeFood";
			}
			
			function move() {
				var i=zmey.length,good=true,tail;
				var head=zmey[i-1].slice(); //голова змейки
				head[way[0]]+=way[1]; //намечаем сдвиг согласно выбранному направлению
				while(i)if(zmey[--i].join()==head.join()){good=false;break}; //если сдвинутая голова попадает на тело - плохо)
				if (head[0]>-1&&head[1]>-1&&head[0]<vars.rows&&head[1]<vars.cells&&good) { //проверяем не выходит ли за область и не пожирает ли себя
					zmey.push(head);
					e.table.rows[head[0]].cells[head[1]].className='snakeBody'; //добавляем в массив и отмечаем на экране
					if(food.join()==head.join()){ //если попадает на еду
						e.points.data=lng.points + ++points; //добавляем очки
						makeFood() //создаём новую еду
					}
					else{
						tail=zmey.shift(); //отрезаем хвост
						e.table.rows[tail[0]].cells[tail[1]].className='';
					}
					e.time.data=new Date(new Date()-time).toLocaleTimeString().slice(2);
					*!* window.opera&&(e.table.style.outlineColor="rgb("+Math.floor(Math.random()*256)+",0,0)"); //грязный хак, ибо опера блеать */!*
					timer=setTimeout(move,vars.speed)
				}
				else {
					e.center.firstChild.data=lng.restart;
					e.center.onclick=restart

				}
				
			}
		})({cells:60,rows:10})
	}
	</script>
</head>
<body>
</body>
</html>

monolithed 14.01.2011 09:56

А почему не сделать таблицу (ячейки в т.ч.) блочной?

Цитата:

Сообщение от Aetae
Именно за это я ненавижу оперу.

это мало чтобы ненавидеть :)

ksa 14.01.2011 10:28

Зачем вообще "физически" нужна таблица? Как вариант простой див (поле)... В нём перемещаются и появляются другие дивы (абсолютно позиционированные)... Все данные в массиве... Координаты на странице просто вычисляются от того же верхнего левого угла "поля"...

B~Vladi 14.01.2011 10:55

Проще создать 10 полос на Canvas, чем 25 дивов :)

Aetae 14.01.2011 11:18

Таблица была нужна для того, что засрала опера - свободного изменения размеров ячеек по заданным размерам таблицы.

ksa 14.01.2011 13:11

Цитата:

Сообщение от B~Vladi
чем 25 дивов

Откуда взялась такая цифра? :)

monolithed 14.01.2011 14:01

Цитата:

Сообщение от B~Vladi
Проще создать 10 полос на Canvas, чем 25 дивов

B~Vladi, дело говорит:

<script type="text/javascript">
window.onload = function () {
    var getWidth = self.innerWidth, getHeight = self.innerHeight,
    canvas = document.getElementById("canvas");
    canvas.width = getWidth;
    canvas.height = getHeight;
    canvas.style.background = '#BFDEE1';
    
    if(canvas.getContext) {
        var ctx = canvas.getContext("2d");
        ctx.fillStyle = "#F1F1F1";
        for(i=1; i<getWidth; i+=18) {
            ctx.fillRect(i, 0, 1, getHeight);
        }
        for(i=1; i<getHeight; i+=18) {
            ctx.fillRect(0, i, getWidth, 1);
        }
    }
};
</script>
<canvas id="canvas">No Canvas!</canvas>

B~Vladi 14.01.2011 14:13

Цитата:

Сообщение от ksa
Откуда взялась такая цифра?

Это как пример таблицы с 5 строками и 5 столбцами. Если взять таблицу 50x50, то получится уже 2500 дивов против 100 линий. С таблицей так ещё больше выйдет.
Цитата:

Сообщение от Aetae
Таблица была нужна для того, что засрала опера - свободного изменения размеров ячеек по заданным размерам таблицы.

Размеры можно передать и в скрипт, который уже сам рассчитает строки и столбцы.

B~Vladi 14.01.2011 14:20

Кстати, можно ещё заюзать это.

ksa 14.01.2011 14:25

Цитата:

Сообщение от B~Vladi
Это как пример таблицы с 5 строками и 5 столбцами

Таблицы в моем предложении вообще нет. :) Дивов столько, сколько видимых элементов + див-поле.

B~Vladi 14.01.2011 15:51

Цитата:

Сообщение от ksa
Таблицы в моем предложении вообще нет.

Имелось ввиду визуальное представление.


Часовой пояс GMT +3, время: 05:20.