Pull to refresh

Comments 64

Помню, много времени провёл, ставя очередной рекорд в dx-ball! Сейчас с удовольствием освежил. Очень здорово, но впечатление портят лаги при стрельбе, и отсутствие кнопки Esc, например :)
Про Esc совсем забыл, завтра поправлю.
Только вчера скачал сабж чтобы поностальгировать, и вот сегодня утром открываю хабр…
почему-то иногда при старте уровня некоторые блоки самоликвидируются
Я так понимаю что это отголосок предыдущего раунда.
Полноэкранный режим не работает — из него вываливаешься от первого же движения мышью. Браузер FF.
Временами жутчайше тормозит, FPS около 1-2. Safari 6.0.2
Помню у меня винт сгорел, так я с одной дискеты дос запускал, а со второй эту игру. Было время!
DX-Ball не работал под DOS, он же DirectX использовал.
Ловлю Жесткие лаги и падение фпс на сафари
Chromuim 22, Linux — падение вкладки (Ow, Snap!) через полминуты игры или около.
Firefox (Iceweasel 10) — фризы при высоком FPS (держится около 50-60).
На Chrome 25, Win7 — то же самое. Постоянно падает вкладка. По моему это случается в момент попадания шарика во «взрывающиеся блоки» в левой части экрана на самом первом уровне.
Может, у нас аппаратного ускорения нет? Или это баг Хрома?
Спасибо, круто.
Стрелялка пробивает «желтые» блоки на 1 уровень.
Спасибо за ремейк, с удовольствием играл в оригинал.

Шарик после ускорения движется слишком быстро. В оригинале такого не было.

Был момент, когда выпало ускорение шарика, и пока оно падало я упустил шарик. Т.е. не поймал ни то ни другое (и даже не пытался поймать ускорение). После рестрта шарик двигался на двойной скорости.

Очень любопытные косяки :)
Пока что скорость мяча крепко привязана к fps, а не переходах с уровня на уровень (при пропуске мяча) fps падает, при восстановлении игры fps не успевает нормализоваться, из за чего скорость увеличивается. Буду править.

Просто нужно отвязать физику от requestAnimationFrame. И считать её с фиксированным шагом, отдельно от рендера. Как это сделано, например, в Unity.

Это великолепно! Видно, что работа проведена огромная, снимаю шляпу :)

Но раз уж мы на хабре, то вот (вбивать в консоль):
user.lives++; // добавляет одну жизнь
user.score += 1000; // добавляет 1000 очков
bonus.fireball = true; // огненный мяч
bonus.magnet = true; // магнит на доску
bonus.thru = true; // мяч проходит через все
bonus.shooting = true; // пушки на доске

function createlevel(a){cl=!1;shadow.aframe=20;clearTimeout(lightning.timout);audioFile.Voltage.pause();shadow.drawing=!0;for(y=remains=0;20>y;y++)for(x=0;20>x;x++)clearTimeout(bricks[x][y].timeout),bricks[x][y].type=file.charCodeAt(20*y+x+400*(a-1)),bricks[x][y].aframe=0,0!=bricks[x][y].type&&2!=bricks[x][y].type&&remains++,8==bricks[x][y].type&&(bricks[x][y].aframe=23)};
user.level++; // текущий уровень
createlevel(user.level); // кидает на следующий мгновенно
Вчера смотрел прохождение чип и дейла 2. Ностальгия такая. Вот бы кто переиздал в HD или с измененной графикой, был бы повод пройти.
Перед запуском игры все изображения (символы) отрисовываются в том же канвасе, что и игра, я сохраняю их как картинки,
то есть: char[...].img.src = canvas.toDataURL(«image/png»);
Так как putImageData() гараздо медленнее чем drawImage() и это не единственный минус.
putImageData, не накладывает изображение сверху, а заменяет его полностью.

Это ошибка. Вы можете отрисовывать ваш canvas точно так же, как отрисовываете картинку:
ctx.drawImage( canvas, fromX, fromY )

Канвас и Картинка — почти одно и то же.

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

Вот это зря. Стоило таки побороть баги ;)

Вообще не вижу смысла прямо портироовать код. Можно сделать быстрее, короче и оптимизированнее, если писать код с нуля, пусть это будет и старая идея.

Ну и, естественно, на LibCanvas — получим код поддерживаемый, расширяемый, на базе кучи готовых вещей, оптимизированный и, при этом, работающий плавно даже в Опере ;)

Я писал арканоид для демки


Написана на девелоперской версии библиотеки, она есть в публичном доступе. Можно заюзать существующий код, так что, при желании — пишите в скайп shock13666
Щас сам пишу арканоид, но блин застрял на collision detection, может кто посоветует как лучше обрабатывать столкновения с блоками и отражение мячика от них как у вас?
Сначала определяю те кирпичи, которые находятся вокруг мяча, затем проверяю их так:
if(bricks[x][y].type!=0&&
this.x>bricks[x][y].x-5&&
this.x<bricks[x][y].x+35&&
this.y>bricks[x][y].y-5&&
this.y<bricks[x][y].y+20){
    действия с кирпичом
}

this — мяч
bricks — кирпич
Конечно это не самое лучшее решение.
Спасибо за подсказку, попробую.
Я по координатам в своей поделке сверял. А потом сверял пересекается ли шарик с квадратным кирпичём, как-то так.
Щас сам пишу арканоид, но блин застрял на collision detection, может кто посоветует как лучше обрабатывать столкновения с блоками и отражение мячика от них как у вас?

Мне было важно, чтобы оно корректно работало даже при лагах (не пролетало сквозь объекты, словно тех нету). Но при этом чтобы корректно работало при маленьких расстояниях (залетело в линию между двумя блоками и ударами влево-вправо поднимается вверх). Для этого я бъю пройденное расстояние на отрезки длиной в 5 пикселей и анализирую их. За 5 пикселей шарик не пролетит никакой элемент. Потому я просто проверяю, находится ли следующая точка в пересечении с платформой или блоком с разными оптимизациями вроде не проверяния блоков, которые за пределами индекса (по сути каждый раз я проверяю, не входит ли шарик в один из ближайших 9 блоков)

Файл ball.js
В начале задумывалось перерисовывать только те элементы котором изменяются, но из за большого количества багов, которые возникали в связи с этим, я остановился на варианте полной перерисовки кадра

Вот это зря. Стоило таки побороть баги ;)

Shock как всегда прав, с этой штукой в канве играться не стоит, простая игра на канве может загрузить проц. по полной перерисовывая весь экран целиком в каждом кадре.
Shock, а не видел хорошего материал почитать на эту тему? Просто вот интересно, заводить у каждого объекта поле «сдвинулся» и если оно истинно перерисовывать объект, меняя после перерисовки поле на false? Как-то не изящно выходит ))
Shock, а не видел хорошего материал почитать на эту тему? Просто вот интересно, заводить у каждого объекта поле «сдвинулся» и если оно истинно перерисовывать объект, меняя после перерисовки поле на false? Как-то не изящно выходит ))

И не только «сдвинулся», но и «увеличился», «перекрасился», «развернулся» и всё остальное.
Ну у меня в последнем LibCanvas сделано так:
Каждый кадр делится на два этапа — этап просчётов и этап отрисовки. В первом происходят математические изменения объектов — смещаются координаты, меняются цвета, свойства, удаляются лишние, запускаются анимации и т.д.
Если объект хоть как-то меняется — вызываем у него «redraw». Теперь он стоит в очереди на отрисовку. Этот метод можно вызывать сотни раз — он просто ставит флаг, что необходимо перерисовать.
Потом начинается этап рендеринга. В этот момент все объекты уже изменились и теперь надо отрисовать новую ситуацию. Стираем старое (если два объекта накладывались друг на друга, то надо перерисовывать их оба, даже если redraw был вызван только у одного из них). Отрисовываем новое.

На практике это выглядит как-то так (псевдокод):

animate({
  object: element,
  props: { fromX: 100 },
  onTick: element.redraw
});

Тут написано — «плавно измени свойство объекта fromX до 100 и каждый раз при изменении его перерисуй».

Т.к. все анимации используют один и тот же таймер — это всё происходит синхронизированно.

Ну или реальный пример:
var helper, vector, target;

// Глобализуем свойства LibCanvas
LibCanvas.extract();

// Создаём приложение размером 600*400
helper = new App.Light(new Size(600, 400));

// теперь внутри target у нас всегда актуальные координаты мыши относительно приложения
target = helper.mouse.point;

/* Создаём векторную фигуру - круг, радиусом 20 пикселей
 * с центром в точке 100/100
 * тёмно-красная середина и красная граница
 *
 * Этот круг у нас будет основным объектом
 */
vector = helper
	.createVector( new Circle(100, 100, 20), { zIndex: 2 })
	.setStyle({ stroke: '#900', fill: '#300' });

// При клике по холсту дописываем координату в очередь на движение
helper.mouse.events.add('click', function () {
	// создаём маленькую зелёную точку, которая будет обозначать цель нашего движения
	var targetVector = helper
		.createVector( new Circle(target.clone(), 2) )
		.setStyle({ fill: '#0f0' });

	// добавляем анимацию перемещения оригинального объекта в стек
	vector.animate({
		props: {
			// плавно изменяем координаты центра
			'shape.center.x': target.x,
			'shape.center.y': target.y
		},
		fn: 'elastic-out',
		// за одну секунду
		time: 1000,
		// при каждом смещении перерисовываем вектор
		onTick: vector.redraw,
		// при завершении движения удаляем точку-цель движения
		onComplete: function () {
			targetVector.destroy();
		}
	});
});
А у вас молоко убежалоУ вас арканоид продолжает работать, даже когда блоки закончились :)
Это не игра, это демка ;)
Да я понимаю ) Решил пройти пока время было, обнаружил что демка бесконечная )
Вся анимация в игре оптимизирована с помощью requestAnimationFrame, но разные устройства выдают разные показатели FPS.

