第 11 週   從 Arduino 送命令給 PC 電腦(與之前相反方向!)

使用可變電阻 (potentiometer) 來控制電腦上的 Processing 畫面上之矩形的水平移動。    這次還是要使用到三色 LED 模組, 請把其中一色(例如紅色R)接在 Arduino 數位腳(Digital pin) 9 號; 並把 V (印錯的) 連接到 Arduino 的 GND 地。 另外, 這次主要增加了可變電阻器(VR,Variable Resistor),又稱電位器(英文:Potentiometer,通俗上也簡稱Pot)。 可變電阻器,或簡稱可變電阻,顧名思義,就是可以調整電阻的大小。可變電阻是一種具有三個連接端子, 其中有兩個固定接點與一個滑動接點,可經由滑動(捲動)而改變滑動端與兩個固定端間電阻值的電子零件。 把滑動端點連接到 Arduino 的類比腳(Analog Pin), 就可以讀取 0 到 1023的值。

投資自己,讓今天的自己 比 昨天的自己 更值錢 !


一位越南學生做的 Flappy Bird: https://youtu.be/Tn9FR4TjqEw 每天光廣告費就賺進大約台幣一百六十五萬元(美金五萬元)! https://youtu.be/Tn9FR4TjqEw
大家要加油 !     如何讓男友戒掉LOL and 神魔之塔? 要拼才會贏啦 !
越南基本工資十五年來增加十六倍(Gogle.com)
Arduino 與 可變電阻的連接: 注意可變電阻中間的腳要接到類比輸入(Analog Input) pin 0 (就是 A0), 剩下的兩支腳,一支接到 5V,另外一支接到 GND 地。 (不過為了方便, 我們用三條杜邦公公線和三條鱷魚夾線連接即可) Hint: 就是先把三條杜邦公公線的一端分別插入Arduino 的 5V, GND, 和 pin A0 (注意是 A0 不是 0 喔!) 然後拿三條鱷魚夾線各自夾住該三條杜邦公公線的另一端, 最後, 把這三條鱷魚夾線的另一端拿來夾可變電阻的三個接點。 ** 注意, 可變電阻的中間那接點要連接到 A0, 另外兩接點隨便, 不過, 建議把可變電阻旋鈕往右轉的那邊接 5V, 這樣往右轉時可讀取到比較大的值。 *** 可以點這看看 https://youtu.be/btDie54Ygzw
黃競賢同學可獲得加分 ! 因為他建議用小麵包板(在我們盒子內一塊小小很多洞孔的)就可以省去那三條鱷魚夾線, 可以直接 把可變電阻的三支連接腳插入麵包板的孔(注意方向), 再把該可變電阻的 三支腳對應的孔連接到 Arduino 的 A0 (中間腳), 以及 5V 和 GND, 可以用杜邦公公線或是網路剝下來的電力連接線, 如下圖:  

注意麵包板的方向, 它每五個洞連在一起, 所以可變電阻的三支腳不是插到同一排喔 ! 請再看一下這陳信安幫忙拍的照片:

以下是林廷儒同學的照片, 很清楚, 有加分 :-)

關於麵包板的使用常識與注意事項, 可以點這看我在開學時給大家的 "Arduino 初體驗" 講義(pdf) (在該篇捲到接近最後處)
關於麵包板的使用常識與注意事項, 可以點這看我在開學時給大家的 "Arduino 初體驗" 講義(pdf) (在該篇捲到接近最後處)
Q: 為何不直接把可變電阻的三支腳插入杜邦公母線的母孔?
Ans: 
     我也很想啊 :-)
     可是你自己插看看, 就是太鬆啊, 會掉下來ㄟ;
     所以, 不想用鱷魚夾線那就請改用小麵包板啦, 但是仍需要三條杜邦公公線或連接線!
    這次也要順便使用到三色 LED 模組,
但 只先用到其中一色, 請接在 Arduino 數位腳(Digital pin) 9 號;
在調整可變電阻時, 除了把讀取的值送去 PC 之外,
也順便控制三色 LED 模組的一種顏色(連接在 Pin 9)。
** 請注意, 不論是圖, 還是貼入程式碼, 
   都請先編號並寫一兩句簡單標題或說明! 例如:
      (1)以下圖片可以看到從電腦調整可變電阻之時, 也可看到 LED 燈光明亮的變化 ! 

