首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在处理过程中,整个动画中只有一个soundFile,但只有一个类对象与声音交互。

在处理过程中,整个动画中只有一个soundFile,但只有一个类对象与声音交互。
EN

Stack Overflow用户
提问于 2021-06-06 09:42:36
回答 2查看 57关注 0票数 0

我对处理还是很陌生的,我正在尽我最大的努力找出这个项目:

我正在尝试创建一个顺序动画,在整个动画中播放一个soundFile。但是,只有第二类需要有声音响应元素。

在它们自己的草图文件中,所有三个类对象都可以单独工作。但不是当他们在一个素描中作为类。

现在我只有第二班的声音文件,因为我不知道如何拥有相同的声音文件,而是响应不同的类。

我不确定当不同的类需要背景时,它是如何工作的。我也不确定我的测序方法是否正确..。我很感谢你的帮助。谢谢你们!

代码语言:javascript
复制
One objectone;
Two objecttwo;
Three objectthree;

int myAnimationCounter = 0; //set myAnimationCounter incerment to 0, so allows to reset to 0 to start the animation.
int myAnimationCounter1 = 0;
int myAnimationCounter2 = 0;//set a parallel myAnimationCounter incerment to 0.
boolean startAnimation = false;  //Boolean switch to control starting animation.
boolean openingAnimation = false;

void setup() {
  size(displayWidth, displayHeight); //sketch present
  frameRate(50);
  objectone=new One();
  objecttwo=new Two();
  objectthree=new Three();
}

void draw() {
  
  if (openingAnimation) { //start the opening seq when press spacebar
    if ( myAnimationCounter>0 && myAnimationCounter<750) {
      objectone.show1();
    }
    myAnimationCounter++;
  }
  
  //when clicking the mouse 'openingAnimation' stops, playing 'startAnimation'
  
  if (startAnimation) {        
    if (myAnimationCounter1 > 0  && myAnimationCounter1 < 2500) {
        objecttwo.update2();
        objecttwo.show2();
      } else
      
        if (myAnimationCounter1 > 2500  && myAnimationCounter1 < 3000) {
objectthree.update3();                  
objectthree.show3();
        }
    myAnimationCounter1++;

//rect shape drawing at the bottom of the screen showing the playing progression of the animation

    if (myAnimationCounter2 > 0 && myAnimationCounter2 < 9000) { //independent animation through out the whole animation 
      fill(d);
      noStroke();
      rect(width, height-10, 10, width/myAnimationCounter2);
    }
    myAnimationCounter2++;
  }
}//end of draw


void keyPressed() {
  if (key == ' ') {
    openingAnimation = true;
  }
}

void mousePressed() {
  if (mousePressed) {
    startAnimation = true;
    openingAnimation=false;

    myAnimationCounter=0;
    myAnimationCounter1=0;
    myAnimationCounter2=0;
  }
代码语言:javascript
复制
class One {
  void show1() {
 background(bg);
}
}
代码语言:javascript
复制
class Two {
  import processing.sound.*;
  SoundFile loadSound; 
  Amplitude measureVol;
 void update2() {
    loadSound = new SoundFile(this, "music.mp3"); 
    loadSound.loop();  
    measureVol = new Amplitude(this);
    measureVol.input(loadSound);
  } 
  void show2() {
   float howLoud = measureVol.analyze();
}
}
代码语言:javascript
复制
class Three {
 void update3() {
  background(0);
}
 void show3() {
}
}
EN

回答 2

Stack Overflow用户

发布于 2021-06-06 17:39:10

您可以将您的声音代码放在它自己的单独类中。然后,将类实例化为Setup,并作为参数注入类Two。确保这个用于传递音频功能的类具有您希望从Two中调用的操作的公共方法。

例如:

代码语言:javascript
复制
class MyAudioClass {

SoundFile loadSound; 
Amplitude measureVol;

    public MyAudioClass() {
        measureVol = new Amplitude(this);
    }

    public void loadSound(String soundFileName) {
        loadSound = new SoundFile(this, soundFileName);
        measureVol = input(loadSound);
    }

    public void playSound() {
        loadSound.loop();
    }

    public float getHowLoud() {
        return measureVol.analyze();
    }
}

然后,在Two

代码语言:javascript
复制
class Two {
    private MySoundClass mySoundClass;
  
    // using Constructor Dependency Injection
    public Two(MySoundClass mySoundClass) {
        this.mySoundClass = mySoundClass;        
    }

    public float showHowLoud() {
        return mySoundClass.getHowLoud();
    }

(注意:我还没有使用过处理,我只是根据最好的猜测来转换您所写的内容--因此可能需要进行一些调整。)

如果您还需要将类注入到OneThree中,请使用IDK。也许你只需要在Setup中开始播放?只要您在Setup中处理的实例与在Two中处理的实例相同(或任何注入到的其他类),一切都会好起来的。

这种编码模式通常被称为依赖注入或控制反转的示例,非常有用。一个变体是使用setter方法而不是构造函数来传递您的声音资源类。

DI背后控制-the概念的倒置 这说明类不应静态地配置其依赖项,而应由其他类从外部配置。 这是S.O.L.I.D的第五个原则,也就是Bob叔叔提出的面向对象编程和设计的五个基本原则,即类应该依赖抽象而不是具体(简单地说,硬编码)。 根据这些原则,一个类应该专注于履行自己的责任,而不是创建完成这些职责所需的对象。这就是依赖注入的作用所在:它为类提供所需的对象。

以上内容摘自依赖项注入的快速介绍一文。

票数 1
EN

Stack Overflow用户

发布于 2021-06-12 22:07:23

从您的代码中,我理解的顺序是:

  • 如果按下空间,One实例将显示前750个“滴答”(15s,50 for )。
  • 如果按下鼠标,所有计数器重置以及标志
  • Two更新和显示的实例,用于前2500“滴答”(50到50 50s)
  • 然后,Three的一个实例将更新并显示在2500到3000“滴答声”之间(50到60之间的50 60s )。
  • 同时,对于前9000“滴答”(180在50 for ),将显示一个缩小的矩形。

关于background():它只是清除以前绘制的内容,否则绘制的内容就会累积起来。

以这个基本例子为例:

代码语言:javascript
复制
void setup(){
  size(300, 300);
  background(255);
}

void draw(){
  if(mousePressed){
    line(mouseX, mouseY, pmouseX, pmouseY);
  }
}

void keyPressed(){
  background(255);
}

当你把鼠标拖动到屏幕上时,线会不断地被画出来(即使是在对方上面)。当按下一个键时,背景(设置为白色)将重新绘制在前面所有行的顶部,并清除它们。

这就引出了代码中的另一个次要点:

代码语言:javascript
复制
void mousePressed() {
  if (mousePressed) {
    startAnimation = true;
    openingAnimation=false;

    myAnimationCounter=0;
    myAnimationCounter1=0;
    myAnimationCounter2=0;
  }
}

只有当鼠标被按下时,mousePressed()函数才会被调用,这使得if条件检查鼠标是否是多余的。这应足以:

代码语言:javascript
复制
void mousePressed() {
  startAnimation = true;
  openingAnimation=false;

  myAnimationCounter=0;
  myAnimationCounter1=0;
  myAnimationCounter2=0;
}

关于背景声音,在update2()中,它似乎每秒加载多次

代码语言:javascript
复制
class Two {
  import processing.sound.*;
  SoundFile loadSound; 
  Amplitude measureVol;
 void update2() {
    loadSound = new SoundFile(this, "music.mp3"); 
    loadSound.loop();  
    measureVol = new Amplitude(this);
    measureVol.input(loadSound);
  } 
  void show2() {
   float howLoud = measureVol.analyze();
}
}

我的假设是,update()将被多次调用以更新数字,而show()将被多次调用以呈现这些值(如文本、形状等)。

由于在Two中实例化了setup(),所以可以在Two的构造函数中加载一次声音:

代码语言:javascript
复制
class Two {

  SoundFile loadSound; 
  Amplitude measureVol;

  float howLoud;
  // this gets called once when you make a new instance (e.g = new Two())
  Two() {
    loadSound = new SoundFile(this, "music.mp3"); 
    loadSound.loop();  
    measureVol = new Amplitude(this);
    measureVol.input(loadSound);
  }

  void update() {
    howLoud = measureVol.analyze();
  } 
  void show() {
    fill(127);
    text("Two instance show() -> howLoud: " + howLoud, 10, 15);
  }
}

通过这种方式,声音被创建并循环一次,然后只在调用update()时(在startAnimation的前2500个更新中)进行分析。

为了保持一致性,我建议使用update()/show(),并在理想情况下将实例命名为类似于其他变量(例如objectOneobjectTwoobjectThree)。理想情况下,导入语句将位于代码的顶部。

下面是一个稍微修改过的代码版本,请记住上面的备注:

代码语言:javascript
复制
import processing.sound.*;

One objectOne;
Two objectTwo;
Three objectThree;

int myAnimationCounter = 0; //set myAnimationCounter incerment to 0, so allows to reset to 0 to start the animation.
int myAnimationCounter1 = 0;
int myAnimationCounter2 = 0;//set a parallel myAnimationCounter incerment to 0.
boolean startAnimation = false;  //Boolean switch to control starting animation.
boolean openingAnimation = false;

color bg = color(255);
color d = color(192, 0, 0);

void setup() {
  size(displayWidth, displayHeight); //sketch present
  frameRate(50);

  objectOne   = new One();
  objectTwo   = new Two();
  objectThree = new Three();
}

void draw() {
  background(255);

  if (openingAnimation) { //start the opening seq when press spacebar
    if ( myAnimationCounter>0 && myAnimationCounter<750) {
      objectOne.show();
    }
    myAnimationCounter++;
  }

  //when clicking the mouse 'openingAnimation' stops, playing 'startAnimation'

  if (startAnimation) {        
    if (myAnimationCounter1 > 0  && myAnimationCounter1 < 2500) {
      objectTwo.update();
      objectTwo.show();
    } else if (myAnimationCounter1 > 2500  && myAnimationCounter1 < 3000) {
      objectThree.update();                  
      objectThree.show();
    }
    myAnimationCounter1++;

    //rect shape drawing at the bottom of the screen showing the playing progression of the animation

    if (myAnimationCounter2 > 0 && myAnimationCounter2 < 9000) { //independent animation through out the whole animation
      fill(d);
      noStroke();
      rect(mouseX, mouseY, 10, width / myAnimationCounter2);
    }
    myAnimationCounter2++;
  }

  // debug
  fill(127);
  text("openingAnimation: " + openingAnimation + "\n" + 
    "startAnimation: " + startAnimation + "\n" + 
    "myAnimationCounter: " + myAnimationCounter + "\n" +
    "myAnimationCounter1: " + myAnimationCounter1 + "\n" + 
    "myAnimationCounter2: " + myAnimationCounter2 + "\n", 10, 30);
}//end of draw


void keyPressed() {
  if (key == ' ') {
    openingAnimation = true;
  }
}

void mousePressed() {
  startAnimation = true;
  openingAnimation=false;

  myAnimationCounter=0;
  myAnimationCounter1=0;
  myAnimationCounter2=0;
}

class One {
  void show() {
    background(bg);
    text("One instance show()", 10, 15);
  }
}

class Two {

  SoundFile loadSound; 
  Amplitude measureVol;

  float howLoud;

  Two() {
    loadSound = new SoundFile(this, "music.mp3"); 
    loadSound.loop();  
    measureVol = new Amplitude(this);
    measureVol.input(loadSound);
  }

  void update() {
    howLoud = measureVol.analyze();
  } 
  void show() {
    fill(127);
    text("Two instance show() -> howLoud: " + howLoud, 10, 15);
  }
}

class Three {

  void update() {
  }
  void show() {
    background(0);
    text("Three instance show()", 10, 15);
  }
}

此外,我还做了一些其他的小改动:

  • 我在text()底部添加了draw(),这样就更容易调试行为了。您可以可视化布尔值和计数器的值。
  • 每个show()方法还使用text()来可视化正在呈现的实例。
  • 目前还不清楚rect()调用的目的是什么,但是坐标在屏幕外。作为一项测试,我已经将rect()位置按到鼠标位置:请随意将其更改为对您的应用程序有意义的东西。如果这是动画持续时间的可视化,则假设总持续时间是9000计数。不过,目前还不清楚其意图是将其变成水平的还是垂直的(也许是垂直的?)如果它应该增长或收缩(目前它收缩)

我还注意到myAnimationCounter2更新与myAnimationCounter1同步/速率,这使得它们完全相同。如果是这样的话,也可以使用myAnimationCounter1绘制矩形,而myAnimationCounter2可以被丢弃以简化代码。如果您有计划让myAnimationCounter1在未来独立于myAnimationCounter2进行更新,那么保持它是值得的。

每次用户单击计数器时,计数器都会重置,但是打开的动画只能在用户按下空格键之后才显示一次,但不能重置。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67857735

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档