【问题标题】:Bounce effect when reaching the limit of the screen到达屏幕极限时的弹跳效果
【发布时间】:2022-08-24 05:19:09
【问题描述】:

我正在用画布制作动画,我已经设法用上、右、下和左键控制图像(ship.png)。但是当达到屏幕的极限时,我遇到了反弹效果的问题。如果你能给我一些关于如何做的建议,你能帮助我吗?

我试图在这部分代码中制作弹跳效果:this.displacement = 函数(e)

我特别想在这里放一个 OR 条件:(e.keyCode == \'38\')但我想不出办法。

    标签: javascript html css canvas


    【解决方案1】:

    update 中,您可以检查您的船的移动方向以及它是否接触到画布的两侧。如果是,则通过乘以 -1 来翻转速度。

    我为你写出了所有的支票(见 sn-p)。您可以通过包含更多if else 语句对其进行一些优化。例如:如果您知道船正在向左移动,那么您无需进行任何其他的边界检查,而不是左边界检查。

    // Check bounds
    const movingLeft = this.ship.get_direction === this.ship.getX && this.ship.getSpeed() < 0;
    const touchingLeftBound = this.ship.x <= 0;
    
    const movingRight = this.ship.get_direction === this.ship.getX && this.ship.getSpeed() > 0;
    const touchingRightBound = this.ship.x >= this.canvas.width - this.ship.image.width;
    
    const movingUp = this.ship.get_direction === this.ship.getY && this.ship.getSpeed() < 0;
    const touchingTopBound = this.ship.y <= 0;
    
    const movingDown = this.ship.get_direction === this.ship.getY && this.ship.getSpeed() > 0;
    const touchingBottomBound = this.ship.y >= this.canvas.height - this.ship.image.height;
    
    if (
      (movingLeft && touchingLeftBound) ||
      (movingDown && touchingBottomBound) ||
      (movingUp && touchingTopBound) ||
      (movingRight && touchingRightBound)
    ) {
      this.ship.setSpeed(this.ship.getSpeed() * -1);
    }
    

    const CREATION = 100;
    const PRECARGE = 200;
    const START   = 300;
    
    class spaceship{
    
       constructor(x, y,image){
          this.x = x;
          this.y = y;
          this.image=image;
          this.speed = 20;//initial speed, before any key
          this.get_direction=null;
          this.set_direction=null;
       }        
       getX() {
         return this.x;
       }
       getY(){
         return this.y;
       }
       getSpeed(){
          return this.speed;
       }    
       setX(x){
          this.x = x;
       }
       setY(y) {
          this.y = y;
       }  
       setSpeed(speed){
          this.speed=speed;
       }     
       setimage(image) {
          this.image = image;
       }
       getimage() {
          return this.image;
       }    
       draw(ctx) {
         ctx.drawImage(this.getimage(),0,0,100,50,this.getX(),this.getY(),100,50);
       }
     }//end of spaceship class 
    
    
    function Animation(){    
       
       this.state = CREATION;
       this.images  = new Array();
       this.canvas = document.getElementById("canvas");
       this.context = this.canvas.getContext("2d");
       this.aux_canvas = document.createElement("canvas"); // "canvas" refer to the <canvas> tag.
       this.aux_context = this.aux_canvas.getContext("2d")
          
       this.canvas.width=document.body.clientWidth;  //current window size
       this.canvas.height=document.body.clientHeight;
       this.aux_canvas.width=document.body.clientWidth;
       this.aux_canvas.height=document.body.clientHeight;
    
       this.ship = null;
          
       var object=this;
       
       this.loadImages = function(){
    
          this.images["ship"] = new Image();
          this.images["ship"].name="ship";
          this.images["ship"].src= "https://i.stack.imgur.com/XQbAW.png";
       }
    
       this.update = function(){
          this.aux_context.clearRect(0, 0, this.canvas.width, this.canvas.height); //clean the canvas of ships
          this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);    // in both canvases the background is not erased
          this.ship.draw(this.aux_context);
          
          // Check bounds
          const movingLeft = this.ship.get_direction === this.ship.getX && this.ship.getSpeed() < 0;
          const touchingLeftBound = this.ship.x <= 0;
    
          const movingRight = this.ship.get_direction === this.ship.getX && this.ship.getSpeed() > 0;
          const touchingRightBound = this.ship.x >= this.canvas.width - this.ship.image.width;
    
          const movingUp = this.ship.get_direction === this.ship.getY && this.ship.getSpeed() < 0;
          const touchingTopBound = this.ship.y <= 0;
    
          const movingDown = this.ship.get_direction === this.ship.getY && this.ship.getSpeed() > 0;
          const touchingBottomBound = this.ship.y >= this.canvas.height - this.ship.image.height;
          
          if (
            (movingLeft && touchingLeftBound) ||
            (movingDown && touchingBottomBound) ||
            (movingUp && touchingTopBound) ||
            (movingRight && touchingRightBound)
          ) {
            this.ship.setSpeed(this.ship.getSpeed() * -1);
          }
      
          this.context.drawImage(this.aux_canvas,0,0,this.aux_canvas.width,this.aux_canvas.height,0,0,this.canvas.width,this.canvas.height);
          this.ship.set_direction(this.ship.get_direction()+(this.ship.getSpeed()));
    
       }
    
       this.displacement = function(e) {
    
          e = e || window.event;
    
          if (e.keyCode == '38'|| e.keyCode == '40') {
             //up
             object.ship.set_direction=object.ship.setY;
             object.ship.get_direction=object.ship.getY;    
             if (e.keyCode == '38') //up
                object.ship.setSpeed(-20);
             else//down
                object.ship.setSpeed(20);    
          }
          else if (e.keyCode == '37' || e.keyCode == '39') {
             object.ship.set_direction=object.ship.setX;
             object.ship.get_direction=object.ship.getX;        
             if (e.keyCode == '37') //left
                object.ship.setSpeed(-20);
             else//right
                object.ship.setSpeed(20);         
          }
    
     }
    
       this.executeMachineStates = function(){
          var imagesUploaded=true;
          if (object.state == CREATION) {
             object.loadImages();
             object.state = PRECARGE;
             setTimeout(object.executeMachineStates, 100);
    
          } else {
             if(object.state==PRECARGE){
    
                console.log("state: PRECARGE");
                for(var i=0;i<object.images.length;i++)
                   if(object.images[i].complete!=true)
                      imagesUploaded=false;                  
                if(imagesUploaded==true){
                   //200 and 100 is the ship's initial position
                   object.ship = new spaceship(200, 100,object.images["ship"]);
                   object.ship.get_direction=object.ship.getX;  //initial movement
                   object.ship.set_direction=object.ship.setX;  //on x-axis
                   object.state = START;
                   document.onkeydown = object.displacement;
                }
                setTimeout(object.executeMachineStates, 100);
             }else{
                if(object.state==START){
                   object.update();
                   setTimeout(object.executeMachineStates, 100);
                }
             }
          }
       }
    
    }//end of class/function Animation
    
    animation= new Animation();
    animation.executeMachineStates();
    body {
      background: black;
      border: 1px solid red;
      width: 400px;
      height: 400px;
    }
    <canvas id="canvas">
    </canvas>

    【讨论】:

    • 感谢反馈,现在更清楚了。我会按照你给我的建议来优化它。
    猜你喜欢
    • 1970-01-01
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多