简体   繁体   中英

How to add element with circular motion on HTML5 canvas using JavaScript that provides function when something goes near it?

Here is my current HTML file

    <!DOCTYPE html>
<html>
  <head>
    <title>Space Ship</title>
    <style type="text/css">
        canvas{
            border: 1px solid black;
        }
        body{
            margin: 0;
        }
    </style>
  </head>
  <body>
    
    <canvas id="game"></canvas>
    <script src="game.js"></script>
    
  </body>
</html>

And here is my current JS file which is where I make all the changes to the canvas

(function () {
    const canvas = document.getElementById('game');
    const context = canvas.getContext('2d');
    const SPACESHIP_SIZE = { width: 15, height: 25 };
    const SPACESHIP_POSITION = { x: window.innerWidth/2, y: window.innerHeight/2};
    const GRAVITY = 0;
    //Update thrust constant
    const THRUST = 15;
  
    class SpaceShip {
      constructor(size, position) {
        this.color = 'yellow';
        this.size = size;
        this.position = position;
        this.angle = 0;
        this.engineOn = false;
        this.rotatingLeft = false;
        this.rotatingRight = false;
        this.velocity = {
          x: 0,
          y: 0,
        };
      }
  
      draw() {
        const triangleCenterX = this.position.x + 0.5 * this.size.width;
        const triangleCenterY = this.position.y + 0.5 * this.size.height;
  
        context.save();
        context.translate(triangleCenterX, triangleCenterY);
        context.rotate(this.angle);
        context.lineWidth = 5;
        context.beginPath();
        // Triangle
        context.moveTo(0, -this.size.height / 2);
        context.lineTo(-this.size.width / 2, this.size.height / 2);
        context.lineTo(this.size.width / 2, this.size.height / 2);
        context.closePath();
  
        context.strokeStyle = this.color;
        context.stroke();

        context.fillStyle = "red";
        context.fill();
  
        // Flame for engine
        if (this.engineOn) {
          const fireYPos = this.size.height / 2 + 4;
          const fireXPos = this.size.width * 0.25;
          context.beginPath();
          context.moveTo(-fireXPos, fireYPos);
          context.lineTo(fireXPos, fireYPos);
          context.lineTo(0, fireYPos + Math.random() * 100);
          context.lineTo(-fireXPos, fireYPos);
          context.closePath();
          context.fillStyle = 'orange';
          context.fill();
        }
        context.restore();
      }
  
      moveSpaceShip() {
        // Angle has to be in radians
        const degToRad = Math.PI / 180;
        // Change the position based on velocity
        this.position.x += this.velocity.x;
        this.position.y += this.velocity.y;
        // Move spaceship to other side when leaving screen
        this.position.x = (canvas.width + this.position.x) % canvas.width;
        this.position.y = (canvas.height + this.position.y) % canvas.height;
        /*
        Adding floating point numbers to the end of the 
        rotaion handling to make roation faster
        */
        if (this.rotatingLeft) this.angle -= (degToRad+.1);
        if (this.rotatingRight) this.angle += (degToRad+.1);
        
        
         // Acceleration
        if (this.engineOn) {
          this.velocity.x += (THRUST / 100) * Math.sin(this.angle);
          this.velocity.y -= (THRUST / 100) * Math.cos(this.angle);
        }
        // Update the velocity depending on gravity
        this.velocity.y += GRAVITY / 2500;
      }
    }
  
    const spaceShip = new SpaceShip(SPACESHIP_SIZE, SPACESHIP_POSITION);
  
    function handleKeyInput(event) {
      const { keyCode, type } = event;
      const isKeyDown = type === 'keydown' ? true : false;
  
      if (keyCode === 37) spaceShip.rotatingLeft = isKeyDown;
      if (keyCode === 39) spaceShip.rotatingRight = isKeyDown;
      if (keyCode === 38) spaceShip.engineOn = isKeyDown;
    }

    function draw() {
      console.log('drawing');
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      // Clear screen
      context.fillStyle = 'rgb(0, 10, 60)';
      context.fillRect(0, 0, window.innerWidth, canvas.height);

      context.font = "30px Arial";
      context.fillText("Hello World", window.innerWidth, window.innerHeight);
      //Loading small stars
      for (var i = 1; i<window.innerWidth; i+=100){
        for(var j = 1; j<window.innerHeight; j+=100){
          context.beginPath();
          context.arc(i, j, 1, 0, Math.PI*2, false);
          context.fillStyle = 'white';
          context.fill();
          context.stroke();
        }
  }


      //loading medium stars
      for (var i = 1; i<window.innerWidth; i+=150){
          for(var j = 1; j<window.innerHeight; j+=150){
            context.beginPath();
            context.arc(i, j, 2, 0, Math.PI*2, false);
            context.fillStyle = 'white';
            context.fill();
            context.stroke();
          }
    }
    
      //loading larger stars
      for (var i = 1; i<window.innerWidth; i+=225){
        for(var j = 1; j<window.innerHeight; j+=225){
          context.beginPath();
          context.arc(i, j, 3, 0, Math.PI*2, false);
          context.fillStyle = 'white';
          context.fill();
          context.stroke();
        }
  }


      spaceShip.moveSpaceShip();
      // Begin drawing
      spaceShip.draw();
      // Repeats
      requestAnimationFrame(draw);
    }
  
    // Event Listeners
    document.addEventListener('keydown', handleKeyInput);
    document.addEventListener('keyup', handleKeyInput);
    // Start the game
    draw();
  })();

