Game development
Comments 63
+5
Помню, много времени провёл, ставя очередной рекорд в dx-ball! Сейчас с удовольствием освежил. Очень здорово, но впечатление портят лаги при стрельбе, и отсутствие кнопки Esc, например :)
0
Только вчера скачал сабж чтобы поностальгировать, и вот сегодня утром открываю хабр…
+2
почему-то иногда при старте уровня некоторые блоки самоликвидируются
+3
Полноэкранный режим не работает — из него вываливаешься от первого же движения мышью. Браузер FF.
+2
Помню у меня винт сгорел, так я с одной дискеты дос запускал, а со второй эту игру. Было время!
+1
Chromuim 22, Linux — падение вкладки (Ow, Snap!) через полминуты игры или около.
Firefox (Iceweasel 10) — фризы при высоком FPS (держится около 50-60).
0
На Chrome 25, Win7 — то же самое. Постоянно падает вкладка. По моему это случается в момент попадания шарика во «взрывающиеся блоки» в левой части экрана на самом первом уровне.
0
Спасибо, круто.
Стрелялка пробивает «желтые» блоки на 1 уровень.
+1
Спасибо за ремейк, с удовольствием играл в оригинал.

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

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

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

Но раз уж мы на хабре, то вот (вбивать в консоль):
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); // кидает на следующий мгновенно
+1
Вчера смотрел прохождение чип и дейла 2. Ностальгия такая. Вот бы кто переиздал в HD или с измененной графикой, был бы повод пройти.
0
Перед запуском игры все изображения (символы) отрисовываются в том же канвасе, что и игра, я сохраняю их как картинки,
то есть: char[...].img.src = canvas.toDataURL(«image/png»);
Так как putImageData() гараздо медленнее чем drawImage() и это не единственный минус.
putImageData, не накладывает изображение сверху, а заменяет его полностью.

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

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

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

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

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

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

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


Написана на девелоперской версии библиотеки, она есть в публичном доступе. Можно заюзать существующий код, так что, при желании — пишите в скайп shock13666
0
Щас сам пишу арканоид, но блин застрял на collision detection, может кто посоветует как лучше обрабатывать столкновения с блоками и отражение мячика от них как у вас?
0
Сначала определяю те кирпичи, которые находятся вокруг мяча, затем проверяю их так:
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 — кирпич
Конечно это не самое лучшее решение.
0
Я по координатам в своей поделке сверял. А потом сверял пересекается ли шарик с квадратным кирпичём, как-то так.
0
У меня проблема в том что шарик может не с одним блоком сразу столкнуться…
0
Щас сам пишу арканоид, но блин застрял на collision detection, может кто посоветует как лучше обрабатывать столкновения с блоками и отражение мячика от них как у вас?

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

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

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

Shock как всегда прав, с этой штукой в канве играться не стоит, простая игра на канве может загрузить проц. по полной перерисовывая весь экран целиком в каждом кадре.
Shock, а не видел хорошего материал почитать на эту тему? Просто вот интересно, заводить у каждого объекта поле «сдвинулся» и если оно истинно перерисовывать объект, меняя после перерисовки поле на false? Как-то не изящно выходит ))
0
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();
		}
	});
});
0
А у вас молоко убежалоУ вас арканоид продолжает работать, даже когда блоки закончились :)
0
Да я понимаю ) Решил пройти пока время было, обнаружил что демка бесконечная )
0
Вся анимация в игре оптимизирована с помощью requestAnimationFrame, но разные устройства выдают разные показатели FPS.

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

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

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

Причина: Данный объект может представлять угрозу (SCRIPT.Virus)
Дата: ‎04.‎12.‎2012 ‏‎10:55
+3
Это для офисных работников угрозу он представляет, сжирая всё рабочее время. Очень опасный скрипт.
0
Нужно управление кнопками. Срочно!

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