javascript - 为什么我的立方体显示的距离是光标的两倍?
问题描述
我是一名 HTML 初学者,我正在尝试制作一个可以用光标控制播放器的游戏。但是,下面的页面似乎显示它比光标远两倍。我的代码错了吗?如果是,哪里错了?非常感谢。
const canvas = document.getElementById('screen');
const ctx = canvas.getContext('2d');
var x = 0;
var y = 0;
canvas.style.top = 0;
canvas.style.left = 0;
function drawPlayer() {
ctx.fillStyle = "yellow";
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.fillRect(x, y, 10, 10);
ctx.fillStyle = "white";
ctx.strokeStyle = "white";
ctx.lineWidth = 0;
ctx.fillRect(x + 1, y + 1, 3, 3);
ctx.fillRect(x + 6, y + 1, 3, 3);
ctx.fillStyle = "black";
ctx.strokeStyle = "black";
ctx.lineWidth = 0;
ctx.fillRect(x + 2, y + 2, 2, 2);
ctx.fillRect(x + 7, y + 2, 2, 2);
ctx.fillStyle = "red";
ctx.strokeStyle = "red";
ctx.lineWidth = 0;
ctx.fillRect(x + 2, y + 6, 6, 2);
}
function handle(event) {
x = event.offsetX;
y = event.offsetY;
}
setInterval(function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPlayer();
}, 10)
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cube Quest</title>
<style>
canvas {
width: 100%;
height: 100%;
position: absolute;
}
</style>
<script src="game.js"></script>
</head>
<body>
<canvas id="screen" onmousemove="handle(event)"></canvas>
</body>
</html>
解决方案
That is because you will need to define the canvas width and height manually, otherwise it falls back to the default values of 300px for width and 150px for height, i.e.:
// Specify the dimensions of the canvas
ctx.canvas.width = canvas.clientWidth;
ctx.canvas.height = canvas.clientHeight;
You might also want to consider setting the canvas width and height when the viewport is resized. See working example here:
const canvas = document.getElementById('screen');
const ctx = canvas.getContext('2d');
var x = 0;
var y = 0;
canvas.style.top = '0px';
canvas.style.left = '0px';
function setCanvasSize() {
// Specify the dimensions of the canvas
ctx.canvas.width = canvas.clientWidth;
ctx.canvas.height = canvas.clientHeight;
}
// Set dimensions at runtime
setCanvasSize();
// Set dimensions when window is resized
window.addEventListener('resize', function () {
setCanvasSize();
});
function drawPlayer() {
ctx.fillStyle = "yellow";
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.fillRect(x, y, 10, 10);
ctx.fillStyle = "white";
ctx.strokeStyle = "white";
ctx.lineWidth = 0;
ctx.fillRect(x + 1, y + 1, 3, 3);
ctx.fillRect(x + 6, y + 1, 3, 3);
ctx.fillStyle = "black";
ctx.strokeStyle = "black";
ctx.lineWidth = 0;
ctx.fillRect(x + 2, y + 2, 2, 2);
ctx.fillRect(x + 7, y + 2, 2, 2);
ctx.fillStyle = "red";
ctx.strokeStyle = "red";
ctx.lineWidth = 0;
ctx.fillRect(x + 2, y + 6, 6, 2);
}
function handle(event) {
x = event.offsetX;
y = event.offsetY;
}
setInterval(function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPlayer();
}, 10)
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cube Quest</title>
<style>
canvas {
width: 100%;
height: 100%;
position: absolute;
}
</style>
<script src="game.js"></script>
</head>
<body>
<canvas id="screen" onmousemove="handle(event)"></canvas>
</body>
</html>
Personally, though, I would not try to redraw the canvas using setInterval
, because you only want to redraw when mousemove is detected. Your code can be further improved by simply listening to the mousemove event on the canvas element:
const canvas = document.getElementById('screen');
const ctx = canvas.getContext('2d');
var x = 0;
var y = 0;
canvas.style.top = '0px';
canvas.style.left = '0px';
function setCanvasSize() {
// Specify the dimensions of the canvas
ctx.canvas.width = canvas.clientWidth;
ctx.canvas.height = canvas.clientHeight;
}
// Set dimensions at runtime
setCanvasSize();
// Set dimensions when window is resized
window.addEventListener('resize', function () {
setCanvasSize();
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPlayer();
});
function drawPlayer() {
ctx.fillStyle = "yellow";
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.fillRect(x, y, 10, 10);
ctx.fillStyle = "white";
ctx.strokeStyle = "white";
ctx.lineWidth = 0;
ctx.fillRect(x + 1, y + 1, 3, 3);
ctx.fillRect(x + 6, y + 1, 3, 3);
ctx.fillStyle = "black";
ctx.strokeStyle = "black";
ctx.lineWidth = 0;
ctx.fillRect(x + 2, y + 2, 2, 2);
ctx.fillRect(x + 7, y + 2, 2, 2);
ctx.fillStyle = "red";
ctx.strokeStyle = "red";
ctx.lineWidth = 0;
ctx.fillRect(x + 2, y + 6, 6, 2);
}
function handle(event) {
x = event.offsetX;
y = event.offsetY;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPlayer();
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cube Quest</title>
<style>
canvas {
width: 100%;
height: 100%;
position: absolute;
}
</style>
</head>
<body>
<canvas id="screen" onmousemove="handle(event)"></canvas>
</body>
</html>
推荐阅读
- html - div 宽度不包含换行符文本
- react-i18next - 根据当前路由预取 i18next 翻译文件
- apache-spark - 400 : Bad Request, py4j.protocol.Py4JJavaError: An error occurred while calling o44.save
- javascript - 如何使用 javascript 从 api 读取 JSON 数据
- c# - 如何从控制器调用构造函数中具有参数(接口)的属性
- xml - 在 XSL 中添加子元素以进行转换
- angular - 从枚举打字稿创建空对象
- mysql - 在这种情况下如何获取表名
- python - 使用 SqlAchemy 创建表时未创建序列
- ml.net - ml.net pipeline.fit 在数据集中的特定行号后没有响应