CANVAS 1K Tank Game

Canvas Tank Game (0.58КиБ)

Решил попробовать уместить какую-нибудь игру с использованием тега CANVAS в 1КБ. После всех оптимизаций, который заняли у меня вдвое больше времени, чем написание игры, получилась несложная игрушка в 1020 1023 байта (то есть на четыре один байт меньше, чем килобайт).

Цель — подбить своим «танком» как можно больше вражеских ракет. Управление — курсорными клавишами, стрелять пробелом. Даётся три жизни, за каждые 20 сбитых ракет жизнь добавляется, если ракета долетит до вашей стороны или коснётся танка, жизнь теряется. Для рестарта игры просто перезагрузите страницу.

Должно работать везде, где поддерживается тег CANVAS, я тестировал в «Опере» 11, «Хроме» 10 и FF 3.6.13.

Have a fun!

Неинтересные технические подробности
Добавлено позднее: оказывается, я вполне уложился бы в правила конкурса JS1K (конкурс программ на JS, занимающих не более 1КБ), на который мне вчера ссылок накидали. У меня чистый JS (без сжатия в PNG) на восемь байт короче килобайта. А все эти пляски с кодом в PNG нужны для того, чтобы у меня весь код (включая HTML) поместился в килобайт.

Ещё позже: на заметку. Я вчера обращался к тегу CANVAS по идентификатору. Это очень длинный способ (не говоря уже о том, что тег должен иметь идентификатор, что ещё тратит место), вчера, когда мне показали JS1K, я там увидел способ короче: «document.body.children[0]», а сегодня я придумал способ ещё короче: «document.all[3]», это нестандартное свойство, но его поддерживают все браузеры.

Если использовать это свойство, то программа начинает занимать 1007 байт и у меня появляется ещё 17 байт. Может танк переделать? Мне пришлось упростить графику, из-за чего танк стал выглядеть странно.

И ещё позже: вернул прежний танк и сменил цвет «спецэффекта» при столкновении на красный, игра снова занимает 1020 байт. Если интересно, можно посмотреть как выглядит исходный код JavaScript моей игрушки. И ещё я внезапно придумал как ещё чуть-чуть сократить код.

И ещё: сократил чуть-чуть код, в частности, стрелять можно любой кнопкой, кроме курсорных. Освободилось несколько байт и я в левом верхнем углу нарисовал ракету, чтобы было понятно, что это количество сбитых ракет. Игра стала занимать 1023 байта.

Читайте также

Игра, занимающая 1023 байт (<1KB) с использованием CANVAS. Простая цель — защищать свою сторону от «захватчиков»
Игра, занимающая 1023 байт (<1KB) с использованием CANVAS. Простая цель — защищать свою сторону от «захватчиков»
2010

Комментарии 195

jankkhvej (jankkhvej.blogspot.com) № 1
В мобильном сафари тоже работает, только нечем управлять. Может, попробуете адаптировали под iPhone?
Евгений Степанищев (bolknote.ru) автор № 2
Это интересно, кстати. Я не пробовал писать ничего под touchscreen. Правда, iPhone у меня нет, но, думаю, если адаптировать под «Андроид», то и iOS приложится.
maxim-zotov № 3
Firefox 3.6.13, linux. Выглядит так:
http://ksim.ru/img/screenshot/scr_wFjtWY.png
никаких танков нет, размер страницы 278 байт, а не 1020. Если перегружать страницу, иногда появляется квадратное поле с работающей игрой.
Евгений Степанищев (bolknote.ru) автор № 4
Firefox 3.6.13, linux. Выглядит так

У меня негде понять что не так, увы. Никаких ошибок в консоли FF нет?

никаких танков нет, размер страницы 278 байт, а не 1020

Это нормально, основной код лежит в PNG-файле (кстати, я создал, наверное, самый маленький загрузчик такого кода).

maxim-zotov № 5
Комментарий для Евгения Степанищева:

Да, в консоли есть ошибка:

Error: uncaught exception: [Exception… «Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMCanvasRenderingContext2D.drawImage]» nsresult: «0x80040111 (NS_ERROR_NOT_AVAILABLE)» location: «JS frame :: https://bolknote.ru/files/tank-1k-game/ :: anonymous :: line 5» data: no]

Посмотрел по трафику: и при ошибке, и при правильной работе одно и то же приходит от сервера, скрипт и картинка.
praeivis (praeivis.lt) № 6
Под вин7 и ФФ 3.6.13 тоже самое что и у Максима. Правда со второго раза как зашол игра запустилась, поиграл, вернулься в коменти и счас как и в впервый раз — тоже самое что уже Максим показал — сколько не заходи только прямоуголник и эта ошибка на 5 строке.
Евгений Степанищев (bolknote.ru) автор № 9
Судя по тому, что пишут в интернетах, это действительно ошибка неготовности DOM. Обходят её, чаще всего, делая setTimeout(…, 0).

Не думаю, что это критично, у меня не хватит терпения записать ещё один таймер в четыре байта, которые остались мне до килобайта :)
Евгений Степанищев (bolknote.ru) автор № 12
Комментарий для LO:

Спасибо! Я пытался сократить код подобным образом, но вы не учитываете, что он у меня сжимается алгоритмом Deflate, а последовательность длинных однородных символом там сжимается очень хорошо. Поэтому как я не крутил это место, но лучше всего сжались единицы и нули (кстати, вместо нулей у меня в первом варианте были пробелы, нули сжались лучше, так как внутри кода есть ещё последовательность нулей).

Поэтому мой сжатый вариант занимает 753 байта, ваш — 766.
LO № 13
Комментарий для Евгения Степанищева:

ОК, не учёл этого. Спасибо!
По поводу идентификатора. Во всех означенных выше браузерах работает обращение к эл-ту из глобальной области по идентификатору, что экономит 14 байт.
Евгений Степанищев (bolknote.ru) автор № 15

Комментарий для LO:

Во всех означенных выше браузерах работает обращение к эл-ту из глобальной области по идентификатору, что экономит 14 байт.

Спасибо! Этого я не знал.

R=_('','…') --> R=_($,'…') ?

Там можно выкинуть массу переменных (например, «v»), но парадокс — сжимается хуже, поэтому я остановился. Думаю, что как-нибудь попробую уместить что-нибудь в килобайт без сжатия, вот там какая-то из идей может пригодиться.

LO № 17
Комментарий для Евгения Степанищева:

Есть ещё кое-что. Вот ,например, такой код:
_=function(p,b){return new Function(p,b)};
Проще заменить на:
_=Function;

И да, G=n+n+914062108081923[s='toString'](2); // -2 это уже в порядке исправления самого себя
Евгений Степанищев (bolknote.ru) автор № 22

Комментарий для LO:

На top нельзя будет в конкурсе JS1K, а тут можно, точно :)

Не, так не могу. У меня JS в PNG-файле весь, а на конкурсе JS1K нужно будет вообще дать чистый JS, без тегов.

LO № 23

Комментарий для Евгения Степанищева:

Не, так не могу.

Можешь. Если говорить о первой версии правил js1k.com, то там, как видно из представленных работ, чистый код участников помещался в тег , контекстом которого,как и у тега , является window. Это значит, что как в твоём случае, так и в рамках правил конкурса, ты можешь вообще не думать на тему, как получить window. Тем более, что в кодах участников использован этот же подход. Т.е. w.onkeyup=… — плохо, onkeyup=… — хорошо. Вот что Я имею в виду!

И, кстати, в последней «рождественской» версии правил вообще запрещены ВСЕ eval-подобные вызовы, в т.ч. Function и setInterval(String).

Надо бы подбить все указанные выше оптимизации, убрать сжатие png и лишние, как оказалось, переменные. И посчитать чистый js , без html. Просто интересно, сколько там осталось.

Евгений Степанищев (bolknote.ru) автор № 24

Комментарий для LO:

Вот что Я имею в виду!

А! Точно :)

И, кстати, в последней «рождественской» версии правил вообще запрещены ВСЕ eval-подобные вызовы, в т.ч. Function и setInterval(String).

Вот чёрт, я там правила не читал. Заразы :)

Надо бы подбить все указанные выше оптимизации, убрать сжатие png и лишние, как оказалось, переменные. И посчитать чистый js , без html. Просто интересно, сколько там осталось.

Впереди праздники, если будет время, попробую.

LO № 29
Комментарий для Евгения Степанищева:

Под «рождественские» правила подстраиваться нет смысла, т.к. тематика игры «не та». Разве что сделать так, чтобы танк палил по Дедам Морозам/Санта Клаусам, а не по ракетам…
Евгений Степанищев (bolknote.ru) автор № 30
Комментарий для LO:

Ну ладно, сделал уже :) При необходимости можно вернуть. Зато всё уместил, я там ещё код сократил и несколько замен сделал.
LO № 31

Комментарий для Евгения Степанищева:

Вобщем посмотрел код.
1)

c.style='border:4px solid #000' // баг в !Opera

заменить на:
c.style.border='4px solid #000'

Но на этом можно не останавливаться и убрать '#000'. Условия запуска сферического коня позволяют это сделать без вреда.

c.style.border='4px solid';

2)
Почти то же самое в строке

fillStyle="red";fillRect(0,0,W,W);fillStyle="#"+T;K=r

убираем второй fillStyle — разницы никакой!
fillStyle="red";fillRect(0,0,W,W);K=r
3)
Переменная R — лишняя, дает читабельность ценой в 4 байта. Убираем R=function(){…} и там, где K=R:
K=function(){…}
4)

with(a){x;y;z}

В твоем коде вместо «;» «\n». Заменяем на:
with(a)x,y,z
Экономия 2 байта.
Общий код стал занимать 995 байт. Надеюсь, на Дедов Морозов хватит. Впрочем, цель уже в любом случае достигнута. http://pastebin.com/DhVDhWRg

Евгений Степанищев (bolknote.ru) автор № 32
c.style.border='4px solid #000'

Ага, ок.

убираем второй fillStyle — разницы никакой!

Кроме того, что цифра счёта становится красной после первого же столкновения.

В твоем коде вместо «;» «\n». Заменяем на:
with(a)x,y,z

Точно, заменю.

Евгений Степанищев (bolknote.ru) автор № 33
Комментарий для LO:

border добавил, {} около with убрал, спасибо. Рано утром плохо думается. :)

Файл стал занимать 1021 байт.
Евгений Степанищев (bolknote.ru) автор № 36
Комментарий для LO:

Круто :) Можно будет ещё что-нибудь впихнуть, например, цвет добавить. Надо будет подумать. С наступающим!
Евгений Степанищев (bolknote.ru) автор № 37
Комментарий для LO:

После отказа от Function это точно имеет смысл. Правда, насчёт B не уверен, надо будет померить. Я оказался от второго её вызова, так как он не помещался. Не критично, но танк себя неправильно ведёт в некоторых случаях.

Спасибо за помощь! Если буду выставлять этот код на JS1K, то тебя упомяну неприменно. Только что написать? LO?
Евгений Степанищев (bolknote.ru) автор № 38

Комментарий для LO:

Правда, насчёт B не уверен

В смысле, раз места хватает, надо будет вернуть все её вызовы на место.

Евгений Степанищев (bolknote.ru) автор № 43
Комментарий для LO:

Кажется, получится ещё байт на 40 сократить. Прототип есть уже. Рабочий код сделаю после НГ.
LO № 44

Комментарий для Евгения Степанищева:

Правда, насчёт B не уверен, надо будет померить.

Функция B необходима, только если в коде она вызывается более 2-х раз. Инфа 100%.

Кажется, получится ещё байт на 40 сократить.

Пилите, Шура, пилите! :)

Только что написать? LO?

Хм… Подождём окончания банкета. Ответ ниже.

С наступающим!

Аналогично!

Евгений Степанищев (bolknote.ru) автор № 48
Комментарий для LO:

Ого, про такие вложенные with я не знал. Всегда думал, что они должны «перешибать» друг друга, спасибо!
Евгений Степанищев (bolknote.ru) автор № 50
Комментарий для Евгения Степанищева:

Какой всё-таки отличный язык JS! :) Жаль только есть очень странные ограничения. Когда братишка вчера спросил почему я сдвигом не пользуюсь, когда вывожу графику, я рассказал, что операции сдвига работают только с int, что так я уже пробовал. А потом осенило попробовать делить на два и использовать для этого число с плавающей точкой.
LO № 54

Комментарий для Евгения Степанищева:

Последний твой — 922

922 — это позиция следующего символа, поэтому всё-таки 921 и 919 соответственно. Едем дальше!

Я заменил || на | в одном месте и && на & в нескольких местах, где обе части являются булевыми.
Кроме того, убрал лишнюю группировку в одном месте

(x=0&&x-X
LO № 55

Комментарий для Евгения Степанищева:

они должны «перешибать» друг друга

Перешибают, если есть конкуренция. Просто в ином случае мы не могли бы вызвать, например, with(document)alert('метод другого объекта')

есть очень странные ограничения

Мне, например, не нравится ограничение 32-мя битами при побитовых операциях. Да и вообще в числах JS пока слаб. Эти все погрешности… Приходится эмулировать 64-битные операции.

Ладно, завтра проверю идейку.

Евгений Степанищев (bolknote.ru) автор № 56

Комментарий для LO:

922 — это позиция следующего символа

Я просто смотрю на длину получившегося файла.

В итоге имеем 909 !

910.

Мне, например, не нравится ограничение 32-мя битами при побитовых операциях

Я про это и говорил выше.

Евгений Степанищев (bolknote.ru) автор № 57

Комментарий для LO:

Перешибают, если есть конкуренция.

Это понятно. Я не думал, что они образуют каскадные зоны.

Евгений Степанищев (bolknote.ru) автор № 59
Комментарий для LO:

Ага, там перенос был лишний в коде.
906 байт, оказывается. Может pastebin лишний перевод вставил.
LO № 62

Комментарий для Евгения Степанищева:

Херю твоё элитное число:
http://pastebin.com/KfWfGshs
872
Изменения коснулись обработки событий. Пытался реализовать onkeydown=onkeyup=… , но в разных браузерах выявлялись свои проблемы.

Я про это и говорил выше.

Ну, а я как бы согласился. ;)

Евгений Степанищев (bolknote.ru) автор № 63

Комментарий для LO:

Изменения коснулись обработки событий.

Я вчера вертел как раз это место :) Только у меня другая идея была, но она не сработала.

LO № 65
Комментарий для Евгения Степанищева:

Отлично! В таком варианте проблем пока не выявил. Теперь можно убрать переменную u:
v={38:-2,40:2,37:-1,39:1}[e.which]
И ещё один малоиспользуемый трюк:
h=splice(i,1)+(++s%20||++V) --> h=splice(i,1)+ ++s%20||++V
Итого: 855
Евгений Степанищев (bolknote.ru) автор № 68
Комментарий для LO:

Круто!

Заметил первые глюки. Когда стреляю, пуля иногда проходит сквозь ракету, не причиняя вреда. Видимо, когда я инвертировал условие столкновения с ракетой, где-то ошибся. Посмотрю.
LO № 71
Комментарий для Евгения Степанищева:

Словил ещё один глюк: если до ракеты оставалось расстояние примерно в длину танка, снаряд поражал танк и летел дальше (или выпускался еще один — это непонятно). Описанный тобой глюк возникал, если между снарядом и танком оставалось ещё меньшее расстояние. Мой глюк возник после моих 849, где Я убрал код в обработчике *w||*. Пришлось вернуть, попутно сделав апгрейт.

w=e.type.length&2&&v --> w=!!e.type[6]&&v

http://pastebin.com/t3TBpswq
846
Евгений Степанищев (bolknote.ru) автор № 73

Комментарий для LO:

w=e.type.length&2&&v --> w=!!e.type[6]&&v

Странно, я вчера так пытался сделать. Проверил в «Опере» javascript:void(alert(«aaa»[0])), словил ошибку. А сегодня работает. Видимо, вчера уже спать хотел, где-то невнимателен был.

++w||h&&(h=0,t=X+8,b=Y+1)

c w тут здорово придумано.

Евгений Степанищев (bolknote.ru) автор № 74
Комментарий для LO:

Там где цвет задаётся можно сократить. Там неочевидное место — используется цвет rgb(9,9,9), на практике выглядит как чёрный. Так что можно чёрный и использовать:

y++>>2&&W

845 байт, надо ещё подумать…
Евгений Степанищев (bolknote.ru) автор № 75

Комментарий для LO:

++w||h&&(h=0,t=X+8,b=Y+1)

мне убегать надо, но рискну предложить w+h&&(h=0,t=X+8,b=Y+1)
не успеваю тщательно обдумать

842 байта

Евгений Степанищев (bolknote.ru) автор № 77
Комментарий для LO:

Хотя, сдаётся мне, последнее не очень хорошая идея. Первоначально это делалось для того, чтобы по вертикали был шаг, кратный 8. Сейчас его не будет. Лучше так не делать.
Евгений Степанищев (bolknote.ru) автор № 81
Комментарий для LO:

Убираем with([]), вводим опять $=[]
перед push и length возвращаем $

вместо всего блока map:

$=$.filter(function(v){S(x=--v[0],y=v[1],G)
return!(x=0&x-X
LO № 82
Комментарий для Евгения Степанищева:

Как будет время, выложи, плиз, полный код в этой редакции на pastebin, ибо у меня меньше 824 выходит и, соотв., глюки. Предположительно, что-то пропущено. Но первая мысль уже возникает: зачем убирать with([]), если далее у тебя как минимум 3 обращения к массиву? Считаем:
1) with($=[])$= // 12
2) $=[],$=$.$.$. // 13
Евгений Степанищев (bolknote.ru) автор № 83
Комментарий для LO:

Ок, сейчас попробую перепечатать (я отдыхаю в Казани, разрабатываю на ноуте, который не подключен к инету).

with не сработает, так как одна из операций обращения к массиву — $=$.filter всё портит. Тут создаётся новый объект, который перетирает старый.
Евгений Степанищев (bolknote.ru) автор № 93

Комментарий для LO:

Завершил объединение 4 функций в 1.

Сильный ход :)

Выявлен еще один баг: подкатываешь к ракете сзади и стреляешь — ракета уничтожается

Он уже исправлен?

Евгений Степанищев (bolknote.ru) автор № 98
Комментарий для LO:

Но так в массиве $ в самом начале будет элемент ноль, т.е. массив будет выглядеть так: [0].
Евгений Степанищев (bolknote.ru) автор № 99
Комментарий для LO:

Подумал что будет в этом случае, похоже, filter сразу отфильтрует этот элемент, так что всё ок.
LO № 111
Комментарий для Евгения Степанищева:

h=(t+=4)>251
Нужно подумать, так ли принципиально число 251? Я так понимаю, что на одной чаше 0.07 секунды у пользователя, а на другой 2 байта.
Евгений Степанищев (bolknote.ru) автор № 112
Комментарий для LO:

Вроде особой деградации производительности нет. Если что, позволит увеличить размер спрайта.
Евгений Степанищев (bolknote.ru) автор № 114

Комментарий для LO:

h=(t+=4)>251

Можно, наверное, поставить W, это координата, когда пуля достигает стены. Но иногда может возникнуть ситуация, когда пуля «вылетит» за стену.
Насколько я знаю CANVAS, он «заворачивает» координаты, то есть при попытке вывести что-то в координату 256 у нас пуля появится слева. Как-то неаккуратно.

Это поведение наблюдается сейчас и у танка, я ещё не правил. Когда-то я ограничение убрал, чтобы в размер влезть.

Евгений Степанищев (bolknote.ru) автор № 115
Надо TODO записать:
1) ввести цвет: танка, стены, ракеты. В качестве цвета стены можно взять «tan» (это имя цвета), что позволит сэкономить байт.
2) сделать ограничение танка, чтобы он не выезжал за стену.
3) что-то сделать с пулей, чтобы она была заметнее (может цвет заменить или сделать, чтобы она переливалась).
4) какое-то подобие уровней. Увеличивать скорость? Количество врагов?
LO № 120

Комментарий для Евгения Степанищева:

Но иногда может возникнуть ситуация, когда пуля «вылетит» за стену.

Наблюдаю такое, только если сам танк вывести за левую границу, чтобы он появился из-за правой границы. Тогда, действительно, пуля пролетает через стену и вылетает из-за левой границы. Но это связано с танком и не зависит от 251 или 255. Иные случаи «пролета» стены Я отловить не могу.

LO № 121

Комментарий для Евгения Степанищева:

Надо TODO записать

У меня чувство, что сам потенциал идеи исчерпан в текущей реализации. Может быть, замахнуться на что-нибудь поражающее воображение? :)

Евгений Степанищев (bolknote.ru) автор № 122

Комментарий для LO:

У меня чувство, что сам потенциал идеи исчерпан в текущей реализации. Может быть, замахнуться на что-нибудь поражающее воображение? :)

Это да, мне уже не хочется доделывать, но я доведу до конца, иначе чувства завершённости нет :) А так, да, хочется замахнуться :) Пока, правда, никаких идей на что :)

Евгений Степанищев (bolknote.ru) автор № 123

Комментарий для LO:

Наблюдаю такое, только если сам танк вывести за левую границу, чтобы он появился из-за правой границы. Тогда, действительно, пуля пролетает через стену и вылетает из-за левой границы. Но это связано с танком и не зависит от 251 или 255. Иные случаи «пролета» стены Я отловить не могу.

Да, у меня тоже не вышло. Тогда меняем 251 на W, будет 766 байт.

LO № 125
Комментарий для SmallFish:

Только что проверил на FF3.6.13,FF4b7 — всё работает. Судя по описанию, у тебя нет на странице объявления переменных, которые даются по условиям «даром» и в подсчете не участвуют (тут смотри https://bolknote.ru/files/tank-1k-game-2/ ). Если причина не в этом — консоль ошибок в студию!
Евгений Степанищев (bolknote.ru) автор № 127

Комментарий для LO:

t>p||p-t>9|y>b||b-y>9 --> t>p|p-t>9|y>b|b-y>9

Из-за этого возникает баг, когда танк может объехать ракету, выстрелить и она пропадёт.

Евгений Степанищев (bolknote.ru) автор № 129
Комментарий для LO:

У меня почему-то 761. Можешь опубликовать твой текущий код?

Я пробовал заменить создание красного экрана на цикл, получается либо очень медленно (когда цикл пробегает всё заново, 255*255*4 итерации), либо размером больше (если я кеширую цикл).
LO № 131
Комментарий для Евгения Степанищева:

Упомяну ещё об одном памятнике на кладбище идей. Пытался вытаскивать имена свойств и методов через цикл for in и трюк с использованием сокращенной версии метода exec в не-IE браузерах ( alert(/xyz/('xyzzzz')) ). Не уложился в размеры, но трюк перспективен на больших просторах (5К,10К).
Евгений Степанищев (bolknote.ru) автор № 132
Комментарий для LO:

Нашёл ошибку :) Я куда-то дел «h|». Это породило бы баг, когда ракеты «спотыкались» о то место, где в последний раз была пуля.
Евгений Степанищев (bolknote.ru) автор № 133
Комментарий для LO:

Из-за того, что ты перенёс V-- внутрь вызова, рисующего красный, стало возможным сократить ещё на два байта: http://pastebin.com/gK38C55g

for(i=V;i>0;P(W-i--*10,245,Z=0x3F6DFFBF12720C)) на for(i=V;i;P(W-i--*10,245,Z=0x3F6DFFBF12720C))
и
K(r(V>0&&P(4,3,G=0x607E416AD57E60) на V>0&&K(r(P(4,3,G=0x607E416AD57E60)

761

теперь V не становится отрицательным и браузер не зависает в конце игры
LO № 140
Комментарий для Евгения Степанищева:

От последнего предложения придется отказаться, ибо в FF и GC это убирает красную заливку в конце игры.
753
Евгений Степанищев (bolknote.ru) автор № 143
Комментарий для LO:

Меняем P(W-i--*10,245,Z=0x3F6DFFBF12720C) на P(i--*-10,245,Z=0x3F6DFFBF12720C)

Как я уже упоминал, CANVAS «заворачивает» значения (почему-то только по горизонтали, надо почитать спецификацию), которые выходят за пределы холста.

752 байта
Евгений Степанищев (bolknote.ru) автор № 144
Комментарий для LO:

Хе. Так это не CANVAS заворачивает, это реализация «setPixel» ещё даже в моём коде так работает :)
Евгений Степанищев (bolknote.ru) автор № 149
Комментарий для LO:

Очевидная штука, а мы оба пропустили до последнего момента :)

Я вот что подумал, доделывать пункты из TODO я не буду, иначе снова захочется оптимизировать, а у меня уже фана нехватает, превращается в рутину.
LO № 151

Комментарий для Евгения Степанищева:

доделывать пункты из TODO я не буду

Так и правильно, Я бы не смог её не пооптимизировать. :)

загадку своей личности-то откроешь?

Мой ник LeverOne, по реальному имени в сети почти никто не знает и слава богу.

пропустили до последнего момента

Уверен, что момент последний?

Евгений Степанищев (bolknote.ru) автор № 152

Комментарий для LO:

Уверен, что момент последний?

Я в том смысле, что долго оптимизировали всякие тонкие вещи, а очевидная была перед глазами :)

LO № 153
Комментарий для Евгения Степанищева:

Так, ладно, вот версия на 744
http://pastebin.com/Gb9mdjDC
Убран, чёрный цвет у border, т.к. он и так во всех браузерах чёрный, и переформированы условия в функции P.

За темой перестаю пристально следить (желание, время) и откланиваюсь.
Евгений Степанищев (bolknote.ru) автор № 155

Комментарий для LO:

http://pastebin.com/X3kZF6ZL
737

Установка ширины или высоты канваса очищает канвас:

