2015年1月25日 星期日

WEEK17


遊戲開始時,會從最上面開始一起掉落



會漸漸的區分為三排(三種速度)


全部清除或失敗時則要顯示計分和經過時間(尚未完成)

WEEK16

遊戲中會使用到的字母圖


WEEK15

置入大量圖片


設定圖片落下的速度及設定圖片XY之座標
         

設定按鍵事件及計分方式
(目前計分的程式碼有BUG)
                                                                         

WEEK12

學習如何用Arduino按鈕來作發出聲音或亮燈

這是一個在網路上的實例教學:有四個按鈕對應四個LED燈,程式會亂數點亮LED,要記住順序依序按下那四個按鈕,若對了就會發出成功的音效,錯了則發出失敗的音效,然後在繼續下一次。

接線如下:
1.從Arduino板的GND接到麵包板
2.Arduino腳位5接開關右上腳,開關佐下腳接地
3.Arduino腳為13接LED長腳,LED短腳接GND



完整電路圖如下


從Arduino板的GND接到麵包板。
先差上四個瞬時型開關,左下腳接地。右上腳,從左到右,接到5、4、3、2。


然後開關的左上腳接LED的短腳,LED的長腳接到100 ohm的電阻。


再然後,從左到右,電阻的另一腳,接到Arduino板的腳位11、10、9、8。



聲音的部分:從Arduino板的腳位Ao接到1k ohm可變電阻的左腳,中腳接蜂鳴器的紅線,蜂鳴器的黑線接地,將以這個可變電組調整音量。

程式碼以功能區塊劃分說明。

#define TONE_PIN A0 // 定義蜂鳴器的腳位
#define NUMBER 4 // 共有四個LED、四個開關

// 定義開關與LED的腳位
const int switches[NUMBER] = {5, 4, 3, 2};
const int leds[NUMBER] = {11, 10, 9, 8};

// 定義各LED對應的音符頻率
const int notes[NUMBER] = {
    NOTE_C4, NOTE_D4, NOTE_E4,NOTE_F4,
};

// 使用狀態機的概念,要定義各種狀態
typedef enum{
    STATE_START, // 重新開始遊戲
    STATE_QUESTION, // 閃爍LED,給出問題
    STATE_ANSWER, // 等待使用者按下開關,回答問題
    STATE_CORRECT, // 正確,播放恭喜的音效,重置
    STATE_WRONG, // 錯誤,播放可惜的音效,重置
    STATE_MAX,
} State;

// 定義播放音效的資料
Melody melodys[MELODY_MAX] = {
    {noteStart, noteDurationsStart, 13},
    {noteCorrect, noteDurationsCorrect, 6},
    {noteWrong, noteDurationsWrong, 8},
};

