触摸限制不起作用时翻转图像(比例(-1,1))?

Flip image (scale(-1,1)) when touching limits not working?

(初学者) 我正在创建一个游戏,我希望图像在触及 canvas 限制时水平翻转,所以当我第一次应用 scale(-1,1) 时它工作正常。对代码进行一些更改后,它停止工作。我还尝试创建一个函数并调用它,但出现“不是函数”错误。有什么建议吗?

let fish1, fish2, fish3, fish4;
let img1, img2, img3, img4;

function preload() {
  img1 = loadImage("Fishes/fish1.png");
  img2 = loadImage("Fishes/fish2.png");
  img3 = loadImage("Fishes/fish3.png");
  img4 = loadImage("Fishes/fish4.gif");
}

function setup() {
  createCanvas(1920, 1080);

  fish1 = new Fish(400, 150, img1);
  fish2= new Fish(200, 150, img2);
  fish3= new Fish(100, 50, img3);
  fish4= new Fish(200, 150, img4);
}

function draw() {
  background(bg);

  fish1.display();
  fish2.display();
  fish3.display();
  fish4.display();
  fish1.swim1();
  fish2.swim2();
  fish3.swim3();
  fish4.swim4();
  fish1.limits();
  fish2.limits();
  fish3.limits();
  fish4.limits();
}

function flip() {
  scale(-1, 1);
}

class Fish{
  constructor(x, y, inImg) {
    this.img1 = inImg;
    this.img2 = inImg;
    this.img3 = inImg;
    this.img4 = inImg;
    this.x1 = x;
    this.y1 = y;
    this.x2 = x + 1000;
    this.y2 = y + 200;
    this.x3 = x + 100;
    this.y3 = y + 400;
    this.x4 = x + 1000;
    this.y4 = y + 400;
    this.x1direction = random(0, 1);
    this.y1direction = random(0, 1);
    this.x2direction = random(0, 2);
    this.y2direction = random(0, 1);
    this.x3direction = random(0, 2.5);
    this.y3direction = random(0, 3);
    this.x4direction = random(0.5, 2);
    this.y4direction = random(0.3, 1.5);
  }
  display() {
    image(img1, this.x1, this.y1);
    image(img2, this.x2, this.y2);
    image(img3, this.x3, this.y3);
    image(img4, this.x4, this.y4);
  }
  swim1() {
    push();
    translate(this.x1 + px / 80, this.y1 + px / 80);
    if (this.x1direction < 0) {
      //this.img1.flip();
      scale(-1, 1);
    }
    pop();
    this.x1 += this.x1direction;
    this.y1 += this.y1direction;
  }
  swim2() {
    push();
    translate(this.x2 + px / 80, this.y2 + px / 80);
    if (this.x2direction < 0) {
      //this.img2.flip();
      scale(-1, 1);
    }
    pop();
    this.x2 += this.x2direction;
    this.y2 += this.y2direction;
  }
  swim3() {
    push();
    translate(this.x3 + px / 80, this.y3 + px / 80);
    if (this.x3direction < 0) {
      //this.img3.flip();
      scale(-1, 1);
    }
    pop();
    this.x3 += this.x3direction;
    this.y3 += this.y3direction;
  }
  swim4() {
    push();
    translate(this.x4 + px / 80, this.y4 + px / 80);
    if (this.x4direction < 0) {
      //this.img4.flip();
      scale(-1, 1);
    }
    pop();
    this.x4 += this.x4direction;
    this.y4 += this.y4direction;
  }
  limits() {
    if (this.x1 > width || this.x1 < 0) {
      this.x1direction = -this.x1direction;
    }
    if (this.y1 > height || this.y1 < 0) {
      this.y1direction = -this.y1direction;
    }
    if (this.x2 > width || this.x2 < 0) {
      this.x2direction = -this.x2direction;
    }
    if (this.y2 > height || this.y2 < 0) {
      this.y2direction = -this.y2direction;
    }
    if (this.x3 > width || this.x3 < 0) {
      this.x3direction = -this.x3direction;
    }
    if (this.y3 > height || this.y3 < 0) {
      this.y3direction = -this.y3direction;
    }
    if (this.x4 > width || this.x4 < 0) {
      this.x4direction = -this.x4direction;
    }
    if (this.y4 > height || this.y4 < 0) {
      this.y4direction = -this.y4direction;
    }
  }
}

您在尝试调用翻转函数时出错的原因是您在 p5.Image 对象而不是 Fish 对象上调用它:

// this is a reference to the current Fish instance
// this.img1 is the field on the Fish instance containing the p5.Image
// So this.img1.flip is not a function because p5.Image has no such function
this.img1.flip();

你的翻转不起作用的原因是你没有在代码中使用 scale(-1, 1):

的地方绘制图像
  swim1() {
    push();
    translate(this.x1 + px / 80, this.y1 + px / 80);
    if (this.x1direction < 0) {
      // The scale function only effects those elements drawn after it is called
      scale(-1, 1);
    } 
    // Calling pop() resets the drawing state (including all translation and
    // scale transformations) back to the point they were at when the last call
    // to push() was made. So the translation and scale above have no effect
    pop();

    this.x1 += this.x1direction;
    this.y1 += this.y1direction;
  }

  display() {
    // When you are drawing your images, no scaling is applied
    image(img1, this.x1, this.y1);
    image(img2, this.x2, this.y2);
    image(img3, this.x3, this.y3);
    image(img4, this.x4, this.y4);
  }

简而言之,您试图做的似乎是翻转实际的源图像,以便下次您以正常缩放比例绘制它时,它会显示为翻转。然而,实际上以这种方式实现它会很复杂且效率较低,因为您必须为每个图像制作 4 个副本(或至少 2 个副本,一个翻转和一个)。

