logo
LIS PUBLICA
☰
  • Новое
  • Горячее
  • Сокровищница
  • Лучшее
  • Сообщества
  • Видео
  • Обсуждаемое

VariusSoft
VariusSoft Серия: Пишем танчики на JavaScript Сообщество: GameDev Опубликовано 2 дня назад
  • [моё]
  • [Сокровищница]
  • GameDev
  • Программирование
  • Battle City
  • Game Engine

«Танчики» на html5

Пишем свой игровой движок

После прошлого поста я что-то так проникся происходящим, что решил воссоздать ещё одну любовь детства. Но как говорил Маркус Персон: «Если вы не можете написать свой движок, то гавно вы, а не разработчики». Там, скорее всего, было как-о иначе, но суть такая. И да, с этой мыслью я в корне не согласен, но написать свой движок – задача, как минимум, интересная. Я решил, что аркадная игра для этого подходит, как ничто другое. По сути, некий аналог движка уже был реализован в тетрисе, но здесь нужна будет и какая-никакая физическая модель, и интеллект врагов и рендер всего этого безобразия в несколько слоёв и с ФПС побольше, чем 2 :)

Так что, приступим. Что нам нужно:

  • Просчёт физики
  • Работа ИИ агентов
  • Считывание действий игрока
  • Отрисовка результата работы предыдущих пунктов.

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

Я решил разделить рисования окружения (статичных объектов), врагов и игроков (динамических объектов) и UI на три разных канваса, которые просто повещены один поверх другого. Там можно будет проще и меньше перерисовывать.

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

    if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', init);
} else {
  init();
}

Если готова, то давай же скорее всё проинициализируем

Тут всё просто:

    function init() {
  console.log('Battle City Remake - Initializing...');

  // Инициализация рендерера
  initRenderer();

  // Очищаем все слои
  clearBackground();
  clearForeground();
  clearUI();

  // Рисуем границу игрового поля и отладочную сетку
  renderGameFieldBorder();
  renderDebugGrid();

  console.log('Initialization complete. Starting game loop...');

  // Запускаем game loop
  requestAnimationFrame(gameLoop);
}

Но понятное дело, что кода тут мало, потому что всё вынесено в отдельные методы.

Есть ли среди них хоть что-то интересное?

Ну, renderDebugGrid и renderGameFieldBorder одним названием уже говорят, что там происходит.

Логично, что самое интересное происходит где-то тут requestAnimationFrame(gameLoop);

Но давайте сначала заглянем в инициализацию рендера

    export function initRenderer() {
  // Получаем canvas элементы
  backgroundCanvas = document.getElementById('background-canvas');
  foregroundCanvas = document.getElementById('foreground-canvas');
  uiCanvas = document.getElementById('ui-canvas');

  // Получаем контексты
  backgroundCtx = backgroundCanvas.getContext('2d');
  foregroundCtx = foregroundCanvas.getContext('2d');
  uiCtx = uiCanvas.getContext('2d');

  // Определяем DPR для HiDPI экранов
  dpr = window.devicePixelRatio || 1;

  // Настраиваем все три canvas
  setupCanvas(backgroundCanvas, backgroundCtx);
  setupCanvas(foregroundCanvas, foregroundCtx);
  setupCanvas(uiCanvas, uiCtx);

  console.log(`Renderer initialized (DPR: ${dpr})`);
}

function setupCanvas(canvas, ctx) {
  // Физический размер canvas
  canvas.width = CANVAS_WIDTH * dpr;
  canvas.height = CANVAS_HEIGHT * dpr;

  // Масштабируем контекст для компенсации DPR
  ctx.scale(dpr, dpr);

  // Отключаем сглаживание для пиксельной графики
  ctx.imageSmoothingEnabled = false;

  console.log(`Canvas ${canvas.id} setup: ${canvas.width}×${canvas.height} (logical: ${CANVAS_WIDTH}×${CANVAS_HEIGHT})`);
}

CANVAS_WIDTH и CANVAS_HEIGHT — это константы, они у меня в отдельном файлике лежат, там просто 800 на 600.

В целом, страничка готова к тому, чтоб рисовать всякое