(1)先測試 可變電阻 的值如何變化?(對啦, 跟測光敏電阻完全相同!)
   注意要把可變電阻的  中間那支Pin, 連接到 Arduino 的 A0 腳 (Analog Pin 0) !!
   (參考前面圖示)
       準備開始囉! 先確定你的電腦認識 Arduino 板子, 開啟 Arduino 的 IDE 開發工具,
   當然還要確認 Board 板子選 Uno, 
   確認 COM 串口編號選擇正確!!
     (a)開啟 AnalogInput 範例檔:(別懷疑, 跟測光敏電阻完全相同!)
           File 檔案 >  Examples 範例  >  3.Analog 類比  >  AnalogInput
     (b)編譯並上傳 Arduino 板子以便測試, 
        請將手指夾於 LED 與 紅外光敏電阻 中間, 注意內建 Pin 13 的 LED 燈變化 !
        以下是原範例的內容+加上要你加入之紅色部分的程式碼:
int sensorPin = A0;    // select the input pin for the potentiometer
int ledPin = 13;      // select the pin for the LED
int sensorValue = 0;  // variable to store the value coming from the sensor
 
void setup() {
  // declare the ledPin as an OUTPUT:
  Serial.begin(9600);  // 啟動通訊 (你須開啟 Serial Monitor 序列埠監視器或稱串口監視器)
  Serial.println("  I am  你的學號 你的英文姓名(自己拼音)");   // 我是誰? 
  pinMode(ledPin, OUTPUT);  
} // setup( 
void myPrint(int ggyy) {  // 把 ggyy(即sensorValue) 連同一些信息印到串口監視器
  Serial.print( ggyy );  // 印到串口監視器 
  Serial.print(String("  at ") + millis( ) );  // 印出當時開機後的 milli second
  Serial.println("   I am  你的學號 你的英文姓名(自己拼音)");   
} // myPrint( 
void loop() {
  // read the value from the sensor: 
  sensorValue = analogRead(sensorPin);   // 讀取 sensorPin 類比腳的值 0 ~ 1023 
  myPrint( sensorValue );  // 印到串口監視器  
  // turn the ledPin on 
  digitalWrite(ledPin, HIGH);  
  // stop the program for  milliseconds:
  delay(sensorValue);          
  // turn the ledPin off:        
  digitalWrite(ledPin, LOW);   
  // stop the program for for  milliseconds:
  delay(sensorValue);   // 關燈後也延遲 (Delay) 一下下               
}
(c)請參考上面程式碼把紅色的那幾列加入你的程式碼; 重新編譯上傳測試; **其實開新檔(File > New) 然後複製我這版本貼入修改即可 :-) 記得開啟 序列埠監控視窗(以後我們跟著老共稱"串口監視器"): Tool 工具 > Serial Monitor 序列埠監控視窗(串口監視器) (此時會彈出一個小視窗, 用來監控從 Arduino 傳入電腦的資料, 其實, 必要時也可用鍵盤打字到在該小窗並傳送給連接在 USB 線的 Arduino 喔 !) 把Serial Monitor窗拉長拉大, 類似下圖的模樣, 且與 IDE 窗 拉開 適當擺放螢幕中間兩側, 準備抓畫面或拍照繳交囉。 (d)轉動可變電阻觀察, 必要時找同學幫忙轉, 確定 Serial Monitor 有變化, 你自己用 CTRL_PrintScr 抓下今天要繳交的第一張圖片 ! 注意這張圖片上方要寫(1)我是..你學號你姓名, 圖片中可看出..(自己寫出狀況!) (2)修改程式碼, PC 端改用 processing 接收資訊做事, 並抓畫面 !? 其實是更換用另一個範例啦 ! 修改過的程式碼如下, 包括 Arduino 這邊的, 以及 PC 端的 processing 程式碼! 你的學號與姓名改為在 PC 端的 processing 程式內秀到電腦螢幕上 ! 注意, Arduino 的 Serial Monitor 一定要關閉以免搶走 processing "接收資訊" 的權力 ! 還有, 請確認 processing 程式碼內的 COM port 是否正確! /// /// ///
//Arduino 程式 //讀取接在 Analog pin 0 (A0)上的可變電阻,並將讀值列印到 Serial Port : int potPin = 0; // 就是 A0, 可變電阻接 analog pin 0 (注意此時 0 就是 A0 喔) int ledPin = 9; // 把三色 LED 的紅色 R 連接到 Arduino D9 數位腳 9 long delayTime = 100; // 0.1 秒 void setup( ) { // 開啟 Serial port, 通訊速率為 9600 bps Serial.begin(9600); } void loop( ) { int sensorValue = analogRead(potPin); // 讀取可變電阻 int gg = map(sensorValue, 0, 1023, 0, 255); // 相當於把讀值除以 4, 把 0-1023 的數值按比例縮放為 0-255 之間的數值 // 就是 int gg = sensorValue/4; analogWrite(ledPin, gg); // 送去給 LED // 以下將讀值列印到 Serial Port, 以一個位元組(Byte)的格式寫出 Serial.write(gg); // 輸出一個位元組( one Byte )到 PC 端 delay(delayTime); } // loop( //////// 以下是 processing ////////////////////////////////////// /// /// Processing 程式, 讀取從 Serial Port 傳進來的 Sensor 讀值, ///// 然後利用 Sensor 的讀取值控制矩形的水平移動: /* Processing 範例: * 讀取從 Serial Port 傳進來的 Sensor 讀值 * 利用 Sensor 讀值移動矩形 (Rectangle) */ import processing.serial.*; Serial ardu; // 定義串口為 ardu int sensorValue; int xx, yy = 66; int rectSize = 50; // 方形大小 String ggyy = "我是008007 張大頭"; // 你的學號與中文姓名 String myArduino = "COM4"; // 請確認你的Arduino 是否接在 COM port # PFont f; // 字型 void drawMyName( ) { fill( color(255, 33, 255) ); // 紫光 text(ggyy, width/2-56, 32); // 你可以改印出的位置 fill( color(22, 255, 255) ); // 民進黨+國民黨 text("哈哈哈", 58, height-28); // 左下角 } // drawMyName( void showValue(int gg) { println("" + gg + " by " + ggyy); // 在座標 (xx, yy) 的位置畫一個 50 x 50 的矩形 background(222); // 白色帶點灰背景 fill(255,0,0); // 填滿顏色為紅色 rect(xx, yy, rectSize, rectSize); fill(22, 22, 255); // 藍色 text(" " + xx, 58, 32); // 左上角 drawMyName( ); } // showValue( void setup( ) { // 設定畫布大小為 256+50 x 168 size(256+rectSize, 168); // 開啟 Serial port,前面命名ardu, 通訊速率為 9600 bps ardu = new Serial(this, myArduino, 9600); f = createFont("SimSun", 24, true); // 仿宋體 textFont(f, 24); // 你可改字型大小 println(ggyy); } // setup( void draw( ) { if ( ardu.available( ) > 0) { // 讀取從 Serial Port 傳進來的 Sensor 值 sensorValue = ardu.read(); xx = sensorValue; showValue(sensorValue); } } // draw( ////////////////////// 請至少拍下兩張照片或圖片, 一張是讀取的可變電阻值在 15到30之間, 另一張是在大於225之時! 畫面要看得到你的學號與姓名; 如果用拍照則請順便把你的可變電阻旋鈕與三色 LED 燈一起拍進去, 這樣可以獲得額外加分 :-)





以下是以前玩過的 processing 簡單範例, 再拿來讓大家參考 !


(一)練習四個 Processing 簡單範例並夾檔繳交4張圖片 !
    因為大部分同學覺得程式碼太大就看不下去,
所以, 在開始修改今天的 Java Applet 範例之前, 
先來玩另一個可以寫小小程式且有趣的程式語言 processing :-) (其實就是Java)
(a)先到 http://processing.org 抓 processing 壓縮檔
     如果網路太慢, 那就點這抓這放在學校的processing版本
(b)解壓縮之後, 找到資料夾內 processing.exe 連點兩下
(c) File  >  Preference  然後把字體改為 SimSun, 並把字型大小改為 14
(d)複製以下程式碼進去執行 (真的只有兩列, 不要懷疑)

void setup( ){  size(666, 555);  }
void draw( ){ if(mousePressed) line(mouseX, mouseY, pmouseX, pmouseY);}
(e)Play執行起來, 把窗拉到適當位置不要擋住程式碼
, 請簡單畫出你的自畫像(類似大頭照樣子即可, 不要花太多時間!), 用滑鼠在畫面上左上角畫出你的學號與姓名; 然後用 Ctrl_PrintScr 抓下全螢幕, 這是今天要繳交的第一張圖片 ! (f)不夠癮? 那再來一個 processing 小程式! 抓完剛剛的圖之後, 複製以下程式碼進去processing: (蓋掉剛剛的程式碼即可)

