Javascript-игра играет СЛИШКОМ БЫСТРО на M1 MacBook Pro

Я только что создал небольшую игру «Space Invaders», используя простой Javascript, и она прекрасно работает на моем MacMini 2018 года, но невероятно быстро на моем MacBook Pro 2021 года (в котором есть чип M1).

Поскольку я использую requestAnimationFrame() для своего основного цикла анимации (в отличие от setInerval), у меня есть полный контроль, я пошел дальше и снизил частоту кадров анимации WAAAY, буквально уменьшив ее с 60 кадров в секунду до 10 кадров в секунду - но она ВСЕ ЕЩЕ работает непомерно быстро на M1 MacBook Pro.

Я знаю, что мой конкретный MacBook Pro M1 имеет частоту обновления экрана 120 Гц — что может быть самым большим виновником и основной причиной проблемы, но если да, то как мне обойти это?

Буду признателен за любые советы и рекомендации.

Спасибо.

Вам следует использовать код, который позволит вам более точно контролировать время, например setTimeout() и setInterval().

Barmar 23.05.2024 00:32

Я прочитал кучу сообщений, в которых говорилось, что requestAnimationFrame() — гораздо лучший вариант, чем setInterval(), потому что он более точен, занимает меньше памяти и т. д. Не могу вспомнить все причины, но общее мнение заключалось в том, что это гораздо лучший способ. Как будто я видел это не в одном или двух местах, а везде. Так что же заставляет тебя говорить это?

Sirab33 23.05.2024 00:51

Пожалуйста, опубликуйте stackoverflow.com/help/minimal-reproducible-example, с которым мы можем работать.

Derek 23.05.2024 03:00
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Да, requestAnimationFrame() действительно гораздо лучший вариант для анимации. Вам просто нужно принять во внимание фактическое время, прошедшее между двумя вызовами. Затем, например, зная скорость и дельту времени, вы можете рассчитать расстояние.

Вот очень упрощенный пример. Вы можете найти больше информации о «игровом цикле» или аналогичном термине в Интернете.

var dt, last
var speed = 0.2;
var totalDistance = 0
var maxDistance = 300

function frame(now) {
  dt = last ? now - last : 0

  update(dt)
  render(dt)

  last = now;
  requestAnimationFrame(frame);
}


function update(dt) {
  totalDistance += dt * speed;
  if (totalDistance >= maxDistance || totalDistance <= 0) {
    speed *= -1
  }
  totalDistance = Math.max(Math.min(maxDistance, totalDistance), 0)
}

function render(dt) {
  element.style.transform = `translateX(${totalDistance}px)`;
}

requestAnimationFrame(frame);
#element {
  width: 100px;
  height: 100px;
  border: 1px solid gray;
}
<div id = "element">Hello</div>

Хорошо, я уже кое-что из этого делаю: у меня уже есть код, который вычисляет точное количество миллисекунд, прошедших между каждым вызовом requestAnimationFrame(), и я стараюсь НЕ отображать другой кадр, если это время МЕНЬШЕ желаемого. 16,6667 мс, потому что это означает, что все происходит СЛИШКОМ БЫСТРО (и я знаю, что это работает) - НО... Я посмотрю на ваш код и посмотрю, делаете ли вы что-нибудь другое. Я скажу, что общее расстояние, которое должны пройти мои Космические захватчики, должно быть фиксированным (я почти уверен), поэтому я не знаю, хочу ли я, чтобы оно каждый раз пересчитывалось...

Sirab33 23.05.2024 02:01

Другие вопросы по теме