考虑这一点的更好方法是将其视为转换为鱼的位置,并在代码中实际绘制鱼的位置有条件地缩放。令人高兴的是,代码看起来与您现在拥有的非常相似:

  swim1() {
    this.x1 += this.x1direction;
    this.y1 += this.y1direction;
  }

  display() {
    push();
    translate(this.x1, this.y1);
    if (this.x1direction < 0) {
      scale(-1, 1);
    }
    image(img1, 0, 0, 100, 100);
    pop();

    // repeat the above for each of the 4 instances of the fish.
  }

还有一些小问题,例如缺少变量 bgpx,但我认为这只是一个问题,将您的代码复制并粘贴到 Whosebug 问题中。

这是对您的代码进行的工作改编,并进行了一些其他调整(调用所有游泳函数,而不是每种鱼类型调用 1 个,大小 canvas 到 window,使用一些随机鱼我周围的图像,并将每条鱼图像限制为 100x100):

let fish1, fish2, fish3, fish4;
let img1, img2, img3, img4;

function preload() {
  img1 = loadImage("https://cdn.glitch.com/0e291b8c-6059-4ca6-a0ae-84e67e1f94e7%2Forange-fish.jpg?v=1613865086898");
  img2 = loadImage("https://cdn.glitch.com/0e291b8c-6059-4ca6-a0ae-84e67e1f94e7%2Fblue-fish.jpg?v=1613865087591");
  img3 = loadImage("https://cdn.glitch.com/0e291b8c-6059-4ca6-a0ae-84e67e1f94e7%2Fpurple-fish.jpg?v=1613865090105");
  img4 = loadImage("https://cdn.glitch.com/0e291b8c-6059-4ca6-a0ae-84e67e1f94e7%2Fwhite-fish.jpg?v=1613865093930");
}

function setup() {
  createCanvas(windowWidth, windowHeight);

  fish1 = new Fish(400, 150, img1);
  fish2 = new Fish(200, 150, img2);
  fish3 = new Fish(100, 50, img3);
  fish4 = new Fish(200, 150, img4);
}

function draw() {
  background(255);

  fish1.display();
  fish2.display();
  fish3.display();
  fish4.display();
  fish1.swim();
  fish2.swim();
  fish3.swim();
  fish4.swim();
  fish1.limits();
  fish2.limits();
  fish3.limits();
  fish4.limits();
}

function flip() {
  scale(-1, 1);
}

class Fish{
  constructor(x, y, inImg) {
    this.img1 = inImg;
    this.img2 = inImg;
    this.img3 = inImg;
    this.img4 = inImg;
    this.x1 = x;
    this.y1 = y;
    this.x2 = constrain(x + random(-400, 400), 0, width);
    this.y2 = constrain(y + random(-400, 400), 0, height);
    this.x3 = constrain(x + random(-400, 400), 0, width);
    this.y3 = constrain(y + random(-400, 400), 0, height);
    this.x4 = constrain(x + random(-400, 400), 0, width);
    this.y4 = constrain(y + random(-400, 400), 0, height);
    this.x1direction = random(0, 1);
    this.y1direction = random(0, 1);
    this.x2direction = random(0, 2);
    this.y2direction = random(0, 1);
    this.x3direction = random(0, 2.5);
    this.y3direction = random(0, 3);
    this.x4direction = random(0.5, 2);
    this.y4direction = random(0.3, 1.5);
  }
  display() {
    push();
    translate(this.x1, this.y1);
    if (this.x1direction < 0) {
      //this.img1.flip();
      scale(-1, 1);
    }
    image(img1, 0, 0, 100, 100);
    pop();
        
    push();
    translate(this.x2, this.y2);
    if (this.x2direction < 0) {
      //this.img2.flip();
      scale(-1, 1);
    }
    image(img2, 0, 0, 100, 100);
    pop();
        
    push();
    translate(this.x3, this.y3);
    if (this.x3direction < 0) {
      //this.img3.flip();
      scale(-1, 1);
    }
    image(img3, 0, 0, 100, 100);
    pop();
        
    push();
    translate(this.x4, this.y4);
    if (this.x4direction < 0) {
      //this.img4.flip();
      scale(-1, 1);
    }
    image(img4, 0, 0, 100, 100);
    pop();
  }
    swim() {
        this.swim1();
        this.swim2();
        this.swim3();
        this.swim4();
    }
  swim1() {
    this.x1 += this.x1direction;
    this.y1 += this.y1direction;
  }
  swim2() {
    this.x2 += this.x2direction;
    this.y2 += this.y2direction;
  }
  swim3() {
    this.x3 += this.x3direction;
    this.y3 += this.y3direction;
  }
  swim4() {
    this.x4 += this.x4direction;
    this.y4 += this.y4direction;
  }
  limits() {
    if (this.x1 > width || this.x1 < 0) {
      this.x1direction = -this.x1direction;
    }
    if (this.y1 > height || this.y1 < 0) {
      this.y1direction = -this.y1direction;
    }
    if (this.x2 > width || this.x2 < 0) {
      this.x2direction = -this.x2direction;
    }
    if (this.y2 > height || this.y2 < 0) {
      this.y2direction = -this.y2direction;
    }
    if (this.x3 > width || this.x3 < 0) {
      this.x3direction = -this.x3direction;
    }
    if (this.y3 > height || this.y3 < 0) {
      this.y3direction = -this.y3direction;
    }
    if (this.x4 > width || this.x4 < 0) {
      this.x4direction = -this.x4direction;
    }
    if (this.y4 > height || this.y4 < 0) {
      this.y4direction = -this.y4direction;
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.js"></script>