2021年1月18日 星期一

week15_鄭皓文

 

       臨近期末要開始準備作品了,所以這星期咱要返璞歸真,回到P語言圖學上,可能會對我們的期末作品有幫助,首先我們先回到矢量顯示圖片的功能上,原理和期中考前我們學過的差不多,只是結構稍微複雜了一些,程式碼如下:

 

size(775,1000);

PImage img=loadImage("img.png");

PVector user=new PVector(10,20,0);

PVector user2=new PVector(30,40,50);

image(img,0,0);

print("user's="+user.x);

println(" user2's="+user2.x);

這樣就可以展示出某部70年代經典電影的海報了

  

所以其實矢量坐標的觀念和我們在圖學中接觸過的十分相似,那通過這個方式我們也可以利用坐標軸將我們需要的圖形設定在特定位置,例如我可以讓一個半徑為5的圓產生在(100100)的位置,程式碼如下:
PVector user;

void setup()

{

  size(600,600);

  user=new PVector(100, 100);

}

void draw()

{

  background(255);

  ellipse(user.x,user.y,50,50);

}

真的可以説是夢回圖學了

   接下來老師教了我們如何使用P寫出Angry Bird的彈弓發射程式,雖是簡化版的但基本有彈弓發射的雛形,要是加上牛頓原理會更逼真,代碼如下:

PVector user;

PVector Y,v=null;

void setup()

{

  size(600,600);

  user=new PVector(100, 300);

  Y= new PVector(100,300);

}

void draw()

{

  background(255);

  line(user.x,user.y,Y.x,Y.y);

  textSize(40);

  fill(255,0,0);text("Y",Y.x,Y.y);

  fill(255); ellipse(user.x,user.y,20,20);

  if(v!=null)

    user.add(v);

}

void mouseDragged()

{

  user.x=mouseX;

  user.y=mouseY;

}

void mouseReleased()

{

  PVector diff = PVector.sub(Y, user);

  v=diff.div(10);

}

但生成的結果綫會一直連著,所以我感覺相對彈弓這更像投石索

  

   現在我們要給游戲加上新功能,使用搖桿操作彈弓,所以理論上我們需要UNO可以回傳搖桿的坐標值給此時的Processing使用,所以我們要先使用如下的程式碼:
void setup()

{

  pinMode(2,INPUT_PULLUP);

  Serial.begin(9600);

}

void loop()

{

  int x = analogRead(A0);

  int y = analogRead(A1);

  int sw = analogRead(2);

  Serial.write(x/4);

  Serial.write(y/4);

  Serial.write(sw);

  delay(20);

}



 

然後我們需要測試一下是否可以在Processing中正常運行,使用如下的程式碼測試⚪的移動軌跡就可以了:

假如把殘影打開的話可以產生連點呈現的效果

   最後只要把這兩部合并,放在剛剛寫出的彈弓上,就是我們要的最終效果了:

import processing.serial.*;

Serial myport;

PVector user;

PVector Y,v=null;

void setup()

{

  size(600,400);

  myport = new Serial(this,"COM3",9600);

  user = new PVector(100,300);

  Y = new PVector(100,300);

}

void draw()

{

  background(255);

  if(myport.available()>=3)

  {

    int x = myport.read();

    int y = myport.read();

    int sw = myport.read();

    user.x = 100+x-128;

    user.y = 900+y-128;

  }

  textSize(40);

  fill(255,0,0); text("Y",Y.x,Y.y);

  fill(255); ellipse(user.x,user.y,20,20);

   if(v!=null)

   {

    user.add(v);

    v.y+=9.8;

   }

}

這樣就是最後的效果,不過好像⚪飛的太快了

      這就是這星期我們學到内容,接下來要進行期末作業製作,這個確實可以給人提供不少項目的靈感。

week14_鄭皓文

 

       這星期要學習的是通過搖桿進行更多的操作,然後還新發了一個可變電阻下來,不過我該怎麽説呢畢竟是免費的東西但運行的時候放出的氣味讓我一度以爲我操作不當把它燒了(那種氣味和顯卡短路的時候挺像的),先從最簡單的通過搖桿控制聲音頻率開始,下面放程式碼:

void setup()

{

  pinMode(13,OUTPUT);

  pinMode(8,OUTPUT);

}

 

void loop()

{

  int now = analogRead(A0);

  tone(8,now);

}

其實不只是搖桿,感覺只要是非綫性電阻就能這麽搞了

      

其實就是通過信號的不同控制某一區域的電流造成音階變化,所以相同的效果也可以運用在板載LED上面,通過下面這個程式就可以控制UNOLED的閃爍變化程度:

void setup() {

  for(int i=2;i<=13;i++){

    pinMode(i,OUTPUT);

  }

}

void loop() {

  int now =analogRead(A0);

  int level =now/(512/13);

  for(int i=2;i<=13;i++){

    if(i<level)digitalWrite(i,HIGH);

    else digitalWrite(i,LOW);

  }

}

所以如果有LED燈條的話接上去就可以作爲RGB控制器了

 

同理,我們也可以讓他顯示搖桿在不同的位置時產生的不同字母符號等等,代碼如下:

void setup() {

  for(int i=2;i<=13;i++){

    pinMode(i,OUTPUT);

  }

  Serial.begin(9600);

}

 

void loop() {

  int now=analogRead(A0);

  int leve1 = now/(1024/13);

  for(int i=2;i<=13;i++){

      if(i<leve1) digitalWrite(i,HIGH);

      else digitalWrite(i,LOW);

    }

    Serial.write(('A'+leve1));

    delay(100);

}

可以顯示A-N,有點類似於數據坐標系

      

       既然我們可以寫出這麽多的功能,那我們肯定可以寫一些有趣的東西,例如通過遙感給血條加血(簡直是開挂啊),但是製作這個功能的時候因爲會用到圖像顯示,所以又要麻煩Processing再跑出來一次,代碼如下:

首先是Arduino的:

void setup() {

  for(int i=2;i<=13;i++){

    pinMode(i,OUTPUT);

  }

  Serial.begin(9600);

}

 

void loop() {

  int now = analogRead(A0);

  int level = now/4;

  for(int i=2;i<=13;i++){

    if(i<level) digitalWrite(i,HIGH);

    else digitalWrite(i,LOW);

  }

  Serial.write(level);

  delay(20);

}



然後是Processing那邊的:

import processing.serial.*;

Serial myPort;

void setup(){

  size(700,100);

  myPort = new Serial(this,"COM3",9600);

}

int level = 0;

void draw(){

  background(255);

  fill(0,50,200);

  rect(0,0,level*3,100);

  if(myPort.available()>0){

    int now = myPort.read();

    level = now;

  }

}

這功能真的NB,要是玩格鬥游戲的時候可以這麽搞就好了

   

week13_鄭皓文

 

      今天又有新設備了,是個手柄上頭的搖桿,講真我總覺得這貨比switch上頭的那個joycon還還好些,而且居然還有下壓回饋,比隔壁N開頭的企業强多了,早知道要用杜邦綫我就上淘寶成捆的,單芯綫真的容易接觸不良。

      接完綫之後我們先寫一個按壓就會發聲的程式,大致的代碼如下:

 

void setup()

{

  pinMode(2,INPUT_PULLUP);

  pinMode(8,OUTPUT);

}

int state=0;

void loop()

{

  if(digitalRead(2)==LOW)

    tone(8,2500,100);

  else

    noTone(8);

}

要注意的是兩個COM端口不能同時用,要不然會衝突

   現在我們的搖桿有了觸發按鍵的功能,但是除了讓它發出聲音,我們也可以通過程式展示它目前的運行狀態,例如我們可以通過顯示1/0查看此時的搖桿是否被按下,程式碼如下:
void setup()

{

  Serial.begin(9600);

  pinMode(2,INPUT_PULLUP);

  pinMode(8,OUTPUT);

}

int state=0;

void loop()

{

  if(digitalRead(2)==LOW && state==0)

  {

    state=1;

    Serial.write("1");

  }

  if(digitalRead(2)==HIGH && state==1)

  {

    state=0;

    Serial.write("0");

  }

  delay(100);

}

所以如果可以識別長按或短按的話是不是可以發摩斯電碼

   再此之後我們便可以利用上周學到的與Processing連接的功能,使用P語言展示此時的按鍵使用狀態,設定好鏈接后Processing程式碼如下:

import processing.serial.*;

Serial myPont;

 

int button=0;

void setup(){

  size(300,300);

  myPont = new Serial(this, "COM5",9600);

 

}

void draw(){

  if(myPont.available()>0){

    int now = myPont.read();

    if(now == '1')button=1;

    else button=0;

  }

  if(button==1)background(#F5ABAB);

  else background(#FF0303);

 

}

          Arduino的代碼基本相同這裏就不放了,多了一個設定步驟

   最後我們還可以學到如何用UDP的方式傳送信息到老師的電腦上,這個比較簡單,所以學了這麽久我寫的第一個網絡相關程式居然是這個?代碼如下:

import hypermedia.net.*;

UDP udp;

void setup(){

  size(300,200);

  udp = new UDP(this,6000);

  udp.send("Connect","120.125.70.41",6100);

 

}

void draw(){

 

}

void mousePressed(){

  udp.send("mousePressed","120.125.70.53",6100);

}

               然後我發現只要你按的夠快就可以手動RGB漸變

最後發一張宿舍的IP地址圖,歡迎大家來DDOS我(誤)

week12_鄭皓文


       上星期我们学习了如何用UNO蜂鸣器播放预先准备好的音乐,这星期我们要学的是如何把UNO变成可以弹奏的乐器,不过这次我们要请出Processing帮忙才可以完成任务,程式码如下:

这边是Arduino要烧录的:

#define Do 523

#define Re 587

#define Mi 659

#define Fa 698

#define So 784

#define La 880

#define Ti 988

#define Doo 1046

void setup() {

  Serial.begin(9600);

  pinMode(2,INPUT_PULLUP);

  pinMode(8,OUTPUT);

  tone(8,Do);

  delay(1000);

  tone(8,Mi);

  delay(1000);

  tone(8,So);

  delay(1000);

  noTone(8);

}

void loop() {

 while(Serial.available()>0){

  int now = Serial.read();

  if(now=='0') noTone(8);

  if(now=='1') tone(8,Do);

  if(now=='2') tone(8,Re);

  if(now=='3') tone(8,Mi);

  if(now=='4') tone(8,Fa);

  if(now=='5') tone(8,So);

  if(now=='6') tone(8,La);

  if(now=='7') tone(8,Ti);

  if(now=='8') tone(8,Doo);

 }

}

根据网上查到的音符表可以补全剩下的音阶

 

这边是Processing里要写的:

import processing.serial.*;

Serial myPort;

void setup(){

  size(200,200);

  myPort = new Serial(this,"COM5",9600);

}

void draw(){

  

}

void keyPressed(){

  if(key=='0') myPort.write("0");

  if(key=='1') myPort.write("1");

  if(key=='2') myPort.write("2");

  if(key=='3') myPort.write("3");

  if(key=='4') myPort.write("4");

  if(key=='5') myPort.write("5");

  if(key=='6') myPort.write("6");

  if(key=='7') myPort.write("7");

  if(key=='8') myPort.write("8");

}

按下0就可以静音,COM可以根据自己電腦的狀況自行调整

     

于是在最后我这个五音不全的人还是做出了一个勉强可以演奏的乐器,不过感觉还是GitHub上边那些大神的作品比较nb些。

2021年1月17日 星期日

week14

 用joysick控制血條

arduino:

void setup() {
  // put your setup code here, to run once:
  for(int i=2;i<=13;i++){
    pinMode(i,OUTPUT);
  }
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  int now = analogRead(A0);
  int level = now/4;
  for(int i=2;i<=13;i++){
    if(i<level) digitalWrite(i,HIGH);
    else digitalWrite(i,LOW);
  }
  Serial.write(level);
  delay(20);
}
processing:
import processing.serial.*;
Serial myPort;
void setup(){
  size(700,100);
  myPort = new Serial(this,"COM4",9600);
}
int level = 0;
void draw(){
  background(255);
  fill(0,50,200);
  rect(0,0,level*3,100);
  if(myPort.available()>0){
    int now = myPort.read();
    level = now;
  }
}

12/7

 按joystick會變色


按下joystick發出聲音

void setup() 
{
  // put your setup code here, to run once:
  pinMode(2,INPUT_PULLUP);
  pinMode(8,OUTPUT);
}
int state=0;
void loop() 
{
  // put your main code here, to run repeatedly:
  if(digitalRead(2)==LOW)//當板上按鈕按下時或joystick按下時
    tone(8,2500,100); //發出聲音
  else
    noTone(8);
}

按下joystick用1、0表示有沒有按
void setup() 
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(2,INPUT_PULLUP);
  pinMode(8,OUTPUT);
}
int state=0;//開關狀態
void loop() 
{
  // put your main code here, to run repeatedly:
  if(digitalRead(2)==LOW && state==0)
  {
    state=1;//當按鈕按下去時
    Serial.write("1");
  }
  if(digitalRead(2)==HIGH && state==1)
  {
    state=0;//按鈕沒按時
    Serial.write("0");
  }
  delay(100);
}

FINAL!!!






 process

import processing.serial.*;////

Serial myPort;////

int count=1800;//60*30

PImage candy;

PImage car;

PImage bg;

PImage die;

PImage heart;

PImage win;

float [] candyX=new float[10];

float [] candyY=new float[10];

float carX=235, carY=450;

int score=150;

int h=0;

void setup() {

  size(513, 615);

  myPort = new Serial(this, "COM5", 9600);////

  for (int i=0; i<10; i++) {

    candyX[i] = random(70, 295);

    candyY[i] = -i*100;

  }

  candy = loadImage("candy.png");///糖果

  car = loadImage("car.png");

  bg = loadImage("bg.jpg");

  die =loadImage("die.png");

  win =loadImage("win.png");

}

float vx=0;

//float vy=0;

void draw() {

  if (h==0) {

     

    image(bg, 0, 0, 513, 615);

    //background(255);

    //carX=mouseX-47;

    while (myPort.available()>=1)

    {

      int x = myPort.read();

      ///int y = myPort.read();

      //int sw = myPort.read();

      vx= (x-128)/32;

      // vy=(y-128)/32;

      println(vx);

      //carY=y;

    }

    carX += vx;

    // carY += vy;

    image(car, carX, carY, 50, 100);

    for (int i=0; i<7; i++) {

      image(candy, candyX[i], candyY[i], 60, 60);

      candyY[i]+=2;

      if (candyY[i]>615)

      {

        candyY[i]=-300;  //-183

        candyX[i]=random(70, 295);///糖果重生

      }

      if (candyY[i]+60>carY) {

        if (carX<candyX[i]+58 && candyX[i]<carX+48) //2cm

        {///車碰到糖果

          score+=10;

          candyY[i]=-150;

        }

      }

    }

    if (count<0) {

      background(0, 0, 0);

      h=1;

    } else {

      count--;

    }

    textSize(50);

    fill(25, 25, 250, 250);

    text("Time: "+int(count/60), 250, 50);

    textSize(50);

    text(score, 50, 100);

  }

  if (count<0 && score<600)

   {

    h=1;

    image(die, -35, 100, 600, 350);

   }

   if (count<0 && score>=600)//超過六百分才贏

   {

    h=1;

    image(win, -35, 100, 600, 350);

   }

}


void keyPressed() {

  //count=1800;

  if (keyCode == ENTER)

  {

    h=0;

    score=150;

  }

}

arduino

void setup()

{

  pinMode(2, INPUT_PULLUP);//拉高的Input

  Serial.begin(9600);//開始設定USB的傳輸速度

}

void loop() {//1000Hz (1000 fps)

  int x = analogRead(A0);//0...1023

  //int y = analogRead(A1);//0...1023

 // int sw= digitalRead(2);//HIGH(放開)

  Serial.write (x/4);//第1個byte

  //Serial.write(y/4);//第2個byte

  //Serial.write (sw); //第3個byte

  delay(20);//1000ms/20ms => 50fps,變慢了

}