问题描述
(初学者) 我正在创建一个游戏,我希望图像在触及画布限制时水平翻转,所以当我第一次应用 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,img2);
fish3= new Fish(100,50,img3);
fish4= new Fish(200,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,100,100);
pop();
// repeat the above for each of the 4 instances of the fish.
}
还有一些小问题,例如缺少变量 bg
和 px
,但我认为这只是一个问题,将您的代码复制并粘贴到 StackOverflow 问题中。
这是对您的代码进行的一些其他调整的工作改编(调用所有游泳函数,而不是每种鱼只调用 1 个,将画布调整到窗口的大小,使用我躺在周围的一些随机鱼图像,并限制每条鱼图片为 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,img2);
fish3 = new Fish(100,50,img3);
fish4 = new Fish(200,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),width);
this.y2 = constrain(y + random(-400,height);
this.x3 = constrain(x + random(-400,width);
this.y3 = constrain(y + random(-400,height);
this.x4 = constrain(x + random(-400,width);
this.y4 = constrain(y + random(-400,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,100);
pop();
push();
translate(this.x2,this.y2);
if (this.x2direction < 0) {
//this.img2.flip();
scale(-1,1);
}
image(img2,100);
pop();
push();
translate(this.x3,this.y3);
if (this.x3direction < 0) {
//this.img3.flip();
scale(-1,1);
}
image(img3,100);
pop();
push();
translate(this.x4,this.y4);
if (this.x4direction < 0) {
//this.img4.flip();
scale(-1,1);
}
image(img4,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>