精华内容
下载资源
问答
  • 鲤——processing动画交互应用

    千次阅读 多人点赞 2019-05-03 21:41:50
    鲤——processing动画交互应用 前言 目录 1.应用设计 2.编写过程 3.最终成果 4.参考资料 应用设计 编写过程 最终成果 参考资料

    鲤——processing动画交互应用

    前言

    鲤鱼在我们的日常生活中是一种非常常见的鱼类,它们中的一部分会成为餐桌上的食物,另一部分——锦鲤,则具有极高的观赏价值。我们在园林、寺庙等景点的水池中经常能看见色彩艳丽的各类锦鲤,其中红色和金色的锦鲤最受欢迎。
    我从很久以前就很喜欢锦鲤的形象,不过比起现实中的锦鲤,我更喜欢的是中国风的水墨画或水彩中的锦鲤,无论是细细描绘还是草草勾勒,鱼身的弧度和色泽都显得灵动缥缈,仿佛下一刻这尾鱼儿就会从画中跳出来,一摆尾便消失在视野中。

    说到鲤,说不定有人会想起一款叫《鲤》的游戏,我当初是在taptap上下载到这个游戏的,画面风格和游戏方式都很清新休闲,不过现在好像无法下载了(不知道发生了啥)。这次作业主题也是因为回想起了这部游戏才产生的,想要实现一个可以控制鲤来完成一些任务的小游戏。

    目录

    1.应用设计
    2.编写过程
    3.总结
    4.参考资料
    5.应用推荐

    应用设计

    自己最初的想法虽然好,但在编写过程中遇到的问题太多了,方案也就变得越来越简单,这里就只写最后成型的程序内容吧。
    1.首先是最基本的,鼠标移动控制鲤鱼在池塘中自由游动,并伴有一定的动画效果。
    2.鼠标按下时,会给鱼一个当前方向的力,让鱼儿加速。
    3.鲤鱼游动时会不断吐出泡泡,泡泡受到浮力与重力影响(浮力肯定是要大一点的)向上移动。
    4.随机地在池塘中产生鱼食,产生时会有波纹,鱼食经过一段时间后消失,鲤鱼吃到鱼食时会在当前位置动态出现莲花。
    5.鲤鱼最初为白色,每吃一次鱼食就会加深颜色直到最终变红。
    6.画面上方有文字提醒,当鲤鱼变成最终心态后赋予一个固定的力让鱼游动,游戏结束。
    编写过程将按照设计内容来一一解说。

    编写过程

    1.虽然我也很想自己设计一个完整的鲤鱼动画…不过时间紧迫加上能力限制,最终使用的鲤鱼蓝本来源于一个开源项目(看到这个项目也促使了我做这个主题),我借鉴了其中绘制鲤鱼的一部分代码,是哪个网站找到的我记不得了…
    项目运行页面:http://mylifeaquatic.herokuapp.com/
    github源码:https://github.com/dasl-/my-life-aquatic
    项目源码好像是需要用ruby运行的(不太了解),所以我只看了proccessing文件夹里面的代码进行参考(在public/processing里面),最终借鉴的是三个文件中的部分代码:Boid,Fish和Flagellum。
    Boid类(包括我自己的注释):

    class Boid {
    	public PVector location;
    	public PVector velocity;
    	private PVector acceleration;
    	private float maxForce;
    	private float maxSpeed;
    	
    	public Boid( PVector _location, float _maxSpeed, float _maxForce) {
         createBoid(_location, _maxSpeed, _maxForce);
         velocity= new PVector( random( -maxSpeed, maxSpeed ), random( -maxSpeed, maxSpeed ) );
        }
      private void createBoid(PVector _location, float _maxSpeed, float _maxForce) {
    		location 		= _location;
    		maxSpeed 		= _maxSpeed;
    		maxForce 		= _maxForce;
    		acceleration 	= new PVector( 0, 0 );
    	}
    	
    	protected void update() {
    		velocity.add(acceleration);
    		velocity.limit(maxSpeed*2);
    		location.add(velocity);
    		acceleration.mult(0);
    	}
    
    	private PVector steer( PVector _target, boolean _slowdown ) {
    		PVector steer;
    		PVector desired = PVector.sub( _target, location );//target minus location now
    		float dist = desired.mag();// get vector length
    		if ( dist > 0 ) {
    			desired.normalize();//danweihua vector,make the length=1
    			if ( _slowdown && dist < 60 ) {
    				desired.mult( maxSpeed * (dist / 60) );
    			}
    			else {
    				desired.mult( maxSpeed );//direction*speed
    			}
    			steer = PVector.sub( desired, velocity );
    			steer.limit( maxForce );
    		}
    		else {
    			steer =new PVector( 0, 0 );
    		}
    		return steer;
    	}
    	
    	protected void seek(PVector _target) {
    		acceleration.add( steer( _target, false ) );
    	}
    }
    

    Boid主要掌管鲤鱼的运动,其中的update和代码本色中的Mover类很相似,由位置,速度,加速度和力的层层累加完成当前时刻鲤鱼位置的计算,不同的是鲤鱼的速度有最大上限,此处最大上限为定义的最大速度(maxspeed)的两倍,原因在下面再解释。这个类被创建时,会定义最初位置,最大速度与最大力并给予一个随机的初始速度。
    下面的seek与steer函数则是控制鱼类向鼠标移动的关键,steer函数接收目标位置target(slowdown参数没用到不用管),用target减去当前位置location得到运动需要的向量desired,单位化这个向量,之后将它乘以初始最大速度,就得到了所需速度(包括方向),用所需速度减去目前速度,得到所需加速度,因为此处不计重量因此用最大力来约束这个加速度后,就可以得到最终的所需加速度。使用seek函数接收目标即可更新当前加速度,成功完成导向。seek函数与代码本色中的自制智能体有关。

    Fish类继承了Boid类,而Flagellum类主要用于确定每一时刻的鲤鱼各个部分的位置与形状,在Fish类中定义了五个Flagellum类:身体,两半尾巴和两个鱼鳍,Fish类中的render函数负责绘制整个鲤鱼,这些部分我粗略看了之后没怎看懂,后来也没有更多时间 细细看了,有兴趣的朋友可以去下了源码研究研究。Fish的update函数中这一部分承接上文实现鲤鱼的游动:

    if(mousePosition.x != mousePositionOld.x ||mousePosition.y != mousePositionOld.y)
                 seek(mousePosition);//move to the mouse but some bugs...
           mousePositionOld = mousePosition;
    

    一般鼠标停留在某处不动后鲤鱼就会朝一个固定方向游动,游出画面后经由checkboders函数再从另一边游出,不过我发现如果鼠标快速在一个位置附近晃动就会出现鲤鱼停住的bug。

    最后在主文件test中创建Fish类就可以实现第一个功能了。

    Fish fish;
    PImage p;
    public void setup() {
      smooth();
      size(1400, 900);
      fish=new Fish(new PVector(700,50),3,5);
      frameRate(45); 
      p=loadImage("1.png");
    }
    
    void drawBackground()
    {
      image(p,0,0);
    }
    
    public void draw() {
      drawBackground();
      fish.render();
      fish.update();
    
    }
    
    public void mouseMoved() {
        PVector mousePosition = new PVector(mouseX, mouseY);
        fish.setMousePosition(mousePosition);
    }
    

    2.鼠标点击后施加力做起来还是挺简单的,在Boid里加入两个函数:

    	public void applyForce() {
        PVector f = velocity;
        f.normalize();
        f.mult(10);
        acceleration.add(f);
      }
      
      public void deleteForce() {
         velocity.normalize();
         velocity.mult(maxSpeed);
      }
    

    在test的draw中加入以下:

      if(mousePressed)
      {
        fish.applyForce();
        PVector mousePosition = new PVector(mouseX, mouseY);
        fish.setMousePosition(mousePosition);
      }
      else
      {
        fish.deleteForce();
      }
    

    鼠标点击后施加力,由于赋予鲤鱼的初始速度为maxspeed,所以上文中曾提到在Boid的update中给速度增加了限制,为两倍的maxspeed,施加力后鲤鱼加速到最大速度后就会匀速游动,松开鼠标则速度变回初始速度。

    3.这一部分要用到粒子系统,基础的粒子类在代码本色里是有的:

    class Particle {
      PVector position;
      PVector velocity;
      PVector acceleration;
      float lifespan;
    
      Particle(PVector l) {
        acceleration = new PVector(0, 0.05);
        velocity = new PVector(random(-1, 1), random(-1, 0));
        position = new PVector (l.x, l.y);
        lifespan = 255.0;
      }
      void run() {
        update();
        display();
      }
      void update() {
        velocity.add(acceleration);
        position.add(velocity);
        acceleration.mult(0);
      }
      void display() {
      }
      boolean isDead() {
        if (lifespan < 0.0) {
          return true;
        } 
        else {
          return false;
        }
      }
    }
    

    不过我虽然最后用到的三类粒子都继承了这个初类,但基本都重写一遍了所有变量和函数…这个就权当参考。
    泡泡类:

    class Particle1 extends Particle
    {
      final static float MAX_SPEED = 0.1;
      PVector vel = new PVector(random(-MAX_SPEED, MAX_SPEED), random(-MAX_SPEED, MAX_SPEED));
      PVector acc = new PVector(0, 0);
      PVector pos;
      float mass = random(1, 2);
      float size = mass*random(3,4);
      int lifespan = 255;
      color c;
      float wei;
      Particle1(PVector p)
      {
        super(p);
        pos = new PVector (p.x, p.y);
        acc = new PVector (random(0.1, 1.5), 0);
        if(random(0,1)<0.5)
           c=#ffffff;
        else
           c=#1E90FF;
        wei=random(1,3);
      }
      public void update()
      {
        vel.add(acc); 
        pos.add(vel); 
        acc.mult(0);
        size += 0.05; 
        lifespan=lifespan-2;
      }
      public void applyForce(PVector force) 
      {
        PVector f = PVector.div(force, mass);
        acc.add(f);
      }
      public void display()
      {
        pushMatrix();
        noFill();
        strokeWeight(wei);
        stroke(c,lifespan);
        ellipse(pos.x, pos.y, size * 4, size * 4);
        popMatrix();
      }
      
    }
    

    其中比较重要的是随机定义泡泡的质量和大小,大小部分由质量决定,随时间泡泡大小会慢慢变大。Update函数更新位置,display函数绘制粒子,之后就是粒子系统的类:

    import java.util.Iterator;
    class ParticleSystem1
    {
      ArrayList<Particle1> particles = new ArrayList<Particle1>();
      void update()
      {
        Iterator<Particle1> i = particles.iterator();
        while (i.hasNext()) {
          Particle1 p = i.next();
          if (p.pos.x > width || p.pos.x < 0) {
            i.remove();
            continue;
          } else if (p.pos.y > height || p.pos.y < 0) {
            i.remove();
            continue;
          }
          p.applyForce(new PVector(random(-1,1),0));
          p.applyForce(new PVector(0,(p.mass-p.size/3)/3));
          p.update();
          if (p.isDead()) {
            i.remove();  
          } else {
            p.display();
          }
        }
      }
    }
    

    这其中重要的是力的施加,一个是随机的左右力让泡泡晃动,另一个就是模拟浮力减去重力,当然为了实现比较良好的效果,力的设计就不太严谨,其次还有当泡泡运动到画面之外或生命到期时就从系统中除去这个粒子。
    在test中实现泡泡效果也很简单:

    ParticleSystem1 system = new ParticleSystem1();
    system.particles.add(new Particle1(new PVector(fish.location.x-5*fish.velocity.x, fish.location.y-5*fish.velocity.y)));
    system.update();
    

    4.出现鱼食也是利用粒子系统,基本架构和前面一样我就不解释贴代码了,鱼食是一个个出现的,同一时间只有一个,鱼食出现的地方会有简单的波纹,鱼食在原地一段时间后会移动并缩小。

    之后吃到鱼食绘制花朵这个想法来源与我对游戏《鲤》里莲花的印象,最后选择绘制花朵张开的动态效果。同样是利用粒子系统,其中比较重要的部分就是display绘制函数。

    pushMatrix();
      fill(255);
      stroke(255,192,200);
      strokeWeight(5);
      translate(pos.x, pos.y);
      scale(0.5);
      ellipse(0,0,120, 120);
      rotate(2*angle);
      for (int i=0; i<16; i++) {
      pushMatrix();
      float i0=30;
      rotate(i* TWO_PI/16);
      translate(0, i0);
      ellipse(0, 0, 30, 30);
      rotate(radians(angle));
      noFill();
      stroke(255,192,200);
      beginShape();
      vertex(0,0);
      bezierVertex(10,50,30,90,100,100);
      bezierVertex(90,30,50,10,0,0);
      endShape();
      popMatrix();  
      }
      if(angle<150*PI)
         angle+=speed;
      else
         ;
      popMatrix();
    

    其中angle的初始大小和speed的大小以及第一个rotate用于控制整朵花的动画幅度与速度(参数都是改来改去调到合适为止没多大深意),第一个ellipse绘制花心的圆,之后的循环用来绘制围绕花心的十六片花瓣,每一片是用自定义图形设计的花瓣形状,使用循环每次绘制后装过一定角度绘制下一片,循环中的ellipse在每片花瓣靠近花心的位置画一个圆,其中i0是指每次将坐标轴转到一片花瓣在花心的位置时,在离y轴30的距离处开始绘制花瓣,rotate(radians(angle))用来控制花瓣总体的转向,会形成花瓣张开的效果。
    在test中简单地判断鲤鱼是否碰到鱼食,出现花并清空鱼食的寿命:

    if((Math.abs(fish.location.x-foodnow.pos.x)<20)&&(Math.abs(fish.location.y-foodnow.pos.y)<20)&&(foodnow.lifespan>0))
      {
        foodnow.lifespan=0;
        flower.particles.add(new Particle3(new PVector(foodnow.pos.x, foodnow.pos.y)));
      }
    

    5.鱼的颜色加深实现起来很简单,每次判断吃到鱼食时改变鱼的颜色就行。

    6.最后是一个简单的文字提示和特效,鱼儿最终变为红色时会改变最上方的文字,初始文字和最后文字都有一点简单的动画效果。
    text类:

    class Text {
      char text;
      float homex, homey; 
      float x, y;
      float theta;
      Text(float x1, float y1, char text1) {
        homex = x = x1;
        homey = y = y1;
        text = text1;
        x = random(width);
        y = random(height);
        theta = random(TWO_PI);
      }
    
      void display() {
        textAlign(LEFT);
        pushMatrix();
        translate(x, y);
        rotate(theta);
        text(text, 0, 0);
        popMatrix();
      }
      void home() { 
        x = lerp(x, homex, 0.04);
        y = lerp(y, homey, 0.04);
        theta = lerp(theta, 0, 0.04);
      }
    }
    

    这个类使用了lerp函数来实现有趣的动画效果,首先赋予x,y和theta一个随机值,每次绘制字体将坐标轴转换到(x,y)处,且进行旋转,lerp函数使得x和y不断向homex和homey(也就是字体最终应该在的位置)靠近,角度也从随机值向0靠近,lerp函数最后一个参数决定每次靠近多少。

    总结

    程序参考了代码本色中一、二、四、六章的功能,原本想要实现很多游戏方法,但是最后只实现了一点点,而且还有很多细节没有完善,不过花了很多时间来研究借鉴的代码与代码本色上的内容,也做过很多尝试,有失败也有成功,算是勉强符合了作业要求,学到了一些东西。以后若有机会我还会把这个小游戏完善的更好,之后再上传到网站上展示,目前还是过于简单。

    参考资料

    1.鲤鱼游动:
    项目运行页面:http://mylifeaquatic.herokuapp.com/
    github源码:https://github.com/dasl-/my-life-aquatic
    2.openprocessing:https://www.openprocessing.org/

    应用推荐

    1.【融入动画技术的交互应用】——PlayWithThePicture
    https://blog.csdn.net/qq_41616984/article/details/89737428

    与图片交互的程序具有多种新奇有趣的功能,flow功能可以选取图像的一部分并让其自由流动,papercut功能使得静止的二维图像变成一条条不断飘动剪纸,赋予了图像生命。操作界面清晰易懂,制作者将多种技术相互融合,实现了自己追求的效果,让读者不由期待更加完善的功能。

    2.交互应用 | 音乐坊
    https://mp.weixin.qq.com/s?__biz=MzU4ODc2OTUyNQ==&mid=2247483745&idx=1&sn=510050b6b4438482fdb25e41c0cdadbb&chksm=fdd6f0fbcaa179edd0ab7aa13b1922d4ff02b290b0871caad79a6df7306c603ff8112a3c1b5b&mpshare=1&scene=23&srcid=#rd

    音乐可视化应用,点击屏幕不同位置可以产生多种多样的不同形状音符,同时发出不同类的声音,创建平板和小球相互碰撞后会发出鼓点的声音。程序胜在交互方式自由度高,使用者可以随心所欲创建音符,而且画面清新优美,看了介绍就忍不住想去试一试。

    3.用Processing制作一个「生态瓶」
    https://zhuanlan.zhihu.com/p/64726213

    推荐这一篇主要是因为应用的创意非常有趣,使用者可以主动设计一个简单的生态系统,控制系统中三个物种的数量,然后观察最终得到的结果。我也曾经在生物课上制作过简易的生态瓶,因此觉得这个作品不仅仅具有娱乐价值,加以完善后会有很好的教育作用。

    展开全文
  • Processing鼠标键盘

    千次阅读 2018-08-25 14:54:20
    一、鼠标 1、鼠标坐标: Processing的2D坐标系统,是以窗口的左上角为起点,作为(0, 0)点,x轴正方向向右延伸,y轴正方向向下延伸。而描述鼠标的位置信息,用的就是坐标值。坐标值其实就是一个点,包括了x坐标值和...

    一、鼠标

    1、鼠标坐标:

    Processing的2D坐标系统,是以窗口的左上角为起点,作为(0, 0)点,x轴正方向向右延伸,y轴正方向向下延伸。而描述鼠标的位置信息,用的就是坐标值。坐标值其实就是一个点,包括了x坐标值和y坐标值。所遵循的坐标系,就是Processing的2D坐标系统。

    那如何实时获取鼠标的坐标值呢?Processing直接给出了两个变量,这两个变量是系统定义好的,直接拿来就可以使用,分别是mouseXmouseY。比如你想实时查看当前坐标的位置,可以直接在draw()方法里打印出这两个值。

    void draw() {
      println(mouseX + " : " + mouseY);
    }

    在程序框架的draw()方法里,使用系统提供的println()方法,即可实时打印出鼠标的x坐标和y坐标值。接下来我们做一个比较示例的例子:

    // 环境初始化。
    // 此方法在软件启动时,被系统调用一次。
    void setup() {
      // 初始化窗口大小
      size(100, 100);
      // 清除填充色
      noStroke();
    }
    // 画图。
    // 此方法被系统默认循环调用。
    void draw() {
      // 设置背景色。
      // 由于是在draw()方法中设置背景色,
      // 所以背景色会被不停的刷新。
      background(126);
      // 画圆形。
      // 中心点为鼠标的x坐标和y坐标值。
      ellipse(mouseX, mouseY, 33, 33);
    }

    运行结果

    有时候,我们可能想知道,每次鼠标的移动间距,所以这时候就需要记录上一次的鼠标坐标点。出于这一点考虑,Processing为我们提供了这样一组变量,用来记录上一次鼠标的坐标点,变量的名称为pmouseXpmouseY,和mouseXmouseY很像,只是变量名称的前面多了一个字母p。这样的话,如果我们想记录鼠标两次移动之间的距离,只要用mouseX - pmouseXmouseY - pmouseY即可,非常方便吧!So easy~

    2、鼠标按键:

    鼠标除了有坐标点以外,还有鼠标按键。那对于鼠标按键状态的获取,Processing也为我们提供了现成的变量。对于任意鼠标按键按下的状态,我们可以统一使用mousePressed来判断。举例来说明。

    // 环境初始化。
    // 此方法在软件启动时,被系统调用一次。
    void setup() {
      // 初始化窗口大小
      size(100, 100);
    }
    // 画图。
    // 此方法被系统默认循环调用。
    void draw() {
      // 设置背景色
      // 由于是在draw()方法中设置背景色,
      // 所以背景色会被不停的刷新。
      background(204);
      // 判断鼠标是否有按键按下。
      // true为有按键按下,
      // 否则无按键按下。
      if (mousePressed == true) {
        // 填充白色
        fill(255);
      } else {
        // 填充黑色
        fill(0);
      }
      // 画矩形
      rect(25, 25, 50, 50);
    }

    上面例子,不论按下鼠标那个按键都会填出白色。如果想判断是哪个按键按下,则就要用另外一个变量了。与之类似,Processing提供的变量名为mouseButton。普通鼠标通常有三个按键,所以判断的状态也就包括了三种,分别为LEFTCENTER以及RIGHT。在上述例子之上,我们做一点小小的修改。代码如下:

    // 环境初始化。
    // 此方法在软件启动时,被系统调用一次。
    void setup() {
      // 初始化窗口大小
      size(100, 100);
    }
    // 画图。
    // 此方法被系统默认循环调用。
    void draw() {
      // 判断鼠标左键是否按下
      if (mouseButton == LEFT) {
        // 填充黑色
        fill(0);
      } else if (mouseButton == RIGHT) {
        // 判断鼠标右键是否按下,
        // 并填充白色
        fill(255); // White
      } else {
        // 若没有按键按下,则填充灰色
        fill(126); // Gray
      }
      // 画矩形
      rect(25, 25, 50, 50);
    }

    3、鼠标事件:

    上面获取鼠标的状态,我们可以统称为鼠标数据。那除了获取鼠标数据以外,我们还可以感知鼠标事件。如果细心,你会发现,上述过程中,我们获取鼠标数据都是在编程框架的draw()方法中。这个draw()方法会不停地被系统循环调用,所以我们获取鼠标的数据也都是实时的。但如果我们只想在鼠标状态发生变化的时候获取鼠标的数据,这个时候如果我们还放在draw()里进行调用,获取就不太合适了。Processing为我们考虑到了这一点,所以提供了几个常用的鼠标事件。这些事件作为单独的方法被系统调用,而且只在鼠标状态发生变化的时候,调用一次,所以这些事件不会没由头的不停调用。对于鼠标来说,Processing为我们提供四个常用的事件。分别如下:

    • mousePressed():只有在鼠标按键按下的那一瞬间,会被系统调用一次;
    • mouseReleased():只有在鼠标按键弹起的那一瞬间,会被系统调用一次
    • mouseMoved():会在鼠标移动的时候,不停的被系统调用;
    • mouseDragged():会在鼠标按键按下,并进行拖拽的时候,不停的被系统调用
    // 定义四个整型变量。
    // 前两个为鼠标拖拽坐标值。
    // 后两个为鼠标移动坐标值。
    int dragX, dragY, moveX, moveY;
    // 环境初始化。
    // 此方法在软件启动时,被系统调用一次。
    void setup() {
      // 设置窗口大小
      size(100, 100);
      // 清空填充色
      noStroke();
    }
    // 画图。
    // 此方法被系统默认循环调用。
    void draw() {
      // 设置背景色
      background(204);
      // 设置填充色为黑色
      fill(0);
      // 画黑色圆形。
      // 此圆形会随着鼠标拖拽进行移动。
      ellipse(dragX, dragY, 33, 33);
      // 设置填充色为灰色
      fill(153);
      // 此圆形会随着鼠标移动进行移动。
      ellipse(moveX, moveY, 33, 33);
    }
    // 鼠标移动方法。
    // 当鼠标移动的时候,
    // 系统会触发鼠标移动事件,并调用此方法。
    void mouseMoved() {
      // 鼠标移动时,获取鼠标坐标,
      // 并改变灰色圆形位置。
      moveX = mouseX;
      moveY = mouseY;
    }
    // 鼠标拖拽方法。
    // 当鼠标拖拽的时候,
    // 系统会触发鼠标拖拽事件,并调用此方法。
    void mouseDragged() {
      // 鼠标拖拽时,获取鼠标坐标,
      // 并改变黑色圆形位置。
      dragX = mouseX;
      dragY = mouseY;
    }

    这个例子里,用到了其中两个鼠标事件,一个是鼠标的拖拽,另一个是鼠标的移动,对于鼠标的按下和抬起,其实大同小异。这里要注意的是,按下和抬起都是在鼠标状态改变的时候,只触发一次。所以,根据应用场景的不同,如果想获取鼠标的连续状态,可以在draw()方法里通过调用mouseButton来获取鼠标状态,如果只是想触发一次,那么可以选择在mousePressed()或mouseReleased()方法里获取鼠标的坐标

    4、鼠标的icon:

    Processing里提供了自定义鼠标的功能。如果想使用系统默认提供的鼠标icon,Processing定义了六个常量,来标示系统常用鼠标的icon,分别是ARROWCROSSHANDMOVETEXT以及WAIT。这六个系统提供的鼠标icon,会随着操作系统的不同更改变。具体如何使用呢?我们还是举一个简单的例子。

    // 环境初始化。
    // 此方法在软件启动时,被系统调用一次。
    void setup() {
      // 设置窗口大小
      size(100, 100);
    }
    // 画图。
    // 此方法被系统默认循环调用。
    void draw() {
      // 设置背景色
      background(204);
      // 判断鼠标是否按下
      if (mousePressed == true) {
        // 将鼠标的icon改为HAND
        cursor(HAND);
      } else {
        // 将鼠标的icon改为CROSS
        cursor(CROSS);
      }
      // 以鼠标的x坐标画一条线
      line(mouseX, 0, mouseX, height);
      // 以鼠标的y坐标画一条线
      line(0, mouseY, height, mouseY);
    }

    当然,除了更改成系统提供的以外,还可以自定义鼠标的图形。Processing提供了noCursor()方法,来隐藏鼠标默认的icon,然后可以自定义一个图形,将鼠标的坐标值赋值给图形,那么这个图形就可以看成为鼠标的icon。自定义的图形可以是通过Processing画出的,也可以从外部加载图片文件,都可以。

    二、键盘

    1、键盘数据:

    类比于鼠标,键盘也有专门的变量,来记录是否有键盘的某个按键按下。Processing提供了keyPressed变量来记录当前是否有按键按下。为了更直观的说明,我们还是用简短的例子来说明。

    // 环境初始化。
    // 此方法在软件启动时,被系统调用一次。
    void setup(){
      // 初始化窗口大小
      size(100, 100);
      // 设置直线的宽度
      strokeWeight(4);
    }
    // 画图。
    // 此方法被系统默认循环调用。
    void draw() {
      // 设置背景色。
      // 由于是在draw()方法中设置背景色,
      // 所以背景色会被不停的刷新。
      background(204);
      // 判断键盘是否有按键按下
      if (keyPressed == true) {
        // 如果有按键按下,
        // 则画一条直线。
        line(20, 20, 80, 80);
      } else {
        // 否则画一个矩形
        rect(40, 40, 20, 20);
      }
    }

    当运行后按下任意键,就会变成上图。如果某一个按键一直处于被按下的状态,那么窗口中就会一直显示直线,直到按键松开为止。

    那么,更进一步,如果我们想知道键盘上按下的是哪个键又该怎样做呢?别担心,Processing同样为我们提供了简单的变量,可以直接获取。哪个变量呢?很简单,就是key

    // 环境初始化。
    // 此方法在软件启动时,被系统调用一次。
    void setup() {
      // 设置窗口大小
      size(100, 100);
      // 设置显示字体大小
      textSize(60);
    }
    // 画图。
    // 此方法被系统默认循环调用。
    void draw() {
      // 由于是在draw()方法中设置背景色,
      // 所以背景色会被不停的刷新。
      background(0);
      // text()方法用来显示字符串,
      // 其中有三个参数:
      // 第一个参数为要显示的字符串,
      // 后两个参数是字符串显示的(x, y)坐标值。
      text(key, 20, 75);
    }

    添加完之后,点击菜单栏里的运行按钮,编译并运行程序。如果一切顺利,会看到类似如下运行结果。

    通过key变量,我们可以获知当前键盘上按下了哪个按键。这里要说明一下,key值是区分大小写的,比如答谢的字母A和小写a是不同的。聪明的朋友可能想到了,如果我按下的不是字母,而是类似于Ctrl键会怎样?Processing也考虑到了这种情况,所以专门为这几个特殊的按键做了定义。而且使用的变量不再是key,而是keyCode变量,对于这些功能键也定义了常量,分别有CONTROLALTSHIFTUPDOWNLEFT以及RIGHT。对于功能键的判断,可以通过判断key是否等于CODED。好!我们还是通过一个例子,来展示到底如何使用。

    // 定义矩形的y轴坐标
    int y = 35;
    // 环境初始化。
    // 此方法在软件启动时,被系统调用一次。
    void setup() {
      // 初始化窗口大小
      size(100, 100);
    }
    // 画图。
    // 此方法被系统默认循环调用。
    void draw() {
      // 设置背景色。
      // 由于是在draw()方法中设置背景色,
      // 所以背景色会被不停的刷新。
      background(204);
      // 画一条细线
      line(10, 50, 90, 50);
      // 判断按下的是否为功能键
      if (key == CODED) {
        // 判断是否按下的是向上按键
        if (keyCode == UP) {
          // 将矩形y轴的位置定位20
          y = 20;
        } else if (keyCode == DOWN) {
          // 若按键按下的是向下的按键
          // 将矩形y轴的位置定位50
          y = 50;
        }
      } else {
        // 设置矩形的y轴坐标
        y = 35;
      }
      // 画矩形
      rect(25, y, 50, 30);
    }

    运行上述代码,点击键盘上的向上和向下按键,你会看到矩形的位置会发生变化。细心观察,你可以看到,判断功能键的语句,使用的是key == CODED语句,而判断具体的功能键,则需要使用变量keyCode

    2、键盘事件:

    和鼠标类似,键盘也有事件。但相比于鼠标来说,键盘的事件就少了许多,只有两个,分别是按下和抬起:

    • keyPressed()
    • keyReleased()

    使用方式和鼠标事件类似,每当键盘有按键被按下或抬起的时候,键盘事件就会被系统调用,而且调用的次数只有一次,比如不管某个按键按多久,按下事件只会触发一次。我们还是举例来说明,看看到底如何使用

    // 定义是否显示图形的布尔变量
    boolean drawT = false;
    // 环境初始化。
    // 此方法在软件启动时,被系统调用一次。
    void setup() {
      // 初始化窗口大小
      size(100, 100);
      // 清空填充色 
      noStroke();
    }
    // 画图。
    // 此方法被系统默认循环调用。
    void draw() {
      // 设置背景色。
      // 由于是在draw()方法中设置背景色,
      // 所以背景色会被不停的刷新。
      background(204);
      // 如果布尔变量为true,
      // 则画出T图形
      if (drawT == true) {
        // 画出横向矩形
        rect(20, 20, 60, 20);
        // 画出纵向矩形
        rect(39, 40, 22, 45);
      }
    }
    // 当键盘某个按键按下时,
    // 系统会触发键盘按下事件,
    // 并调用此方法。此方法只会被调用一次。
    void keyPressed() {
      // 如果按下是T或t,
      // 则将drawT布尔变量改为true
      if ((key == 'T') || (key == 't')) {
        // drawT变量设为true,
        // 随后屏幕上将画出T图形
        drawT = true;
      }
    }

     

    参考:

    http://ohcoder.com/blog/2016/03/26/processing-fun-mouse/

    http://ohcoder.com/blog/2016/03/27/processing-fun-keyboard/

    展开全文
  • 基于processing交互动态绘画系统

    千次阅读 2018-12-30 15:45:34
    关于绘画 我认为绘画就是将自己的意识与思想通过一些手段呈现在载体上的作品,这种呈现方式可以是多种多样的,不论是用画笔涂鸦,颜料泼洒,或者是通过手势肢体控制,...这次的绘画系统结合了一些交互动态的效果,...

    关于绘画

    我认为绘画就是将自己的意识与思想通过一些手段呈现在载体上的作品,这种呈现方式可以是多种多样的,不论是用画笔涂鸦,颜料泼洒,或者是通过手势肢体控制,只要倾注了自己的感情自己的想法,那么就是一张绘画作品,如果能给自己带来愉悦,那就是一张完美的绘画作品,如果这张作品不仅能给自己带来愉悦还能给别人带来愉悦或者说是带来联想,那就是一张非常优秀的绘画作品了。

    这次的绘画系统结合了一些交互动态的效果,可以看到绘画更多的可能性以及变化性。

    一、 系统展示与实现

    1.整体界面与展示

    主要完成的是一个基于processing的笔刷绘制系统,
    有交互式笔刷,有动态性的笔刷,还有装饰性笔刷,以及模仿性笔刷。

    可以选择颜色,也可以清空屏幕。
    同时除了背景音乐之外,点击也会有声音的交互。

    实现了按钮以及滑动条的功能。在这里插入图片描述

    2.笔刷展示与实现

    笔刷1: Cell:

    在这里插入图片描述

    这个笔刷最主要可以体现这个系统的交互性,首先它是可以根据这个processing的绘画系统上的选择颜色按键来选择颜色的,点击这个画笔后,可以再画布上进行点击,每点击一次都会出现一个细胞,再点击的话如果这两次点击的距离比260短,就会将他们进行连线。同时这些细胞会有规律的“呼吸”,是根据cos值来调节收缩速度的。

    
    class Circle {
      float x, y;
      Circle(float x, float y) {
        this.x = x; 
        this.y = y;
      }
     
      void show() {
        pushMatrix();
        noStroke();
        fill(0, 100);
        float lfo1 = cos(frameCount*0.1)*10;
        ellipse(x, y, 20+lfo1, 20+lfo1);
        popMatrix();
        pushMatrix();
        fill(brushColor);
        ellipse(x, y, 16, 16);
        noFill();
        stroke(brushColor);
        strokeWeight(4);
        float lfo2 = cos(frameCount*0.05)*25;
        circlePoint(x, y, 100+lfo2, 10);
        popMatrix();
      }
      
      void circlePoint(float x, float y, float d, int c){
       float da = TWO_PI/c; 
       strokeCap(SQUARE);
       for(int i = 0; i < c; i++){
          arc(x, y, d, d, da*i, da*(i+0.5)); 
       }
    }
    }
    

    笔刷2: Grow:

    在这里插入图片描述
    这个笔刷模拟了生长效果
    每次点击产生的生长点种子是随机颜色的,同时它的半径会逐渐变大,这个粒子是单独写了一个类来进行模拟的,然后在这个笔刷的函数中进行判定,如果mousepressd在鼠标的位置进行粒子的实例化来完成个数增加。
    这个生长粒子的类进行了行为的规定,其中用了noise函数来进行角度增加的随机,还有cos值与sin值来进行更多情况的模拟。

      for (int i = 0; i < cant; i++) {
        Particula aux = (Particula) p.get(i);
        aux.act();
        if (aux.tam > 60) {
          p.remove(i);
          i--;
          cant--;
        }
      }
    
    class Particula {
      float x, y, ang, tam;
      color col, cola;
      Particula(float nx, float ny) {
        x = nx; 
        y = ny;
        ang = random(2*PI);
        col = color(random(256), 256, 256, 40);
        cola = color(hue(col), 256, 256, 20);
        tam = 1;
      }
      void act() {
        ang += noise(variacion+((x-y)/10))-0.5;
        x += cos(ang);
        y += sin(ang);
        if (x < 0) {
          x = width;
        }
        else if ( x > width) {
          x = 0;
        } 
        if (y < 0) {
          y = height;
        }
        else if ( y > height) {
          y = 0;
        }
        draw();
        tam += 0.15;
      }
    
    }
    

    笔刷3:Float:

    在这里插入图片描述
    这是一个粒子系统,通过鼠标按动实现在鼠标位置初始化生成粒子,之后在我一定的范围进行漂浮运动,为了防止太卡将最大粒子数设为了150。
    同时在按下鼠标的时候给它设定了一个类似于吹泡泡的音效。

    pushMatrix();
          rectMode(CORNER);
          fill(255,0,100);
          rect(0, indexHeight + margin*2, width, height - indexHeight - margin*2);
      popMatrix();
      
      for (int a = 0; a < cf; a++) {
        if (m[a] < 0) fill(brushColor, 192);
        else          fill(brushColor-70, 192);
    
        int diameter = abs(m[a]);
        ellipse(fx[a], fy[a], diameter, diameter);
      }
      
      if(mousePressed&&mouseY>80){
      pushMatrix();
      addNewParticle();
        if  ( player.position() == player.length() ) {
    
        player.rewind();
        player.play();
      } else
      
      {
       player.play();
      }
      popMatrix();
      }
      
    }
    }
    

    笔刷4:Line:

    在这里插入图片描述
    这个灵感是来源于一些屏保图案,会有那种进行递增的连线的动态图案,这个实现的原来就是根据鼠标的位置坐标通过整个画布的长度与鼠标坐标的运算加减来进行每一帧的连线。构成规律的图案。
    同时自己为了使这种模式多点变化,将整个画布分为了四个部分,鼠标落在不同部分都会有不同的计算以及对称方式,为了使颜色鲜艳且有规律的变化,这里将颜色与时间的秒数来进行拟合,可以让颜色有规律的变化。

    float s=second();
      stroke(s*6,50,100);
      if (mouseX>=540&&mouseY<360){
      line(mouseX,mouseY,540,(mouseX-500)); 
      line((1080-mouseX),mouseY,540,(mouseX-500)); 
      }
      if (mouseX<540&&mouseY<360){
      line(mouseX,mouseY,540,(mouseX)); 
      line((1080-mouseX),mouseY,540,mouseX); 
      }
      
        if (mouseX>=540&&mouseY>=360){
      line(mouseX,mouseY,1380-mouseY,360); 
      line((mouseX),720-mouseY,1380-mouseY,360); 
      }
      
          if (mouseX<540&&mouseY>=360){
      line(mouseX,mouseY,mouseY-300,360); 
      line((mouseX),720-mouseY,mouseY-300,360); 
      }
      
      
      if (mousePressed){
      stroke(s*30,5000,2000);
      if (mouseX>=540){
      line(mouseX,mouseY,540,(mouseX-500)); 
      line((1080-mouseX),mouseY,540,(mouseX-500)); 
      }
      
      }
    

    笔刷5:Ink:

    在这里插入图片描述在这里插入图片描述

    这个画笔是自己整个绘画系统中最喜欢的一个,实现原理不算复杂但是我认为效果非常好,模拟了国画中水墨画笔的感觉。

    实现这个的过程是自己先写了一个喷溅的液体模型,是通过randomGaussian这个随机函数来进行位置的随机化的,这样可以做成一个较为完整的喷溅模型,同时在这个画笔的主函数里根据鼠标的位置来进行调用,自己写了一个计算速度的方法,用这一帧的鼠标位置与上一帧的鼠标位置做减法,再调用scale通过计算得到的速度进行大小的调整,以及用透明度实现深浅的模拟,完成了这个水墨笔刷。

    if (mousePressed == true) {
      noStroke();
    float speed=getspeed(mouseX,mouseY,pmouseX,pmouseY);
    float a=speed/300;
    //constrain(a,0,0.1);
    if (a>0.2){a=0.2;}
    float alpha=map(speed,0,7,0,1);
    fill(0,0,0,alpha);
    pushMatrix();
    translate(mouseX,mouseY);
    scale(a);
    penjian(mouseX,mouseY);
    popMatrix();
    }
    }
    
    void penjian(float x,float y ){
    
      for (int i=0; i<500; i++) {
        
         x = (width/7.0)*randomGaussian();
         y = (height/7.0)*randomGaussian();
        float r = ((width-abs(x)-abs(y))/15.0)*randomGaussian();
        
        ellipse(x, y, r, r);
      }
    

    笔刷6:Leaves:

    在这里插入图片描述
    在这里插入图片描述
    这个是一个偏向装饰性的笔刷,枝条部分是通过鼠标连线完成的,叶子部分分为了两边来画,因为不想画成对称的,所以将两边分开进行绘制,最后还是与鼠标运动的速率进行了联动,鼠标滑动的越快,枝条的叶子就更长。

    if (mousePressed && erase != true) {
        float x2 = tx + dx;
        float y2 = ty + dy;
        float d = dist(tx, ty, mouseX, mouseY);
        float steps = d/random(12,15);
        stroke(208-branchR, 158-branchR, 25-branchR); 
        line(mouseX, mouseY, pmouseX, pmouseY); 
        if (d > 10) {
          float angle = atan2(mouseY-ty, mouseX-tx); 
      
          for (int i = 0; i <= steps; i += 1) {
            float t = i/steps;
            float cx = lerp(tx, x2, t); 
            float cy = lerp(ty, y2, t); 
            pushMatrix();
            drawNeedle(cx, cy, angle, d, weight, "left"); 
            drawNeedle(cx, cy, angle, d, weight, "right"); branch
            popMatrix();
          }
    
          tx  = mouseX;
          ty  = mouseY; 
        }
        
        digit++; 
        if (digit >= 3){digit = 0;}
        if (d > 35) {
          float baubleTilt = random(0, TWO_PI);
          pushMatrix();
            translate(tx,ty);
            rotate(baubleTilt);
          popMatrix();
        }
    

    Processing按钮滑条实现:

    除了笔刷自带的动态效果,界面的交互功能还有滑条和按钮。
    Processing自身是没有gui的功能的,所以实现 按钮的选择就是通过调用processing的mouseclick方法来进行实现的,判断点击的区域是否落入按钮的区域来进行完成的,所以难点在于…算坐标。

    以一个笔刷来举例,代码如下:

     if(1120< mouseX && mouseX < 1180 && 20 < mouseY && mouseY < 60){
       canbrush3=true;  
       canbrush2=false;
       canbrush1=false;
       canbrush4=false;
       canbrush5=false;
       canbrush6=false;
      }
    

    关于这个绘画系统中颜色的选择是做了一个滑条系统来实现的,首先是用写循环的方式来进行所有颜色渐变的实现,就是一个颜色画一根线,最终画完整个色卡,最后用鼠标获取值的方法进行颜色的传参,传给笔刷等工具。
    在这里插入图片描述
    为了实现笔刷的选择不对别的笔刷和界面产生影响,进行了无数布尔变量的设定,同时大量的进行入栈出栈来保证不对别的功能进行影响。

    画渐变条的代码如下:

      noStroke();
      for ( int i=0; i<255; i++ ) {
          fill(i*1.2,100,100);
        for ( int j=0; j<40; j++ ) {
          rect(20 + i, 20 + j, 1, 1);
        }
      }
      
      pushMatrix();
      fill(brushColor);
      ellipse(indexWidth + margin*3, indexHeight/2 + margin, 20, 20);
      popMatrix();
    
    

    关于颜色

    因为有很多笔刷涉及到了随机颜色的选取,
    一开始自己是选择rgb进行随机的,结果发现这个随机非常不保险因为你有超过四分之三的可能选到明度饱和度都很低的颜色,这在画面中并不好看。

    后来为了解决这个问题选择了hsb来进行颜色的选取,这样可以达到颜色十分鲜艳的效果。

    二、 关于代码实现的思考

    这次实验完成下来自己感受最深的地方是:数学在动态中的应用

    总结下来可以分为多元化和复杂化

    不同的数学公式不同的计算方法可以达到很多很有趣的效果,而且在循环中稍作改变就会产生相差很多的效果,可以说数学公式在动态中应用十分的多变,甚至有些不可控,你不试一下很有可能与你想象的效果有很大出入。

    同时这种在动态图中进行数学公式的加入一定程度上帮助自己理解了这个公式,也一定程度上进行了数学公式的可视化。比如我在cell笔刷中运用的半径变换就是通过cos来进行模拟的,可以看出流畅了许多,更加有生命力了。
    在这里插入图片描述
    除此之外这次实验量用了随机数random方法,randomGaussian方法,还有为了将数学公式得到的结果变为可以用的数字使用了一些映射函数比如map()constrain()等等,还有一些变换函数如cos sin函数,通过这些数学公式来使自己形成的图案更加多变。

    三、 关于绘画系统的感悟

    这次实验让我更加看到了绘画的多种可能多种变化,不拘泥于传统的绘画方式,用更多的方式来实现绘画创作且创造出很多不同于传统的绘画效果。

    也对绘画有了一些更深的理解,近年来板绘的发展,已经是结合了传统绘画与电脑交互的一大步了,通过数位板,我们既可以让手绘线条的粗细,轻重,手法复刻在电脑上,也可以通过电脑上的工具来将手绘的内容进行复制,旋转,以及图像处理,这便是一个很好的结合。

    而在此传统绘画与码绘结合的基础上进行动态的交互手法,之后的绘画作品在电子设备上展示的时候可能会更加赋有创造性。

    参考文档

    https://processing.org/tutorials/gettingstarted/

    https://blog.csdn.net/y511374875/article/details/79362957

    https://github.com/magicbrush/PixelArray

    https://github.com/magicbrush/StrokeAbstraction

    展开全文
  • 【搬运】processing 实现声音交互
  • 写在前面,最近需要利用Processing作为上位机来控制机器人的动作和姿态。故在B站上学习了一下Process。https://www.bilibili.com/video/BV1m5411G74Y void setup(){ size(500,500);//用来控制弹出的界面大小 } void...

    写在前面,最近需要利用Processing作为上位机来控制机器人的动作和姿态。故在B站上学习了一下Process。https://www.bilibili.com/video/BV1m5411G74Y

    void setup(){
        size(500,500);//用来控制弹出的界面大小
    }
    void draw(){
        //background(0);//设置弹出框背景色
        //fill(100);//告诉计算机我要填充什么颜色
        //noStroke();//不需要任何描边
        //ellipse(width/2,height/2,50,50);//画圆,width与height分别是弹框的宽和高;
        background(mouseY);//获取鼠标坐标作为颜色;
        fill(mouseX);//获取鼠标坐标作为填充颜色;
        noStroke();//不需要任何描边;
        ellipse(width/2,height/2,50,50);//画圆,width与height分别是弹框的宽和高;前两项是圆心位置,后面的两项是长轴和短轴
    }
    

    在这里插入图片描述

    void setup(){
        size(500,500);
        background(255);//背景色
    }
    void draw(){
       
        fill(mouseX/2);//获取鼠标坐标作为颜色
        noStroke();//不需要任何描边
        ellipse(mouseX,mouseY,50,50);//这里圆心是鼠标的位置,长轴=短轴=50
    }
    


    呈现出拖动效果,表明void draw是循环多次的

    2全局变量和本地变量

    float L =2.5;//相当于全局变量;设置过多的全局变量会消耗内存。
    int Z=50;
    
    void setup(){
        size(500,500);
       // background(255);//背景色
    }
    void draw(){
        float circleSize=50;//本地变量,仅仅会在所在的大括号中被识别
        background(255);//背景色
        fill(mouseX/3);//获取鼠标坐标作为颜色
        noStroke();//不需要任何描边
        //ellipse(mouseX,mouseY,circleSize,circleSize);
        for(int y=0;y<10;y++){
          for(int x=0;x<10;x++)
          {
          ellipse(x*50,y*50,circleSize,circleSize);
          }
      }
    }
    

    在这里插入图片描述
    在这里插入图片描述
    通过translate平移起始位置

    float L =2.5;//相当于全局变量;设置过多的全局变量会消耗内存。
    int Z=50;
    
    void setup(){
        size(500,500);
       // background(255);//背景色
    }
    void draw(){
        float circleNum=mouseX/10;
        float circleSize=width/circleNum;//本地变量,仅仅会在所在的大括号被识别
        translate(circleSize/2,circleSize/2);//平移起始位置
        background(255);//背景色
        fill(mouseX/3);//获取鼠标坐标作为颜色
        noStroke();//不需要任何描边
        //ellipse(mouseX,mouseY,circleSize,circleSize);
        for(int y=0;y<circleNum;y++){
          for(int x=0;x<circleNum;x++)
          {
          ellipse(x*circleSize,y*circleSize,circleSize,circleSize);
          }
      }
    }
    

    在这里插入图片描述

    头像处理

    float L =2.5;//相当于全局变量;设置过多的全局变量会消耗内存。
    int Z=50;
    PImage myHead;
    
    void setup(){
        size(500,500);
       // background(255);//背景色
       myHead = loadImage("i.JPG");
       myHead.resize(500,500 );
    }
    void draw(){
        float circleNum=mouseX/5;
        float circleSize=width/circleNum;//本地变量,仅仅会在所在的大括号被识别
        translate(circleSize/2,circleSize/2);//平移起始位置
        background(255);//背景色
      
        for(int y=0;y<circleNum;y++){
          for(int x=0;x<circleNum;x++){
          color c=myHead.get(int(x*circleSize),int(y*circleSize));//color用于获取对应坐标的颜色
          //float realSize=brightness(c);
          fill(c);//并将对应坐标颜色填入圆形中
          noStroke();
          ellipse(x*circleSize,y*circleSize,circleSize,circleSize);//绘制当前坐标上的圆形。(也就是把对应坐标上的颜色填入到该坐标的圆上)
          }
      }
      //image(myHead,0,0);
    }
    

    在这里插入图片描述

    展开全文
  • 基于Processing的动画交互

    千次阅读 多人点赞 2019-04-25 11:25:41
    基于processing的动画交互基本介绍总览结果分部设计及源代码1、 添加字体2、球随鼠标3、两个对象之间的引力4、小型粒子系统心得想法 基本介绍 大致看了《代码本色》这本书之后,在原有的编程经验的基础上,对于在...
  • processing小项目,实现了鼠标点击屏幕向下释放一个弹力球 ,同时有动态背景
  • 【06】processing-交互(中文)

    千次阅读 2020-07-14 19:24:22
    互动性 Casey Reas 和 Ben Fry 屏幕在我们的身体和计算机内部的电路和电之间形成了一座桥梁...鼠标的概念在施乐帕洛阿尔托研究中心(PARC)得到了进一步的发展,但它在1984年与苹果Macintosh(苹果Macintosh)一起.
  • Processing交互应用——躲避炸弹

    千次阅读 2019-05-05 10:54:57
    Processing交互应用——躲避炸弹融入动画技术的交互应用交互游戏的构思游戏程序结构的介绍截图 融入动画技术的交互应用 这是一个涉及到动画技术的小的交互应用游戏,通过鼠标移动来控制飞机的移动方向和移动速度,...
  • 成品如下图所示,基于Processing和Arduino的交互,给定一种颜色,用Processing分析实时摄像图案的像素,传输控制信号至Arduino,调整摄像头的角度,跟踪选定的色彩。 简介 主要组成部分如下图所示,都是比...
  • 基于processing实现的数据可视化,用户做出的测试结果保存在表格中,程序可读取数据并绘制出图像,与鼠标进行交互鼠标放上去时显示具体分数。增加了平均值与标准差,把浮动直接加于平均值上绘制
  • Arduino与Processing交互学习笔记一

    千次阅读 2019-06-10 21:51:12
    更进一步,可以通过第三方软件进行串口数据可视化处理,Processing是使用得比较多的一个,以下是第一篇Processing学习笔记。通过两个简单的案列说明了Arduino如何与Processing传输数据,第一个是通过Procesing发送...
  • processing实现动态和交互-屁民科普

    万次阅读 多人点赞 2018-11-24 18:43:25
    processing实现动态和交互-屁民科普 一开始看了很多的例子,寻找灵感,做了几个小尝试 (因为博主不太会搞动态图,所以这些交互的部分,没有办法看动图233,所以就贴了个图,有点丑陋,想看效果的可以把代码复制...
  • 简介: 本博文主要基于... font, 2,(255,255,255),2,cv.LINE_AA) 显示和保存图片 cv.imshow("hello world",img) cv.imwrite("python_opencv_drawing.jpg",img) cv.waitKey(0) 使用鼠标交互画图 双击画圆,esc退出 ...
  • 作为游戏交互热爱者,一直想靠自己的力量制作出交互的小玩意儿,发在朋友圈、微博里,期待着别人的赞许。想必读者也是有过这类的想法。本人触及交互领域时间也不长,然而希望给大家分享一些知识,这也是自我需求的...
  • 《春·蜂》processing下的动画技术交互应用《春·蜂》代码绘制蜂巢绽放的分形花空气、液体中蜂蜜下降阻力不同蜂巢细胞自动机随大流的蜂群如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、...
  • 3.4 鼠标点击和键盘操作 当前,你正使用setup()和draw()框架,以及mouseX和...点击鼠标时,如何让Processing发生相应的交互行为?为了了解这一点,你需要回到程序的运行流程中去。你已经了解setup()仅运行一次...
  • 融入动画技术的交互应用 根据《代码本色》书本内容前四章实现了本次实验项目 1.Perlin噪声实现随机游走 每个小球的移动都根据受其速度影响,同时速度由受加速度影响,为了实现每个小球的运动有明显区别...
  • 在第一篇中,学习了如何绘图,我们现在学习如何让图形运动起来以及Processing鼠标、键盘等事件交互方式。 一、运动 把2d图形中的坐标点设置为变量,在draw()函数中,让变量不断的变化,那么2d图形就动起来了。...
  • 终于到了Processing与Arduino交互
  • 本节书摘来华章计算机《交互式程序设计 第2版》一书中的第3章 ,第3.7节,Joshua Noble 著 毛顺兵 张婷婷 陈宇 ...目前已经介绍了一些Processing绘图基础和基本的用户交互捕获方式,你还要学习如何在Processing中载...
  • Processing--鼠标响应(2)

    2011-10-08 17:37:00
    鼠标响应事件的基本结构为 void setup() { } void draw() { } void mousePressed() { } void mouseMoved() { } void mouseDragged() { } mousePressed()函数用在鼠标被按下的响应事件中,如 void setup...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,429
精华内容 2,171
关键字:

processing鼠标交互