@sljfhwo

Что не так с кодом js?

Как сделать, чтобы этот код работал правильно - отрисовывался задний фон и персонаж ходил?
document.getElementById("canvas");
var ctx = canvas.getContext("2d");

x = 0;
y = 0;
x1 = 0;
y1 = 0;
g = 4;
b = 7;


var ground1 = new Image();
ground1.src = "Ground.png"
var pick1 = new Image()
pick1.src = "Pick.png"

function draw(){
ctx.drawImage(pick1, x1, y1);
document.addEventListener("keydown", function pick(e) {
	if(e.keyCode == 87){
		y1-=32;
		ctx.drawImage(pick1, x1, y1);
	}
	if(e.keyCode == 65){
		x1-=32;
		ctx.drawImage(pick1, x1, y1);
	}
	if(e.keyCode == 83){
		y1+=32;
		ctx.drawImage(pick1, x1, y1);
	}
	if(e.keyCode == 68){
		x1+=32;
		ctx.drawImage(pick1, x1, y1);
	}
})
	if(g < b){
	ctx.drawImage(ground1, x, y);
	x+=32;
	if(x-32 > 290){
		x = 0;
		y+=32;
	} 

	if(y-32 > 578){
		y = 0;
		x = 0;
	}
 }
}

ctx.clearRect(0,0,316,632);

setInterval(draw, 20);
  • Вопрос задан
  • 216 просмотров
Решения вопроса 2
0xD34F
@0xD34F Куратор тега JavaScript
Это чё, в setInterval запихнули подключение обработчика keydown? Умно. Не нужен тут никакой setInterval.

Сам обработчик keydown слишком сложно выглядит - зачем в четырёх разных местах делать один и тот же вызов функции? Сначала меняете координаты, а в самом конце - дёргаете перерисовку.

Размер картинок - а если решите поменять? Или опечатаетесь где-нибудь? Сделайте константу.

Что касается рисования, то наверное, проще всего будет замостить холст фоновым изображением, а потом рисовать персонажа.

Как это всё может выглядеть:

const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

const TILE_SIDE = 32;

let pickX = 0;
let pickY = 0;

const ground = new Image();
ground.src = 'Ground.png';
const pick = new Image();
pick.src = 'Pick.png';

document.addEventListener('keydown', function(e) {
  switch (e.keyCode) {
    case 87: pickY -= TILE_SIDE; break;
    case 65: pickX -= TILE_SIDE; break;
    case 83: pickY += TILE_SIDE; break;
    case 68: pickX += TILE_SIDE; break;

    default: return;
  }

  draw();
});

function draw() {
  for (let x = 0; x < canvas.width; x += TILE_SIDE) {
    for (let y = 0; y < canvas.height; y += TILE_SIDE) {
      ctx.drawImage(ground, x, y);
    }
  }

  ctx.drawImage(pick, pickX, pickY);
}

draw();
Ответ написан
Комментировать
@h88p
Pre-Junior HTML Developer
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Что не так с кодом js?
он некорректный с самой первой строки...

// тут очевидно было пропущено объявление переменной куда сохраняем полученный из DOM canvas
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

// вангую, что тут не объявленные переменные, и их нужно объявить
var x = 0;
var y = 0;
var x1 = 0;
var y1 = 0;
var g = 4;
var b = 7;

// тут норм, но все же стоит включить себе линтер
// ибо порядок в коде == порядок в голове
var ground1 = new Image();
ground1.src = "Ground.png";
var pick1 = new Image();
pick1.src = "Pick.png";

// а вот в функции draw началась полная дичь...
function draw() {
  ctx.clearRect(0,0,316,632); // очистку перенес внутрь функции отрисовки

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

  if(g < b) {
    ctx.drawImage(ground1, x, y);
    x+=32;
    if(x-32 > 290){
      x = 0;
      y+=32;
    }
    if(y-32 > 578){
      y = 0;
      x = 0;
    }
  }

  // я так думаю эту картинку надо рисовать после фона
  ctx.drawImage(pick1, x1, y1);

  requestAnimationFrame(draw); //зациклим анимацию
}

// анимировать что-то по таймеру плохая затея, есть более подходящие инструменты
requestAnimationFrame(draw);

// подписку на событие клавиатуры вынес из отрисовки
// а саму отрисовку выкинул из обработчика
// его дело переменные пересчитывать, а рисовать будет draw
document.addEventListener("keydown", function pick(e) {
  if(e.keyCode == 87){
    y1-=32;
  }
  if(e.keyCode == 65){
    x1-=32;
  }
  if(e.keyCode == 83){
    y1+=32;
  }
  if(e.keyCode == 68){
    x1+=32;
  }
});

по хорошему надо еще, чтоб цифры от времени зависели, ибо requestAnimationFrame будет вызывать вкфц с частотой соответствующей доступному FPS
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы