2013年1月15日 星期二

Week19,final,project

作品名稱:划船遊戲

1. 遊戲進行及裝置介紹

首先是開頭畫面



再來是進入到遊戲畫面



然後努力滑要到終點了 ! !



















如果在時間內趕上終點  你就贏了

就會顯示贏的畫面




















如果沒辦法就會顯示輸的畫面



















這是我們 arduino 的裝置圖 - 划船裝置




這張是裝置的內部

是採用彈簧與桿子的槓桿原理做出划船力道的模擬








我們把按鈕黏上彈簧讓控制時需要力道才能順利案到按鍵

然後利用保麗龍塊固定按鈕位置


















接者是控制示意圖



























下面是遊戲進行畫面 方向示意圖

右上角是剩餘時間





















2. 遊戲玩法說明

        當畫面一開始,就按下紅色開始鍵開始遊戲,雙手放在桿子上,模擬划船的槳
當手往前推動,遊戲畫面中的船就會往該方向前去,而在 30 秒內要到達終點
如果 30 秒內抵達就是任務達成,否則就是任務失敗遊戲結束


3. 心得

        這個划船遊戲能夠完整的利用裝置來操控,真的是非常的幸運
在整個遊戲作品的製作過程中,遇見了許許多多的問題,有和一些同學們共同討論解決
謝謝他們提供的建議和解決方式,也謝謝助教建議的軟體與硬體操控的方向 :)

         在完成裝置之前都是理想中的設計裝置,製作過程中便是狀況一堆
不僅僅是按鈕和搖桿的結合,再加上 arduino 接線、程式撰寫等等搭配,遇到的問題真不少
尤其是裝置的方形按鈕與接線處頻頻出錯,一下是按鈕壞掉接觸不良,一下是接線鬆掉
後來嘗試用了課堂上做的小鋼琴按鈕,結果卻是如我們預期的控制船的方向移動

        但這樣就要捨棄掉利用桿子進行操控裝置的方法,讓我們非常挫折與無奈
也因為捨棄掉操控裝置的方法可惜,我們不斷地的嘗試,看還有甚麼方式能補救
運氣很好的,在我們裝上小按鈕,再接上方形按鈕後卻可以操控了 ! ! ! ! !
划船裝置也在那時候如我們預期成果般地完成,順利地完成 demo
也很感謝同學和老師、助教的肯定,讓我們獲得了獎品,謝謝大家 :D

        很開心這學期學到了這麼多和互動相關的東西,這堂課很充實 :P 
我們從同學、老師、助教身上學到很多寶貴的經驗、程式撰寫技巧以及遊戲設計概念等等
也完成兩個簡單的小作品,雖然這兩個小作品不是非常的完整 ˊ  ˇ  ˋ
但對我們來說是很好的經驗,也讓我們更了解自己不足的地方,希望之後能表現得更好:D

4. 遊戲 demo 影片



5. 作品分工狀況


遊戲作品構思:王靚暄、詹中豪
遊戲背景素材貼圖:王靚暄
遊戲程式:王靚暄、詹中豪
遊戲裝置構思:詹中豪
遊戲裝置製做:王靚暄、詹中豪


6. 程式碼
*processing

import processing.serial.*;
Serial myPort;
PImage sence1;
PImage sence3;
PImage sence4;
PImage ship;
PImage bg;
int W=1000,H=700;
float boatX=320,boatY=100, boatVX=0, boatVY=0;
float bgX=0,bgY=-1232;
int gameTime,s;
boolean ctrl=true;
int lastTime;
import ddf.minim.*; 
Minim minim; 
int testState=0;
AudioPlayer player;


void setup(){
  size(W,H);
  sence1 = loadImage("sence1.jpg");
  sence3 = loadImage("sence3.jpg");
  sence4 = loadImage("sence4.jpg");
  image(sence1,0,0);
  ship = loadImage("ship.png");
  bg=loadImage("bg.jpg");
  s=millis()/1000;
  minim = new Minim(this);
  myPort = new Serial(this,"COM3", 9600); 
   player = minim.loadFile("abdc.mp3");
  player.play();
}

void draw(){
  
  testState = myPort.read();
  println(testState);
  
  if (testState=='G') {
    ctrl=false;
  }
   if(ctrl==true){
    s = millis();
    image(sence1,0,0); 
    } 
    else if(ctrl==false){{
    image(bg, bgX, bgY);
    if (bgY>0)
    bgY=0;
    boat(boatX, boatY);
    boatMove();
    
  }
  
    fill(255,0,0);
    textSize(60);

    lastTime = millis()- s; 
    gameTime = 30-lastTime/1000;  
    text(gameTime,900,70); 
  
  
  
    if(gameTime>0 && bgY==0){
    image(sence4,0,0);
    
    } 
    else if(gameTime <=0){
    image(sence3,0,0);
    gameTime = 0;
    
    }
  
    }
}
boolean [] keys=new boolean[250];
void boatMove() {
  if ( testState == 'A') {
    boatVY-=1;
    boatVX+=1;
    if (boatVX<0)boatVX=0;
    if (boatVY>-0.5)boatVY=-0.5;
  }
  if (testState == 'S') {
    boatVX-=0.5;
    boatVY-=0.5;
    if (boatVX<-1)boatVX=-1;
    if (boatVY>-0.5)boatVY=-0.5;
  }
  
  boatX+=boatVX;
  boatY+=boatVY;
  if (boatY<H/2) {
  bgY-=(boatY-H/2);
  boatY=H/2;
  }
  if (boatX<0) {
    boatX=0;
  }
   if (boatX>600) {
    boatX=600;
  }
  
  if (boatY>650) {
    boatY=650;
  }
  
  
  boatVY*=0.9;
  boatVX*=0.9;
}