// a simple processing program -- by tsaiwn@ydu.edu.tw
// Processing 是 MIT 專為不懂程式的藝術家設計的電腦語言(其實是把Java簡單化!)
void setup( ) {  // 只做一次
   size(666, 555);  background(123);
}
int w = 8;
void draw( ) {  // 就是 Java 的 paint( )
  int g = (mouseX + mouseY)*7 % 255;  // 黑白算的啦
  int r = (mouseX * mouseY) %255;  // 也是慶菜算 :-)
  stroke(r, g, 255);  // 筆顏色
  strokeWeight( w ) ;  // 筆粗細
  if(mousePressed) line(mouseX, mouseY, pmouseX, pmouseY);
} // draw(
void mouseReleased( ) {  // 每當滑鼠被放掉時
  w =  int(3 + random(8));
}
//////////////
(g)把程式 Play 起來, 左下角畫出你學號, 右上角畫出你姓名; 並且要在畫面中央畫個最像你自己臉的素描自畫像(簡單就好:-) 然後用 Ctrl_PrintScr 抓下全螢幕, 這是今天要繳交的第 2 張圖片 ! (h)還是不夠癮, 再來一個比較有畫家味道的!! 抓好剛剛畫的圖片之後, 請複製以下程式蓋掉原程式:

//請畫你印象中的梅花, 可參考 http://goo.gl/mMyY2r 
// by tsaiwn@ydu.edu.tw
// 也可用 gogle.com 搜尋 "吳冠中" 畫家
//////
  int c = int(random(0, 8)); 
  color clr = color(88, 88, 88, 255);
void setup() { 
 size(777, 666);  background(251); smooth( ); 
} // setup(
void draw() { 
  if ( !mousePressed ) return;
  float a = dist(mouseX, mouseY, pmouseX, pmouseY); 
  stroke(clr); strokeWeight(random(1, 5)); 
  if(mouseButton != RIGHT ) {
     c = int(random(0, 8)); 
     line(mouseX, mouseY, pmouseX, pmouseY); 
  }
  if(c < 3) fill(204, 51, random(50, 68), random(120, 255));
  if(c == 3)  fill(255, 255, 0, random(153, 255));  
  if(c == 4)  fill(255, 128, 0, random(128, 153)); 
  if(c > 4) fill(0, random(102, 255)); 
  if(a > 158) a = a / 2.0;
  float w = random(2, 11) - a/3;
  println("a=" + a+",  w="+w);
  noStroke( );  // 不要外框線
  ellipse(mouseX+random(3-a, a-3), mouseY+random(3-a, a-3), w, w); 
} // draw(
void mousePressed( ) {
  c = int(random(0, 8)); 
}
/// End of the program
(i)Play執行起來, 把窗拉到適當位置不要擋住程式碼, 請簡單畫出畫你印象中的梅花樹叢, 隨便畫, 也是不要花太多時間!, 在右上角畫出你學號, 右下角畫出你姓名(直的寫); 然後用 Ctrl_PrintScr 抓下全螢幕, 這是今天要繳交的第 3 張圖片 ! (j)再來, 要修改一下 processing 程式 ! 請先把以下程式碼複製貼上到 processing 程式窗測試:

// a simple processing program -- by tsaiwn@ydu.edu.tw
// Processing 是 MIT 專為不懂程式的藝術家設計的電腦語言(其實是把Java簡單化!)
PFont f; 
String message = "育達科技大學多遊系"; 
String ggyy = "我是008007張大頭";
float angle = 0; 
void setup() { 
  size(300,300);  
  f = createFont("SimSun", 20, true);  // 仿宋體
  println(ggyy+", 我在 " + message);
} 
void draw() { 
   background(255); fill(0); 
   color c = color(0,128,255);  // RGB
   fill(c); textFont(f);
   translate(width/2,height/2); // 由中間點旋轉
   rotate(angle);     //旋轉 angle  徑度
   textAlign(CENTER) ; 
   text(message,0,0);   
   textFont(f, 14); text("他 你 我", 38, 20); 
   angle += 0.02;  // 順時針
   ellipse(mouseX, mouseY, 18, 28);
   fill(color(255, 0, 0));  // 其實不必先弄個變數
   ellipse(mouseX+33, mouseY+33, 18, 18);
   fill(0, 255, 0);   // 這樣就可以啦
   ellipse(mouseX/2, mouseY-55, 18, 18);
}
//////////////
(k)修改程式碼, 要秀出你的學號與姓名在旋轉視窗內, 改好後, 執行Play起來, 把窗拉到適當位置不要擋住程式碼, 等看到你名字接近水平時用 Ctrl_PrintScr 抓下全螢幕, 這是今天要繳交的第 4 張圖片 ! (二)用 processing 玩"特訓99"遊戲前三名可獲得加分 :-) 練習完以上四個 Processing 簡單範例並夾檔繳交4張圖片之後, 先不要急著把 Processing 關掉! 因為要先來"玩遊戲拚加分" !! 點這跳到最後面看如何用 processing 玩今天的遊戲準備拚加分 !!

      Top

// 玩遊戲贏的前三名可以獲得加分 :-)
/////////////
// (1)先到 http://processing.org 抓 processing
///   如果網路太慢, 請點這抓我放在學校網站這份Processing
// (2)解壓縮後執行裡面 processing.exe
// (3)File  >  Preferences  把字型改為 SimSun 並把兩隔字體大小改為18
// 來源:   http://goo.gl/vsp7Fm    (Game 特訓 99)
/// elearning.ydu.edu.tw/base/10001/course/10023354/content/Week00/processing-2.2.1-windows32.zip
//////////
// (1)到 http://processing.org 抓 processing
// (2)解壓縮後執行裡面 processing.exe
// (3)File  >  Preferences  把字型改為 SimSun 並把兩個字體大小都改為18
// 來源:   http://goo.gl/vsp7Fm    (Game 特訓 99)
/// modified by tsaiwn@ydu.edu.tw  蔡文能 @ 育達科大多媒體與遊戲設計系
int mapSizeX=480; //地圖x軸寬度
int mapSizeY=480; //地圖y軸寬度
int inset = 10;  // 邊界空白點數
int maxCannon = 99; //畫面上最大砲彈數

float minSpeed = 0.2;

int playerSizeX = 6;
int playerSizeY = 8;

int cntOne = 1000;
int cntTwo = cntOne + cntOne;
int cntThree = cntTwo + cntTwo;

int playerX=mapSizeX/2, playerY=mapSizeY/2; //玩家位置

int i=0; //迴圈專用暫存

float maxWalkSpeed=2.8; //最大走速
float walkAccelX=0; //x走路加速度
float walkAccelXtmp=0; //x走路加速度temp
float walkSpeedX=0; //x初走速
float walkAccelY=0; //y走路加速度
float walkAccelYtmp=0; //y走路加速度temp
float walkSpeedY=0; //y初走速

float minCannonSpeed=0.25; //炮彈最小速
float maxCannonSpeed=2.5; //炮彈最大速
float[] CannonV= new float[maxCannon+1];  //特定一顆砲彈總速度(會有x分速跟y分速)
float[] CannonX= new float[maxCannon+1];  //特定一顆砲彈x
float[] CannonXV= new float[maxCannon+1]; //特定一顆砲彈x速
float[] CannonY= new float[maxCannon+1];  //特定一顆砲彈y
float[] CannonYV= new float[maxCannon+1]; //特定一顆砲彈y速
float[] CannonW= new float[maxCannon+1]; //特定一顆砲彈寬度

boolean gameStart=false; //遊戲開始沒
boolean gameOver=true; //死了沒
int score=0; //得分
//變數設定END----------------------------------------------------------------------------

//剛開始時初值設定, 只做一次
void setup( ){
  size(mapSizeX, mapSizeY+10);
  background(0);  // 黑色底
  
  playerX=floor(mapSizeX/2); //玩家位置重設
  playerY=floor(mapSizeY/2);
  
  for(i=1; i <= maxCannon; ++i){ 
    //砲彈用for迴圈來設定砲彈1號~99號的x位置、y位置、發設初速、x分速、y分速、砲彈大小
    setCanI(i);  // 設定第 i 顆砲彈資料
  }// for(
  requestFocus( );
} // setup(
//初值設定END------------------------------------------------------------------------

