触摸限制不起作用时翻转图像(比例(-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.
}
还有一些小问题,例如缺少变量 bg
和 px
,但我认为这只是一个问题,将您的代码复制并粘贴到 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>
(初学者) 我正在创建一个游戏,我希望图像在触及 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.
}
还有一些小问题,例如缺少变量 bg
和 px
,但我认为这只是一个问题,将您的代码复制并粘贴到 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>