Дёргаем requestAnimationFrame и отдаём её наш gameLoop

    function gameLoop(currentTime) {
  // Вычисляем deltaTime
  const deltaTime = currentTime - lastTime;
  lastTime = currentTime;

  // Накапливаем время
  accumulator += deltaTime;

  // Fixed timestep - обновляем логику с фиксированным шагом
  while (accumulator >= FRAME_TIME) {
    update(FRAME_TIME);
    accumulator -= FRAME_TIME;
  }

  // Рендерим независимо от update
  render();

  // Продолжаем loop
  requestAnimationFrame(gameLoop);
}

Я решил фиксировать ФПС на 30

    export const FPS = 30;                    // Фиксированный FPS
export const FRAME_TIME = 1000 / FPS;     // ~33.33ms на кадр

Метод update содержит (ну, будет содержать) всю нашу игровую логику. Пока он только считает фпс и выводит его на экран для отладки.

    function update(dt) {
  // Пока пусто - здесь будет логика игры

  // Подсчёт FPS для отладки
  frameCount++;
  fpsTimer += dt;

  if (fpsTimer >= 1000) {
    fps = frameCount;
    frameCount = 0;
    fpsTimer = 0;

    // Обновляем FPS на странице
    const fpsElement = document.getElementById('fps');
    if (fpsElement) {
      fpsElement.textContent = fps;
    }
  }
}

Ну и когда всё закончено, отрисовываем

    function render() {
  // Background canvas - перерисовывается только при изменении карты
  // (пока только отладочная сетка, нарисованная в init)

  // Foreground canvas - очищаем и рисуем сущности каждый кадр
  clearForeground();
  // TODO: Здесь будет рендер танков, пуль, эффектов

  // UI canvas - очищаем и рисуем UI каждый кадр
  clearUI();
  renderUI();
}

То есть, по сути, ничего интересного, просто рисую полосочки и квадратики для UI

Результат выглядит вот так

Следующий пост будет посвящён второму этапу

И да, я упоролся и расписал себе полноценный план реализации на 13 этапов. Без ДизДока последнее время вообще не представляю как работать. А раз уж я в команде один, то сам себе и ТЗ пишу... Но лучше так, чем лепить полную отсебятину.

Вопросы замечания предложения в комментариях жду с нетерпением)

А пойду пилить обновление для Лиспублики)


Всем хороших игр!

Читать дальше...
14
+14 / -0
14
33
ТГ ВК
Pepels
Pepels Опубликовано 2 дня назад

Это ты намекаешь, что скоро появится раздел "игры" на лиспублике?

4
+4 / -0
[ Свернуть ]
AlNiKo
AlNiKo Опубликовано 2 дня назад
Ответ на Комментарий от Pepels

Это ты намекаешь, что скоро появится раздел "игры" на лиспублике?

Дурак на раздевание

sticker
2
+2 / -0
Pepels
Pepels Опубликовано 2 дня назад
Ответ на Комментарий от AlNiKo

Дурак на раздевание

sticker

Идея для следующей лиспубликанской сходки

2
+2 / -0
VariusSoft
VariusSoft Опубликовано 2 дня назад
Ответ на Комментарий от Pepels

Это ты намекаешь, что скоро появится раздел "игры" на лиспублике?

sticker
3
+3 / -0
Warp_World
Warp_World Опубликовано 2 дня назад

Сколько раз ни сталкивался с новоделом по старым игрушкам, почему-то вызывают они только разочарование, независимо от движка, дизайна, звука и всего остального. Тут вопрос, обозначенный в начале поста о том, что вы не разраб, коли свой движок не написали для игры, мне кажется, нужно расширить - "для СВОЕЙ игры". Тогда не будет и и сопутствующих ожиданий и разочарования. И еще: в плане обучения разработке игр - это интересно. Только вот все же нужно исходить из того, что учиться разработке на повторении прошлого, опять же имхо, это неправильно. Когда-то кто-то сделал понг, тетрис, Марио, Соника - и это было круто. Да и до сих пор поиграть приятно. Только клоны на своем движке, с новой физикой и дизайном ничего нового в плане ощущений не дадут. ПыСы. У меня пост так полностью на телефоне и не раскрылся

1
+1 / -0
[ Свернуть ]
VariusSoft
VariusSoft Опубликовано 2 дня назад
Ответ на Комментарий от Warp_World

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

Обучение на повторении – это единственное верный путь. Учиться сразу на своём – это лишь упорствовать в собственных ошибках и заблуждениях, как слепой котёнок пытаясь найти миску с молоком, при учёте, что ты ещё не знаешь, как пахнет молоко.