When the canvas element is created, and subsequently whenever the width and height attributes are set (whether to a new value or to the previous value), the bitmap and any associated contexts must be cleared back to their initial state and reinitialized with the newly specified coordinate space dimensions.
Евгений Степанищев (bolknote.ru) автор № 156
Комментарий для LO:

Попробовал ещё with© сделать, но не прокатило: keyup/keydown в этом случае биндятся на CANVAS, несмотря на то, что CANVAS (по крайней мере в «Опере») их не поддерживает. Из-за этого не работает нажатие на клавиши.

И, кстати, вспомнил, в копилку мёртвых идей: пробовал заменить циклы на рекурсивные вызовы, код вырос.
Евгений Степанищев (bolknote.ru) автор № 159
Комментарий для LO:

У меня в «Опере» размер некрасиво скачет. Сначала виден первый кадр с неправильными размерами.
Олег № 160
Ребят, ну вы даете!
Вдохновляет.
(особенно порадовал JS под бой курантов :) )
LO № 162

Комментарий для Евгения Степанищева:

Сначала виден первый кадр с неправильными размерами.

Если задержка в 0.07 сек существенна, то решается это просто: убираем c.style.border='4px solid'
за c.width=W (т.е. рисуем рамку после).

Евгений Степанищев (bolknote.ru) автор № 167
Комментарий для LO:

А… мы же это проходили, это убивает заливку красным в конце игры в некоторых браузерах.
chun lu № 168
*спс* ребзя, напомнили мне асмовые гонки за байтами )))
вот только не понимаю, баг или фича: вторая пуля не вылетает из танка, пока первая жива
тестирую на Chromium 8.0.552.224 (68599) Ubuntu 10.10
в этом же chromium не работает отсылка комментария по ctrl+enter (
Евгений Степанищев (bolknote.ru) автор № 169
*спс* ребзя, напомнили мне асмовые гонки за байтами )))

Да уж, помню. Я писал на трёх ассемблерах, на последнем (x86) — несколько лет.

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

Фича, иначе просто всё будет.

в этом же chromium не работает отсылка комментария по ctrl+enter (

Ого, странно, я использую jQuery, а что за версия?

chun lu № 170
кстати, подумал
годы назад (на асме) гонки за байтами хоть как-то были оправданы практически--память была дорога, процессорное время тоже
то, что вы делаете сейчас, на javascript, требует как минимум «интерпретатор» скрипта, т.е. в принципе ваши 200 с лишним байт оптимизации никому особой погоды не сыграют
выходит, что, загоняя себя в такие строгие рамки при фантастических возможностях современных обычных настольных компьютеров или айфоней там всяких, вы творите искусство, просто ради искусства
радостно, что можно не брюзжать «как было раньше здато, а ща не здато», ведь появился например js1k
chun lu № 171

Комментарий для Евгения Степанищева:

>в этом же chromium не работает отсылка комментария по ctrl+enter (
Ого, странно, я использую jQuery, а что за версия?

Chromium 8.0.552.224 (68599) Ubuntu 10.10

Евгений Степанищев (bolknote.ru) автор № 172

Комментарий для chun lu:

вы творите искусство, просто ради искусства

Точно так :) Практической пользы от этого никакой.

LO № 173

Комментарий для chun lu:

вы творите искусство, просто ради искусства

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

Мы создаем пpогpаммы в той же меpе, в какой они создают нас.

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

Евгений Степанищев (bolknote.ru) автор № 179
Комментарий для LO:

Не, так глючит — координаты получаются putImageData(I, 1, 1) и так «режется» перед краем (если до конца влево поехать), замена на ~ несколько улучшает ситуацию (получается putImageData(I, -1, -1)), но тогда танк на пиксель «проваливается» (правда это куда менее заметно), но надо сдвинуть координаты печати текста очков.
LO № 180
Комментарий для Евгения Степанищева:

В процессе теста обнаружил, ещё один глюк, присутствовавший в игре изначально. Заводим танк влево чуть более, чем до башни, и поднимаем до верхней границы, чтобы шасси оставалось едва видимым: результат — текст очков становится красным, игра зависает.
LO № 181

Комментарий для Евгения Степанищева:

и так «режется» перед краем

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

замена на ~ несколько улучшает ситуацию…, но надо сдвинуть координаты печати текста.

Может быть, тем более, что это экономит ещё 1 байт.

Евгений Степанищев (bolknote.ru) автор № 182

Комментарий для LO:

В процессе теста обнаружил, ещё один глюк, присутствовавший в игре изначально. Заводим танк влево чуть более, чем до башни, и поднимаем до верхней границы, чтобы шасси оставалось едва видимым: результат — текст очков становится красным, игра зависает.

Ого, надо будет глянуть.

Евгений Степанищев (bolknote.ru) автор № 183
Комментарий для LO:

http://pastebin.com/S97wbMyn

Hotfix ошибки (я решил её саму не искать, а убить два зайца махом — ещё и запретить танку заезжать за границы) + сделал, чтобы при выстреле танк подавался назад, как при отдаче.

761 байт
Евгений Степанищев (bolknote.ru) автор № 185
Комментарий для LO:

Да, вполне получается.

В общем, надо заменить все координаты на одну. Из расчёта C=x+y*W
При выборе клавиш будет что-то вроде
v=[-1,-510,1,510][x.which-37],w=!!x.type[6]&&v,v?S=w:…
И вообще всё (кроме расчёта столкновений) сильно упрощается.

Но дописать пока не могу — хочется сегодня выспаться.
LO № 186
Комментарий для Евгения Степанищева:

Класс! Эффект с отдачей на два байта вызывает какую-то детскую радость. :)
Там нужно опять вернуть abs, но подождём окончательной реализации последней идеи.
Евгений Степанищев (bolknote.ru) автор № 187

