Javascript - 将对象指向鼠标
Javascript - Point object towards mouse
我试图让这个玩家角色指向鼠标指针,但它根本没有移动。我不知道从哪里开始,有人可以帮我吗?
完整代码如下:
我需要帮助的部分是播放器对象中的 updatevalues() 函数 (javascript)
var canvas = document.getElementById("tanks-canvas");
var game = canvas.getContext("2d");
canvas.height = screen.height / 1.175;
canvas.width = screen.width / 1.05;
game.translate(canvas.width / 2, canvas.height / 2);
clear();
txt(0, 0, "Loading...", "100px georgia", "rgb(0, 0, 0)");
var mousex = 0;
var mousey = 0;
var angle;
var mode = "menu";
var key = [];
var scale = 1;
for (i = 0; i <= 255; i += 1) {
key[i] = false;
}
/*
Class Definition:
*/
// Bodies:
var circle_body = {
x: 0,
y: 0,
radius: 100,
draw: function() {
this.setvals();
circ(this.x, this.y, this.radius, "rgb(0, 150, 255)");
},
setvals: function() {
this.radius = 25 * scale;
}
};
// Turrents:
var rect_turrent = {
x: 0,
y: 0,
width: 0,
height: 0,
offset: 0,
draw: function() {
this.setvals();
rect(this.x + this.offset, this.y, this.width, this.height, "rgb(150, 150, 150)");
},
setvals: function() {
this.offset = 35 * scale;
this.width = 30 * scale;
this.height = 15 * scale;
}
};
// Classes:
var base = {
draw: function() {
rect_turrent.draw();
circle_body.draw();
}
};
/*
Functions & Objects
*/
function txt(x, y, content, font, color) {
game.fillStyle = color;
game.textAlign = "center";
game.font = font;
game.fillText(content, x, y);
}
function rect(x, y, width, height, color) {
x -= width / 2;
y -= height / 2;
game.fillStyle = color;
game.strokeStyle = color.black;
game.fillRect(x, y, width, height);
game.strokeRect(x, y, width, height);
}
function img(x, y, img) {
x -= img.width / 2;
y -= img.height / 2;
game.drawImage(img, x, y);
}
function circ(x, y, radius, color) {
game.fillStyle = color;
game.strokeStyle = color.black;
game.beginPath();
game.arc(x, y, radius, 0, Math.PI * 2);
game.fill();
game.stroke();
}
function clear() {
rect(0, 0, canvas.width + 10, canvas.height + 10, "rgb(200, 200, 200)");
}
/*
IMPORTANT: Player Character:
*/
var player = {
// Variables
x: 0,
y: 0,
type: "base",
angle: 0,
autorotate: false,
// Functions
update: function() {
this.updatevalues();
game.save();
game.rotate(this.angle);
this.draw();
game.restore();
txt(0, -100, "Mouse x: " + mousex + " | Mouse y: " + mousey + " | Angle: " + this.angle, "20px georgia", "rgb(0, 0, 0)");
},
draw: function() {
if (this.type == "base") {
base.draw();
}
},
updatevalues: function() {
this.offsetY = mousex - this.x;
this.offsetX = mousey - this.y;
this.angle = Math.atan(mousex / mousey);
}
};
function menu() {
player.update();
}
function update() {
if (mode == "menu") {
menu();
}
clear();
player.update();
}
/*
Intervals:
*/
game.interval = setInterval(update, 50);
/*
Event Listeners
*/
document.addEventListener("keydown", function(event) {
for (i = 0; i <= 255; i++) {
if (event.keyCode == i) {
key[i] = true;
}
}
});
document.addEventListener("keyup", function(event) {
for (i = 0; i <= 255; i++) {
key[i] = false;
}
});
document.addEventListener("mousemove", function(event) {
mousex = event.offsetX - (canvas.width / 2);
mousey = (canvas.height / 2) - event.offsetY;
});
/* Everything */
* {
transition: 1s;
}
body {
background-color: rgb(100, 100, 100);
}
/* Flexbox: */
.flex-container {
display: flex;
flex-direction: column;
padding: 5vw;
}
#header {
flex-direction: row;
background-color: rgb(200, 0, 0);
}
#main {
background-color: rgb(200, 150, 50);
}
#navbar {
z-index: 1;
overflow: hidden;
background-color: rgb(200, 200, 200);
position: fixed;
top: 0;
width: 100%
}
/* Images */
img {
display: block;
margin-left: auto;
margin-right: auto;
}
.imgcontainer {
position: relative;
width: 50%
}
.imgoverlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 100, 200, 0.75);
overflow: hidden;
width: 100%;
height: 0;
}
.imgtext {
text-align: center;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: rgba(200, 200, 200, 0.75);
}
.imgcontainer:hover .imgoverlay {
height: 100%;
}
.image {
width: 100%;
height: auto;
}
/* Navigation Menu */
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.75);
overflow-x: hidden;
padding-top: 5vw;
}
/* The navigation menu links */
.sidenav a {
padding: 1vw 1vw 1vw 4vw;
text-decoration: none;
overflow-x: hidden;
font-size: 2vw;
color: rgba(150, 150, 150, 0.75);
display: block;
}
/* When you mouse over the navigation links, change their color */
.sidenav a:hover {
color: rgb(255, 255, 255);
}
/* Position and style the close button (top right corner) */
.sidenav .closebtn {
position: absolute;
top: 0;
right: 1vw;
font-size: 5vw;
margin-left: 50px;
}
/* Styles: */
h1 {
font: 10vw courier;
color: rgb(0, 0, 200);
text-align: center;
padding: none;
}
h2 {
font: 9vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
h3 {
font: 8vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
h4 {
font: 7vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
h5 {
font: 6vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
h6 {
font: 5vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
p {
font: 2vw georgia;
color: rgb(0, 100, 0);
text-align: justify;
}
/* Other */
.link {
color: rgb(150, 150, 150);
}
.link:hover {
color: rgb(255, 255, 255);
}
code {
font-family: courier;
}
canvas {
padding: none;
margin-left: auto;
margin-right: auto;
margin-top: auto;
margin-bottom: auto;
display: block;
background-color: rgb(255, 255, 255);
border: 5px solid rgb(0, 0, 0);
}
<!DOCTYPE html>
<html>
<head>
<title>Game Goods</title>
<link rel="stylesheet" href="style.css">
<script src="functions.js"></script>
</head>
<body>
<!-- Game -->
<canvas id="tanks-canvas"></canvas>
<script src="tanks-script.js"></script>
</body>
</html>
(如果你运行它,点击"full page",否则它不会起作用。)
编辑 10-30-18:我已经根据 Helder 的回答更改了代码。至少 mousex 现在能用了……
编辑 10-31-18:我将 mousex 和 mousey 更改为当鼠标位于中间时也位于坐标 0、0。 canvas 现在就像一个坐标平面。我还添加了调试文本(如果你 运行 代码片段,你可以看到它)。
你的角度计算有误,看看这个例子...
这绝不是确切的解决方案,但应该会让您朝着正确的方向前进,我在计算中只使用了 mousex。
var canvas = document.getElementById("tanks-canvas");
var game = canvas.getContext("2d");
canvas.height = canvas.width = 170;
game.translate(canvas.width / 2, canvas.height / 2);
clear();
var mousex = 0;
var mousey = 0;
var angle;
var mode = "menu";
var key = [];
var scale = 1;
for (i = 0; i <= 255; i += 1) {
key[i] = false;
}
var player = {
x: 0, y: 0,
type: "base",
angle: 0,
autorotate: false,
update: function() {
this.updatevalues();
game.save()
game.rotate(this.angle);
this.draw();
game.restore();
},
updatevalues: function() {
this.offsetY = mousex - this.x;
this.offsetX = mousey - this.y;
this.angle = 360 * Math.sin(mousex/30000);
},
draw: function() {
if (this.type == "base") {
base.draw();
}
}
};
/*
Class Definition:
*/
// Bodies:
var circle_body = {
x: 0,
y: 0,
radius: 100,
draw: function() {
this.setvals();
circ(this.x, this.y, this.radius, "rgb(0, 150, 255)");
},
setvals: function() {
this.radius = 25 * scale;
}
};
// Turrents:
var rect_turrent = {
x: 0,
y: 0,
width: 0,
height: 0,
offset: 0,
draw: function() {
this.setvals();
rect(this.x + this.offset, this.y, this.width, this.height, "rgb(150, 150, 150)");
},
setvals: function() {
this.offset = 35 * scale;
this.width = 30 * scale;
this.height = 15 * scale;
}
};
// Classes:
var base = {
draw: function() {
rect_turrent.draw();
circle_body.draw();
}
};
/*
Functions & Objects
*/
function rect(x, y, width, height, color) {
x -= width / 2;
y -= height / 2;
game.fillStyle = color;
game.strokeStyle = color.black;
game.fillRect(x, y, width, height);
game.strokeRect(x, y, width, height);
}
function circ(x, y, radius, color) {
game.fillStyle = color;
game.strokeStyle = color.black;
game.beginPath();
game.arc(x, y, radius, 0, Math.PI * 2);
game.fill();
game.stroke();
}
function clear() {
rect(0, 0, canvas.width + 10, canvas.height + 10, "rgb(200, 200, 200)");
}
function update() {
clear();
player.update();
}
game.interval = setInterval(update, 50);
document.addEventListener("mousemove", function(event) {
mousex = event.offsetX;
mousey = event.offsetY;
});
<canvas id="tanks-canvas"></canvas>
我在数学老师的帮助下找到了这个公式和一个不同的问题。
公式为
Math.atan2(-y, x);
我试图让这个玩家角色指向鼠标指针,但它根本没有移动。我不知道从哪里开始,有人可以帮我吗?
完整代码如下:
我需要帮助的部分是播放器对象中的 updatevalues() 函数 (javascript)
var canvas = document.getElementById("tanks-canvas");
var game = canvas.getContext("2d");
canvas.height = screen.height / 1.175;
canvas.width = screen.width / 1.05;
game.translate(canvas.width / 2, canvas.height / 2);
clear();
txt(0, 0, "Loading...", "100px georgia", "rgb(0, 0, 0)");
var mousex = 0;
var mousey = 0;
var angle;
var mode = "menu";
var key = [];
var scale = 1;
for (i = 0; i <= 255; i += 1) {
key[i] = false;
}
/*
Class Definition:
*/
// Bodies:
var circle_body = {
x: 0,
y: 0,
radius: 100,
draw: function() {
this.setvals();
circ(this.x, this.y, this.radius, "rgb(0, 150, 255)");
},
setvals: function() {
this.radius = 25 * scale;
}
};
// Turrents:
var rect_turrent = {
x: 0,
y: 0,
width: 0,
height: 0,
offset: 0,
draw: function() {
this.setvals();
rect(this.x + this.offset, this.y, this.width, this.height, "rgb(150, 150, 150)");
},
setvals: function() {
this.offset = 35 * scale;
this.width = 30 * scale;
this.height = 15 * scale;
}
};
// Classes:
var base = {
draw: function() {
rect_turrent.draw();
circle_body.draw();
}
};
/*
Functions & Objects
*/
function txt(x, y, content, font, color) {
game.fillStyle = color;
game.textAlign = "center";
game.font = font;
game.fillText(content, x, y);
}
function rect(x, y, width, height, color) {
x -= width / 2;
y -= height / 2;
game.fillStyle = color;
game.strokeStyle = color.black;
game.fillRect(x, y, width, height);
game.strokeRect(x, y, width, height);
}
function img(x, y, img) {
x -= img.width / 2;
y -= img.height / 2;
game.drawImage(img, x, y);
}
function circ(x, y, radius, color) {
game.fillStyle = color;
game.strokeStyle = color.black;
game.beginPath();
game.arc(x, y, radius, 0, Math.PI * 2);
game.fill();
game.stroke();
}
function clear() {
rect(0, 0, canvas.width + 10, canvas.height + 10, "rgb(200, 200, 200)");
}
/*
IMPORTANT: Player Character:
*/
var player = {
// Variables
x: 0,
y: 0,
type: "base",
angle: 0,
autorotate: false,
// Functions
update: function() {
this.updatevalues();
game.save();
game.rotate(this.angle);
this.draw();
game.restore();
txt(0, -100, "Mouse x: " + mousex + " | Mouse y: " + mousey + " | Angle: " + this.angle, "20px georgia", "rgb(0, 0, 0)");
},
draw: function() {
if (this.type == "base") {
base.draw();
}
},
updatevalues: function() {
this.offsetY = mousex - this.x;
this.offsetX = mousey - this.y;
this.angle = Math.atan(mousex / mousey);
}
};
function menu() {
player.update();
}
function update() {
if (mode == "menu") {
menu();
}
clear();
player.update();
}
/*
Intervals:
*/
game.interval = setInterval(update, 50);
/*
Event Listeners
*/
document.addEventListener("keydown", function(event) {
for (i = 0; i <= 255; i++) {
if (event.keyCode == i) {
key[i] = true;
}
}
});
document.addEventListener("keyup", function(event) {
for (i = 0; i <= 255; i++) {
key[i] = false;
}
});
document.addEventListener("mousemove", function(event) {
mousex = event.offsetX - (canvas.width / 2);
mousey = (canvas.height / 2) - event.offsetY;
});
/* Everything */
* {
transition: 1s;
}
body {
background-color: rgb(100, 100, 100);
}
/* Flexbox: */
.flex-container {
display: flex;
flex-direction: column;
padding: 5vw;
}
#header {
flex-direction: row;
background-color: rgb(200, 0, 0);
}
#main {
background-color: rgb(200, 150, 50);
}
#navbar {
z-index: 1;
overflow: hidden;
background-color: rgb(200, 200, 200);
position: fixed;
top: 0;
width: 100%
}
/* Images */
img {
display: block;
margin-left: auto;
margin-right: auto;
}
.imgcontainer {
position: relative;
width: 50%
}
.imgoverlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 100, 200, 0.75);
overflow: hidden;
width: 100%;
height: 0;
}
.imgtext {
text-align: center;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: rgba(200, 200, 200, 0.75);
}
.imgcontainer:hover .imgoverlay {
height: 100%;
}
.image {
width: 100%;
height: auto;
}
/* Navigation Menu */
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.75);
overflow-x: hidden;
padding-top: 5vw;
}
/* The navigation menu links */
.sidenav a {
padding: 1vw 1vw 1vw 4vw;
text-decoration: none;
overflow-x: hidden;
font-size: 2vw;
color: rgba(150, 150, 150, 0.75);
display: block;
}
/* When you mouse over the navigation links, change their color */
.sidenav a:hover {
color: rgb(255, 255, 255);
}
/* Position and style the close button (top right corner) */
.sidenav .closebtn {
position: absolute;
top: 0;
right: 1vw;
font-size: 5vw;
margin-left: 50px;
}
/* Styles: */
h1 {
font: 10vw courier;
color: rgb(0, 0, 200);
text-align: center;
padding: none;
}
h2 {
font: 9vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
h3 {
font: 8vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
h4 {
font: 7vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
h5 {
font: 6vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
h6 {
font: 5vw courier;
color: rgb(0, 0, 150);
text-align: center;
padding: none;
}
p {
font: 2vw georgia;
color: rgb(0, 100, 0);
text-align: justify;
}
/* Other */
.link {
color: rgb(150, 150, 150);
}
.link:hover {
color: rgb(255, 255, 255);
}
code {
font-family: courier;
}
canvas {
padding: none;
margin-left: auto;
margin-right: auto;
margin-top: auto;
margin-bottom: auto;
display: block;
background-color: rgb(255, 255, 255);
border: 5px solid rgb(0, 0, 0);
}
<!DOCTYPE html>
<html>
<head>
<title>Game Goods</title>
<link rel="stylesheet" href="style.css">
<script src="functions.js"></script>
</head>
<body>
<!-- Game -->
<canvas id="tanks-canvas"></canvas>
<script src="tanks-script.js"></script>
</body>
</html>
(如果你运行它,点击"full page",否则它不会起作用。)
编辑 10-30-18:我已经根据 Helder 的回答更改了代码。至少 mousex 现在能用了……
编辑 10-31-18:我将 mousex 和 mousey 更改为当鼠标位于中间时也位于坐标 0、0。 canvas 现在就像一个坐标平面。我还添加了调试文本(如果你 运行 代码片段,你可以看到它)。
你的角度计算有误,看看这个例子...
这绝不是确切的解决方案,但应该会让您朝着正确的方向前进,我在计算中只使用了 mousex。
var canvas = document.getElementById("tanks-canvas");
var game = canvas.getContext("2d");
canvas.height = canvas.width = 170;
game.translate(canvas.width / 2, canvas.height / 2);
clear();
var mousex = 0;
var mousey = 0;
var angle;
var mode = "menu";
var key = [];
var scale = 1;
for (i = 0; i <= 255; i += 1) {
key[i] = false;
}
var player = {
x: 0, y: 0,
type: "base",
angle: 0,
autorotate: false,
update: function() {
this.updatevalues();
game.save()
game.rotate(this.angle);
this.draw();
game.restore();
},
updatevalues: function() {
this.offsetY = mousex - this.x;
this.offsetX = mousey - this.y;
this.angle = 360 * Math.sin(mousex/30000);
},
draw: function() {
if (this.type == "base") {
base.draw();
}
}
};
/*
Class Definition:
*/
// Bodies:
var circle_body = {
x: 0,
y: 0,
radius: 100,
draw: function() {
this.setvals();
circ(this.x, this.y, this.radius, "rgb(0, 150, 255)");
},
setvals: function() {
this.radius = 25 * scale;
}
};
// Turrents:
var rect_turrent = {
x: 0,
y: 0,
width: 0,
height: 0,
offset: 0,
draw: function() {
this.setvals();
rect(this.x + this.offset, this.y, this.width, this.height, "rgb(150, 150, 150)");
},
setvals: function() {
this.offset = 35 * scale;
this.width = 30 * scale;
this.height = 15 * scale;
}
};
// Classes:
var base = {
draw: function() {
rect_turrent.draw();
circle_body.draw();
}
};
/*
Functions & Objects
*/
function rect(x, y, width, height, color) {
x -= width / 2;
y -= height / 2;
game.fillStyle = color;
game.strokeStyle = color.black;
game.fillRect(x, y, width, height);
game.strokeRect(x, y, width, height);
}
function circ(x, y, radius, color) {
game.fillStyle = color;
game.strokeStyle = color.black;
game.beginPath();
game.arc(x, y, radius, 0, Math.PI * 2);
game.fill();
game.stroke();
}
function clear() {
rect(0, 0, canvas.width + 10, canvas.height + 10, "rgb(200, 200, 200)");
}
function update() {
clear();
player.update();
}
game.interval = setInterval(update, 50);
document.addEventListener("mousemove", function(event) {
mousex = event.offsetX;
mousey = event.offsetY;
});
<canvas id="tanks-canvas"></canvas>
我在数学老师的帮助下找到了这个公式和一个不同的问题。
公式为
Math.atan2(-y, x);