Что касается написать движок для своей игры. Тоже не соглашусь. Если ты способен написать движок – ты способен написать движок. И не важной для какой игры. Этот опыт так же универсален, как умение держать в руках молот. При минимальном раскладе ты забьёшь гвоздь, при определённом – станешь кузнецом, а если придут орки, то можно и черепа начать крушить.

Ну а по поводу переделки старых игр, тут и соглашусь и нет. У меня нет цели повторить те самые эмоции. Дать что-то новое? Да, я планирую в самом конце добавить ультимативную киллерфичу, которая, скорее всего, никому нафиг не упрётся, но тем не менее. Я это делаю для развития себя как разработчика игр, для того, чтобы те, кому вопрос интересен, смогли почерпнуть что-то новое или полезное. А если в итоге ещё и получится играбельная версия, то, как будто, это будет ещё и приятным бонусом.

2
+2 / -0
Warp_World
Warp_World Опубликовано 2 дня назад
Ответ на Комментарий от VariusSoft

Обучение на повторении – это единственное верный путь. Учиться сразу на своём – это лишь упорствовать в собственных ошибках и заблуждениях, как слепой котёнок пытаясь найти миску с молоком, при учёте,...

По поводу движка для новодела не согласен. Сто процентов уверен, что они уже есть подо все, достаточно в сети поискать, вот даже под Battle Tank тот же. Причем даже с комментариями разрабов по коду. Забивать же один и тот же гвоздь одним и тем же молотком, пусть хоть и с красной рукояткой смысла не вижу. По поводу новодела - единственное, что хочу увидеть, это мультик для "Ну, погоди", после набора 1000 очков в конце, хотя уверен, что и такое уже есть, просто не искал

0
+0 / -0
VariusSoft
VariusSoft Опубликовано 2 дня назад
Ответ на Комментарий от Warp_World

По поводу движка для новодела не согласен. Сто процентов уверен, что они уже есть подо все, достаточно в сети поискать, вот даже под Battle Tank тот же. Причем даже с комментариями разрабов по коду. З...

Именно поэтому начинающие художники сразу рисуют свой шедевр, а не пресловутые кружочки и тысячную вазу.

Поэты сразу пишут поэму-эпос.

Пацаны в гараже собирают свой супер-кар, а не изучают, как работает впрыск, и в чём смысл трамблёра.

Повторение существующих игр – это прекрасный способ войти в гейм дев при наличии уже 300 раз выверенного геймплея, концепции и механик. Разработчик может сконцентрироваться непосредственно на воссоздании конкретных аскпеков, а не тратить полгода на написание диздока.

Брать готовый движок нужно в том случае, если ты просто хочешь сделать конкретную игру. Нет смысла разрабатывать свой велосипед, если ты хочешь сделать свою визуальную новеллу. Уже давно есть РенПай, или Юнити на худой конец. Это подход человека, который хочет получить конкретный результат. Он хочет рассказать миру свою историю.

Подход разработчика в умении написать свой движок – это развитие умения создать в итоге то, чего ещё не было. Это понимания принципов построения архитектуры. Ты не построишь небоскрёб, не выучив сопромат и не сделав по дороге три сотни курсовых, которые делали до тебя тысячи других студентов.

2
+2 / -0
Warp_World
Warp_World Опубликовано 2 дня назад
Ответ на Комментарий от VariusSoft

Именно поэтому начинающие художники сразу рисуют свой шедевр, а не пресловутые кружочки и тысячную вазу.

Поэты сразу пишут поэму-эпос.

Пацаны в гараже собирают свой супер-кар, а не изучают, как работает...

Так вот, к чему я. Если говорить о том, что выше. Было бы интересно проследить весь путь создания игры для человека с минимальным пониманием о ее создании. Потому что те же минимальные поэты могут написать стихи "За окном я увидел рассвет, от меня вам пламенный привет", а после уже, прочитав кучу книг со стихами, критикой, по теории литературы, поэтики и всего остального, что-то создать. Сейчас же по постам о создании игры что я вижу - чел, который полный ноль: "Щаз мы будем писать игруху на html5, напишем движок" - охренеть, я ж ни в зуб ногой, ибо пока что "не поэт". Может, тогда все же начать хотя бы с тех же "Наша Таня громко плачет"? А так я точно так же возьму код в сети и буду в него втыкать, ничего не понимая, но зато в перспективе смогу написать "Одиссею" гекзаметром, которую уже Гомер до меня написал. Или это нужно тогда просто воспринимать не как обучение, а просто дневник разраба

0
+0 / -0
VariusSoft
VariusSoft Опубликовано 2 дня назад
Ответ на Комментарий от Warp_World

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

Так я и не говорил, что эта серия постов для человека в полным отсутствием фундамента)

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

0
+0 / -0
Warp_World
Warp_World Опубликовано 2 дня назад
Ответ на Комментарий от VariusSoft

Так я и не говорил, что эта серия постов для человека в полным отсутствием фундамента)

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

мне бы было интересно, например, поразбираться с тем же html5, я не полный нуб в программировании, но все же прекрасно понимаю, что свой движок мне ни на чем не написать, даже используя соответствующие наработки - скорее всего, если рационально мыслить, проще было использовать тот же опен сурс, читая мануалы и выдергивая у себя последние седины. Вообще, как я понимаю, в геймдев идут все равно с каким-то фундаментом. Тут же просто посты идут именно как раз для тех, кто с ним. Просто объясню, как я вижу сейчас посты. Мне тема ретро интересна, конечно. Вот для примера - пришла ко мне вчера главбух с двумя токенами, рутокенами, если быть точным. Один лайт, второй - 3.0. Просит сделать копию ЭП, чтобы не дергать других, не таскать токены постоянно из сейфа и все такое прочее. По регламенту я этого делать не должен, но обычно все же делаю. С токеном лайт все просто - выдираю контейнер, делаю экспортируемый сертификат, устанавливаю на компы заинтересованных. Естественно, все это не задокументировано и неофициально. С токеном 3.0 хер там, все на уровне аппаратном, его даже ФНС и всякие Сберы в гробу видели для копирования, ибо себе дороже. Есть энтузиасты, что их перепаивают, снимают дампы и все расшифровывают - стоит ООООЧЕНЬ много деньгов, поэтому проще купить другой токен и перевыпустить ЭП. К чему я веду. Главбуху я ж не буду объяснять, что я тут делал - ей нужен конечный результат. Опять же есть бухи, которые в этом разбираются, я их учу, после они уже сами понимают, что тут делать и все сами и делают. Вернусь к постам. Сейчас я не понимаю, для кого они - особенно с примерами кода. Наверное, если бы я засел за них серьезно, то что-то бы и вынес. Но на это ушло много времени, ибо основы у меня такой нет. Да и желания, если честно. Именно поэтому посты сейчас воспринимаю не как наставление для полных нубов по разработке, а как дневник разработчика, но опять же он не вызывает у меня какого-то отклика, так как я уже представляю результат и в него играл. Вот, наверное, это была завершающая часть моих таких размытых по мысли и тупых, конечно же, комментариев

1
+1 / -0
vervolph
vervolph Опубликовано 2 дня назад

О, я тоже когда-то давным давно танчики писал... на паскале!!!

1
+1 / -0
[ Свернуть ]
VariusSoft
VariusSoft Опубликовано 2 дня назад
Ответ на Комментарий от vervolph

О, я тоже когда-то давным давно танчики писал... на паскале!!!

ту-ду-ду-ду-ду..... *подозрительный взгляд*

Мой путь разработчика игры начался с того, что будучи первокурсников факультета прикладной математики я нашёл в папке с курсовиками по агоритмам работу третьекурсника. И это были танчики на паскале...

2
+2 / -0
vervolph
vervolph Опубликовано 2 дня назад
Ответ на Комментарий от VariusSoft

ту-ду-ду-ду-ду..... *подозрительный взгляд*

Мой путь разработчика игры начался с того, что будучи первокурсников факультета прикладной математики я нашёл в папке с курсовиками по агоритмам работу треть...

🤣🤣🤣 не, не я ) я вроде максимум на втором на паскале писал. С третьего у нас уже делфи начался

1
+1 / -0
Войти

Вход

Регистрация

Я не помню пароль

Войти через Google
Порог горячего 15
  • Kukabara
    Kukabara

    значит, под конец недели затестим)

    +0
  • Porked
    Porked

    а я как-то замечаю разницу.

    +1
  • Kukabara
    Kukabara

    та щааас блять! нехуй))

    +1
Правила сайта
Пользовательское соглашение
О ПД
Принципы самоуправления
Нашёл ошибку?
©2026 Varius Soft