javascript - 连续跟踪触摸屏
问题描述
在学习 js 的时候,我做了这个。它在具有跟踪鼠标位置的计算机上工作(移动),但我无法将其集成到智能手机中。我希望它不断地随着触摸而移动。我想我需要使用触摸事件,有人可以帮我吗?另外我是新手,如果您发现任何可笑的错误并告诉我,我将非常感激!
// setup canvas
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width = window.innerWidth;
const height = canvas.height = window.innerHeight;
let Audio1 = new Audio("a.wav")
// function to generate random number
function random(min, max) {
const num = Math.floor(Math.random() * (max - min + 1)) + min;
return num;
}
class Shape {
constructor(x, y, velX, velY, size, color, exists) {
this.x = x;
this.y = y;
this.velX = velX;
this.velY = velY;
this.color = color;
this.size = size;
this.exists = exists;
}
}
class Ball extends Shape {
constructor(x, y, velX, velY, size, color, exists) {
super(x, y, velX, velY, size, color, exists)
}
draw() {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
ctx.fill();
}
update() {
if ((this.x + this.size) >= width) {
this.velX = -(this.velX);
}
if ((this.x - this.size) <= 0) {
this.velX = -(this.velX);
}
if ((this.y + this.size) >= height) {
this.velY = -(this.velY);
}
if ((this.y - this.size) <= 0) {
this.velY = -(this.velY);
}
this.x += this.velX;
this.y += this.velY;
}
collisionDetect() {
for (let j = 0; j < balls.length; j++) {
if (!(this === balls[j]) && balls[j].exists) {
const dx = this.x - balls[j].x;
const dy = this.y - balls[j].y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < this.size + balls[j].size) {
balls[j].color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')';
this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')';
this.velX = -(this.velX) + 1;
this.velY = -(this.velY);
balls[j].velX = (balls[j].velX);
balls[j].velY = (balls[j].velY)
}
}
}
}
}
let balls = [];
let i = balls.length;
for (i = 0; i < 10; i++) {
let size = random(2, 10);
let ball = new Ball(
// ball position always drawn at least one ball width
// away from the edge of the canvas, to avoid drawing errors
random(0 + size, width - size),
random(0 + size, height - size),
random(-9, 9),
random(-9, 9),
size,
'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')', true
);
balls.push(ball);
}
let dir = -10;
var pctOpen = 100;
class EvilCircle extends Shape {
constructor(x, y, velX, velY, size) {
super(x, y, velX, velY, size)
}
draw(pctOpen) {
// Convert percent open to a float
var fltOpen = pctOpen / 100;
// An arc which stops at a specific percent to allow for the
// open mouth to be drawn
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, (fltOpen * 0.2) * Math.PI, (2 - fltOpen * 0.2) * Math.PI);
// The line leading back to the center and then closing the
// path to finish the open mouth.
ctx.lineTo(this.x, this.y);
ctx.closePath();
// Fill pacman's head yellow
ctx.fillStyle = "#FF0";
ctx.fill();
// Outline the head
ctx.strokeStyle = '#000';
ctx.stroke();
// A circle for the eye
var angle = Math.PI * (0.3 + fltOpen * 0.2),
xDelta = (this.x + (this.size / 4)),
yDelta = (this.y - (this.size / 2));
ctx.beginPath();
ctx.arc(xDelta, yDelta, this.size / 5, 0, 2 * Math.PI);
ctx.fillStyle = "#000";
ctx.fill();
// Outline the eye
ctx.strokeStyle = '#FFF';
ctx.stroke();
}
checkBounds() {
if ((this.x + this.size) >= width) {
this.x = width - this.size;
}
if ((this.x - this.size) <= 0) {
this.x = this.size;
}
if ((this.y + this.size) >= height) {
this.y = height - this.size;
}
if ((this.y - this.size) <= 0) {
this.y = this.size;
}
}
setControls() {
this.x = window.event.clientX;
this.y = window.event.clientY;
}
setControls2() {
this.x = Touch.clientX;
this.y = Touch.clientY;
}
collisionDetect() {
for (let j = 0; j < balls.length; j++) {
if (!(this === balls[j]) && balls[j].exists) {
const dx = this.x - balls[j].x;
const dy = this.y - balls[j].y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < this.size + balls[j].size) {
balls[j].exists = false;
this.size += balls[j].size;
balls.splice(j, 1);
Audio1.play()
}
}
}
}
}
let EvilCircle1 = new EvilCircle(15, 15, 10, 10, 10);
document.querySelector('canvas').onmousemove = function () { EvilCircle1.setControls() };
document.querySelector('canvas').addEventListener("touchstart", EvilCircle1.setControls2())
document.querySelector('canvas').addEventListener("touchmove", EvilCircle1.setControls2())
document.querySelector('canvas').addEventListener("touchend", EvilCircle1.setControls2())
function loop() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
ctx.fillRect(0, 0, width, height);
for (let i = 0; i < balls.length; i++) {
balls[i].draw();
balls[i].update();
balls[i].collisionDetect();
}
EvilCircle1.draw(pctOpen += dir);
if (pctOpen % 100 == 0) {
dir = -dir;
}
EvilCircle1.checkBounds();
EvilCircle1.collisionDetect()
requestAnimationFrame(loop);
}
loop();
html, body {
margin: 0;
cursor: none;
}
html {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
height: 100%;
}
body {
overflow: hidden;
height: inherit;
}
h1 {
font-size: 22;
letter-spacing: -1px;
position: absolute;
margin: 0;
top: 20px;
left: 42.5%;
color: white;
}
<!DOCTYPE html>
<html>
<head>
<link rel="shortcut icon" href="#">
<meta charset="utf-8">
<title>Bouncing balls</title>
<link rel="stylesheet" href="egee.css">
</head>
<body>
<h1>Are you high?</h1>
<canvas></canvas>
<script src="eg.js"></script>
</body>
</html>
解决方案
这个:
document.querySelector('canvas').addEventListener("touchstart", EvilCircle1.setControls2())
调用的是返回的值EvilCircle1.setControls()
,而不是函数。您应该改为使用:
document.querySelector('canvas').addEventListener("touchstart", EvilCircle1.setControls2)
// setup canvas
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width = window.innerWidth;
const height = canvas.height = window.innerHeight;
let Audio1 = new Audio("a.wav")
// function to generate random number
function random(min, max) {
const num = Math.floor(Math.random() * (max - min + 1)) + min;
return num;
}
class Shape {
constructor(x, y, velX, velY, size, color, exists) {
this.x = x;
this.y = y;
this.velX = velX;
this.velY = velY;
this.color = color;
this.size = size;
this.exists = exists;
}
}
class Ball extends Shape {
constructor(x, y, velX, velY, size, color, exists) {
super(x, y, velX, velY, size, color, exists)
}
draw() {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
ctx.fill();
}
update() {
if ((this.x + this.size) >= width) {
this.velX = -(this.velX);
}
if ((this.x - this.size) <= 0) {
this.velX = -(this.velX);
}
if ((this.y + this.size) >= height) {
this.velY = -(this.velY);
}
if ((this.y - this.size) <= 0) {
this.velY = -(this.velY);
}
this.x += this.velX;
this.y += this.velY;
}
collisionDetect() {
for (let j = 0; j < balls.length; j++) {
if (!(this === balls[j]) && balls[j].exists) {
const dx = this.x - balls[j].x;
const dy = this.y - balls[j].y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < this.size + balls[j].size) {
balls[j].color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')';
this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')';
this.velX = -(this.velX) + 1;
this.velY = -(this.velY);
balls[j].velX = (balls[j].velX);
balls[j].velY = (balls[j].velY)
}
}
}
}
}
let balls = [];
let i = balls.length;
for (i = 0; i < 10; i++) {
let size = random(2, 10);
let ball = new Ball(
// ball position always drawn at least one ball width
// away from the edge of the canvas, to avoid drawing errors
random(0 + size, width - size),
random(0 + size, height - size),
random(-9, 9),
random(-9, 9),
size,
'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')', true
);
balls.push(ball);
}
let dir = -10;
var pctOpen = 100;
class EvilCircle extends Shape {
constructor(x, y, velX, velY, size) {
super(x, y, velX, velY, size)
}
draw(pctOpen) {
// Convert percent open to a float
var fltOpen = pctOpen / 100;
// An arc which stops at a specific percent to allow for the
// open mouth to be drawn
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, (fltOpen * 0.2) * Math.PI, (2 - fltOpen * 0.2) * Math.PI);
// The line leading back to the center and then closing the
// path to finish the open mouth.
ctx.lineTo(this.x, this.y);
ctx.closePath();
// Fill pacman's head yellow
ctx.fillStyle = "#FF0";
ctx.fill();
// Outline the head
ctx.strokeStyle = '#000';
ctx.stroke();
// A circle for the eye
var angle = Math.PI * (0.3 + fltOpen * 0.2),
xDelta = (this.x + (this.size / 4)),
yDelta = (this.y - (this.size / 2));
ctx.beginPath();
ctx.arc(xDelta, yDelta, this.size / 5, 0, 2 * Math.PI);
ctx.fillStyle = "#000";
ctx.fill();
// Outline the eye
ctx.strokeStyle = '#FFF';
ctx.stroke();
}
checkBounds() {
if ((this.x + this.size) >= width) {
this.x = width - this.size;
}
if ((this.x - this.size) <= 0) {
this.x = this.size;
}
if ((this.y + this.size) >= height) {
this.y = height - this.size;
}
if ((this.y - this.size) <= 0) {
this.y = this.size;
}
}
setControls() {
this.x = window.event.clientX;
this.y = window.event.clientY;
}
setControls2() {
this.x = Touch.clientX;
this.y = Touch.clientY;
}
collisionDetect() {
for (let j = 0; j < balls.length; j++) {
if (!(this === balls[j]) && balls[j].exists) {
const dx = this.x - balls[j].x;
const dy = this.y - balls[j].y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < this.size + balls[j].size) {
balls[j].exists = false;
this.size += balls[j].size;
balls.splice(j, 1);
Audio1.play()
}
}
}
}
}
let EvilCircle1 = new EvilCircle(15, 15, 10, 10, 10);
document.querySelector('canvas').onmousemove = function() {
EvilCircle1.setControls()
};
document.querySelector('canvas').addEventListener("touchstart", EvilCircle1.setControls2)
document.querySelector('canvas').addEventListener("touchmove", EvilCircle1.setControls2)
document.querySelector('canvas').addEventListener("touchend", EvilCircle1.setControls2)
function loop() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
ctx.fillRect(0, 0, width, height);
for (let i = 0; i < balls.length; i++) {
balls[i].draw();
balls[i].update();
balls[i].collisionDetect();
}
EvilCircle1.draw(pctOpen += dir);
if (pctOpen % 100 == 0) {
dir = -dir;
}
EvilCircle1.checkBounds();
EvilCircle1.collisionDetect()
requestAnimationFrame(loop);
}
loop();
html,
body {
margin: 0;
cursor: none;
}
html {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
height: 100%;
}
body {
overflow: hidden;
height: inherit;
}
h1 {
font-size: 22;
letter-spacing: -1px;
position: absolute;
margin: 0;
top: 20px;
left: 42.5%;
color: white;
}
<!DOCTYPE html>
<html>
<head>
<link rel="shortcut icon" href="#">
<meta charset="utf-8">
<title>Bouncing balls</title>
<link rel="stylesheet" href="egee.css">
</head>
<body>
<h1>Are you high?</h1>
<canvas></canvas>
<script src="eg.js"></script>
</body>
</html>
推荐阅读
- angular - Angular 多个项目的路由 url 被更改但页面未呈现
- c# - 通过键字典搜索
- c# - 嵌套集合属性更改时更改集合属性
- haskell - 当 lambda 中有常量值时,Haskell 急切地评估跟踪?
- c# - c# 和 vue 之间的 POST
- reactjs - 收到错误:在 Reactjs 挂钩中添加 deckGL 时无法反转矩阵
- angular - 拖放列表 - 不适用于我的数据结构(包括 stackblitz)
- rabbitmq - 在 rabbit 中是否允许具有读取权限的用户执行 queue.bind 操作
- python - 在 mac 上安装 flask_cors 和枕头时遇到问题
- python - 在 python 中将数据帧隐蔽到 sqlite 时出错