//主要的程式, 就是 Java 的 paint(Graphics)
void draw( ){
  if(gameStart){  //判斷是否開始玩了
    startGame( );  //這是我自己設定的函數,用來重繪畫面的邊線
    updatePlayer( );   //這也是我自己設定的函數用來每次更新玩家位置
    moveCannon(); //設定砲彈位置用
    showScore();  //顯示分數
  }else{
    //如果還沒開始玩就在畫面上顯示字"Click to Start!"
    textSize(20);
    fill(250, 160, 0);
    text("Click to Start!", floor(mapSizeX/3), floor(mapSizeY/2)); 
  }
}

//鍵盤按下 ------------------------------------------------------------------------
//  (主要判斷方向鍵來控制移動的加速度)
void keyPressed( ){
  //只要按了該鍵,該方向的加速度就會改變
  //這樣的用意是讓玩家移動更順暢,不需要靠連按就能移動
  //不過我沒有設定如果反方向同時按會怎樣...有興趣可以自己加判斷式
  switch(keyCode){
    case LEFT:
      walkAccelX=-minSpeed;
      walkAccelXtmp=0;
    break;
    case RIGHT:
      walkAccelX=minSpeed;
      walkAccelXtmp=0;
    break;
    case UP:
      walkAccelY=-minSpeed;
      walkAccelYtmp=0;
    break;
    case DOWN:
      walkAccelY=minSpeed;
      walkAccelYtmp=0;
    break;
  }
} // keyPressed( 

//鍵盤放開  ------------------------------------------------------------------------
// (主要用來判斷當方向鍵放開時要減速的、及按空白鍵Replay)
//跟上面按下的不同,我把加速度設成0,另外用tmp來記住原本的加速度,用來為玩家減速
void keyReleased( ){
  switch(keyCode){
    case LEFT:
      walkAccelXtmp=walkAccelX;
      walkAccelX=0;
      break;
    case RIGHT:
      walkAccelXtmp=walkAccelX;
      walkAccelX=0;
      break;
    case UP:
      walkAccelYtmp=walkAccelY;
      walkAccelY=0;
      break;
    case DOWN:
      walkAccelYtmp=walkAccelY;
      walkAccelY=0;
      break;
    case ' ':     //game over後按空白鍵
      if(gameOver) prepareGame( );
      break;
  }
} // keyReleased( 

//滑鼠按一下 ---------------------------------------------------------------------------
//主要是Game over後用來重新開始遊戲
void mouseClicked( ) {
   if(gameOver) prepareGame( );
} // mouseClicked( 

void prepareGame( ) {
   gameOver=false;
   score=0;
   frameCount=0;
   setup( ); //如果已經Game over我就把所有值都重設
   gameStart=true; //按了之後就開始遊戲
   redraw( ); //draw那邊重新再run
} // prepareGame(

//=====================================================================================
//自己設的函數-----------------------------------------------------------------------
//_____________________________________________________________________________________

void startGame( ){
  background(0);//背景設定為黑
  stroke(50); //畫四條邊界線用,其實不一定需要啦~我只是想顯示玩家移動範圍邊邊
  line(inset, inset, mapSizeX-inset, inset);
  line(mapSizeX-inset, inset, mapSizeX-inset, mapSizeY-inset);
  line(mapSizeX-inset, mapSizeY-inset, inset, mapSizeY-inset);
  line(inset, mapSizeY-inset, inset, inset);
}

void updatePlayer( ){
  moveYY( );  //更新玩家目前 y 的位置
  moveXX( );  //更新玩家目前 x 的位置
  //把玩家的點畫出來
  noStroke();
  fill(240,220,0);
  ellipse(playerX,playerY, playerSizeX, playerSizeY);
} // updatePlayer(

/////////////////////////////////////////////////////////////////////
void setCanI(int i) {
    //砲彈用for迴圈來設定砲彈1號~99號的x位置、y位置、發設初速、x分速、y分速、砲彈大小
    switch(floor(random(1, 4.99))){ //看從上下左右哪邊發射
      case 1: //從左 發射就將x定在-10位置,y位置隨機
        CannonX[i]=-10;
        CannonY[i]=random(-10,mapSizeY+10);
        break;
      case 2: //從上 發射就將y定-10位置,x位置隨機
        CannonX[i]=random(-10,mapSizeX+10);
        CannonY[i]=-10;
        break;
      case 3: //從右 發射就將x定在總x軸寬度+10位置,y位置隨機
        CannonX[i]=mapSizeX+10;
        CannonY[i]=random(-10,mapSizeY+10);
        break;
      case 4://從下 發射就將y定在總y軸寬度+10位置,x位置隨機
        CannonX[i]=random(-10,mapSizeX+10);
        CannonY[i]=mapSizeY+10;
        break;
    } // switch(
    CannonV[i]=random(minCannonSpeed,maxCannonSpeed); //砲彈射速
    CannonXV[i]=CannonV[i]*((playerX-CannonX[i])/
        sqrt(sq(CannonX[i]-playerX)+sq(CannonY[i]-playerY))); //x分速
    CannonYV[i]=CannonV[i]*((playerY-CannonY[i])/
        sqrt(sq(CannonX[i]-playerX)+sq(CannonY[i]-playerY))); //y分速
    CannonW[i]=3; //預設砲彈寬度是3,之後難度閃久一點之後難度變難才會有變化
} // setCanI(

/////////////////////////////////////////////////////////////////////
void moveYY( ){  //更新玩家目前 y 的位置
  //我先判斷是否在移動範圍內,若沒有就先把玩家擋下
  if(playerY >= inset && playerY <= mapSizeY-inset){
    //先更新位置
    playerY += walkSpeedY;
    //如果玩家是在按著上或下鍵的情況下才需要去移動,我就是用加速度來判斷
    if(walkAccelY!=0){ 
      //判斷有沒有大於最大速度,如果沒有的話就加速,否則速度就是最大速不能再加
      if(abs(walkSpeedY) < maxWalkSpeed){
        walkSpeedY += walkAccelY;
      }else{
        if(walkSpeedY > 0) walkSpeedY=maxWalkSpeed;
        else walkSpeedY=-maxWalkSpeed;
      }
    } // if(有按著上下鍵
    if(walkAccelY == 0){  ///若玩家沒有按著上或下鍵盤
      //要是y速度的絕對值還比0.2大就繼續減速,若小於0.2就變成0
      if(abs(walkSpeedY) > minSpeed){
        walkSpeedY -= walkAccelYtmp;
      }else{
        walkSpeedY=0;
        walkAccelYtmp=0;
      }
    } // if(沒按著上下鍵
  } // if(playerY 在內
  //若已經在移動範圍外就讓玩家停住並且強制擋在邊邊
  if(playerY < inset){  // 太上邊
     walkSpeedY=0;
     playerY= inset;
     walkAccelY=0;
  }
  if(playerY > mapSizeY-inset){  // 太下面
     walkSpeedY=0;
     playerY=mapSizeY-inset;
     walkAccelY=0;
  }
} // moveYY(

/////////////////////////////////////////////////////////////////////
void moveXX( ){  //更新玩家目前 x 的位置
  //x跟y差不多的意思,就不多解釋囉
  if(playerX < inset){  // playerX 跑到範圍外, 太左邊
      walkSpeedX=0;
      playerX = inset;
      walkAccelX=0;
      return;
  }
  if(playerX > mapSizeX-inset){ // 跑到範圍外, 太右邊
      walkSpeedX=0;
      playerX = mapSizeX-inset;
      walkAccelX=0;
      return;
  }
  /// if(playerX >= inset && playerX <= mapSizeX-inset)
  playerX += walkSpeedX;
  if(walkAccelX != 0){ // 有按著 左右 鍵
    if(abs(walkSpeedX) < maxWalkSpeed){  // 還沒到最快
      walkSpeedX += walkAccelX;
    }else{
      if(walkSpeedX > 0) walkSpeedX=maxWalkSpeed;
      else walkSpeedX = -maxWalkSpeed;
    }
  }else{ //沒按著 左右 鍵; 即 if(walkAccelX == 0
    if(abs(walkSpeedX) > minSpeed){
      walkSpeedX -= walkAccelXtmp;
    }else{
      walkSpeedX=0;
      walkAccelXtmp=0;
    }
  }
} // moveXX(

////////////////////////// 判斷是否撞到第 i 顆砲彈
boolean hitI(int i) {
  if(abs(CannonX[i]-playerX) < CannonW[i]
      && abs(CannonY[i]-playerY) < CannonW[i]) return true;
  return false;
}

