作业汇报:融入动画技术的交互应用

2019-04-29  本文已影响0人  Pippi_

一、要求

主题:自拟

技术:
参考《代码本色》教程,运用不少于3个章节的动画技术,实现一个交互应用,将动画技术充分运用于交互过程中;
最好能充分融入其他课程的知识。

报告:
撰写一篇博文/推文,介绍该应用的背景、创意、功能、用法、技术等各个方面,并可自行选定特殊主体做深入讨论,尽可能从多种角度、关联多学科的方式来探讨;

开发工具:p5.js, processing, openframeworks, unity, 若涉及其他工具或语言,要提前找老师讨论并征求意见

二、实践

1、作品预览

粒子效果
其他动态

2、开发工具
Windows10&processing3(Java)

3、功能及关键代码
(1)、GUI界面设计

GUI界面
页面中一共有六个控制按钮,还有四个滑块控制。六个控制按钮分别为:功能操作介绍、雨、雪、暴风雪、其他功能介绍。
GUI功能的部分代码:
birdButton birdButton;
scrollBar hs;
Handle[] handles;
helpButton helpButton;
rainButton rainButton;
snowButton snowButton;
blizzardButton blizzardButton;
otherButton otherButton;
..............
void GUI() {
    birdButton.draw();
    helpButton.draw();
    rainButton.draw();
    snowButton.draw();
    blizzardButton.draw();
    otherButton.draw();
    hs.display();
    
      for (int i = 0; i < handles.length; i++) {
     
    handles[i].update();
    handles[i].display(i);
  }

(2)、三种粒子动态
下雨:
雨和暴雪数组是相似的,唯一的区别是:(1)暴雪类使用rotation()函数使其看起来像是在大风中行进的雪;(2)使用ellipse() 创建雪的形状;(3)雪的大小没有随机性;(4)使用push和pop矩阵防止随机旋转受到影响。以及使generateBlizzard()函数中的屏幕变白,使其看起来更自然。

下雨
class Rain {
  
  float xpos, ypos, z, len, yspeed;
  
  
  Rain() {
    xpos = random(width);
    ypos = random(-1000, -500);
    z = random(0, 10);
    len = map(z, 0, 1, 1, 2);
    yspeed = map(z, 0, 20, 4, 10);
  }
  
  void fall() {
   
      ypos = ypos + yspeed;
      float gravity = map(z, 0, 20, 0, 0.2);
      yspeed = yspeed + gravity;
      
      if (ypos > height) {
         ypos = random(-1000, -500);
         yspeed = map(z, 0, 20, 10, 30);
      }
      
  }
  
  void display() {
     float thickness = map(z, 0, 20, 1, 2);
     fill(0, 0, 225, 90);
     rect(xpos, ypos, thickness, (ypos+len)/10);
  }
}

下雪:
snow类使用一个数组,该数组在一个名为getsnow()的函数中初始化和填充。我参考了一个关于数组的处理教程,它演示了如何在屏幕上制作点。因为它是一个简单的例子,并且与缺乏随机性保持一致,所以除了值(例如雪的数量和Y轴位置使雪看起来更自然)、变量名和封装之外,我没有对代码做太多的更改。


下雪
class Snow {
  
   float x, y;
   float diameter;
   float speed;
   float r;  
  float g;  
   float b;  
   int direction = 1;
   
   Snow(float xpos, float ypos, float dia, float sp) {
    
       x = xpos;
       y = ypos;
       diameter = dia;
       speed = sp;
   }
  
    void move() {
        if (y > height) {
         y = -50; 
        }
       y += (speed * direction);
    }
    
    void display() {
         
      //r = x/4;     
      //g= y/4;    
      //b = (x+y)/8;
      // fill(r,g,b);
       ellipse(x, y, diameter, diameter);
    }
}

暴风雪:


暴风雪

class Blizzard {
  
  float xposBlizzard, yposBlizzard, z, len, yspeed;
  
  
  Blizzard() {
    xposBlizzard = random(width);
    yposBlizzard = random(-1000, -500);
    z = random(20, 100);
    len = map(z, 0, 20, 10, 20);
    yspeed = map(z, 0, 20, 1, 20);
  }
  
  void fall() {
   
      yposBlizzard = yposBlizzard + yspeed;
      float gravity = map(z, 0, 20, 0, 0.02);
      yspeed = yspeed + gravity;
      
      if (yposBlizzard > height) {
         yposBlizzard = random(-1000, -500);
         yspeed = map(z, 0, 20, 1, 20);
      }
      
  }
  
  void display() {
    pushMatrix();
    rotate(radians(z));
    fill(255);
    ellipse(xposBlizzard, yposBlizzard, 5, 5);
  popMatrix();
  }
}

(3)、鼠标和键盘交互
例如:按“2”键会在鼠标光标所在位置种一棵随机大小的小树。
首先,声明arraylist并为tree类打开了一个新标签。使用add()函数添加树,该函数根据光标的X轴和Y轴传递值。这允许在用户选择的位置创建树,以及树的高度。与其他对象(如human)相比,使用forloop和get()函数(位于draw()函数内部)访问tree类。它将获取索引并将其传递给get()函数,然后获取并调用display()函数,该函数将绘制树。display()函数包括使用rect()函数绘制树的木材,使用triangle()函数作为基础绘制树叶,然后使用更多的triangle()函数在其顶部添加forloop和更改的值。


种树
void Weather() {
    if (key == '3') {
       snowFlag = true;
    }
    
    if (key == '2') {
      treeFlag = true;
      trees.add(new Tree(mouseX, mouseY)); 
      keyReleased();
    }
    
    if (key == '4') {
       rainFlag = true;
    }
    
    if (key == '5') {
       blizzardFlag = true; 
    }
    
    if (key == '1') {
       birdFlag = true; 
    }

    else if (key == '6') {  //remove weather functions
       snowFlag = false;
       treeFlag = false;
       rainFlag = false;
       blizzardFlag = false;
       birdFlag = false;
    }
    
 }
......
void checkFlags() {
     if (snowFlag == true) {
    generateSnow();
  }
  
  if (rainFlag == true) {
     generateRain(); 
  }

  if (blizzardFlag == true) {
     generateBlizzard();
  }
  
  if (birdFlag == true) {
    generateBird();  
  }
 }

(4)、图片动画


动画
class Bird {

  PImage[] images;
  int imageCount;
  int frame;
 
 float xposBird;
 float yposBird = height * 0.25;

  Bird(String imagePrefix, int count) {
     imageCount = count;
     images = new PImage[imageCount];
     
     for (int i = 0; i < imageCount; i++) {
        String filename = imagePrefix + i + ".png";
        images[i] = loadImage(filename);
     }
  }

  
  void display(float xpos, float ypos) {
    frame = (frame+1) % imageCount;
    image(images[frame], xpos, ypos);
    image(images[frame], xpos, ypos);
  }
  
  void draw() {
     float drag = 30.0;
     float dx = mouseX - xposBird;
     xposBird += dx/drag;
     float dy = mouseY - yposBird;
     yposBird += dy/drag; 
     bird_1.display(xposBird-bird_1.getWidth()/2, yposBird-bird_1.getHeight()/2);  
  }

  
  int getWidth() {
     return images[0].width; 
  }
  
  int getHeight() {
     return images[0].height; 
  }
}

(5)、操作说明
键盘交互:
“a”向左走
“d”向右走
“1”召唤一只鸟
“2”种一棵树
“3”下雪
“4”下雨
“5”暴风雪
“6”删除所有内容
鼠标交互:
-鼠标点击狗来改变它摇摆尾巴的速度。
-鸟跟着光标移动。
-生成的树由光标位置决定,包括放置树的位置(光标的X轴)和树的高度(光标的Y轴)。

功能简介
 if (mousePressed) {
           fill(255, 255, 255, 50);
           rect(imageX, imageY, 1000, 500);
           fill(0);
           
           textSize(18);
           textFont(myFont);
           text("功能简介", imageX + 20, imageY + 20);
           textSize(12);
           text("“a”和“d”键移动人的向左向右。或者,使用上面的灰色滑块移动人。", imageX + 20, imageY + 40);
           text("按'1'键召唤小鸟跟随光标。或者,单击bird图标来调用它。它会跟随你的光标。", imageX + 20, imageY + 60);
           text("按“2”键种植一棵树。根据光标的x轴创建树;树的高度取决于光标的y轴;树干的宽度是随机的;叶的高度、宽度和层数是随机的。", imageX + 20, imageY + 80);
           text("按‘3’键下雪。或者,点击“Snow”按钮。可以使用滑块来改变雪的直径。", imageX + 20, imageY + 100);
           text("按“4”键使天下雨。或者,点击“Rain”按钮。可以使用滑块来改变水滴的大小。", imageX + 20, imageY + 120);
           text("按‘5’键制造暴风雪。或者,点击“暴雪”按钮。使用黑色的“暴雪”滑块来改变速度。", imageX + 20, imageY + 140);
           text("按'6'键删除所有内容。", imageX + 20, imageY + 160);
           text("鼠标点击狗来改变它摇尾巴的速度。", imageX + 20, imageY + 180);
      }
        
     }
     ......
 if (mousePressed) {
           fill(255, 255, 255, 50);
           rect(imageX, imageY, 1000, 180);
           fill(0);
           textSize(18);
           text("树、删除和狗的说明", imageX + 20, imageY + 20);
           textSize(12);
           text("对于树,按'2'键种植一棵树。根据光标的x轴创建树;\n \t树的高度取决于光标的y轴;树干的宽度是随机的;叶的高度、宽度和层数是随机的。", imageX + 20, imageY + 40);
           text("按'6'键删除所有内容。", imageX + 20, imageY + 80);
           text("鼠标点击狗来改变它摇尾巴的速度.", imageX + 20, imageY + 100);
           text("在‘介绍’按钮中列出的更多功能。.", imageX + 20, imageY + 120);
        
      }

4、知识涉及
1)、ArrayList
构造函数:
ArrayList<Type>()
ArrayList<Type>(initialCapacity)
参数:
类型类名:要放置在ArrayList中的对象的数据类型。
initialCapacity int:定义列表的初始容量;默认为空。
ArrayList存储的对象数量可变。这类似于创建对象数组,但使用arraylist,可以轻松地添加和删除arraylist中的项,并动态调整其大小。这可能非常方便,但比在使用许多元素时创建对象数组要慢。请注意,对于整数、浮点数和字符串的可调整大小的列表,可以使用处理类intlist、floatlist和stringlist。
ArrayList是Java列表接口的可调整数组实现。它有许多方法用于控制和搜索其内容。例如,arraylist的长度由其size()方法返回,该方法是列表中元素总数的整数值。元素用add()方法添加到arraylist,用remove()方法删除。get()方法返回列表中指定位置的元素。
2)、中文字体的设置与使用
a、首先,使用PFont类的静态函数list,可以列出当前系统可用字体,返回一个String[]数组。使用printArray显示。
b、要在Processing中绘制文字,必须创建PFont字体类型。
如图,根据系统字体创建,最简单的用法为:
PFont字体变量=createFont("字体名",字体大小);

设置字体

c、在默认渲染模式下,对于矢量字体,createFont函数中指定的字体大小无关紧要。但是在P2D模式和P3D模式下,createFont是创建纹理图片。
函数使用说明:
PFont -> 创建字体类型对象
loadFont("字体类型") //在工具中创建字体文件 (.vlw 类型的文件)
textFont(类型对象) //引用新创建的字体类型对象
textSize(x) //修改字体的大小
text("文本文件", x, y) //x,y 设定水平和垂直的位置, 这个位置是想对于文字的基线而言的
text("文本文件", 26, 30, width, height) //同上, width, height 表示绘制文字的区间高低宽度,

5、参考资料
1)、《代码本色:用编程模拟自然系统》
2)、Processing 入门教程(三十七)图层动画:https://blog.csdn.net/qq_39097425/article/details/85110281
3)、Processing 入门教程(十九) 图片动画:http://www.pianshen.com/article/1148135405/
4)、Processing大神教程:The Nature of Code -- 粒子系统:https://www.bilibili.com/video/av4044431/
5)、Processing 教程3--Arry和For Loop :http://www.sohu.com/a/205366456_654105

上一篇下一篇

猜你喜欢

热点阅读