Комментарий для LO:

Там нужно опять вернуть abs, но подождём окончательной реализации последней идеи

Ага, вчера времени не было на это. Всё-таки очень много переделывать нужно.

Евгений Степанищев (bolknote.ru) автор № 188
Комментарий для LO:

Немного отложу. Сейчас сильно занят. Нужно в комнате сделать перестановку мебели. Так что вечера пока заняты.
Евгений Степанищев (bolknote.ru) автор № 189

Комментарий для LO:

Что-то я так и не вернулся к той идее, лень было. Но сейчас немного стряхнул пыль с проекта и сделал следующее:

dhcp-218-158-wifi:Tanks bolk$ diff index.js index.js.old
1c1
< for(i in a)a[i[V=4]]=a[i]
---

V=4

6c6
< setInterval(function(){X+=L
---

with(a)setInterval(function(){X+=L

8c8
< I=a.t(W=255,W)
---

I=createImageData(W=255,W)

12c12
< y?0:x?(v=[-1,-2,1,2][x.which-37],w=!!x.type[6]&&v,v?v&1?L=w:U=w:w+h&&(h=0,t=X+8,b=Y+1)):a.R(0,!V--,W,W,a.fillStyle='red',K=r)})
---

y?0:x?(v=[-1,-2,1,2][x.which-37],w=!!x.type[6]&&v,v?v&1?L=w:U=w:w+h&&(h=0,t=X+8,b=Y+1)):fillRect(0,!V--,W,W,fillStyle='red',K=r)})

17c17
< V&&K(P(4,3,G=0x607E416AD57E60)+a.m(I,0,0)+a.T(s,15,10))>.93&!$[3]&&$.push([246,r()*25.93&!$[3]&&$.push([246,r()*25

LO № 190
Комментарий для Евгения Степанищева:

Восстановил with(a), убрав конфликт имен (замены имен переменных: m --> e, t --> d). Переместил with выше имен глобальных переменных. Повезло, что в контексте «a» нет конфликта с глобальной «c», иначе пришлось бы искать другой индекс.
Экономия целых 3 байта.
// 709
http://pastebin.com/r5xMCUQZ

И Я как-то заблудился средь просек аллейных. Я так понял, ты взял предыдущую версию на 726, тогда как последней бажной была версия на 720. Т.е. еще 6 байт скинуть можно.
Евгений Степанищев (bolknote.ru) автор № 191

Комментарий для LO:

Я как-то заблудился средь просек аллейных. Я так понял, ты взял предыдущую версию на 726, тогда как последней бажной была версия на 720. Т.е. еще 6 байт скинуть можно.

Что-то я не разобрался. А можешь дать ссылку на версию в 720?

Евгений Степанищев (bolknote.ru) автор № 193
Комментарий для LO:

Как разгребусь немного, посмотрю в чём разница. И я сейчас не могу проверять под IE, кстати. У меня ОС сменилась.
LO № 194
Комментарий для Евгения Степанищева:

Строковые индексы работают, начиная с IE 8 standards mode, cаnvas — c IE9. Таким образом, всё отлично работает в IE9. Проверил.