首页 > 解决方案 > 连续跟踪触摸屏

问题描述

在学习 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>

标签: javascript

解决方案


这个:

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>


推荐阅读