Meta Description" name="description" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>
/* FIX LAG: Sử dụng GPU để render giao diện */
body {
background: #000; margin: 0; overflow: hidden;
touch-action: none; -webkit-font-smoothing: antialiased;
}
#ui { position: absolute; width: 100%; text-align: center; color: #0f0; font: 20px Arial; top: 10px; pointer-events: none; }
canvas {
display: block; margin: 20px auto; background: #000;
box-shadow: 0 0 10px #222; transform: translateZ(0); /* Kích hoạt tăng tốc phần cứng */
}
.ctrls { display: grid; grid-template-areas: ". u ." "l d r"; gap: 10px; justify-content: center; margin-top: 5px; }
.b {
width: 65px; height: 65px; background: rgba(50,50,50,0.8);
border-radius: 15px; display: flex; justify-content: center;
align-items: center; color: #fff; font-size: 24px;
-webkit-tap-highlight-color: transparent; /* Xóa khung xanh khi bấm trên iPhone */
}
</style>
</head>
<body>
<div id="ui">SCORE: <span id="s">0</span></div>
<canvas id="g"></canvas>
<div class="ctrls">
<div class="b" style="grid-area:u" ontouchstart="move('U')">▲</div>
<div class="b" style="grid-area:l" ontouchstart="move('L')">◀</div>
<div class="b" style="grid-area:d" ontouchstart="move('D')">▼</div>
<div class="b" style="grid-area:r" ontouchstart="move('R')">▶</div>
</div>
<script>
const cvs = document.getElementById("g"), ctx = cvs.getContext("2d", { alpha: false }); // Tăng tốc bằng cách tắt alpha channel
const scoreEl = document.getElementById("s");
const size = 20;
let snk = [{x:10, y:10}], fd = {x:5, y:5}, dr = "R", nxt = "R", sc = 0, lastT = 0;
// Tự động chỉnh kích thước canvas mượt hơn
cvs.width = 360; cvs.height = 360;
const tile = cvs.width / size;
function move(d) {
if(d=="L" && dr!="R") nxt="L"; if(d=="U" && dr!="D") nxt="U";
if(d=="R" && dr!="L") nxt="R"; if(d=="D" && dr!="U") nxt="D";
}
// FIX LAG: Sử dụng requestAnimationFrame thay vì setInterval
function loop(t) {
requestAnimationFrame(loop);
if (t - lastT < 120) return; // Khóa FPS ở mức ổn định (~8 FPS cho rắn)
lastT = t;
dr = nxt;
let h = {...snk[0]};
if(dr=="L") h.x--; if(dr=="U") h.y--; if(dr=="R") h.x++; if(dr=="D") h.y++;
// Xuyên tường
if(h.x<0) h.x=size-1; if(h.x>=size) h.x=0;
if(h.y<0) h.y=size-1; if(h.y>=size) h.y=0;
if(snk.some((p,i)=>i!==0 && p.x==h.x && p.y==h.y)) return location.reload();
snk.unshift(h);
if(h.x==fd.x && h.y==fd.y) {
sc += 10; scoreEl.innerText = sc;
fd = {x:Math.floor(Math.random()*size), y:Math.floor(Math.random()*size)};
} else snk.pop();
render();
}
function render() {
ctx.fillStyle = "#000"; ctx.fillRect(0,0,cvs.width,cvs.height);
ctx.fillStyle = "#f00"; ctx.beginPath(); ctx.arc(fd.x*tile+tile/2, fd.y*tile+tile/2, tile/2-2, 0, 7); ctx.fill();
ctx.fillStyle = "#0f0";
snk.forEach(p => ctx.fillRect(p.x*tile+1, p.y*tile+1, tile-2, tile-2));
}
requestAnimationFrame(loop);
</script>
</body>
</html>1
1
4KB
4KB
202.0ms
596.0ms
204.0ms