///////////////////////// 判斷第 i 顆砲彈是否超出界外
boolean outside(int i) {
  if(CannonX[i] > mapSizeX+10 || CannonX[i] < -10) return true;
  if(CannonY[i] < -10 || CannonY[i] > mapSizeY+10) return true;
  return false;
}
//砲彈走動
void moveCannon(){
  //這邊一樣用for迴圈來更新砲彈
  for(i=1; i <= maxCannon; i++){
    //先判斷任何一顆砲彈目前有沒有打到玩家
    //因為砲彈是圓的所以就判斷砲的圓心跟玩家圓心距離是否小於半徑跟半徑
    //但其實我這邊判斷式如果砲彈半徑大的話就會有問題,正確而言要用畢式定理來判斷才行
    //不過現在暫時懶得改XDDD
    if( hitI(i) ){
      gameOver=true;
    }
    if( ! hitI(i) ) { // 沒撞到第 i 顆砲彈
      if( outside(i) || gameOver){
        //如果已經射出界就再重新設定新砲彈,並且加一分代表閃過一顆砲彈
        setCanI(i);
        ///
        //如果還沒Game over的話,只要閃過一顆就加一分
        if(!gameOver) score += 1;
        //如果時間超過一千影格就把砲彈半徑加大
        if(frameCount >= cntOne && frameCount < cntTwo){
          CannonW[i]=floor(random(3,15));
        }
        if(frameCount >= cntTwo && frameCount < cntThree){
          CannonW[i]=floor(random(5,30));
        }
        if(frameCount >= cntThree){
          CannonW[i]=floor(random(7,88));
        }
      }else{  //砲彈還沒射出界的話就繼續飛
        CannonX[i] += CannonXV[i];
        CannonY[i] += CannonYV[i];
        noStroke( );
        fill(250,20,0);
        ellipse(CannonX[i],CannonY[i],CannonW[i],CannonW[i]);
      }
    } // ! hitI(
  } // for(
} // moveCannon(

//分數、顯示Game over
void showScore( ){
  if(gameOver){
    fill(0);
    rect(-10,-10,mapSizeX+10,mapSizeY+30);
    textSize(32);
    fill(250, 160, 0);
    text("Your Score: "+score, floor(mapSizeX/3), floor(mapSizeY/2)); 
  }else{
    textSize(10);
    fill(240, 220, 0);
    text("Your Score: "+score, 10, mapSizeY+5);
  }
} // showScore( 
//////////////////////////// ====== END ====== //////////////////////////// 
//////////////////////////// ====== END ====== //////////////////////////// 
///

///
   Top


如何讓男友戒掉LOL and 神魔之塔 https://youtu.be/jy6bGOPPtVI
神魔之塔--希特勒都不想再抽巨像 https://youtu.be/EBsHO1RuUhI


熱情、夢想、拼勁

///

///
   Top
   
    投資自己,讓今天的自己 比 昨天的自己 更值錢 !
 
      


龍族拼圖 https://youtu.be/4AtxjfCQq2M https://www.youtube.com/watch?v=4AtxjfCQq2M


12 歲就會寫 APP 遊戲

https://tw.voicetube.com/videos/1239




  每天 15 分鐘 voicetube.tw , 一年後你的英文就可以很厲害! http://voicetube.tw



成功的 8 個祕訣 -- 到 TED 看

成功的 8 個祕訣 -- 可用 voicetube.tw 看

邁向成功的八個秘訣 ---
1. Passion 熱情 -- 熱情是工作的原動力; 不要再埋怨了 !
      勿忘初衷、記得來時路,重新燃起你的熱情。
2. Work 努力奮鬥 -- 要在競爭中生存,便要奮鬥。(孫中山)
      若想要成功,必須很努力! 即使很努力,未必能成功!
3. Good 好還要更好 - 練習(Practice )練習再練習 !
     (因為 沒有奇蹟、沒有捷徑 ! no magic, no shortcut !)
4. Focus 專注 -- 專注可使事情更簡單,專注就能感受到那股力量!
5. Push 督促自己 -- 勇敢追求你的夢想。
          克服害羞與沒自信; 不要害羞,相信自己!
6. Serve 服務 -- 別人的問題就是你賺錢的機會。
  (that's why we have the course of "服務學習")
7. Idea 創意 -- 要多聽、要多看、要多問、
          要有好奇心、要試著解決問題、要建立人脈存摺
8. Persist 毅力(堅持) --不怕失敗、不怕壓力、
          不怕被批評、不怕被拒絕、不怕被罵混蛋 :-)

投資自己,讓今天的自己 比 昨天的自己 更值錢 !


///

///
   Top