Это не оптимизация) Это просто небольшое удобство, которое не даёт существенного выиграша в скорости.
Ок, у меня в Фоксе 57 фпс. А вот есть ли какая-то реальная причина, почему в Опере 12.11 х64 не работает? Сейчас проверил, много других игр и примеров на Canvas отлично работают.
на 286м летала, а на i5 притормаживает
а так прикольно, забавно и доставляет фана
*.mds — MIDI файлы музыки, сконвертировать их в *.mp3 мне помог savex.

Выложите куда-нибудь, пожалуйста, отличные получатся рингтоны
Можно и в midi
Посмотрел, сильно отличается от оригинала. Звучание инструментов не такое. Но имена файлов помогли найти в Интернете нормальную версию с расширением .mid: http://www.ekn.net/midi/misc/Dance/index.html (заглавная тема — ethno_pa)

В QuickTime Player, по крайней мере, воспроизводится как надо.
Музычка не закольцована. Закончилась и как-то одиноко стало.
всё ок но
глюков много
самопроизвольные переходы с уровня на уровень
высокая, относительно оригинала, скорость шарика...*или мне кажется?*
1) В некоторых случаях в начале игры при запуске шарика оный внезапно исчезает, а затем теряется жизнь
2) После прохождения первого уровня всегда вылетает критическая ошибка chrome «опаньки, что то пошло не так»
Chrome 24.0.1312.0 (164656) Windows 7
По поводу определения столкновений стоит поправить — если два кирпича находятся один над другим и мячик попадает сбоку в их общую границу, он не может отскочить от верхней грани нижнего кирпича, т.е. столкновение должно обрабатываться как удар от вертикальную поверхность, а не горизонтальную.
Здорово! То дюна2 в браузере, теперь вот и DX-Ball… Месяц старых игр в новых браузерах? )
Это Мега игра!!!
Помню коротал за ней не один вечер!
Спасибо!
Заинтриговали ведь. Рассказывайте теперь, что секретные бонусы делают.
Это для офисных работников угрозу он представляет, сжирая всё рабочее время. Очень опасный скрипт.
Нужно управление кнопками. Срочно!

И захват курсора мыши заодно, как уже писали. Спасибо.
Сделаем, но с начало надо избавиться от основных багов
Спасибо за игрушку моего детства :-) Небольшой баг-репорт настрочу вам…
Насколько помню, в оригинале у каждого бонуса была некая частота появления. Например, реже всех появлялись бонусы окончания уровня и добавления жизни, а чаще всех — смерть. У вас хоть и чистый рандом, но жизни быстро увеличиваются и становится неинтересно играть.
Частенько неправильно срабатывают коллизии на стыке двух кубиков. Наверное, вы убираете первый кубик сразу после проверки на коллизию с шариком, и в результате сразу отрабатывается и вторая коллизия тоже.
Ну и не помню, как точно было в оригинале… но вроде бы «сквозные» шарики пролетали и через непробиваемые кирпичики.
По поводу бонусов, у нас не получилось вытащить вероятности выпадов, поэтому там чистый random(); конечно можно засесть часа на 3-4 и посчитать вероятности, но на это много времени и терпения надо.
Опытным путем было выявлено что, например, добавление жизни чаще всего падало из обределенных блоков на определённых уровнях. Т.е. Если в конкретный блок попасть шариком без бонусов в момент, когда не падает никакой другой бонус, то с большой вероятностью от туда выпадет +1.
Когда шар в режиме кометы +1 почти никогда не падает. Как-то так.
Скоро новый хаб под ремейки придется открывать! :)
Спасибо!
У меня проявлялка (бонус проявляющий невидимые кирпичи и делающий непробиваемые пробиваемыми) глючит. Она сделала золотые кирпичи пробиваемыми, а розово-позалоченные, которые после удара становятся золотыми, оставила без изменений. Тем самым заблокировала мне 4й уровень.
На ZXSpectrum Арканоид называлась, я ее так запомнил)
не вы один, много где это арканойдом называется.
В Chrome 25.0.1337.0 dev-m падает в течение минуты — «упс»
В IE 9.0.8112.16421 не стартует — чёрный квадрат малевича.
Only those users with full accounts are able to leave comments. Log in, please.