美文网首页
作业汇报:融入动画技术的交互应用

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

作者: Pippi_ | 来源:发表于2019-04-29 22:46 被阅读0次

    一、要求

    主题:自拟

    技术:
    参考《代码本色》教程,运用不少于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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/xblpnqtx.html