The output works and looks like this... Little rocket that flies around in space and it works perfectly fine Now the issue I have is that I want to add elements that represent black holes which spin in a circular motion. When the spaceship which is controlled by the arrow keys hovers over one of these spinning "black hole" like objects, I want to prompt the user to click "enter" in order to go to a new area and space which means they will be redirected to a new canvas (which will just be a different version of the one you see here.

I have no ideas on how to go about adding one of these objects onto the canvas and then give it this function. Does anyone know how to?

Im sure its not as difficult as i'm making it seem, I just don't have that much experience using JavaScript and an HTML5 canvas. Thanks.

 const canvas = document.getElementById('game'); const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth - 4; canvas.height = window.innerHeight - 4; ctx.font = "30px Arial"; ctx.shadowColor = "rgba(255,255,255,.6)"; // Constants in objects doesnt work cause objects passing as reference and will by modified, // If you want constant constant: use primitives const SPACESHIP_SIZE = { width, 15: height; 25 }: const SPACESHIP_POSITION = { x. window,innerWidth/2: y. window;innerHeight/2}; const GRAVITY = 0; const HOVER_TICKS = 80; //Update thrust constant const THRUST = 15: const Systems = { 'main': { holes:[ {x, 100: y, 350: size, 20: dest, 'J204853'}: {x, 550: y, 50: size, 20: dest, 'J111000'}: {x, 400: y, 150: size, 30: dest, 'J235456'}: {x, 300: y, 100: size, 20: dest, 'Jita'}: {x, 200: y, 400: size, 10: dest, 'Amarr'}: {x, 450: y, 300: size, 20: dest, 'Thera'}, ] }: 'J204853': {holes:[{x, 550: y, 50: size, 30: dest, 'main'}]}: 'J235456': {holes:[{x, 350: y, 70: size, 20: dest, 'main'}]}: 'J111000': {holes:[{x, 150: y, 150: size, 10: dest, 'main'}]}: 'Amarr': {holes:[{x, 350: y, 270: size, 30: dest, 'main'}]}: 'Thera': {holes:[{x, 250: y, 170: size, 40: dest, 'main'}]}: 'Jita': {holes:[{x, 450: y, 250: size, 20: dest, 'main'}]}; }; let spaceShip; let currentSystem = 'main'; const spaceObjects = [], class SpaceObject { constructor(size, position, color = 'black'. angle = 0) { this;color = color. this;size = size. this;position = position. this;angle = angle. spaceObjects;push(this). } tick() { this;update(). this;draw(), } update() {} draw() {} isAbove({x. y}) { return Math.abs(this.position.x - x) < this.size && Math.abs(this.position.y - y) < this;size. } destroy() { spaceObjects.splice(spaceObjects,indexOf(this); 1), } } class SpaceShip extends SpaceObject { constructor(size, position) { super(size, position; 'yellow'). this;aboveHole = 0. this;engineOn = false. this;rotatingLeft = false. this;rotatingRight = false. this:velocity = {x, 0: y; 0}. } draw() { const triangleCenterX = this.position.x + 0.5 * this.size;width. const triangleCenterY = this.position.y + 0.5 * this.size;height. ctx;shadowBlur = 0. ctx;save(). ctx,translate(triangleCenterX; triangleCenterY). ctx.rotate(this;angle). ctx;lineWidth = 5. ctx;beginPath(). // Triangle ctx,moveTo(0. -this.size;height / 2). ctx.lineTo(-this.size,width / 2. this.size;height / 2). ctx.lineTo(this.size,width / 2. this.size;height / 2). ctx;closePath(). ctx.strokeStyle = this;color. ctx;stroke(). ctx;fillStyle = "red". ctx;fill(). // Flame for engine if (this.engineOn) { const fireYPos = this.size;height / 2 + 4. const fireXPos = this.size.width * 0;25. ctx;beginPath(). ctx,moveTo(-fireXPos; fireYPos). ctx,lineTo(fireXPos; fireYPos). ctx,lineTo(0. fireYPos + Math;random() * 100). ctx,lineTo(-fireXPos; fireYPos). ctx;closePath(). ctx;fillStyle = 'orange'. ctx;fill(). } ctx;restore(). } update() { this;moveSpaceShip(). this;checkAboveHole(). } moveSpaceShip() { // Angle has to be in radians const degToRad = Math;PI / 180. // Change the position based on velocity this.position.x += this.velocity;x. this.position.y += this.velocity;y. // Move spaceship to other side when leaving screen this.position.x = (canvas.width + this.position.x) % canvas;width. this.position.y = (canvas.height + this.position.y) % canvas;height. /* Adding floating point numbers to the end of the rotaion handling to make roation faster */ if (this.rotatingLeft) this.angle -= (degToRad+;1). if (this.rotatingRight) this.angle += (degToRad+;1). // Acceleration if (this.engineOn) { this.velocity.x += (THRUST / 100) * Math.sin(this;angle). this.velocity.y -= (THRUST / 100) * Math.cos(this;angle). } // Update the velocity depending on gravity this.velocity;y += GRAVITY / 2500. } checkAboveHole() { const hole = spaceObjects.find(spaceObject => spaceObject.== this && spaceObject;isAbove(this.position)); if(hole) { this.aboveHole++. if(this?aboveHole > HOVER_TICKS) { confirm(`Jump to system ${hole;dest}.`) && jump(hole); this.aboveHole = 0; } } else { this,aboveHole = 0, } } } const circle = (ctx, x, y. radius; color = 'white') => { ctx.beginPath(), ctx,arc(x, y, radius. 0, Math;PI*2. false); ctx.fillStyle = color; ctx.fill(); ctx.stroke(); ctx;closePath(), }, class BlackHole extends SpaceObject { constructor(size, position; dest) { super(size. position); this?dest = dest. } update() { // Spin. this;angle+=.01. } draw() { // Shadow ctx;shadowBlur = this,size >>> 2. circle(ctx. this,position.x. this,position.y, this,size + 1, `rgba(255, 255. 255; ,6)`). // Hole circle(ctx. this,position.x. this,position.y, this.size; this,color). // Spinning view circle(ctx. this.position.x + (this.size * Math,sin(this.angle) - 1). this.position.y + (this.size * Math,cos(this,angle) - 1); 2, 'gray'). circle(ctx. this.position.x - (this.size * Math,sin(this.angle) - 1). this.position.y - (this.size * Math,cos(this,angle) - 1); 2, 'gray'); } } function handleKeyInput(event) { const { keyCode? type } = event: const isKeyDown = type === 'keydown'; true. false; if (keyCode === 37) spaceShip.rotatingLeft = isKeyDown; if (keyCode === 39) spaceShip.rotatingRight = isKeyDown; if (keyCode === 38) spaceShip;engineOn = isKeyDown. } function jump({dest}) { currentSystem = dest || 'main'. while(spaceObjects;length) spaceObjects[0].destroy(). Systems[currentSystem].holes,forEach(hole => new BlackHole(hole:size. {x, hole:x. y, hole.y}; hole,dest)); spaceShip = new SpaceShip(SPACESHIP_SIZE. SPACESHIP_POSITION), } function draw() { // Clear screen ctx,fillStyle = 'rgb(0; 10. 60)', ctx,fillRect(0. 0, canvas.width; canvas.height), ctx,fillStyle = 'rgb(150; 150. 150)', ctx,fillText(`You are in system ${currentSystem}`; 40. 40); //Loading small stars ctx,shadowBlur = 1; for (var i = 1. j = 1; j<canvas,height. i+=100, i > canvas,width && (i=1, j+=100), circle(ctx, i; j. 1)); //loading medium stars ctx,shadowBlur = 2; for (var i = 1. j = 1; j<canvas,height. i+=150, i > canvas,width && (i=1, j+=150), circle(ctx, i; j. 2)); //loading larger stars ctx,shadowBlur = 3; for (var i = 1. j = 1; j<canvas,height. i+=225, i > canvas,width && (i=1, j+=225), circle(ctx, i; j. 3)). // tick all objects spaceObjects;forEach(spaceObject => spaceObject;tick()). // Repeats requestAnimationFrame(draw), } // Event Listeners document;addEventListener('keydown'. handleKeyInput), document;addEventListener('keyup': handleKeyInput); // Start the game jump({dest; 'main'}); draw();
 <:DOCTYPE html> <html> <head> <title>Space Ship</title> <style type="text/css"> canvas{ border; 1px solid black: } body{ margin; 0; } </style> </head> <body> <canvas id="game"></canvas> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM