设为首页收藏本站

[基础教程] 趣味编程指南(5-2)-程序的流程控制-循环语句2

kaka 发表于 2017-2-22 13:26:15 | 显示全部楼层 [复制链接]
5 1938
本帖最后由 kaka 于 2017-8-18 08:25 编辑

1.jpg
继续上一节的内容
制造简单笔刷 再回到 for 循环。前面例举的示例都是没有交互的,要让结果更有趣可不能忘记将 mouseX,mouseY 结合到代码中。
--代码示例(5-10):
[AppleScript] 纯文本查看 复制代码
 void setup(){
      size(700, 700);
      background(255);
      noStroke();
  }

  void draw(){
      for(int i = 0; i < 1000; i++){
          fill(0, 30);
          float x = mouseX + random(-50, 50);
               float y = mouseY + random(-50, 50);
          ellipse(x, y, 2, 2);
      }
  }


11.gif
12.png
13.png
一个“散点”笔刷就诞生了。由于每个细密的圆点坐标都是基于鼠标位置,往左右上下四个方向随机移动有限的距离,所以笔刷最终的形状分布就会近似于方形。
--代码示例(5-11):
[AppleScript] 纯文本查看 复制代码
        void setup(){
      size(700, 700);
      background(255);
      noStroke();
   }
  
          void draw(){
      for(int i = 0; i < 1000; i++){
          float ratio = mouseX/(float)width;
          float x = mouseX + random(-50, 50);
               float y = mouseY + random(-50, 50);
               fill(0, ratio * 255, 255 * (1 - ratio), 30);  
          ellipse(x, y, 2, 2);
      }
   }

14.gif
15.png
若是用 mouseX 的值来影响填充颜色,会得到更迷幻的色彩渐变
for 循环的嵌套 for 循环是可以嵌套的。可以在 for 循环里面再写一个 for 循环。当你需要绘制二维的矩阵就可以采取这种写法。
--代码示例(5-12):
[AppleScript] 纯文本查看 复制代码
        void setup(){
      size(700, 700);
      background(202, 240, 107);
   }

        void draw(){
      fill(0);
      for(int i = 0;i < 5;i++){
          for(int j = 0;j < 5;j++){
                  float x = 150 + i * 100;
                  float y = 150 + j * 100;
              ellipse(x, y , 60, 60);
              println(i + ":" + j);
          }
      }
   }

16.png
初次使用嵌套循环,需要理清其中的逻辑关系。程序中的代码执行顺序始终是由上至下的,因此首先执行的必定是最外层的循环。外循环每执行一次,内循环就要持续执行直到不满足条件为止,此后才执行第二次的外循环。第二次开始后,内循环又会继续从头执行直到条件不满足,如此反复,直到所有条件都不满足,跳出循环为止。
上面的代码,外循环中的循环体一共执行了 5 次,而内循环中的循环体则执行了 25 次。这 25 次中,根据 i ,j 的数值不同,分别用来确定圆的横纵坐标。例子中嵌入了一段 print ,你可以观察输出的数值揣摩其中的变化。仅仅用两个循环嵌套,就能将 i,j 的数值组合都遍历了。
  • Tips
  • 第二层的 for 循环一般在开头键入 Tab 进行缩进,这样做可以使代码结构更清晰
  • 两层 for 循环中的局部变量必须起不同的变量名。其中,”i”,“j”,“k” 是最为常用的
灵活运用 “i” ,”j” “i”,“j” 这两个变量名指代的是两层 for 循环中的局部变量。下面的例子会加深你对 “i””j” 的理解。根据“i” ,“j” 值的不同,可以传入参数来对元素进行“分组”。
--代码示例(5-13):
[AppleScript] 纯文本查看 复制代码
void setup() {
  size(700, 700);
  background(0);
  noStroke();
}

void draw() {
  background(0);
  fill(250, 233, 77);  

  for (int i = 0; i < 7; i++) {
    for (int j = 0; j < 7; j++) {
      pushMatrix();
      translate(50 + i * 100, 50 + j * 100);

      // 设置 1
      //float angle = sin(millis() / 1000.0) * PI/2;

      // 设置 2
      //float ratio = i/7.0;
      //float angle = sin(millis() / 1000.0 + ratio * (PI/2)) * PI/2;

      // 设置 3
      float ratio = (i * 7 + j)/49.0;
      float angle = sin(millis() / 1000.0 +  ratio * (PI/2)) * PI/2;

      rotate(angle);
      rectMode(CENTER);

      // 绘制图形 1
      rect(0, 0, 80, 80);

      // 绘制图形 2
      // rect(0, 0, 100, 20);

      // 绘制图形 3
      //rect(0, 0, ratio * 50, ratio * 50);

      popMatrix();
    }
  }
}

代码说明
  • rectMode(CENTER) 可以改变矩形的绘制方式,原来 rect 的前两个参数是用来确定矩形左上角的坐标。开启此命令后,这两个参数会用于设定矩形中心的坐标。由于这里是通过 rotate 来对图形进行旋转操作的,所以就需要通过这种方式,将矩形的中心绘制到坐标原点上。
  • millis() 获取的是程序从运行到当前所经过的时间,单位是毫秒。此值会影响 sin 输出值的变化速度,若直接写 millis ,变化幅度则太大,因此将它除以 1000.0
这段代码中运用注释符 “//” 隐藏了多个设置。你可以通过开启或是关闭去快速地切换效果。例如开启了 “设置 3” 后的语句,就需要把 “设置 1” 和 “设置 2” 后的代码块用注释符关闭掉。对于这类程序结构相似而局部代码有所区别的例子,就可以用这种形式去写,这样就无需分别保存多个工程文件了。练习和创作的时候可以多运用这种技巧,以此来保存一些自己满意的参数设置。
其中 i,j 值对程序的影响,主要通过切换 “设置1(设置2)(设置3)” 来体现。可以对比下面的输出结果
绘制图形 1:设置 1
17.gif
绘制图形 1:设置 2
18.gif
绘制图形 1:设置 3
19.gif

绘制图形 2:设置 1
20.gif
绘制图形 2:设置 2
21.gif

绘制图形 2:设置 3
22.gif

在设置 1 中,没有使用到 i 或 j 去影响每个元素的旋转角度。因此可以看到每个元素的运动效果都是一致的。而设置 2 用到了 i 值,设置 3 同时用到了 i 和 j。它们最终通过 ratio 值去影响 sin 函数的参数输入,以此改变 angle 的周期变化。由于设置 2 与设置 3 的具体效果在动图中并不明显,我们可以通过下面的截图去观察。
绘制图形2( 左图:设置2 - 右图:设置3 )
24.png
绘制图形3( 左图:设置2 - 右图:设置3 )
26.png
第一张图中,ratio 用于影响矩形的旋转角度。而第二张图,则直接用来控制圆形的半径大小。可以看到,只使用了 i 值的语句:

float ratio = i/7.0;


它的纵向元素的变化都是完全一致,因为控制图形横坐标的只依赖 i 值,所以横坐标相同的图形,ratio 的值也相同,旋转角度,圆的半径大小也相同。
而同时用到 i,j 的语句

float ratio = (i * 7 + j)/49.0;


它可以描述“渐变”,这里通过相乘一个系数的方式,将行与列的影响组合到了一起。使每个元素都有所区别。
While 循环 for 循环还有一个兄弟。那就是 while 循环。for 循环能做的事,while 循环也能做。只是 while 循环的在 creativeCoding 中的使用频率并没有 for 循环高。
--代码示例(5-14):
[AppleScript] 纯文本查看 复制代码
        void setup(){
            int a = 0;
            while(a < 10){
                println(a);
                a++;
            }
        }

while 的语法结构其实比 for 更好理解。while 语句的前面先创建变量,接着中括号内填写一个表达式,当满足时就执行循环体中的语句,最后在循环体内放上一个对变量进行更新的表达式,这样 while 循环就完成了。对于循环次数确定的,多用 for 循环。当变量的数值不确定时,更推荐使用 while 循环。
转自www.inslab.cn


发表于 2017-3-22 08:53:58 | 显示全部楼层
请问如何把动画效果输出成可以直接运行的程序或文件?
回复 支持 反对

使用道具 举报

发表于 2017-3-27 09:14:02 | 显示全部楼层
gray6666 发表于 2017-3-22 08:53
请问如何把动画效果输出成可以直接运行的程序或文件?

有个打包发布的功能
回复 支持 反对

使用道具 举报

发表于 2017-3-29 14:33:14 | 显示全部楼层
kaka 发表于 2017-3-27 09:14
有个打包发布的功能

找到个生成EXE的功能,转GIF的功能模块如何用 ?
回复 支持 反对

使用道具 举报

发表于 2017-3-29 17:37:49 | 显示全部楼层
gray6666 发表于 2017-3-29 14:33
找到个生成EXE的功能,转GIF的功能模块如何用 ?

转GIF需要把每一帧保存下来,然后自己做,也有一个库,欢迎继续关注,我后面会介绍
回复 支持 反对

使用道具 举报

发表于 2017-3-29 17:39:16 | 显示全部楼层
kaka 发表于 2017-3-29 17:37
转GIF需要把每一帧保存下来,然后自己做,也有一个库,欢迎继续关注,我后面会介绍 ...

继续关注,感谢回复
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则 允许回帖同步到新浪微博  

推荐阅读

精华导读




公司简介| 联系我们| 小黑屋| 加入我们| 微博| 优酷| 英文网站| DF创客社区 ( 沪ICP备09038501号-4  
友情链接| 硬创邦| 花生壳社区| 模友之吧| 电子发烧友社区| 创客星球| 云汉电子社区| 电子工程网| 与非网| Arduino中文社区| 南极熊3D打印网| OneNET|

上海智位机器人有限公司  沪ICP备09038501号-4   

Powered by Discuz! X3.1

Licensed Comsenz Inc.

返回顶部 返回列表