使画布游戏响应调整大小 [英] Making a Canvas game responsive on resize

查看:104
本文介绍了使画布游戏响应调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力使pong帆布游戏响应调整大小,我也不确定我错过了什么,以及什么是最好的方式让它响应,同时仍然没有处理沉重。我试图删除并重新调整画布大小调整我认为这是一个坏主意,到目前为止,响应性对负载起作用...非常感谢洞察,非常感谢

I am trying to make a pong canvas game responsive on resize, i am nor sure what i am missing and what would be the best way to have it responsive while still not being to process heavy. i tried to delete and reinject the canvas on resize what is a bad idea i think, the responsiveness works on load so far... thanks a lot for the insights, much appreciated

http://jsfiddle.net/ut0hsvd4/1/

var animate = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {
  window.setTimeout(callback, 1000 / 60)
};
var canvas = document.createElement("canvas");
var width = document.getElementById('pong').offsetWidth;
var height = document.getElementById('pong').offsetHeight;
canvas.width = width;
canvas.height = height;
var context = canvas.getContext('2d');
var player = new Player();
var computer = new Computer();
var ball = new Ball(width / 2, height / 2);

var keysDown = {};

var render = function() {
  context.fillStyle = "red";
  context.fillRect(0, 0, width, height);
  player.render();
  computer.render();
  ball.render();
};

var update = function() {
  player.update();
  computer.update(ball);
  ball.update(player.paddle, computer.paddle);
};

var step = function() {
  update();
  render();
  animate(step);
};

function Paddle(x, y, width, height) {
  this.x = x;
  this.y = y;
  this.width = width;
  this.height = height;
  this.x_speed = 0;
  this.y_speed = 0;
}

Paddle.prototype.render = function() {
  context.fillStyle = "#0000FF";
  context.fillRect(this.x, this.y, this.width, this.height);
};

Paddle.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  this.x_speed = x;
  this.y_speed = y;
  if (this.x < 0) {
    this.x = 0;
    this.x_speed = 0;
  } else if (this.x + this.width > width) {
    this.x = width - this.width;
    this.x_speed = 0;
  }
};

function Computer() {
  this.paddle = new Paddle(width / 2 - 25, 10, 50, 10);
}

Computer.prototype.render = function() {
  this.paddle.render();
};

Computer.prototype.update = function(ball) {
  var x_pos = ball.x;
  var diff = -((this.paddle.x + (this.paddle.width / 2)) - x_pos);
  if (diff < 0 && diff < -4) {
    diff = -5;
  } else if (diff > 0 && diff > 4) {
    diff = 5;
  }
  this.paddle.move(diff, 0);
  if (this.paddle.x < 0) {
    this.paddle.x = 0;
  } else if (this.paddle.x + this.paddle.width > width) {
    this.paddle.x = width - this.paddle.width;
  }
};

function Player() {
  this.paddle = new Paddle(width / 2 - 25, height - 20, 50, 10);
}

Player.prototype.render = function() {
  this.paddle.render();
};

Player.prototype.update = function() {
  for (var key in keysDown) {
    var value = Number(key);
    if (value == 37) {
      this.paddle.move(-4, 0);
    } else if (value == 39) {
      this.paddle.move(4, 0);
    } else {
      this.paddle.move(0, 0);
    }
  }
};

function Ball(x, y) {
  this.x = x;
  this.y = y;
  this.x_speed = 0;
  this.y_speed = 3;
}

Ball.prototype.render = function() {
  context.beginPath();
  context.arc(this.x, this.y, 5, 2 * Math.PI, false);
  context.fillStyle = "#000000";
  context.fill();
};

Ball.prototype.update = function(paddle1, paddle2) {
  this.x += this.x_speed;
  this.y += this.y_speed;
  var top_x = this.x - 5;
  var top_y = this.y - 5;
  var bottom_x = this.x + 5;
  var bottom_y = this.y + 5;

  if (this.x - 5 < 0) {
    this.x = 5;
    this.x_speed = -this.x_speed;
  } else if (this.x + 5 > width) {
    this.x = width - 5;
    this.x_speed = -this.x_speed;
  }

  if (this.y < 0 || this.y > height) {
    this.x_speed = 0;
    this.y_speed = 3;
    this.x = width / 2;
    this.y = height / 2;
  }

  if (top_y > height / 2) {
    if (top_y < (paddle1.y + paddle1.height) && bottom_y > paddle1.y && top_x < (paddle1.x + paddle1.width) && bottom_x > paddle1.x) {
      this.y_speed = -3;
      this.x_speed += (paddle1.x_speed / 2);
      this.y += this.y_speed;
    }
  } else {
    if (top_y < (paddle2.y + paddle2.height) && bottom_y > paddle2.y && top_x < (paddle2.x + paddle2.width) && bottom_x > paddle2.x) {
      this.y_speed = 3;
      this.x_speed += (paddle2.x_speed / 2);
      this.y += this.y_speed;
    }
  }
};

document.getElementsByClassName('js-pong')[0].appendChild(canvas);
animate(step);

window.addEventListener("keydown", function(event) {
  keysDown[event.keyCode] = true;
});

window.addEventListener("keyup", function(event) {
  delete keysDown[event.keyCode];
});

var resizer = function() {
  document.getElementsByTagName('canvas').remove();
  document.getElementsByClassName('js-pong')[0].appendChild(canvas);
  animate(step);
}

window.addEventListener('resize', resizer);


推荐答案

不要将Resize事件用于动画。



(如果您使用 requestAnimationFrame

请勿向resize事件添加调整大小。调整大小事件不会与显示器同步触发,并且它还可以比显示速率更快地激发很多时间。这可能会使窗口大小控件拖动时调整大小和游戏变得迟钝。

Do not add a resize to the resize event. The resize event does not fire in sync with the display, and it can also fire many time quicker than the display rate. This can make the resize and game feel sluggish while dragging at the window size controls.

对于最平滑的调整大小,只需检查主循环内的画布大小。如果画布与包含元素大小不匹配,则调整其大小。这确保您只在需要时调整大小并始终与显示同步(如果您使用 requestAnimationFrame

For the smoothest resize simply check the canvas size inside the main loop. If the canvas does not match the containing element size then resize it. This ensures you only resize when needed and always resize in sync with the display (if you use requestAnimationFrame)

例如

// get a reference to the element so you don't query the DOM each time
const pongEl = document.getElementById("pong");

// then in the main loop
function mainLoop() {
    // do first thing inside the render loop
    if(canvas.width !== pongEl.offsetWidth  || canvas.height !== pongEl.offsetHeight ){
        canvas.width = pongEl.offsetWidth;
        canvas.height = pongEl.offsetHeight;   
        // note the above clears the canvas.
    }

    // game code as normal

    requestAnimationFrame(mainLoop);
}

这篇关于使画布游戏响应调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