繁体   English   中英

javascript计时器在webview中的android上运行太快

[英]javascript timer runs too fast on android in webview

编辑:我找到了解决方案。 查看下面的答案


我用html5编写了一个游戏。 我使用setTimeout(func,1000 / FPS)运行游戏。 然后我回想起超时,因此进行了循环。 (FPS设置为等于30。)我的android手机上的Chrome一切正常,但是当我将其放入android的webview中时,计时器的运行速度似乎比浏览器快10倍。 我该如何解决/为什么会这样? 谢谢!

 <html> <head> <title>...</title> <style> ... </style> </head> <body style="-webkit-user-select:none; cursor:default; margin:0px; padding:0px; overflow:hidden; position : fixed;"> <script> var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); canvas.width = 480; canvas.height = 800; canvas.style.width = window.innerWidth; canvas.style.height = window.innerHeight; canvas.style.float = "left"; //canvas.style.transform = "translate3d(0,0,0)"; document.body.appendChild(canvas); var started = 0; var vy = 0; var startImage = new Image(); startImage.src = "img/start.png"; startImage.onload = function(){ ctx.drawImage(startImage,0,0); //touchstart addEventListener("touchstart",function(e) { if(started == 0){ loadGame(); started = 1; }else{ vy = -15; } },false); }; var bgImage; function loadGame(){ bgImage = new Image(); bgImage.src = "img/background.png"; bgImage.onload = function(){ loadPlayer(); }; } var player; var playerX = 64; var playerY = 0; var playerHeight = 60; var playerWidth = 76; var stopTime = false; var stopFall = false; function loadPlayer(){ player = new Image(); player.src = "img/hero.png"; player.onload = function() { loadwalls(); }; } var walls; function loadwalls(){ wall = new Image(); wall.src = "img/wall.png"; wall.onload = function() { loadGameover(); }; } var gameO; function loadGameover(){ gameO = new Image(); gameO.src = "img/gameover.png"; gameO.onload = function() { init(); }; } var walls = []; function draw(){ canvas.width = 480; canvas.height = 800; ctx.drawImage(bgImage,0,0); ctx.drawImage(player,playerX,playerY); for(var i=0;i<walls.length;i++){ if(walls[i][0] > -200){ ctx.drawImage(wall,walls[i][0],walls[i][1]); ctx.drawImage(wall,walls[i][0],walls[i][1]-839-3.25*playerHeight); walls[i][0] -= 4; if((walls[i][1] < 785 || vy < 0) && (walls[i][1] > 15 || vy > 0)){ walls[i][1] += vy; } if(vy < 10){ vy += 2; } } if(playerX > walls[i][0]+128-playerWidth && walls[i][2] == 0){ walls[i][2] = 1; score += 1; } if(playerX < walls[i][0]+128 && playerX > walls[i][0]-playerWidth){ if(playerY < walls[i][1]-3.25*playerHeight-5 || playerY > walls[i][1]-playerHeight+5){ gameOver(); } } } } function drawFall(){ canvas.width = 480; canvas.height = 800; ctx.drawImage(bgImage,0,0); for(var i=0;i<walls.length;i++){ ctx.drawImage(wall,walls[i][0],walls[i][1]); ctx.drawImage(wall,walls[i][0],walls[i][1]-839-3.25*playerHeight); } ctx.scale(1, -1); ctx.drawImage(player,playerX,-playerY-playerHeight); ctx.scale(1, -1); var score = 0; var highscore = 0; var state = window.localStorage.getItem("...."); if (state) { highscore = parseInt(state); } var FPS = 30; function init(){ var time = 0; var wallTime = 0; stopTime = false; stopFall = false; setTimeout(function (){ if(started == 1){ playerY = playerHeight/2*Math.sin(time)+canvas.width/2+playerHeight; draw(); time+=0.1; wallTime += 0.1; if(time > Math.PI*2){ time = 0; } if(wallTime >= 10){ walls.push([480,Math.random()*(800-3.25*playerHeight*2)+5*playerHeight,0]); wallTime = 0; } } if(!stopTime){ setTimeout(arguments.callee, 1000/FPS); } },1000/FPS); setTimeout(function(){ var advert=document.getElementById("ad"); advert.style.top = "0"; },1000); document.getElementById('iad').src += ''; } function gameOver(){ stopTime = true; var fallSpeed = 5; var fall = setTimeout(function(){ playerY+=fallSpeed; fallSpeed += 1; playerX+=5; drawFall(); if(playerY>800+50){ stopFall = true; canvas.width = 480; canvas.height = 800; canvas.style.width = window.innerWidth; canvas.style.height = window.innerHeight; ctx.drawImage(gameO,0,0); walls = []; if(score > highscore){ window.localStorage.setItem(".....", ""+score); highscore = score; } score = 0; vy = 0; playerX = 64; playerY = 0; started = 0; var advert=document.getElementById("ad"); advert.style.top = ""+parseInt(canvas.style.height); } if(!stopFall){ setTimeout(arguments.callee, 1000/FPS); } },1000/FPS); } </script> <div id="ad" style="height:200px; overflow:hidden; position:absolute; top:-200;left:0;"><iframe src="ads/ad.html" scrolling="no" frameBorder="0" id="iad" onload="this.width = window.innerWidth;" height="200"></iframe></div> </body> </html> 

由于某些原因,requestAnimationFrame()在Android上运行良好,但setTimeout()的运行速度比预期的要快。 对于其他遇到此问题的人,并且因为requestAnimationFrame()比设置间隔/超时更准确和更有效,所以只需替换所有

setTimeout(func,1000/FPS);

//it will (try to) run at a constant 60 FPS
requestAnimationFrame(func);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM