Я провел последние две недели, создавая игру с несколькими друзьями, используя тег HTML Canvas и JavaScript. Ни у кого из нас не было опыта работы с проектами такого масштаба, поэтому мы не думали о совместимости браузера и размера экрана. Игра запускается и отлично смотрится на наших ноутбуках (у всех одинаковые размеры экрана), но она выглядела плохо, когда мы отправили ссылку другому другу, размер экрана которого сильно отличается от того, что мы имели в виду.
Чтобы обсудить макет игры более подробно, он настроен с элементом холста, действующим как фактическая игра с рядом разделов div, расположенных под холстом, для представления таких вещей, как диалоговое окно или меню паузы (только один из этих div является показаны одновременно, а остальные будут скрыты).
Игра основана на сетке, так как каждый объект, от плиток стены до врагов, имеет размер относительно некоторой постоянной ширины блока (определенной ниже), которая сама по себе зависит от желаемого количества квадратов на экране, numSquares (также определяется ниже).
Изменение свойств высоты и ширины холста в JavaScript позволило успешно исправить соотношение размеров холста и обеспечить загрузку текстур стены и пола на свои места. Однако игрок и другие неигровые персонажи появляются на экране в странных местах, а иногда и вовсе не отображаются при загрузке.
Я не совсем уверен, к чему приписать эту проблему, но я думаю, что это как-то связано с системой координат холста, которая плохо сочетается с явно плохо выполненной блочной системой, которую мы создали.
//some relevant misc variables
var numSquares = 30;
const blockWidth = 1132 / numSquares * 0.75;
screen.width = 1132;
screen.height = 600;
//some relevant player variables
stats.x = 678;
stats.y = 600;
stats.width = blockWidth * 3 * 0.37;
stats.height = blockWidth * 3;
Опять же, я подозреваю, что проблема как-то связана с тем фактом, что плитки, которые отображаются правильно (например, текстуры стен и пола), имеют свои координаты с точки зрения ширины блока, тогда как плитки, которые отображаются неправильно (например, игрок), имеют свои координаты как обычные числа.
Есть ли способ настроить нашу игру для разных размеров монитора, кроме как переделать всю систему координат?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


попробуйте эту мета, которая решит проблему кроссплатформенного экрана (ноутбук, компьютер, вкладка, мобильный):
<head>
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
</head>
Ваша основная проблема заключается в использовании жестко запрограммированных значений для ваших переменных. Если stats.x = 678; и ваш экран имеет ширину 480 пикселей (например), stats выпадет из экрана.
Также: screen.width и screen.height - это жестко запрограммированные числа. Наверное, вам нужно что-то вроде: screen.width = window.innerWidth и screen.height = window.innerHeight
Чего мне не хватает в вашем соответствующие разные переменные: в вашем коде у вас есть это:
var numSquares = 30;
const blockWidth = 1132 / numSquares * 0.75;
Где 1132 - это на самом деле screen.width. Это означает, что у вас нет grid, как вы говорите. Это означает, что у вас есть только ряд квадратов 1 (один). В качестве альтернативы у вас есть 30 квадратов в строке, и в этом случае у вас есть сетка.
Также было бы неплохо увидеть, как вы рисуете свою сетку. Я бы сделал это так:
for (let y = 0; y < ch; y += cw / numSquares) {
for (let x = 0; x < cw; x += cw / numSquares) {
let o = { x: x, y: y, w: blockWidth, h: blockWidth };
drawRect(o);
}
}
Где drawRect - это настраиваемая функция для рисования прямоугольника. Поскольку у вас blockWidth = screen.width / numSquares * 0.75;, я предполагаю, что вы допускаете зазор между прямоугольниками, но это предполагается.
Как я уже отмечал ранее, вы не можете указывать жестко запрограммированные значения для вашего stats. Вам нужно будет вычислить эти значения в зависимости от ваших ячеек сетки. Например, ваш stats.x может быть x 5-го столбца вашей сетки, а stats.y может быть y 3-й строки. Но это снова предположение, и я могу ошибаться.
Далее идет пример кода. Пожалуйста, взгляните и дайте мне знать, если это то, что вам нужно.
const screen = document.getElementById("canvas");
const ctx = screen.getContext("2d");
let cw = (screen.width = window.innerWidth);
let ch = (screen.height = window.innerHeight);
let stats = {};
let numSquares = 30;
let blockWidth;
generateGrid();
function Init() {
// a function to re-generate the grid and re-draw the stats when screen.width and/or screen.height changed
cw = screen.width = window.innerWidth;
ch = screen.height = window.innerHeight;
generateGrid();
drawStats(5, 3);
}
// recalculate everything on resize
setTimeout(function() {
Init();
addEventListener("resize", Init, false);
}, 15);
// some useful functions
function drawRect(o) {
ctx.beginPath();
ctx.fillStyle = "rgba(0,0,0,.05)";
ctx.fillRect(o.x, o.y, o.w, o.h);
}
function drawStats(x, y) {
stats.x = x * cw / numSquares;
stats.y = y * cw / numSquares;
stats.width = blockWidth * 3 * 0.37;
stats.height = blockWidth * 3;
ctx.fillStyle = "red";
ctx.beginPath();
ctx.fillRect(stats.x, stats.y, stats.width, stats.height);
}
function generateGrid() {
blockWidth = cw / numSquares * 0.75;
for (let y = 0; y < ch; y += cw / numSquares) {
for (let x = 0; x < cw; x += cw / numSquares) {
let o = { x: x, y: y, w: blockWidth, h: blockWidth };
drawRect(o);
}
}
}*{margin:0;padding:0}<canvas id = "canvas"></canvas>Если это не то, что вам нужно, обновите свой вопрос и добавьте дополнительные пояснения и дополнительный код.
Вы пробовали установить масштабатор, который соответствует размеру контейнера и т. Д .; Масштабируемый / пропорциональный контент