// 以tone()播放音效
void playtone(int *note, int *noteDurations, int num){
  for(int thisNote = 0; thisNote < num; thisNote++){
    int noteDuration = 3000 / noteDurations[thisNote];
    tone(TONE_PIN, note[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
  }
}

// 程式裡有三種音效,開始遊戲、回答正確、回答錯誤
typedef enum{
    MELODY_START,
    MELODY_CORRECT,
    MELODY_WRONG,
    MELODY_MAX,
} Melody_Enum;
// 把playtone()包一層,用起來比較簡單
void playMelody(Melody_Enum me){
    playtone(melodys[me].note, melodys[me].duration, melodys[me].number);
}

// 初始化,開關的腳位,開啟上拉電阻,所以預設狀態會是HIGH,
// 之後讀取開關狀態時,若讀到LOW,代表按下按鍵
void setup(){
    for(int i = 0; i < NUMBER; i++){
        pinMode(switches[i], INPUT);
        digitalWrite(switches[i], HIGH);
        
        pinMode(leds[i], OUTPUT);
        digitalWrite(leds[i], LOW);
    }
    
    // 亂數,將以亂數製作問題
    randomSeed(analogRead(A1));
}

// 只播放一個音符的函式,秀出問題時可用,
// 使用者回答時也可用。
void playOneTone(int note, float delayScale){
    int noteDuration = 3000 / 8;
    tone(TONE_PIN, note, noteDuration);
    
    int pauseBetweenNotes = noteDuration * delayScale;
    delay(pauseBetweenNotes);

}

// 準備好問題後,放出音效、閃爍LED 
void playQuestionsTone(){
    for(int i = 0; i < q_num; i++){
        digitalWrite(leds[questions[i]], HIGH);
        playOneTone(notes[questions[i]], 1.3);
        digitalWrite(leds[questions[i]], LOW);
    }


// 檢查問題跟使用者的回答是不是一樣
boolean check(){
    for(int i = 0; i < q_num; i++){
        if(questions[i] != answers[i]){
            return false;
        }
    }
    return true;
}

// 重點
void loop(){
    switch(state){ // 以state記錄目前狀態,根據狀態作事
        case STATE_START:{ // 開始遊戲,播放開始音效,進入問題狀態
            reset();
            playMelody(MELODY_START);
            state = STATE_QUESTION;
            break;
        }
        
        case STATE_QUESTION:{ // 問題狀態,以亂數製作問題
            questions = (int *)(malloc(sizeof(int) * q_num));
            answers = (int *)(malloc(sizeof(int) * q_num));
            for(int i = 0; i < q_num; i++){
                questions[i] = random(0, NUMBER);
            }
            answer_num = 0;
            playQuestionsTone(); // 顯示問題
            lastClickTime = millis(); // 記錄目前時間
            state = STATE_ANSWER;
            break;
        }
        
        case STATE_ANSWER:{
            // 看看使用者多久沒按開關了,超過10就宣布失敗
            const unsigned long nowTime = millis();
            if(nowTime >= lastClickTime + 10000UL){
                state = STATE_WRONG;
                break;
            }
            
            // 讀取每個開關的狀態
            for(int i = 0; i < NUMBER; i++){
                int ss = digitalRead(switches[i]);
                if(ss == LOW){
                    digitalWrite(leds[i], HIGH);
                    lastClickTime = nowTime;
                    answers[answer_num] = i; // 把使用者的輸入答案存起來
                    answer_num++;
                    playOneTone(notes[i], 1);
                    digitalWrite(leds[i], LOW);
                    delay(200);
                    break;
                }
                
            }
            
            if(answer_num >= q_num){ // 判斷是不是已經回答完了
                // 檢查回答正不正確
                state = check() ? STATE_CORRECT : STATE_WRONG;
            }
            break;
        }
        
        case STATE_CORRECT:{ // 回答正確,恭喜
            q_num++;
            playMelody(MELODY_CORRECT);
            delay(2000);
            state = STATE_START;
            break;
        }
        
        case STATE_WRONG:{ // 回答錯誤,可惜
            playMelody(MELODY_WRONG);
            delay(2000);
            state = STATE_START;
            break;
        }
        
        default:{
            state = STATE_START;
            break;
        }
    }
}


實際操作影片網址:https://www.youtube.com/watch?v=ZDvK9AbC1eY#action=share
資料來源 網址:http://yehnan.blogspot.tw/2012/02/arduinosimon-says.html

WEEK05

希望能作英打輸入法類型的遊戲,步驟如下
1.隨機掉落26個英文字母且速率不同
2.成功或失敗消去字母時會有相對應的音樂
3.隨著時間掉落速度越來越快
4.無規定時間,再失敗10次後結束遊戲
5.計分方式,消去字母則加分,按錯則扣分

WEEK03

         


                                                      點擊畫面後即開始播放音樂




PImage boy, girl;
import ddf.minim.*;
Minim minim;
AudioPlayer song;

void setup() {
background(0);
size(600, 400);
minim=new Minim(this);
song=minim.loadFile("song.mp3");
boy=loadImage("boy.jpg");
girl=loadImage("girl.jpg");
}

void draw() {
  image(boy, 0, 0);
  image(girl, 300, 200);
}

void mousePressed(){
  song.play();
}

week01


void setup() {
size(400, 400);
background(0);}
void draw() {
  fill(255,0,0);
  rect(50,50,300,300);
 
  fill(0,255,0);
  ellipse(200,200,250,250);
 
  fill(0,0,255);
  triangle(120, 270, 200, 100, 280, 270);
}