void keyPressed() {
 if (testState=='G') {
   ctrl=false;
  }
  else if (testState=='A') {
    boatVY-=1;
    boatVX+=1;
  }
  else if (testState=='S') {
    boatVX-=0.5;
    boatVY-=0.5;
  }
  
}

void keyReleased() {
 if (testState=='A') {
    boatVY=0;
    boatVX=0;
  }
  else if (testState=='S') {
    boatVX=0;
    boatVY=0;
  }
} 

void boat(float X, float Y) {
  image(ship, boatX, boatY);
}



*arduino
/*
DigitalReadSerial
Reads a digital input on pin 2, prints the result to the serial monitor
This example code is in the public domain.
*/
// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton2= 2;
int pushButton3 = 3;
int pushButton4 = 4;
int buttonState2 =0;
int buttonState3 =0;
int buttonState4 =0;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// make the pushbutton's pin an input:
pinMode(pushButton2, INPUT);
pinMode(pushButton3,INPUT);
pinMode(pushButton4,INPUT);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input pin:
int buttonState2 = digitalRead(pushButton2);
int buttonState3 = digitalRead(pushButton3);
int buttonState4 = digitalRead(pushButton4);
// print out the state of the button:
if (buttonState2 == HIGH) {     
   Serial.write('A');
  } 
  if (buttonState3== HIGH) {     
   Serial.print('S');
  }
  if (buttonState4 == HIGH ) {     
    Serial.print('G');
    buttonState4 = 1;}

   else {
   Serial.print('H');
  }
   delay(100);
}

98160860黃麒, 98163021張耀璇, Final,



介紹:
我們這組所做的是剪紅線,名字只是個比喻,就好像有五顆炸彈,其中一顆會爆炸,而我們必須猜對那一顆炸彈才能讓贏得遊戲,本來是思考享用很多很多顆假炸彈參雜數顆真炸彈,可是手邊的材料沒有那麼多,所以就縮減成五顆。

程式碼:

import processing.serial.*;
Serial myPort;
import ddf.minim.*;
Minim minim;
AudioPlayer wrong,right;
int com;
int x=0;
int val;
PImage a1,a2,a3,a4,a5,b1,b2,b3,b4,b5,r1,r2;
void setup(){
   myPort = new Serial(this, "COM4", 9600);
  com=int(random(4))+1;
  minim = new Minim(this);
  size(800,600);
  wrong= minim.loadFile("w.mp3");
  right = minim.loadFile("r.mp3");
  a1 = loadImage("a1.png");
  b1 = loadImage("b1.png");
  a2 = loadImage("a2.png");
  b2 = loadImage("b2.png");
  a3 = loadImage("a3.png");
  b3 = loadImage("b3.png");
  a4 = loadImage("a4.png");
  b4 = loadImage("b4.png");
  a5 = loadImage("a5.png");
  b5 = loadImage("b5.png");
  r1 = loadImage("r1.png");
  r2 = loadImage("r2.png");
}
void draw(){
  if(myPort.available()&rt;0){
    val = myPort.read();
 //   println(val);
   }
   if(val=='1'){
     x=1;
   }
   else if(val=='2'){
     x=2;
   }
   else if(val=='3'){
     x=3;
   }
   else if(val=='4'){
     x=4;
   }
   else if(val=='5'){
     x=5;
   }
   else if(val=='R'){
     x=0;
     right.pause();
     right.rewind();
    com=int(random(4))+1;
   }
  background(244,219,142);
  rect (200,0,400,75);
  if(x==1)  image(b1,50,100,200,200);
  else image(a1,50,100,200,200);
  
  if(x==2)  image(b2,300,100,200,200);
  else image(a2,300,100,200,200);
  
  if(x==3)  image(b3,550,100,200,200);
  else image(a3,550,100,200,200);
  
  if(x==4)  image(b4,175,300,200,200);
  else image(a4,175,300,200,200);
  
  if(x==5)  image(b5,425,300,200,200);
  else image(a5,425,300,200,200);
  
  if(x==6)  image(r2,0,510,800,90);
  else image(r1,0,510,800,90);
  
  
 println("com="+com);
//  println(x);
  if (x==com && x!=0)  {fill(183,244,69);
  right.play();
}
  else if (x!=com && val!='H' && x!=0)  {
    wrong.play();
    wrong.rewind();
}
  else
    fill(255,0,0);
  rect (200,0,400,75);  
}
void keyPressed(){
  if(key=='1') x=1;
  if(key=='2') x=2;
  if(key=='3') x=3;
  if(key=='4') x=4;
  if(key=='5') x=5;
  if(key==' '){x=6;
    com=int(random(4))+1;
  }
}

遊戲畫面:




Week15,HW12

期末進度

原本打算做出新的程式,但是沒有好的想法
可能還是使用期中作品的修改
但是其中的操作是使用滑鼠,要對應到Arduino可能還有問題
首先得先把鍵盤部分做出來。

Week13,HW11

簡易鋼琴(可變音)

1.影片
2.心得

喇叭的線容易接觸不良,在接線時有些麻煩。

3.程式碼

int val[6];
int sensorPin = A0;
int sensorValue = 0;
void setup(){
  for(int i=2;i<7;i++) pinMode(i, INPUT);
}
void loop(){
  sensorValue = analogRead(sensorPin); 
  for(int i=2;i<7;i++) val[i-2] = digitalRead(i);
  for(int i=0;i<6;i++)
    if (val[i] == HIGH) {
      switch(i){
        case 0 : tone(8,262+sensorValue,4); break;
        case 1 : tone(8,294+sensorValue,4); break;
        case 2 : tone(8,330+sensorValue,4); break;
        case 3 : tone(8,349+sensorValue,4); break;
        case 4 : tone(8,392+sensorValue,4 ); break;
      }
    }
}


Week19, Final Project


Processing程式碼:

import processing.serial.*;
Serial port;
int word;
PImage img;
int rx=28,ry=5;
boolean move = true;
int a=0,b=0,c=0,d=0;
void setup() {
  size(400, 400);
  img = loadImage("maze.jpg");
  port = new Serial(this, "COM3", 9600);
}
void draw() {
 
  if(port.available()>0){
    word = port.read();
    }
 
  image(img, 0, 0);
  loadPixels();
 
  fill(225, 0, 0);//點點
  ellipse(rx, ry, 10, 10);
 
  if (move==true) {
    if(word=='W')ry=ry-1;
    if(word=='S')ry=ry+1;
    if(word=='A')rx=rx-1;
    if(word=='D')rx=rx+1;
  }
  color now_color = pixels[ry*400+rx];
 
  if (rx>398){
    rx=398;
    fill(0, 0, 0);
    rect(0, 0, 400, 400);
    textSize(50);
    fill(255, 255, 0);
    text("Congratulation", 20, 220);
  }
 
  if (red(now_color)<100){
    move = false;
    fill(0, 0, 0);
    rect(0, 0, 400, 400);
    textSize(50);
    fill(255, 255, 0);
    text("GAME OVER", 60, 220);
  }
 
  else move = true;

}

----------------------------------------------------------------------------

Arduino程式碼:

int buttonPin1 = 2;
int buttonPin2 = 3;
int buttonPin3 = 4;
int buttonPin4 = 6;

int buttonState1 = 0;  
int buttonState2 = 0;  
int buttonState3 = 0;  
int buttonState4 = 0;  
 
void setup() {
  
  Serial.begin(9600);
  pinMode(buttonPin1, INPUT);     
  pinMode(buttonPin2, INPUT);     
  pinMode(buttonPin3, INPUT);     
  pinMode(buttonPin4, INPUT);     
  
}

void loop() {
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  buttonState4 = digitalRead(buttonPin4);
  
  if (buttonState1 == HIGH) {     
   Serial.write('W');
  }  
  if (buttonState2 == HIGH) {     
   Serial.print('S');
  }
  if (buttonState3 == HIGH) {     
   tone(8, 165 , 300);
   Serial.print('A');
  }
  if (buttonState4 == HIGH) {     
   tone(8, 175 , 300);
   Serial.print('D');
  }
  delay(100);
}

2013年1月14日 星期一

期末作品 Final


系統名稱:  <piano>

如何製作:

  1、用黑白膠帶纏住由冰棍製成的黑鍵與白鍵
  2、連接電路板、七個電阻、一個喇叭。
  3、製作由processing點選開始的畫面、進入鋼琴的畫面。
  4、撰寫arduino的程式碼。
  5、搜尋processing與arduino相互連接的程式。

圖片:
一開始執行的畫面
點選"Enter to play"後的畫面
按第一個按鈕,發出Do的聲音
按第二個按鈕,發出Re的聲音
按第三個按鈕,發出Me的聲音
按第四個按鈕,發出Fa的聲音
按第五個按鈕,發出So的聲音
小鋼琴圖片-1
小鋼琴圖片-2
小鋼琴圖片-3
電路板接線圖

程式碼

processing程式碼


import processing.serial.*;
Serial myPort;

PImage bg1,Do,Re,Mi,Fa,So,La,Si;

void setup() {
  size(800, 600);
  bg1 = loadImage("piano.jpg");  //載入圖檔
  Do = loadImage("piano-Do1.jpg");
  Re = loadImage("piano-Re1.jpg");
  Mi = loadImage("piano-Mi1.jpg");
  Fa = loadImage("piano-Fa1.jpg");
  So = loadImage("piano-So1.jpg");
  La = loadImage("piano-La1.jpg");
  Si = loadImage("piano-Si1.jpg");
  myPort = new Serial(this, "COM15", 9600);
}

void draw() {
  image(bg1, 0, 0, 800, 600);
  image(Do, 86, 82, 89, 333);
  image(Re, 169, 80, 89, 333);
  image(Mi, 253, 81, 89, 333);;
  image(Fa, 338.5, 84, 89, 333);
  image(So, 425, 81, 89, 333);;
  image(La, 509, 82, 89, 333);
  image(Si, 593, 82, 89, 333);
}


arduino程式碼


const int inPin1 = 1;
const int inPin2 = 2;
const int inPin3 = 3;
const int inPin4 = 4;
const int inPin5 = 5;
const int inPin6 = 6;
const int inPin7 = 7;

int val1 = 0, val2 = 0, val3 = 0, val4 = 0, val5 = 0, val6 = 0, val7 = 0;

void setup() {
   Serial.begin(9600);

   pinMode(inPin1, INPUT);
   pinMode(inPin2, INPUT);
   pinMode(inPin3, INPUT);
   pinMode(inPin4, INPUT);
   pinMode(inPin5, INPUT);
   pinMode(inPin6, INPUT);
   pinMode(inPin7, INPUT);
}

void loop() {
   val1 = digitalRead(inPin1);
   val2 = digitalRead(inPin2);
   val3 = digitalRead(inPin3);
   val4 = digitalRead(inPin4);
   val5 = digitalRead(inPin5);
   val6 = digitalRead(inPin6);
   val7 = digitalRead(inPin7);

      if(val1==HIGH){
         tone(8,524,8);
      }
      if(val2==HIGH){
         tone(8,588,8);
      }
      if(val3==HIGH){
         tone(8,660,8);
      }
      if(val4==HIGH){
         tone(8,698,8);
      }
      if(val5==HIGH){
         tone(8,784,8);
      }
       if(val6==HIGH){
         tone(8,880,8);
      }
       if(val7==HIGH){
         tone(8,988,8);
      }
}





