Processing互动编程开发实践之动态文字打乱功能(别嫌长,代码多,图片多)

这篇文章有什么价值?

  1. 简单介绍Processing编程
  2. 提供一份基于鼠标响应的动画的Processing代码
  3. 重头戏:描述动态文字打乱功能实现的重要细节,并将源码公开

1.什么是Processing编程?

这里是~~非官方~~ 简介:Processing是一个为开发面向图形的应用(visually oriented application)而生的简单易用的编程语言和编程环境。Processing的创造者将它看作是一个代码素描本。它尤其擅长算法动画和即时交互反馈,所以近年来在交互动画,复杂数据可视化,视觉设计,原型开发和制作方向越发流行,大家都喜欢这个可爱贴心,简洁好用的编程工具。 Processing基于Java,其语法规则和Java是一致的 。

2.入门演示代码

本博文免费提供Processing编程学习的链接: 西天取经的路在这里
首先是承诺好的鼠标响应动画代码:
void setup(){

size(400, 400);

}

 

void draw(){

background(#FFEE31);

pushMatrix();

translate(200, 200 - 60);

//eyes

PVector mouse = new PVector(mouseX, mouseY);

mouse.sub(200, 200 - 60, 0);

mouse.limit(7);

fill(0);

noStroke();

rectMode(CENTER);

rect(-1*40+mouse.x, -15+mouse.y, 15, 25, 8);

if(mousePressed)

rect(40+mouse.x, -15+mouse.y, 28, 10, 5);

else

rect(40+mouse.x, -15+mouse.y, 15, 25, 8);

//mouth

noFill();

strokeWeight(12);

stroke(0);

arc(0, 0, 150, 120, PI/4, PI-PI/4);

popMatrix();

//text

textSize(25);

textAlign(CENTER);

text("Enjoy your hacking with\nProcessing!\n I am LSS.", width/2, height/2+100);
println("We are the super star .Love is enough for me");

}

粘贴复制,保存运行,如果你没有做任何改动的话,显示效果应该像下面这样:效果图片

重头戏:文字打乱功能实现

既然是重头戏,不如回忆一下当时事情发生的全过程。事情是这样子的。。。。。。。某一天,突然在某个接单群看到一个任务(天上掉馅饼了),说要用java模仿某个网页做一个功能(网页地址在这里:https://www.qqxiuzi.cn/zh/daluan/)。这还不简单,JSP,HTML,JavaScript随你选,分分钟给你实现了。然而,被客服拉到一个讨论组时才发现,客户其实是想要使用Processing这个互动编程工具,辅助以Arduino控制,做一个课堂小作品。那么,客户为什么一上来说这个是java的编程任务呢?博文前面说了,processing的底层就是java写的,所以,,,,对吧。我当即去网上百度学习一下客户口中的Processing编程是个什么东东,emmm,它竟然是老外用来教自家孩子入门编程的工具,不过呢,主要的还是用来做交互动画,动态数据图表等功能,贼强大。在简单学习了之后,我在本地processing环境运行了我的第一个“hello world ”代码后,觉得这个开发环境很友好(其实是客户给出的报酬很诱惑人),有把握把客户的作品给搞出来。最后,谈妥,客户下订单,我便开始工作,下面是正文部分。
第一步,我先到这个网站https://www.qqxiuzi.cn/zh/daluan/体验一把所谓的“文本打乱”功能,然后客户说了,你的界面大小是要有限制的,必须是585*828 ,其次,你这个Processing代码需要能接收到Arduino端口发过来的控制数据,(控制数据由一个传感器发出,这个我不用管),每接受一个控制信号,就打乱一次文本。而且,文本的段落样式不能变,比如换行位置不能变。呵呵,要求还挺多,可是客户真的是很好说话,这次接单任务中,与人沟通的能力也提升不少,客户的需求也不是说铁定不能变的,我们技术人员可以明确表示,某某功能点“不科学”,咱们可以换一种方式去实现一个类似的功能等等方式。
第二步,开始 解决客户问题。其实,当时整个过程是不是完全分成敲定任务需求细节和各种功能细节的,而是采取了编程开发的“最佳实践模式”(忘了是谁说的什么名词了):快速上线,边做边改。当时,首项工作是实现Processing环境能接收到Arduino端的控制数据。还好,做过89C52系列的单片机开发(也就是点亮了几个流水灯,控制串口数据收发),arduino端数据发送和端口部分代码是客户写的,我这边主要负责写接收和显示控制信号的代码,完美分工。客户的电脑是Mac Air ,所以在网上找到的arduino串口发送代码都是面向Windows操作系统的,花了两天时间才搞定这个数据接收。
下一步任务是,画框框,这个界面中的文本内容是不可以随便显示的,要和像素尺寸打交道。我的天啊,这个是前端或者美工的任务好吧,,,,emm,没事儿,有钱,管他那么多干啥。计算像素,最后画出来文本框了。然后开始进入下一步,动态刷新。
Processing中存在一个draw()函数,这个函数在setup()函数结束之后,默认是死循环无限次运行的,一直在自动刷新页面。这就导致了一个问题,就是你上一次在界面上显示的文本,会被下一次的打乱后的文本覆盖,,,3秒左右,那个界面就模糊不清了,原本理想中,即便会自动刷新界面,上一个界面中的文本应该要自动消失的,现实中确实发生了重叠。这个重影问题又花费了两天时间才搞定,怎么做的呢?一方面,客户把 background(0)背景设置函数从setup()函数中搬到了draw()函数中,这样每一次刷新后,界面背景颜色就要重新设定一次,然后,上一次的文本就神奇般地消失了,匪夷所思啊,太不科学了,这个现象,凭我三天来学习的Processing知识是解释不了的。(其实三天来,我只是上午在做任务,学习Processing,主要是查英文版的API,也会查别人的博文,寻找思路,其他时间该干嘛还干嘛,我又不是全职做这个滴)转念一想,我又不是要深入搞这个的。更何况,我自己也找到了解决方案,而且是官方API推荐的:将要显示的内容使用一个PGraphic对象的text()方法保存,这个对象有一个clear()方法,可以清楚对象的文本信息。把这个对象显示在界面上,问题就解决了。
既然重影问题解决了,也能接收到arduino传过来的控制信号了,那就开始编写实现文本打乱功能的函数吧。我的设计大致是这个样子:随机交换N次文本中的字符位置,然后再把文本对象传出去显示在界面上。难点是,段落控制这个样式,如果不考虑这个话,指不定原来是空格的地方,下一次就会显示字符了。这个问题困扰了我一上午。第二天的上午,我选择分段显示,把有样式发生变化的字符 的像素坐标作为参数传递给我编写的函数。“隔离变化,解耦”这一句话一直在大脑中会响,能抽象就别节约脑力。
最后,整个任务搞定了,代码发给客户了,Processing也失宠了,在我的编程语言世界里,.NET 环境中C#用的最多,Java开发环境的地位在逐步提升,追上.NET只是时间问题,最近在空闲时间会偶尔调戏一下Python大蟒蛇,真香。
这是我承诺的文本打乱Processing代码部分,欢迎复制运行
功能说明:运行后,每次单击鼠标,文本便会随机打乱一次,重新显示。
  
String datas="第,一,编, ,艺,术,品,的,本,质,及,其,产,生, 41,由,此,我,们,可,以,定,下,一,条,规,则,:,要,了,解,一,件,艺,术,品,,,一,个,艺,术,家,,,一,群,艺,术,家,,,必,须,正,确,的,设,想,他,们,所,属,的,时,代,的,精,神,和,风,俗,概,况,。,这,是,艺,术,品,最,后,的,解,释,,,也,是,决,定,一,切,的,基,本,原,因,。,这,一,点,已,经,经,由,经,验,证,实,;,只,要,翻,一,下,艺,术,史,上,各,个,重,要,的,时,代,,,就,可,以,看,到,某,种,艺,术,是,和,某,些,时,代,精,神,与,风,俗,情,况,同,时,出,现,,,同,时,消,失,的,。,—,—,例,如,希,腊,悲,剧,:,埃,斯,库,罗,斯,,,索,福,克,勒,斯,,,欧,里,庇,得,斯,的,作,品,诞,生,的,时,代,,,正,是,希,腊,人,战,胜,波,斯,人,的,时,代,,,小,小,的,共,和,城,邦,从,事,与,壮,烈,斗,争,的,时,代,,,以,极,大,的,努,力,争,取,独,立,,,在,文,明,世,界,中,取,得,领,先,地,位,的,时,代,。,等,到,民,气,的,消,沉,与,马,其,顿,的,入,侵,使,希,腊,受,到,异,族,统,治,,民,族,的,独,立,与,元,气,一,齐,丧,失,的,时,候,,,悲,剧,也,就,跟,着,消,灭,。,—,—,同,样,,,哥,德,式,建,筑,在,封,建,制,度,正,式,建,立,的,时,期,发,展,起,来,,,正,当,十,一,世,纪,的,黎,明,时,期,,,社,会,摆,脱,了,诺,曼,人,与,盗,匪,的,骚,扰,,,开,始,稳,定,的,时,候,。,到,十,五,世,纪,末,叶,,,近,代,君,主,政,体,诞,生,,,促,使,独,立,的,小,诸,侯,割,据,的,制,度,,,以,及,与,之,有,关,的,全,部,风,俗,趋,于,瓦,解,的,时,候,,,哥,德,式,建,筑,也,跟,着,消,灭,。,—,—,同,样,,,荷,兰,绘,画,的,勃,兴,,,正,是,荷,兰,凭,着,顽,强,与,勇,敢,推,翻,西,班,牙,的,统,治,,,与,英,国,势,均,力,敌,的,作,战,,,在,欧,洲,成,为,最,富,庶,,,最,自,由,,,最,繁,盛,,,最,发,达,的,国,家,的,时,候,。,十,八,世,纪,初,期,荷,兰,绘,画,衰,落,的,时,候,,,正,是,荷,兰,的,国,势,趋,于,颓,唐,,,让,英,国,占,了,第,一,位,,,国,家,缩,成,一,个,组,织,严,密,,,管,理,完,善,的,商,号,与,银,行,,,人,民,过,着,安,分,守,己,的,小,康,生,活,,,不,再,有,什,么,壮,志,雄,心,,,也,不,再,有,激,动,的,情,绪,的,时,代,。,—,—,同,样,,,法,国,悲,剧,的,出,现,,,恰,好,是,正,规,的,君,主,政,体,在,路,易,十,四,统,治,下,确,立,了,规,矩,立,法,,,提,倡,宫,廷,生,活,,,讲,究,优,美,的,仪,表,和,文,雅,的,起,居,习,惯,的,时,候,。,而,法,国,悲,剧,的,消,灭,,,又,正,好,是,贵,族,社,会,和,宫,廷,风,气,被,大,革,命,一,扫,而,空,的,时,候,。,"+
",我,想,做,一,个,比,较,,,使,风,俗,和,时,代,精,神,对,美,术,的,作,用,更,明,显,。,假,如,你,们,从,南,方,向,北,方,出,发,,,可,以,发,觉,进,到,某,一,地,带,就,有,某,种,特,";

String[] Str = split(datas,',');

void firstly(int n){
  int ColNum = 0;
  int beginPixel= 276;
  for(int i=0;i<n+1 ;i++)
  { 
     if(i == 14){
        text(Str[i],284+ColNum*13+10,59);
        continue;
    }
    text(Str[i],beginPixel+ColNum*13,59);
    ColNum++;
  }
}

void secondly(int start,int end  ){
  int ColNum = 0;
  int beginPixel= 94;
  for(int i = start; i<end+1 ;i++)
  { 
    text(Str[i],beginPixel+ColNum*16,111);
    ColNum++;
  }
  
}

void thirdly(int start,int end){
  
    int ColNum=0,RowNum=0;
    int count=0;
    int beginPixel= 62;
    for(int i=start;i<end+1;i++)
    {
      if(count == 28)
        {
          ColNum=0;
          RowNum++;
          count =0;
        }
     text(Str[i],beginPixel+ColNum*16,131+RowNum*20);
     ColNum++;
     count++;
    }
}

void lastly(int start,int end1,int end2){
    int ColNum=0;
    int beginPixel= 94;
    for(int i=start;i<end1+1;i++)
    {
      text(Str[i],beginPixel+ColNum*16,610);
      ColNum++;
    }
    
     ColNum=0;
     for(int i=end1+1;i<end2+1;i++)
    {
      text(Str[i],beginPixel-28+ColNum*16,630);
      ColNum++;
    }
}

 
void disorder(int start,int end)
{
  String temp = null;
  for(int i=start;i<= end;i++){
     int randomNum1 =(int) random(start,end);
     int randomNum2 =(int) random(start,end);
     temp=Str[randomNum1];
     Str[randomNum1]=Str[randomNum2];
     Str[randomNum2]=temp;
   }
  
}


void setup(){
  size(585,828);
 // background(10);
  textAlign(LEFT);
 // myPort = new Serial(this, "/dev/cu.wchusbserial1450", 9600); 
  
  //this for() function is to display the indexes of different chars. It could be erased.
  for(int i=0;i<743 ;i++)
  { 
    print(Str[i]+i);
  }
  println(Str.length);
 
}

void draw(){
  background(10);
 
      firstly(14);
      secondly(15,40);
      thirdly(41,687);
      lastly(689,714,741);
 
 delay(2000); 
}

//the mousePressed() event used to test the functions above ,It could be erased too.
void mousePressed(){
  disorder(0,741);
}
  
  

效果图:
在这里插入图片描述在这里插入图片描述

《围城》
  • 9
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坏码农来福

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值