I am trying to make a game on javascript. In Computer version it works correctly, but when I try to prove in mobile version (Google chrome > F12 > Toggle device toolbar or Ctrl+Shift+M), game is lagging at tap the left/right bottoms.
I have tried to change div elements to buttoms, but really I dont know where is the problem. It is not a complex game, or at least I think.
Here is the code:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
//paleta
var paddleHeight = 10;
var paddleWidth = 75;
var paddleXD = (canvas.width-paddleWidth)/2;
var paddleXU = (canvas.width-paddleWidth)/2;
var rightPressedU = false;
var leftPressedU = false;
var rightPressedD = false;
var leftPressedD = false;
document.addEventListener("keydown", keyDownHandlerD, false);
document.addEventListener("keyup", keyUpHandlerD, false);
document.addEventListener("keydown", keyDownHandlerU, false);
document.addEventListener("keyup", keyUpHandlerU, false);
document.getElementById("der").addEventListener("mousedown", function () {
rightPressedD = true;
}, false);
document.getElementById("izq").addEventListener("mousedown", function () {
leftPressedD = true;
}, false);
document.addEventListener("mouseup", function () {
rightPressedD = false;
leftPressedD = false;
}, false)
document.getElementById("der").addEventListener("touchstart", function () {
rightPressedD = true;
}, false);
document.getElementById("izq").addEventListener("touchstart", function () {
leftPressedD = true;
}, false);
document.addEventListener("touchend", function () {
rightPressedD = false;
leftPressedD = false;
}, false)
//flechas (ABAJO)
function keyDownHandlerD(e) {
if(e.keyCode == 39) {
rightPressedD = true;
}
else if(e.keyCode == 37) {
leftPressedD = true;
}
}
function keyUpHandlerD(e) {
if(e.keyCode == 39) {
rightPressedD = false;
}
else if(e.keyCode == 37) {
leftPressedD = false;
}
}
//A y D ARRIBA
function keyDownHandlerU(e) {
if(e.keyCode == 100) {
rightPressedU = true;
}
else if(e.keyCode == 97) {
leftPressedU = true;
}
}
function keyUpHandlerU(e) {
if(e.keyCode == 100) {
rightPressedU = false;
}
else if(e.keyCode == 97) {
leftPressedU = false;
}
}
//lugar donde aparecerá la bola
var x = canvas.width/2;
var y = canvas.height-30;
//esto es la 'velocidad', los pixeles que recorren cada 10 milisegundos.
var dx = 2;
var dy = -2;
//el radio del balon
var ballRadius = 10;
function drawBall() {//esto simplemente pinta la bola
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI*2);
//ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function drawPaddleU() {
ctx.beginPath();
ctx.rect(paddleXU, 0, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function drawPaddleD() {
ctx.beginPath();
ctx.rect(paddleXD, canvas.height-paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
drawPaddleD();
drawPaddleU();
if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
dx = -dx;
//ctx.fillStyle = getRandomColor();
}
if(y + dy < ballRadius) {
dy = -dy;
} else if(y + dy > canvas.height-ballRadius) {
if(x > paddleXD && x < paddleXD + paddleWidth) {
dy = -dy;
}
else {
//alert("GAME OVER");
document.location.reload();
}
}
if(rightPressedD && paddleXD < canvas.width-paddleWidth) {
paddleXD += 7;
}
else if(leftPressedD && paddleXD > 0) {
paddleXD -= 7;
}
if(rightPressedU && paddleXU < canvas.width-paddleWidth) {
paddleXU += 7;
}
else if(leftPressedU && paddleXU > 0) {
paddleXU -= 7;
}
x += dx;
y += dy;
}
//document.write("la bola esta en X: "+x+" Y: "+y);
setInterval(draw,10);
* { padding: 0; margin: 0; }
canvas { background: #eee; display: block; margin: 0 auto; border: 1px solid black;}
table{touch-action: manipulation;}
#izq{
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#der{
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>game</title>
</head>
<body>
<center>
<table>
<tr >
<td colspan="2">
<canvas id="myCanvas" width="480" height="320"></canvas>
</td>
</tr>
<tr>
<td>
<div id="izq" style="background-color: green; width: 240px; height: 160px;">left</div>
</td>
<td>
<div id="der" style="background-color: green; width: 240px; height: 160px;">right</div>
</td>
</tr>
</table>
</center>
</body>
</html>
This also happened to me and I had no idea what the problem was. I submitted a bug report to the Chrome team, and the response was the following:
I believe this is expected. If you add an event listener, a touchstart may indicate that scrolling is about to happen (Chrome can't tell a priori whether the event will be preventDefaulted). We thus avoid scheduling any Javascript tasks like timers to ensure touch handlers remain responsive so the potential upcoming scroll can start ASAP.
So, basically, Chrome stops timers for a bit of time after the user begins touching the screen to ensure responsiveness in scrolling.
There are two easy ways to avoid this:
This is a promise to Chrome that the handler doesn't call
ev.preventDefault()
so we can tell ahead of time that a touch drag will cause scrolling. Because of that, when we're ready to scroll (off the Javascript thread) we don't have to wait for handlers to respond and we can scroll immediately, so we don't have to keep the JS thread idle to get responsiveness.
document.getElementById("der").addEventListener("touchstart", function () {
rightPressedD = true;
}, {passive: true});
Call ev.preventDefault()
. This will prevent scrolling, click
events and other stuff, but might result in even better performance.
document.getElementById("der").addEventListener("touchstart", function (ev) { // You need to use the first argument
ev.preventDefault();
rightPressedD = true;
});
Just be sure never to call ev.preventDefault()
inside a passive event listener, otherwise you will get an error.