英文:
Learning to code in P5.js and getting jammed up with for loops
问题
I am still relatively new to P5 and coding in general. 我对P5和编程还比较新。
I wanted to figure out how to create a series of rotating and shrinking rectangles. 我想弄清楚如何创建一系列旋转和缩小的矩形。
I got it figured out but I coded it one shape at a time. 我已经弄清楚了,但是我一次只编码一个形状。
Was pretty proud of myself until I tried to update the sizes and realized it really could become very tedious. 直到我尝试更新尺寸并意识到这可能会变得非常乏味时,我才感到相当自豪。
So, I know this can be done cleaner with a for loop or a nested for loop but I cannot get my head around it. 所以,我知道可以使用for循环或嵌套的for循环更干净地完成,但我无法理解它。
Could someone take a look and offer up some guidance? 有人可以看一下并提供一些指导吗?
Here is the link to the code: https://editor.p5js.org/Rico2022/sketches/AYXKzSwpm 这是代码链接:https://editor.p5js.org/Rico2022/sketches/AYXKzSwpm
After I figure out and practice creating more, I want to see if I can make every other shape rotate in the opposite direction but that is for a different day 在我弄清楚并练习更多之后,我想看看是否可以使每个其他形状以相反的方向旋转,但那是另一天的事情
Thank you in advance! 提前感谢您!
I've watched and tried the examples from "Coding Train" and a couple other videos. 我已经观看并尝试了来自“Coding Train”和其他一些视频的示例。
I can follow along with the examples and they make total sense. 我可以跟随示例并且它们完全有意义。
I know I need more practice and it will "click". 我知道我需要更多的练习,它会“恍然大悟”。
I am just stuck in my own head and could use a little help. 我只是卡在自己的思维中,需要一点帮助。
英文:
I am still relatively new to P5 and coding in general. I wanted to figure out how to create a series of rotating and shrinking rectangles. I got it figured out but I coded it one shape at a time. Was pretty proud of myself until I tried to update the sizes and realized it really could become very tedious. So, I know this can be done cleaner with a for loop or a nested for loop but I cannot get my head around it.
Could someone take a look and offer up some guidance?
Here is the like to the code: https://editor.p5js.org/Rico2022/sketches/AYXKzSwpm
After I figure out and practice creating more, I want to see if I can make every other shape rotate in the opposite direction but that is for a different day
Thank you in advance!
I've watched and tried the examples from "Coding Train" and a couple other videos. I can follow along with the examples and they make total sense. I know I need more practice and it will "click". I am just stuck in my own head and could use a little help.
答案1
得分: 2
以下是翻译好的部分:
我认为这里要学习的第一个概念是函数。当你有一系列重复的指令,只有少数几个不同的值时,你可以考虑创建一个函数。代码序列将成为函数体,而不同的值将成为参数。
这就是我在这里用你的代码做的,将9行重复的代码提取到参数为w
的函数drawSquare
中。
之后,你可以考虑使用for
循环进一步简化代码。由于正方形宽度的值不完全遵循数学公式(至少最后两个不是),你可以定义一个数组并循环遍历该数组:
function draw() {
background(220);
const square_widths = [125, 100, 75, 50, 25, 10, 6];
for(let i = 0; i < square_widths.length; i++){
drawSquare(square_widths[i]);
}
angle += 6;
}
正如注释中所述,图形旋转的方向和速度由angle += 6;
控制,符号是方向,值与速度有关。
根据George Profenza的消息,除了上面的数组解决方案之外,还有一个有趣的替代方法是使用函数map:
function draw() {
background(220);
for (let i = 0; i < 7; i++) {
drawSquare(map(i, 0, 6, 125, 6));
}
angle += 6;
}
现在,在这种情况下,函数map
返回的值不完全是你最初创建的值 - 它们更好!这些值构成了一个均匀间隔的7个数字序列(当然,你可以生成多少个你需要的)。这个解决方案特别有价值,因为它是一个好的模式,可以在循环中创建均匀间隔的值,这是你迟早会需要的 - 你已经需要了;均匀间隔的数据以比手动定义的值更高效的方式覆盖了你想要覆盖的空间。
希望我在这篇文章中没有推得太多,但这引发了一个关于我如何知道这些值的讨论:一种非常基本的调试代码的技巧 - 使用函数console.log
:
function draw() {
background(220);
for (let i = 0; i < 7; i++) {
let w = map(i, 0, 6, 125, 6);
if (angle === 0) {
console.log(w);
}
drawSquare(w);
}
angle += 6;
}
console.log(w)
调用在p5编辑器下方的控制台区域中显示w
的值(我从那里复制粘贴了它们)。它由一个if(angle===0)
保护,因此它仅在函数draw
第一次运行时(当angle
为零时)打印w
的值;很明显,值每次运行时都是相同的,我们不需要不断用相同的数据填充控制台 - 只需一次足够了。
**重要提示:**我们使用console.log
调用来获取一些我们不确定的信息。在了解了事情的真相后,我们不再需要这个调用,因此最好的做法是尽快从我们的代码中删除这部分内容,它不应该出现在最终的产品中。
这是我保存的示例。
英文:
I think the first concept to learn here is functions. You think of creating a function when you have a repeated sequence of instructions with only a few values that are different. The sequence of code will become the function body and the varying values will be the parameters.
That's what I did here with your code, factoring 9 repeated lines of code to the function drawSquare
of parameter w
var randomColor;
var angle = 0;
function setup() {
createCanvas(windowWidth, windowHeight);
background(random(255, 70));
noFill();
angleMode(DEGREES);
rectMode(CENTER);
frameRate(4);
}
function drawSquare(w) {
push();
randomColor = color(random(255, 50));
stroke(randomColor);
strokeWeight(3);
translate(windowWidth / 2, windowHeight / 2);
rotate(angle);
fill(randomColor);
rect(0, 0, w, w);
pop();
}
function draw() {
background(220);
//------------------Centered Rotating Shrinking Squares - each shrinking by 25 with a random greyscale fill-----
drawSquare(125);
drawSquare(100);
drawSquare(75);
drawSquare(50);
drawSquare(25);
drawSquare(10);
drawSquare(6);
angle += 6;
}
After that, you may think of further simplifying the code using a for
loop. Since the values of the square widths don't exactly
follow a mathematical formula (at least the last two don't), you can
define an array and loop through that array:
function draw() {
background(220);
const square_widths = [125, 100, 75, 50, 25, 10, 6];
for(let i = 0; i < square_widths.length; i++){
drawSquare(square_widths[i]);
}
angle += 6;
}
As stated in the comment, the direction and speed with which the figure rotates is controlled by angle += 6;
the sign is the sense and the value relates to the speed - I'm sure you'll figure it out.
Edit As per George Profenza's message, an interesting alternative to the array solution above, is using the function map:
function draw() {
background(220);
for (let i = 0; i < 7; i++) {
drawSquare(map(i, 0, 6, 125, 6));
}
angle += 6;
}
Now, the values returned by the function map
in this scenario are not exactly the values you created initially - they are even better! These values make an equally-spaced sequence of 7 numbers (of course you can generate as many as you need) that starts at 125 and ends at 6 (125, 105.16666666666667 85.33333333333334, 65.5, 45.66666666666667, 25.83333333333333, 6).
This solution is especially valuable because it is a good pattern one can follow to create equally spaced values in a loop, something one would need sooner or later - you already do; the equally spaced data cover the space you wanted covered in a more efficient way than a sequence of manually defined values.
I hope I'm not pushing too much in this post, but this opens the discussion on how I knew those values: a very basic technique to debug your code - using the function console.log
:
function draw() {
background(220);
for (let i = 0; i < 7; i++) {
let w = map(i, 0, 6, 125, 6);
if (angle === 0) {
console.log(w);
}
drawSquare(w);
}
angle += 6;
}
The console.log(w)
call displays in the console area below the p5 editor the values of w
(from where I copy-pasted them). It is guarded by an if(angle===0)
so it only prints the values of w
for the first time the function draw
runs (when angle
is zero); it's quite obvious the values will be the same every time it runs, and we don't need to fill up the console continuously with the same data - only once is enough.
An important note: we use console.log
calls to get some information we're not sure about. After we found out how things are, we don't need that call any more, so it is good practice to delete that part from our code as soon as we got the information; it should never make it to the final product
Here's the sketch I saved.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论