心得介紹:
  我們在家執行時,程式碼是可以執行的;但在學校卻不能執行,經過老師的指導才知道原來
  是程式碼的問題,我們把之前在家裡寫得很完整的有些程式碼註解掉了,導致程式在執行
  時,狀況一堆 。
  原本我們的構想是想在這次的期末作品中,利用二維陣列寫出錄音的功能,可以記錄時間、
  音樂,讓玩家可以儲存自己在彈奏的旋律,並加入播放的功能,聲音是由電腦發出剛剛輸入
  的聲音。希望之後可以完成這兩項功能。

影片:




組員分工:

  陳孟琳:主要負責processing、arduino的程式碼。

  紀詠心:主要負責電路連接。

Week19,Final project


1.系統名稱
越吃越長貪食蛇

2.製作方式
用processing 結合arduino板 製作出一個簡易的貪食蛇遊戲

並設置4個按鈕 控制貪食蛇上下左右行走 讓自己越吃越長
隨心所欲愛吃什麼就吃什麼

3.圖片




 



















4.心得介紹
由於之前所做的跟其他組相似,所以全部都重新來過,所以我們做一個貪食蛇的遊戲
遊戲非常簡單,讓大家操作起來更得心應手也有趣,所以瞞開心的也蠻有成就感的yeah

5.影片

6.組員分工情況
我們的程式設計 還有配接電路加上所有的美觀美術都是大家一起分工合作完成的,非常和樂融融,開心萬分。

WEEK19, Final Project

專案名稱 : 我要打星星
程式碼 :
arduino :

const int buttonPin1 = 2;
const int buttonPin2 = 4;
const int buttonPin3 = 6;
const int buttonPin4 = 8;
const int buttonPin5 = 10;
const int buttonPin = 6;
const int ledPin1 = 3;
const int ledPin2 = 5;
const int ledPin3 = 7;
const int ledPin4 = 9;
const int ledPin5 = 11;
int buttoni=0;
int buttoni1=0;
int buttoni2=0;
int buttoni3=0;
int buttoni4=0;
int buttoni5=0;
int switchi=0;
int ledi=0;
int uv=0;
int buttonState=0;
int bt=1;
int rdn=random(1, 6);
unsigned long time;
unsigned long time1;
unsigned long dtime1;
unsigned long dtime=1000;
void setup() {
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
pinMode(buttonPin4, INPUT);
pinMode(buttonPin5, INPUT);
}
void loop(){
buttonState = digitalRead(buttonPin);
if(buttonState==HIGH)
{uv=1;
dtime=1000;
buttoni=0;
bt=1;
}
if(uv==1)
{
int i;
for(i=0;i<=2;i++){
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, HIGH);
digitalWrite(ledPin5, HIGH);
delay(1000);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
digitalWrite(ledPin5, LOW);
delay(1000);
if(i==2)
{
uv=2;
}
 }
}
if(uv==2)
{
if(bt==1){
bt=0;
switch (rdn) {
case 1:
digitalWrite(ledPin1, HIGH);
break;
case 2:
digitalWrite(ledPin2, HIGH);
break;
case 3:
digitalWrite(ledPin3, HIGH);
break;
case 4:
digitalWrite(ledPin4, HIGH);
break;
case 5:
digitalWrite(ledPin5, HIGH);
break;
}
time = millis();
}
time1=millis();
dtime1=time1-time;
if(dtime1>=dtime&&bt==0){
uv=3;
}
buttoni1 = digitalRead(buttonPin1);
buttoni2 = digitalRead(buttonPin2);
buttoni3 = digitalRead(buttonPin3);
buttoni4 = digitalRead(buttonPin4);
buttoni5 = digitalRead(buttonPin5);
if(buttoni1==HIGH)
buttoni=1;
if(buttoni2==HIGH)
buttoni=2;
if(buttoni3==HIGH)
buttoni=3;
if(buttoni4==HIGH)
buttoni=4;
if(buttoni5==HIGH)
buttoni=5;
if(buttoni!=0&&buttoni!=rdn)
uv=3;
if(buttoni==rdn)
{
bt=1;
dtime-=20;
switch (buttoni) {
case 1:
digitalWrite(ledPin1, LOW);
break;
case 2:
digitalWrite(ledPin2, LOW);
break;
case 3:
digitalWrite(ledPin3, LOW);
break;
case 4:
digitalWrite(ledPin4, LOW);
break;
case 5:
digitalWrite(ledPin5, LOW);
break;
}
rdn=random(1, 6);
delay(dtime);
time=millis();
buttoni=0;
}
}
if(uv==3)
{
int i;
for(i=0;i<=2;i++){
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, HIGH);
digitalWrite(ledPin5, HIGH);
delay(500);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
digitalWrite(ledPin5, LOW);
delay(500);
if(i==2)
{
uv=0;
}
}
}
 }

processing :
按中間的開始鍵會有加10分
import processing.serial.*;
Serial myPort;
int score = 0;
float count=1.5;
float count2=0;
void setup(){
size(600,400);
//background(255, 204, 0);
myPort = new Serial(this, "COM3", 9600);
float yrope = 100;
}
int value=0;
void draw(){
background(255, 204, 0);
fill(0);
textSize(150);
text(score, 300, 350);
while(myPort.available()>0)
{
value = myPort.read();
println(value);
if(value=='G'){
score+=10;//分數跳一次加10分
count2+=1;
}
}
}
圖片 :
心得:
在製作的過程中電線有時候一直短路很困擾,再連接processing 時一直出現狀況
燈有時候會一直閃不停QQ
原本processing是用來加分數,可是只做到傳送開始鈕的值~
我們利用遊戲時間即次數來控制遊戲結束與否。

Week 19, Final Project

processing
import processing.serial.*;
Serial myPort;
int now=1;
int val;
int ballY=607;
int ballX=367;
float monsterX,monster2X,monster3X,monster4X,monster5X;
float monsterY,monster2Y,monster3Y,monster4Y,monster5Y;
float startX=0;
float start2X=0;
float start3X=0;
float start4X=0;
float start5X=0;
import ddf.minim.*;
AudioPlayer backmusic,stopcar,frogsound;
Minim minim;
PImage img0,img1,img2,img3,img4,img5,
img6,img7,img8,img9;

void setup()
{
size(800,700);
img0=loadImage("background.png
");
img1=loadImage("frog.gif");
img2=loadImage("show3.png");
img3=loadImage("car1.gif");
img4=loadImage("car2.gif");
img5=loadImage("car3.gif");
img6=loadImage("car4.gif");
img7=loadImage("car5.gif");
img8=loadImage("show4.png");
img9=loadImage("show0.png");
monsterX=0;
monster2X=0;
monster3X=0;
monster4X=0;
monster5X=0;
String portName=Serial.list()[0];
myPort=new Serial(this,"COM3",9600);
minim=new Minim(this);
backmusic=minim.loadFile("back
music.mp3", 2048); //music
backmusic.play();
}
void show1(){
image(img9,0,0);
}
void show2(){
image(img0,0,0);
image(img1,ballX,ballY,70,90);
}
void show3(){
image(img2,0,0);
}
void show4(){
image(img8,0,0);
}
void draw(){
while(myPort.available() >0) val=myPort.read();


if(now==1){
show1();
if(mousePressed&&mouseX>=0&&mo
useX<=700&&mouseY>=0&&mouseY<=800) now=2;
if (val=='a') now=2;
if (val=='c') now=2;
if (val=='e') now=2;
if (val=='g') now=2;

}
if(now==2){
show2();

monsterX-=4;
monsterY=520;
image(img3,monsterX,520);
if (monsterX<-100) {
monsterX +=800;
}
monster2X-=8;
monster2Y=440;
image(img4,monster2X,440);
if (monster2X<-100) {
monster2X +=800;
}
monster3X+=5;
monster3Y=360;
image(img5,monster3X,360);
if (monster3X>+800) {
monster3X -=900;
}
monster4X-=8;
monster4Y=270;
image(img6,monster4X,monster4Y
);
if (monster4X<-100) {
monster4X +=800;
}
monster5X+=6;
monster5Y=190;
image(img7,monster5X,monster5Y
);
if (monster5X>+800) {
monster5X -=800;
}
if(ballX<monsterX+45&&ballX>mo
nsterX-45&&ballY>monsterY-45&&ballY<monsterY+45)
{
now=4;
stopcar=minim.loadFile("stop.w
av", 2048);
stopcar.play();
monsterX+=800;
ballY=607;
ballX=367;
}
if(ballX<monster2X+45&&ballX>m
onster2X-45&&ballY>monster2Y-45&&ballY<monster2Y+45)
{
now=4;
stopcar=minim.loadFile("stop.w
av", 2048);
stopcar.play();
monster2X+=800;
ballY=607;
ballX=367;
}
if(ballX<monster3X+45&&ballX>m
onster3X-45&&ballY>monster3Y-45&&ballY<monster3Y+45)
{
now=4;
stopcar=minim.loadFile("stop.w
av", 2048);
stopcar.play();
monster3X+=800;
ballY=607;
ballX=367;
}
if(ballX<monster4X+45&&ballX>m
onster4X-45&&ballY>monster4Y-45&&ballY<monster4Y+45)
{
now=4;
stopcar=minim.loadFile("stop.w
av", 2048);
stopcar.play();
monster4X+=800;
ballY=607;
ballX=367;
}
if(ballX<monster5X+45&&ballX>m
onster5X-45&&ballY>monster5Y-45&&ballY<monster5Y+45)
{
now=4;
stopcar=minim.loadFile("stop.w
av", 2048);
stopcar.play();
monster5X+=800;
ballY=607;
ballX=367;
}
if (val=='a')ballY-=6; //top
if (val=='c')ballY+=6; //down
if (val=='e')ballX+=8; //right
if (val=='g')ballX-=8; //left
if(ballY>608)ballY=607;
if(ballY<-5)ballY=-4;
if(ballX>728)ballX=727;
if(ballX<2)ballX=3;
if(ballY<20&&ballX<410&&ballX>
325)now=3;
if(ballY<20&&ballX<410&&ballX>
325)ballY=607;
if(ballY<20&&ballX<410&&ballX>
325)ballY=367;
println("monster5Y:"+ballY+" monster5X:"+monster5X);
}
if(now==3){
show3();
if(mousePressed&&mouseX>=680&&
mouseX<=770&&mouseY>=590&&mouseY<=690)
now=2;
}
if(now==4){
show4();
if(mousePressed&&mouseX>=680&&
mouseX<=770&&mouseY>=590&&mouseY<=690)
now=2;
}
}
arduino

/*
DigitalReadSerial
Reads a digital input on pin 2, prints the result to the serial monitor
This example code is in the public domain.
*/
// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton = 2;
int pushButton2 = 3;
int pushButton3 = 4;
int pushButton4 = 5;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// make the pushbutton's pin an input:
pinMode(pushButton, INPUT);
pinMode(pushButton2, INPUT);
pinMode(pushButton3, INPUT);
pinMode(pushButton4, INPUT);
}
int a1=0;
int a2=0;
int a3=0;
int a4=0;
// the loop routine runs over and over again forever:
void loop() {
// read the input pin:
int buttonState = digitalRead(pushButton);
int buttonState2 = digitalRead(pushButton2);
int buttonState3 = digitalRead(pushButton3);
int buttonState4 = digitalRead(pushButton4);
// print out the state of the button:
if (buttonState == HIGH && a1==0 ) { // If switch is ON,
Serial.print('a');
a1=1; // send 1 to Processing
}
if (buttonState == LOW && a1==1) { // If the switch is not ON,
Serial.println('b');
a1=0; // send 0 to Processing
}
if (buttonState2 == HIGH && a2==0 ) { // If switch is ON,
Serial.print('c');
a2=1; // send 1 to Processing
}
if (buttonState2 == LOW && a2==1) { // If the switch is not ON,
Serial.println('d');
a2=0; // send 0 to Processing
}
if (buttonState3 == HIGH && a3==0 ) { // If switch is ON,
Serial.print('e');
a3=1; // send 1 to Processing
}
if (buttonState3 == LOW && a3==1) { // If the switch is not ON,
Serial.println('f');
a3=0; // send 0 to Processing
}
if (buttonState4 == HIGH && a4==0 ) { // If switch is ON,
Serial.print('g');
a4=1; // send 1 to Processing
}
if (buttonState4 == LOW && a4==1) { // If the switch is not ON,
Serial.println('h');
a4=0; // send 0 to Processing
}
// Serial.println(buttonState);
delay(10); // delay in between reads for stability
}

http://www.youtube.com/watch?v=g0ORjiFmzmU

Week 19, Final Project

系統名稱: 傳奇戰役 (Rise of The Argonauts)


目的: 

  能夠單純使用一支手控制、遊玩一個2D橫軸的遊戲,能夠控制英雄在眾多怪獸中生存,依據殺敵數量不同而得到不同的分數。並能夠在排行榜中爭取高分!

遊戲畫面:

開始畫面(按下即可開始)


進入遊戲畫面,怪物一定間格時間會產生一隻,並隨機產生其中一種及方向


攻擊畫面,成功擊殺怪物分數增加


可以跳躍迴避攻擊


受到攻擊時,左上角的血量會減少


成績排行(白色代表你當次遊戲的成績)


遊戲設備介紹及控制方法:

  控制手套(正面)


控制手套(背面)


以下同時為控制介紹:

正面(同時為遊戲初始狀態,靜止不動)


控制人物左移


控制人物右移


紅色按鈕為攻擊



附註:手向上甩,人物跳躍

如何製作:

  環境:

    作業系統:Windows 7
    硬體主機板:Arduino
    軟體撰寫:Processing(Java) + Arduino(C)

  製作重點:
      遊戲分為main、Hero Class以及Monster Class,主要撰寫的部分
    是Class。在那二個Class中分別記錄大小、生命值、座標、方向、
    向上跳躍的向量以及攻擊力及攻擊間隔,再各別撰寫函式去控制
    。

      而Serial傳遞數值的部分全部放在serialControl()函數裡面,以便
    於撰寫及控制。排行部分則是使用reader and writer去讀取以及寫檔
    。

程式碼:

Arduino:

#include <string.h>

int btn_left = 2;
int btn_right = 3;
int btn_atk = 4;
int past_leftState =1;
int past_rightState = 1;
int past_atkState = 1;
void setup() {
  Serial.begin(9600);
  pinMode(btn_left, INPUT_PULLUP);
  pinMode(btn_right, INPUT_PULLUP);
  pinMode(btn_atk, INPUT_PULLUP);
}
void loop(){
  int leftState = digitalRead(btn_left);
  int rightState = digitalRead(btn_right);
  int atkState = digitalRead(btn_atk);
  if(past_leftState != leftState) Serial.print(0);
  if(past_rightState != rightState) Serial.print(1);
  if(past_atkState != atkState && atkState == 0) Serial.print(2);
  past_leftState = leftState ;
  past_rightState = rightState ;
  past_atkState = atkState ;
  delay(10);        // delay in between reads for stability
}
Processing 

main

import processing.serial.*;
import java.io.*;
import java.util.*;
import ddf.minim.*;
import java.util.Arrays;
//define
final static int SIZE = 3;
final static int ATK_TIME = 15;

//file process about (in fact , is about rank )
BufferedReader rank;
PrintWriter rankin;

//Music about
Minim minim;
AudioPlayer groove,p;
//Serial
Serial myPort;
//linked list
List<monsterClass> lt;
//hero class
heroClass hero = new heroClass(50,75);
//control kind of avtivity
boolean[] ctl = new boolean[SIZE] ;
//Number Image
PImage[] num = new PImage[10];
//back ground img
PImage img_bg_game = loadImage(basicPath + "background\\gameBg.png");
PImage img_start = loadImage(basicPath + "background\\start.jpg");
//parameter
int ctlEnd = 0;
int grade=0;
int count;
int monsterNumber=0;
int nowRunFrame=0;
int monsterNewTime=50;
int dtime = 0;
//0:: game , 1:: rank ,  2::start
int type = 2;
void setup()
{
  size(640, 480);
  //load music
  minim = new Minim(this);
  groove = minim.loadFile(basicPath + "sound\\1.mp3", 512);
  p = minim.loadFile(basicPath + "sound\\atk.mp3", 512);
  groove.loop();
  //initialize
  lt = new LinkedList<monsterClass>();
  myPort = new Serial(this,"COM3", 9600);
  for(int i=0;i<SIZE;i++) ctl[i] = false;
  for(int i=0;i<10;i++) num[i] = loadImage(basicPath + "number\\" + i + "b.png");
}

void draw()
{
  if(type == 0){
    ctlEnd = 0 ;
    //contorl monster create time
    if(++nowRunFrame>monsterNewTime){
      monsterNewTime = 50;
      //add to list
      monsterClass m = new monsterClass(50,75,(int)random(0,199.99));
      lt.add(m); 
      monsterNumber++;
      nowRunFrame=0;
    }
    
    image(img_bg_game,0,0);
    fill(255,0,0);
    rect(0,0,hero.getHealth()*2,50);
    //show hero
    hero.showImage();
    //show grade
    showGrade();
    //detector monsters motion and attack
    for(int i=0;i<lt.size();i++){
      lt.get(i).move(hero.getPoint());
      lt.get(i).showImage();
      hero.setHealth(lt.get(i).atkDetector(hero.getPoint()));
      if(hero.getHealth() <=0) type =1;
    }
    //serial control about
    serialControl();
    if(count>0) grade += hero.atk(lt);
    //control attack img show time
    count--;
  }
  else if(type == 2 ){
     serialControl();
     image(img_start,0,0,640,480);
     dtime--;
  }
  else{
    dtime--;
    serialControl();
    background(0);
    rank=createReader(basicPath + "data\\rank.txt");
    int[] rankArr = new int[11];
    for(int i=0;i<10;i++){
      try{
          rankArr[i] = int(rank.readLine());
          println(rankArr[i]);
       } 
       catch (IOException e) {
          e.printStackTrace();
       }  
    }
    rankArr[10] = grade;
    Arrays.sort(rankArr);
    for(int k=1;k<11;k++){
      int temp=rankArr[k]*10;
      fill(255);
      if(grade == rankArr[k]) rect(650-240-k*25-5,100+(9-k)*35,230,35);
      image(num[10-k],650-240-k*30-60,100+(9-k)*35,50,50);
      for(int i=3;i>=0;i--)
         image(num[(temp/=10)%10],650-60*(4-i)-k*25,100+(9-k)*35,40,40);
    }
     if(ctlEnd == 1 && dtime<=0){
       rankin=createWriter(basicPath + "data\\rank.txt");
       for(int i=1;i<11;i++) rankin.println(rankArr[i]);
       rankin.flush();
       rankin.close();
       type = 2;
       for(int i=0;i<lt.size();i++) lt.remove(i--);
       hero.setHealth(100);
       grade = 0;
       dtime = 500;
     }
  }
}
void showGrade()
{
  
   int temp=grade*10;
   for(int i=3;i>=0;i--)
     image(num[(temp/=10)%10],640-60*(4-i),0,60,60);
   
}
void serialControl()
{
  int temp;
  if ( myPort.available() > 0){
    temp =myPort.read();
    //If btn push is attack
    if((temp - 48) == 2){
      if(type == 1 ) ctlEnd = 1;
      else if(type == 2 && dtime <= 0){
        type = 0;
        dtime = 500; 
      }
      else if(type== 0){
        grade += hero.atk(lt);
        count=ATK_TIME; 
        p.play(0);
      }
    }
    else ctl[temp-48] = !ctl[temp-48];
  }
  // if left and right together is jump
  if(ctl[0] == true && ctl[1] == true) hero.setJump(17);
  //left
  else if(ctl[0] == true){
     hero.setPoint(hero.getPoint().x-3,hero.getPoint().y);
     hero.setState(FACE_LEFT);
  }
  //right
  else if(ctl[1] == true){
     hero.setPoint(hero.getPoint().x+3,hero.getPoint().y);
     hero.setState(FACE_RIGHT);
  }
}

//Keyboard use

void keyPressed() {
  if (key == CODED) {
    if (keyCode == RIGHT || ctl[1] == true) {
      hero.setPoint(hero.getPoint().x+3,hero.getPoint().y);
      hero.setState(FACE_RIGHT);
    } 
    else if (keyCode == LEFT ) {
      hero.setPoint(hero.getPoint().x-3,hero.getPoint().y);
      hero.setState(FACE_LEFT);
    }
    else if(keyCode == UP){
      hero.setJump(17);
    }
    else if(keyCode == DOWN){
      grade += hero.atk(lt);
      count=ATK_TIME; 
      p.play(0);
    }
  }
}

class

final static String basicPath = "D:\\修\\學校課業\\大三\\互動技術\\期末作業\\game\\"; 
final static int ATK_DURING = 100;

//This class use to save site and size ( 2D information )
class Index2D
{
  public int x;
  public int y;
  public Index2D(int x,int y)
  {
    this.x = x;
    this.y = y; 
  }
};

//define :: To make me more easy to know
final static int FACE_RIGHT = 1;
final static int FACE_LEFT = 0;

class heroClass
{
  private Index2D point,size;
  private int health ;
  private int state ;  //Face 0 :: left , 1 :: right
  private PImage img,img_mirro ; 
  private PImage atk,atk_mirro ;
  private int w,h;
  private int vector;
  private boolean lock;
  
  public heroClass(int w,int h)
  {
     img = loadImage(basicPath + "role\\hero.png");
     img_mirro= loadImage(basicPath + "role\\hero_mirro.png");
     atk = loadImage(basicPath + "role\\attack.png");
     atk_mirro= loadImage(basicPath + "role\\attack_mirro.png");
     point = new Index2D(320-w,350-h);
     size = new  Index2D(w,h);
     state = vector = 0;
     lock = false;
     health = 100;
  }
  
  public void setHealth(int x)
  {
    health += x ;
  }
  public int getHealth()
  {
    return health; 
  }
  public PImage getImage()
  {
    return img;
  }
  public Index2D getPoint()
  {
    return point; 
  }
  public Index2D getSize()
  {
    return size; 
  }
  public void showImage()
  {
    point.y -= vector;
    
    //Jump parameter
    if(point.y +size.y!=350){
      vector-=1;
      lock = true;
    }else{
      vector = 0;
      lock = false ; 
    }
    //do not over the window board
    point.x = point.x < 0 ? 0 : point.x;
    point.x = point.x > 640-size.x ? 640-size.x : point.x;
    //control face which site
    if(state == FACE_LEFT ) image(img,point.x,point.y,size.x,size.y);
    else image(img_mirro,point.x,point.y,size.x,size.y);
  }
  public void setPoint(int x , int y)
  {
    point.x = x;
    point.y = y;
  }
  public void setState(int type)
  {
    state = type; 
  }
  public void setJump(int h)
  {
    if(lock == false ) vector = h ;
  }
  public int atk(List<monsterClass> lt)
  {
    //return value is kill number and will add to grade
    int tmp;
    int killNum = 0;
    if(state == FACE_LEFT ) image(atk,point.x-size.x,point.y,size.x,size.y);
    else image(atk_mirro,point.x+size.x,point.y,size.x,size.y);
    
    for(int i=0;i<lt.size();i++){
      //get monster's x site
      tmp =lt.get(i).getPoint().x;
      if(state == FACE_LEFT){
        //if is in range      reduce their life point
         if(tmp >= point.x-size.x && tmp <= point.x){
           lt.get(i).setHealth(-5);
           if( lt.get(i).getHealth()<=0){
             lt.remove(i--);
             killNum++; 
           }
         }
      }
      else{
        if(tmp >= point.x && tmp <= point.x+size.x){
           lt.get(i).setHealth(-50);
           if( lt.get(i).getHealth()<=0){
             lt.remove(i--);
             killNum++;
           }
         }
      }
    }
    return killNum;
  }
 
};

class monsterClass
{
  private Index2D point,size;
  private int health ;
  private int state ;  //Face 0 :: left , 1 :: right
  private PImage img,img_mirro ; 
  private PImage atk;
  private int w,h;
  private int type; 
  private int during,atkPower; //during is how long will attack hero
  private boolean lock ;
  private int count;
  
  public monsterClass(int w,int h,int t)
  {
    count = 0;
    lock = false;
    //t use to decide which kind monster will appear and their parameter
     if( t < 10){
       img = loadImage(basicPath + "role\\monster.png");
       img_mirro= loadImage(basicPath + "role\\monster_mirro.png");
       atk = loadImage(basicPath + "role\\matk.png");
       health = (int)random(200,1000.99);
       during = 40;
       atkPower = -25;
       type = 0;
     }
     else{
       img = loadImage(basicPath + "role\\monster2.png");
       img_mirro= loadImage(basicPath + "role\\monster2_mirro.png");
       atk = loadImage(basicPath + "role\\matk.png");
       health = 50;
       during = 30;
       atkPower = -5;
       type = 1;
     }
     //decide which site will appear
     if(t%2 == 1) state = FACE_LEFT;
     else state = FACE_RIGHT;
     if(state == FACE_LEFT) point = new Index2D(640,350-h);
     else point = new Index2D(0-w,350-h);
     //if is a stronge monster will become bigger;
     if(type == 0){
       size = new Index2D(w*2,h*2);
       point.x -= w;
       point.y -= h; 
     }
     else size = new Index2D(w,h);
  }
  public void setHealth(int x)
  {
    health+=x;  
  }
  public int getHealth()
  {
     return health; 
  }
  public Index2D getPoint()
  {
    return point; 
  }
  public void move(Index2D hero)
  {
    if(lock == false){
      if (point.x < hero.x ) state = FACE_RIGHT ;
      else state = FACE_LEFT ;
      
      if(state == FACE_LEFT ){
        if(type == 0) point.x -= 1;
        else point.x-=2; 
      }
      else{
         if(type == 0) point.x += 1;
        else point.x+=2; 
      }
    }
    
  }
  public int atkDetector(Index2D hero)
  {
    //detector is hero in the attack range 
    //if yes !!  will increase the during time
    //when is over the threshold will attack and do not miss!! XD
    if(hero.y >= point.y-5){
      if(state == FACE_LEFT) {
         if(hero.x > point.x - size.x && hero.x < point.x){
            during++;
            lock = true;
         }
         else lock = false;
      } 
      else{
         if(hero.x < point.x+size.x && hero.x > point.x){
            during++;
            lock = true;
         } 
         else lock = false;
      }
      if(during > ATK_DURING){
         during = 0;
         count = 12;
         return atkPower; 
      }
      else return 0;
    }
    else return 0;
  }
  public void showImage()
  {
    if(state == FACE_LEFT ) image(img,point.x,point.y,size.x,size.y);
    else image(img_mirro,point.x,point.y,size.x,size.y);
    if(count-->0) atk();
  }
  public void atk()
  {
    if(state == FACE_LEFT ) image(atk,point.x-size.x,point.y,size.x,size.y);
    else image(atk,point.x+size.x,point.y,size.x,size.y);
  }
};

小組分工:

Processing、Arduino、硬體部分:徐修謙
購買硬體:謝睿峰

心得:

在這次的作業當中,深深的體會到接駁硬體的困難。不過在製作的過程中,雖然困難但是是非常有趣的,將一段段的線路銜接,最後所製作而成的作品出現,這是非常有成就感的。而程式部分,由於沒有直接使用期中作業去更改,在最後的製作過程其實並不輕鬆。每一個怪物以及英雄所寫成的class,其實也耗費的不少的力氣。雖然以後不太會用到它,不過這個class其實寫出來有不錯的後續延伸性,如果未來我有需要用到相關的功能也可以直接套用就好,不過這好像短期內不太可能。總而言之、言而總之,在這次作業讓我對java更加熟悉,而且也了解到硬體以及電腦軟體之間的通訊,是甚麼一回事,有很大的收穫,也很開心。

Week19 Final Project



系統名稱:接香菇瑪利歐


圖片:

此圖為遊戲開始畫面

此圖為遊戲進行畫面

此圖為硬體arduino線路接法
 
 
 
 

心得介紹

這次期末作業從單純的processing加上硬體arduino,一開始我們不太會接arduino到後來自己成功的做出自己的期末作品,雖然只是按鈕功能,但還是很有趣。我們的遊戲計分方式分別是紅色的香菇代表得五分,綠色的香菇代表得一分,怪物代表減生命值,金幣可以讓生命值增加一個。我們設計這樣的遊戲計分方面玩遊戲的人可以增加遊戲的刺激度。

影片

這是遊戲失敗的影片



這是遊戲過關的影片




組員分工情況

邱舒曼之負責工作:

1 撰寫部落格
2.寫processing遊戲的計分程式
3.寫arduion連接processing部分的程式

潘瀅玉 之負責工作:

1.拍攝成果的影片
2.寫processing遊戲的兩種香菇、怪物、金幣的掉落方式
3.接arduion的按鈕,負責接硬體