2023年1月13日 星期五

CY.hsin week19

 //加入下棋音效

import processing.sound.*;

SoundFile soundHit;

void setup(){

    size(600,600);

    soundHit=new SoundFile(this,"hit.mp3");

    

}

int [][] go={

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},  

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

};

int N=0;//現在有幾個棋子

void draw(){

  background(#FFAA64);

  //畫線

  for(int i=1;i<=19;i++){//畫19條線

    line(30,30*i,570,30*i);//直線

    line(30*i,30,30*i,570);//橫線

  }

  //畫棋盤上的點點

  fill(0);//黑色的

  ellipse(120,120,10,10);

  ellipse(120,300,10,10);

  ellipse(120,480,10,10);

  ellipse(300,120,10,10);

  ellipse(300,300,10,10);

  ellipse(300,480,10,10);

  ellipse(480,120,10,10);

  ellipse(480,300,10,10);

  ellipse(480,480,10,10);

  //畫黑棋/白棋

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

    for(int j=0;j<19;j++){

      if(go[i][j]==1){

        fill(0);

        ellipse(30+j*30,30+i*30,30,30);//30*30的黑棋,下在鼠標按的位置

      }else if(go[i][j]==2){

        fill(255);

        ellipse(30+j*30,30+i*30,30,30);//30*30的白棋,下在鼠標按的位置

       }

    }

  }

}

void mousePressed(){

  int i=(mouseY-15)/30;//x座標

  int j=(mouseX-15)/30;//y座標

  soundHit.play();//下棋播放音效

  go[i][j]=(N%2==0)?1:2;//不是1就是2,1=白色、2=黑色。

  N++;//增加棋子

}

2023年1月12日 星期四

Ru的互動技術筆記

貓狗大戰

Stage1 (遊戲封面)

這是自己仿畫原版貓狗大戰的遊戲封面圖,底下有利用 rect 製作開始遊戲以及遊戲說明的按鈕,mousePressed() 去設定滑鼠點擊的範圍,跳轉到 stage2 或者 stage5。

Stage2 (遊戲介面)


在期末作業裡,我們增加了道具的選項 (子彈放大、雙倍傷害、血量+10%),道具的部份我們宣告了 boolean button=true,就是一開始道具的按鈕會顯示在場景中,然後在 mousePressed() 中,道具按鈕的範圍點選後,改成 button=false,這樣按鈕就會消失了!還有一個問題是子彈放大後,如果在那一回合中沒有擊中,子彈會回復原本的大小,所以宣告了 boolean toolbomb1Enable = false,在滑鼠點擊按鈕範圍時 toolbomb1Enable = true,射擊到其他地方時 toolbomb1Enable = false,這樣就能在射擊失敗後回復原本的大小了。

第二個新增的是時間,設定一回合進行的時間是十秒,如果沒有在時間內射出去就會轉換球權。

第三個是改變彈道的線條,期中的時候我們是沿用老師一開始教的直線去瞄準,後來改拋物線這樣看起來比較好看一點!這段因為要跟著回合轉換所以寫在 who=1、who=2 裡面,nowX1、nowY1 表示拋物線的起始點在 dogX1、dogY1 (狗子)的位置,貓咪回合的拋物線同理,t 表示畫的圓圈個數 (拋物線是虛線的感覺)。

Stage3 (狗子勝利)


當貓咪的血量扣完時,會自動跳轉到狗子勝利的場景,同時 sound1.stop (把遊戲的背景音樂關閉),播放勝利的擊掌聲。

Stage4 (貓咪勝利)


當狗子的血量扣完時,會自動跳轉到貓咪勝利的場景,同時 sound1.stop (把遊戲的背景音樂關閉),播放勝利的擊掌聲。

Stage4 (玩法說明)    

玩法的地方,圖片有點做壞掉了,因為要把貓狗跟道具的圖示去背貼到裡面所以畫質被吃掉。


統整:需要改進的地方是畫面太小,當初是用老師原本設定的值去製作,所以沒改到,而且增加很多按鈕之後,要再改畫面大小每個東西都要重改,所以就沒更動了。當初再做進階版本的時候有想過要增加風力,也想增加力量條,如果有更多時間感覺可以做得更好!

期末作業 過馬路

 

import processing.sound.*;  // 加入音樂函式庫

SoundFile sound  // 宣告音檔

 

int fin = 0;  // 初始狀態為0

PImage playerStay;  // 宣告圖片 (玩家上下左右移動時之圖、車子、房子、底圖)

 

int roleMoveX = 250;  // 宣告玩家初始位置

int roleMoveY = 450;

 

int send_letter = 1;  // 關卡數

 

void setup() {

  size(500, 500);

  playerStay = loadImage("Stay.png");  // 載入圖片(玩家上下左右移動時之圖、車子、房子、底圖)

  sound = new SoundFile(this, "squaredance.wav");  // 載入音檔

  sound.play();  // 開始播放音樂

  sound.loop();  // 於音樂播畢時從頭重複播放

}

void draw() {

  最初fin為0時

    顯示主頁底圖

    point(mouseX, mouseY);  // 判斷鼠標位置

  fin為1時 開始遊戲

    顯示遊戲底圖

    drawRoad();     // 繪製道路

    drawRiver();       // 繪製河流

    Build();  // 放置房屋

    Player();  // 玩家位置

  }

  End();  // 改變狀態

  point(mouseX, mouseY);  // 判斷鼠標位置

}

   

float []carX = new float[20];  // 定義車於

void drawRoad();

void drawRiver();

void Build();

void Player();

void End();

互動技術 week07

接續上周未完

1.自動洗牌


2.選擇棋子時 顯示綠色


3.移動棋子


4.棋子移動後 清空原位置


5.放入音樂

互動技術 week05

1.先畫出格線


2.用陣列以迴圈方式排上字


3.放入中文字替代數字


4.棋子字上顏色(黑、紅)


5.設定鼠標,點擊消失及長按後移動位置


6.改變陣列 做出暗棋


7.加上翻棋


Week_17 2022.12.26

1. 期末作品目前成果

---------------------------------- github ----------------------------------

Week_16 2022.12.19

1. 期末作品目前成果

---------------------------------- github ----------------------------------

Week_15 2022.12.12

1. 期末作品目前成果

---------------------------------- github ----------------------------------

Week_14 2022.12.05

1. 期末作品目前成果

---------------------------------- github ----------------------------------

Week_13 2022.11.28

1. 期末作品目前成果

---------------------------------- github ----------------------------------

Week_12 2022.11.21

1. 期末作品目前成果

---------------------------------- github ----------------------------------

Week_11 2022.11.14

1. 期末作品目前成果


---------------------------------- github ----------------------------------

Week_10 2022.11.07

1. 期末作品目前成果


2. 作品問題

    (1) 圖片沒辦法去背

    (2) 遊戲不完整

    (3) 切換畫面不流暢(已解決)


3. 程式碼

---------------------------------- github ----------------------------------

TC*(˙Ⱉ˙ฅ)​-week19(期末作品展示)

這周終於要來展示作品啦~

遊戲名稱:躲避撞球趣

遊戲規則:

在2分鐘左右的期間,看能夠將多少顆白色球撞入六個洞裡~每掉一顆球下去就能夠得到一分,並且白色球會被重新隨機生成在場面上

同時間場地上面會有不同顏色的障礙球,紅色障礙球會一直固定在場地上進行干擾,他色障礙球則是會不定期冒出場上來進行妨礙,只要碰到障礙球就會被扣一分~白色球就會死亡然後隨機復活在場面上

有運用到的程式與結合:
讀入圖片、按鈕製作、設定字體、播放音樂、場景變換、分頁呼叫、球的碰撞偵測反彈、計時器、計分器、布林變數、各類的滑鼠事件等等

上周內容或許有點不是那麼的清楚,因此這邊會重新放上完整的程式碼與註解
程式碼主頁
import processing.sound.*;//聲音的函式庫
SoundFile sound1;//音檔1
PImage home_img,start_img,go_img;//讀入封面,開始遊戲,點go
PImage table_img,sayrule_img,stage4_img;//讀入遊戲畫面桌子,規則說明
int w=1200,h=750,stage=1;//畫面寬度,畫面高度,當前場景編號
int startTime;//遊戲開始時間
int Time;//計時
void setup(){//基本設定
  size(1200,900);//視窗長寬
  sound1=new SoundFile(this,"music01.mp3");//載入音樂
  sound1.play();//播放音樂
  PFont font=createFont("標楷體",20);//設定創建字體,全部的字體都會被設置為標楷體
  textFont(font);//文字字體
  home_img = loadImage("home.png");//載入封面圖home.png
  start_img = loadImage("start.png");//載入開始遊戲鍵start.png
  go_img = loadImage("go.png");//載入go.png
  table_img = loadImage("table.png");//載入遊戲畫面table.png
  sayrule_img = loadImage("sayrule.png");//載入規則說明sayrule.png
  stage4_img = loadImage("stage4.png");//載入stage4.png
}
void draw(){//畫圖
  if(stage==1){//初始頁面舞台1,首頁場景設定
    image(home_img,0,0,1200,900);//home圖片的x,y座標(0,0),(1200,900)是圖片寬高
    image(start_img,1000,750,150,75);//start圖片的x,y座標(1000,600),(150,75)是圖片寬高
    if(pressed_start == true)rect(1000,600,150,75);//按下開始遊戲的按鈕後
  }
  if(stage==2){//當被切換到舞台2進入遊戲畫面的設定
    image(sayrule_img,0,0,1200,900);//可以調整圖片大小,規則說明的x,y座標(0,0),(1200,900)是圖片寬高
    image(go_img,860,750,150,75);//rule圖片的x,y座標(800,600),(150,75)是圖片寬高
    if(pressed_go == true)rect(860,750,150,75);//按下go的按鈕後
  }
  if(stage==3){//當被切到舞台3時
    draw2();//執行分頁stage3的程式
  }
  if(stage==4){//當被切換到舞台4時
    image(stage4_img,0,0,1200,900);//可以調整圖片大小,規則說明的x,y座標(0,0),(1200,900)是圖片寬高
  }
}
boolean pressed_start=false;//預設按壓開始遊戲鍵為關閉狀態
boolean pressed_go=false;//預設按壓規則介紹鍵為關閉狀態
void mousePressed(){//按下滑鼠時
  if(stage==1){//當被切換到舞台1
    if(1000<mouseX && mouseX < 1000+200 && 750<mouseY && mouseY<750+100){
      //判定圖片範圍,xy座標(1000,600),1000+200就是判定範圍有多寬,600+100就是判定範圍有多高
      pressed_start=true;//如果按壓開始遊戲鍵成立
      stage=2;//切換到場景2,介紹遊戲
      pressed_start=false;//關閉按下開始鍵
    }
  }
  if(stage==2){//當被切換到舞台2
    if(860<mouseX && mouseX < 860+150 && 750<mouseY && mouseY<750+80){
      //判定圖片範圍,xy座標(1000,600),1000+200就是判定範圍有多寬,750+100就是判定範圍有多高
      pressed_go=true;//如果按壓開始遊戲鍵成立
      stage=3;//切換到場景3,開始遊戲
      pressed_go=false;//關閉按下go鍵
    }
  }
  if(stage==3){//當被切換到舞台3
    len0 = dist(ballX,ballY,mouseX,mouseY);//計算白色母球和鼠標(X,Y)座標的距離向量
  }
}
void mouseReleased(){//放開滑鼠時
  if(stage==3){//當切換到舞台3時
    len1 = dist(ballX,ballY,mouseX,mouseY);//計算白色母球和鼠標(X,Y)座標的距離向量
    float v = len1-len0;//計算兩者向量相減後的力矩
    ballVX = -v * cos(angle);//COS角度
    ballVY = -v * sin(angle);//SIN角度
    shooting=true;//打開布林變數,球可以被射出
  }
}

程式碼分頁(stage3)
float [] holeX={50,600,1148,50,600,1151};//48,600,1150,65,600,1150
float [] holeY={52,46,57,692,703,695};//50,50,60,690,700,700
float ballX=180,ballY=200,ballVX=0,ballVY=0,angle=0;//設定球一開始出現的xy位置,以及角度初始化
float ballX2=200,ballY2=300,ballVX2=0,ballVY2=0;//設定球一開始出現的XY位置
float ballX3=300,ballY3=400,ballVX3=0,ballVY3=0;//設定球一開始出現的XY位置
float ballX4=400,ballY4=500,ballVX4=0,ballVY4=0;//設定球一開始出現的XY位置
float ballX5=400,ballY5=500,ballVX5=0,ballVY5=0;//設定球一開始出現的XY位置
float ballX6=200,ballY6=300,ballVX6=0,ballVY6=0;//設定球一開始出現的XY位置
float score=0;//將成績初始化歸0
float len0=0,len1=0;//距離向量歸0
boolean shooting=false;//射擊的布林變數預設關閉
void draw2(){
  image(table_img,0,0,1200,750);//可以調整圖片大小,table圖片的x,y座標(0,0),(1200,750)是圖片寬高
  fill(#2B793A);//綠色的長方形
  rect(47,47,1110,660);//測試畫長方(47,47是x,y座標/1110,660是長寬
  
  fill(#A76565);//棕色的長方形
  rect(0,750,1200,300);//測試畫長方(47,47是x,y座標/1110,660是長寬
  
  int m = (150-((millis()/1000)-(startTime/1000)))/60%60;//計時器,毫秒是千分之一秒,150秒約2:30,因為要倒數就要%60,設定分鐘
  int s = (150-((millis()/1000)-(startTime/1000)))%60;//計時器,毫秒是千分之一秒,150秒約2:30,因為要倒數就要%60,設定秒鐘
  String mm = nf(m, 2);//00,ex:01分鐘
  String ss = nf(s, 2);//00,ex:01秒鐘
  String time = "剩下"+":"+mm+":"+ss;//顯示剩餘的時間

  if(millis()-startTime>=150000){//如果時間超過或剛好等於兩分半,切換到場景4
    stage=4;
  }else if(millis()-startTime<=150000){//如果時間還沒超過兩分半,就還在倒數
    fill(#FFFFFF);//剩餘時間的白色字體顏色
    textSize(40);//字體大小
    text(time,20,830);//時間,X座標20,Y座標830
  }
  
  fill(#FFFFFF);//白色字體顏色
  textSize(40);//字體大小
  text(score,300,830);//成績
  
  fill(#FFFFFF);//白色的球
  ellipse(ballX,ballY,30,30);//畫個20*20圓形
  angle = atan2(mouseY-ballY,mouseX-ballX);//算出角度的tan2(),這裡是公式
  
  if(shooting==false){//如果布林變數為關閉
    strokeWeight(10);//粗度為10的直線
    stroke(#FFFF00);//直線顏色是黃色
    line(ballX,ballY,ballX+cos(angle)*100,ballY+sin(angle)*100);//x,y座標固定,
    
    strokeWeight(5);//粗度為5的直線
    stroke(#0000FF);//直線顏色是藍色
    line(ballX,ballY,ballX+cos(angle)*len0,ballY+sin(angle)*len0);//x,y座標固定,
    
    strokeWeight(3);//粗度為3的直線
    stroke(#00FF00);//直線顏色是綠色
    line(ballX,ballY,ballX+cos(angle)*len0,ballY+sin(angle)*len0);//x,y座標固定,
    
    strokeWeight(1);//粗度為1的直線
    stroke(0);//直線顏色是黑色
    line(ballX,ballY,mouseX,mouseY);//x,y座標固定,mouse會隨著滑鼠移動而改變線的長度
  }
  if(ballX+ballVX>1200-5 || ballX+ballVX<10){//ballX+vx>1200控制右邊x邊界,ballX+vx<10控制左邊x邊界
    ballVX=-ballVX;//會反彈
  }
  if(ballY+ballVY>720-5 || ballY+ballVY<25){//ballY+vy>720控制下面y邊界,ballY+vy<10控制上面y邊界
    ballVY=-ballVY;//會反彈
  }
  for(int i=0;i<6;i++){//繪製六個球袋
    fill(#000000);//黑色的球袋
    ellipse(holeX[i],holeY[i],50,50);//最後面兩個數字是桌面六個圓形洞大小
    if(shooting && dist(ballX,ballY,holeX[i],holeY[i])<30){//計算白色母球和球袋的XY座標距離是否小於30
     score++;//如果母球射入球袋就會扣分
     reset();//隨機復活
     println(score);//顯示成績
    }
    ballX += ballVX/10;
    ballY += ballVY/10;
    ballVX*=0.99;//替球增加摩擦力
    ballVY*=0.99;//替球增加摩擦力
  }
  
  fill(#FF6A6A);//粉色的球
  ellipse(random(1100),random(750),20,20);//畫個20*20圓形
  //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
  if(shooting && dist(ballX,ballY,ballX2,ballY2)<15){//計算白色母球和橘球的XY座標距離是否小於15
     score--;//如果母球射入球袋就會扣分
     reset();//隨機復活
     println(score);//顯示成績
  }
  
   if(m==2 && s>0 && s<15){//在2:00~2:15秒時,會有橘色球來搗亂
    fill(#FFCB1C);//橘色的球
    ellipse(random(500),random(600),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX6,ballY6)<20){//計算白色母球和橘球的XY座標距離是否小於20
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
   }
  
  if(m==1 && s>0 && s<59){//在1:00~1:59秒時,會有藍色球來搗亂
    fill(#93B9EA);//藍色的球
    ellipse(random(900),random(600),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX3,ballY3)<15){//計算白色母球和藍球的XY座標距離是否小於15
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
   }
   
    if(m==1 && s>0 && s<30){//在1:00~1:30秒時,會有綠色球來搗亂
    fill(#3BB281);//綠色的球
    ellipse(random(900),random(600),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX5,ballY5)<20){//計算白色母球和綠球的XY座標距離是否小於20
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
   }
   
   if(m==0 && s>0 && s<59){//在0:00~0:59秒時,會有藍色球來搗亂
    fill(#93B9EA);//藍色的球
    ellipse(random(800),random(300),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX3,ballY3)<20){//計算白色母球和藍球的XY座標距離是否小於20
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
  }
   
    if(m==0 && s>0 && s<59){//在0:00~0:59秒時,會有黃色球來搗亂
    fill(#FFFCA7);//黃色的球
    ellipse(random(1000),random(800),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX4,ballY4)<30){//計算白色母球和黃球的XY座標距離是否小於30
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
  }
}
void reset(){//隨機生成在場地上
  ballX=random(1100);//隨機X座標
  ballY=random(750);//隨機Y座標
  shooting=false;//關閉布林函數,預設非射擊狀態
  ballVX=0;//X方向的速度歸0
  ballVY=0;//Y方向的速度歸0
}

附上幾張遊戲畫面





展示影片的連結網址:https://youtu.be/B868n5GcnaA


2023年1月11日 星期三

為哥互動技術week17

 

#2022互動技術


修改算分的bug


TC*(˙Ⱉ˙ฅ)​-week17

上周做出了白色母球如果被射進六邊的黑色球袋中,就會被扣分
這周我想把剩餘的撞球寫完,並且改良了一下玩法
如果將規則改為,在規定的時間內看看可以射出多少顆母球呢?
當然事情並不會這麼簡單,若場地上還有其他障礙物,且被碰到後會倒扣一分呢?

當然我們要先結合之前學過的知識來繼續寫遊戲,目前用到了音樂播放、布林變數、滑鼠事件、碰撞偵測等等

像是如果撞到了其他顏色的球就會死亡隨機重生在場地上,所以還要設置一個回復按鍵,我們只需要改寫上周最後一段的reset()函式
void reset(){
  ballX=random(1100);//隨機生成的x座標範圍
  ballY=random(750);//隨機生成的y座標範圍
  shooting=false;
  ballVX=0;
  ballVY=0;
}
只要是隨機就會運用到random這個函式,但範圍不要設置超出場地,因此取(1100,750)的值內

接下來還需要使用場景切換,宣告初始場景並在draw()函式執行該場景會需要做到的指令(已經先將程式碼分成兩頁,當有需要使用到分頁程式碼時在進行呼叫)

程式碼主頁
import processing.sound.*;//聲音的函式庫
SoundFile sound1;//音檔1
PImage home_img,start_img,go_img;//讀入封面,開始遊戲,點go
PImage table_img,sayrule_img,stage4_img;//讀入遊戲畫面桌子,規則說明
int w=1200,h=750,stage=1;//畫面寬度,畫面高度,當前場景編號
void setup(){//基本設定
  size(1200,900);//視窗長寬
  sound1=new SoundFile(this,"music01.mp3");//載入音樂
  sound1.play();//播放音樂
  home_img = loadImage("home.png");//載入封面圖home.png
  start_img = loadImage("start.png");//載入開始遊戲鍵start.png
  go_img = loadImage("go.png");//載入go.png
  table_img = loadImage("table.png");//載入遊戲畫面table.png
  sayrule_img = loadImage("sayrule.png");//載入規則說明sayrule.png
  stage4_img = loadImage("stage4.png");//載入stage4.png
}
void draw(){//畫圖
  if(stage==1){//初始頁面舞台1,首頁場景設定
    image(home_img,0,0,1200,900);//home圖片的x,y座標(0,0),(1200,900)是圖片寬高
    image(start_img,1000,750,150,75);//start圖片的x,y座標(1000,600),(150,75)是圖片寬高
    if(pressed_start == true)rect(1000,600,150,75);//按下開始遊戲的按鈕後
  }
  if(stage==2){//當被切換到舞台2進入遊戲畫面的設定
    image(sayrule_img,0,0,1200,900);//可以調整圖片大小,規則說明的x,y座標(0,0),(1200,900)是圖片寬高
    image(go_img,860,750,150,75);//rule圖片的x,y座標(800,600),(150,75)是圖片寬高
    if(pressed_go == true)rect(860,750,150,75);//按下go的按鈕後
  }
  if(stage==3){//當被切到舞台3時
    draw2();//執行分頁stage3的程式
  }
  if(stage==4){//當被切換到舞台4時
    image(stage4_img,0,0,1200,900);//可以調整圖片大小,規則說明的x,y座標(0,0),(1200,900)是圖片寬高
  }
}
boolean pressed_start=false;//預設按壓開始遊戲鍵為關閉狀態
boolean pressed_go=false;//預設按壓規則介紹鍵為關閉狀態
void mousePressed(){//按下滑鼠時
  if(stage==1){//當被切換到舞台1
    if(1000<mouseX && mouseX < 1000+200 && 750<mouseY && mouseY<750+100){
      //判定圖片範圍,xy座標(1000,600),1000+200就是判定範圍有多寬,600+100就是判定範圍有多高
      pressed_start=true;//如果按壓開始遊戲鍵成立
      stage=2;//切換到場景2,介紹遊戲
      pressed_start=false;//關閉按下開始鍵
    }
  }
  if(stage==2){//當被切換到舞台2
    if(860<mouseX && mouseX < 860+150 && 750<mouseY && mouseY<750+80){
      //判定圖片範圍,xy座標(1000,600),1000+200就是判定範圍有多寬,750+100就是判定範圍有多高
      pressed_go=true;//如果按壓開始遊戲鍵成立
      stage=3;//切換到場景3,開始遊戲
      pressed_go=false;//關閉按下go鍵
    }
  }
  if(stage==3){//當被切換到舞台3
    len0 = dist(ballX,ballY,mouseX,mouseY);//計算白色母球和鼠標(X,Y)座標的距離向量
  }
}
void mouseReleased(){//放開滑鼠時
  if(stage==3){//當切換到舞台3時
    len1 = dist(ballX,ballY,mouseX,mouseY);//計算白色母球和鼠標(X,Y)座標的距離向量
    float v = len1-len0;//計算兩者向量相減後的力矩
    ballVX = -v * cos(angle);//COS角度
    ballVY = -v * sin(angle);//SIN角度
    shooting=true;//打開布林變數,球可以被射出
  }
}

程式碼分頁(stage3)
float [] holeX={50,600,1148,50,600,1151};//48,600,1150,65,600,1150
float [] holeY={52,46,57,692,703,695};//50,50,60,690,700,700
float ballX=180,ballY=200,ballVX=0,ballVY=0,angle=0;//設定球一開始出現的xy位置,以及角度初始化
float score=0;//將成績初始化歸0
float len0=0,len1=0;//距離向量歸0
boolean shooting=false;//射擊的布林變數預設關閉
void draw2(){
  image(table_img,0,0,1200,750);//可以調整圖片大小,table圖片的x,y座標(0,0),(1200,750)是圖片寬高
  fill(#2B793A);//綠色的長方形
  rect(47,47,1110,660);//測試畫長方(47,47是x,y座標/1110,660是長寬
  
  fill(#A76565);//棕色的長方形
  rect(0,750,1200,300);//測試畫長方(47,47是x,y座標/1110,660是長寬
  
  fill(#FFFFFF);//白色的球
  ellipse(ballX,ballY,30,30);//畫個20*20圓形
  angle = atan2(mouseY-ballY,mouseX-ballX);//算出角度的tan2(),這裡是公式
  
  if(shooting==false){//如果布林變數為關閉
    strokeWeight(10);//粗度為10的直線
    stroke(#FFFF00);//直線顏色是黃色
    line(ballX,ballY,ballX+cos(angle)*100,ballY+sin(angle)*100);//x,y座標固定,
    
    strokeWeight(5);//粗度為5的直線
    stroke(#0000FF);//直線顏色是藍色
    line(ballX,ballY,ballX+cos(angle)*len0,ballY+sin(angle)*len0);//x,y座標固定,
    
    strokeWeight(3);//粗度為3的直線
    stroke(#00FF00);//直線顏色是綠色
    line(ballX,ballY,ballX+cos(angle)*len0,ballY+sin(angle)*len0);//x,y座標固定,
    
    strokeWeight(1);//粗度為1的直線
    stroke(0);//直線顏色是黑色
    line(ballX,ballY,mouseX,mouseY);//x,y座標固定,mouse會隨著滑鼠移動而改變線的長度
  }
  if(ballX+ballVX>1200-5 || ballX+ballVX<10){//ballX+vx>1200控制右邊x邊界,ballX+vx<10控制左邊x邊界
    ballVX=-ballVX;//會反彈
  }
  if(ballY+ballVY>720-5 || ballY+ballVY<25){//ballY+vy>720控制下面y邊界,ballY+vy<10控制上面y邊界
    ballVY=-ballVY;//會反彈
  }
  for(int i=0;i<6;i++){//繪製六個球袋
    fill(#000000);//黑色的球袋
    ellipse(holeX[i],holeY[i],50,50);//最後面兩個數字是桌面六個圓形洞大小
    if(shooting && dist(ballX,ballY,holeX[i],holeY[i])<30){//計算白色母球和球袋的XY座標距離是否小於30
     score++;//如果母球射入球袋就會扣分
     reset();//隨機復活
     println(score);//顯示成績
    }
    ballX += ballVX/10;
    ballY += ballVY/10;
    ballVX*=0.99;//替球增加摩擦力
    ballVY*=0.99;//替球增加摩擦力
  }
}
void reset(){//隨機生成在場地上
  ballX=random(1100);//隨機X座標
  ballY=random(750);//隨機Y座標
  shooting=false;//關閉布林函數,預設非射擊狀態
  ballVX=0;//X方向的速度歸0
  ballVY=0;//Y方向的速度歸0
}

然後就可以得到這幾個頁面(會播放音樂




1.遊戲進行中,還會用到計時器的寫法
先宣告時間變數(宣告在哪頁都沒有關係)
int startTime;//遊戲開始時間
int Time;//計時

然後寫進分頁的void draw2()函式裡
  int m = (150-((millis()/1000)-(startTime/1000)))/60%60;//計時器,毫秒是千分之一秒,150秒約2:30,因為要倒數就要%60,設定分鐘
  int s = (150-((millis()/1000)-(startTime/1000)))%60;//計時器,毫秒是千分之一秒,150秒約2:30,因為要倒數就要%60,設定秒鐘
  String mm = nf(m, 2);//00,ex:01分鐘
  String ss = nf(s, 2);//00,ex:01秒鐘
  String time = "剩下"+":"+mm+":"+ss;//顯示剩餘的時間


2.若想控制字體(ex:剩餘時間的剩餘),就使用PFont font=createFont("字體名稱",字體大小);來固定
PFont font=createFont("標楷體",20);//設定創建字體,全部的字體都會被設置為標楷體 textFont(font);//文字字體

將1、2點結合起來,如程式所示
程式主頁
import processing.sound.*;//聲音的函式庫
SoundFile sound1;//音檔1
PImage home_img,start_img,go_img;//讀入封面,開始遊戲,點go
PImage table_img,sayrule_img,stage4_img;//讀入遊戲畫面桌子,規則說明
int w=1200,h=750,stage=1;//畫面寬度,畫面高度,當前場景編號
void setup(){//基本設定
  size(1200,900);//視窗長寬
  PFont font=createFont("標楷體",20);//設定創建字體,全部的字體都會被設置為標楷體
  textFont(font);//文字字體
  sound1=new SoundFile(this,"music01.mp3");//載入音樂
  sound1.play();//播放音樂
  home_img = loadImage("home.png");//載入封面圖home.png
  start_img = loadImage("start.png");//載入開始遊戲鍵start.png
  go_img = loadImage("go.png");//載入go.png
  table_img = loadImage("table.png");//載入遊戲畫面table.png
  sayrule_img = loadImage("sayrule.png");//載入規則說明sayrule.png
  stage4_img = loadImage("stage4.png");//載入stage4.png
}
void draw(){//畫圖
  if(stage==1){//初始頁面舞台1,首頁場景設定
    image(home_img,0,0,1200,900);//home圖片的x,y座標(0,0),(1200,900)是圖片寬高
    image(start_img,1000,750,150,75);//start圖片的x,y座標(1000,600),(150,75)是圖片寬高
    if(pressed_start == true)rect(1000,600,150,75);//按下開始遊戲的按鈕後
  }
  if(stage==2){//當被切換到舞台2進入遊戲畫面的設定
    image(sayrule_img,0,0,1200,900);//可以調整圖片大小,規則說明的x,y座標(0,0),(1200,900)是圖片寬高
    image(go_img,860,750,150,75);//rule圖片的x,y座標(800,600),(150,75)是圖片寬高
    if(pressed_go == true)rect(860,750,150,75);//按下go的按鈕後
  }
  if(stage==3){//當被切到舞台3時
    draw2();//執行分頁stage3的程式
  }
  if(stage==4){//當被切換到舞台4時
    image(stage4_img,0,0,1200,900);//可以調整圖片大小,規則說明的x,y座標(0,0),(1200,900)是圖片寬高
  }
}
boolean pressed_start=false;//預設按壓開始遊戲鍵為關閉狀態
boolean pressed_go=false;//預設按壓規則介紹鍵為關閉狀態
void mousePressed(){//按下滑鼠時
  if(stage==1){//當被切換到舞台1
    if(1000<mouseX && mouseX < 1000+200 && 750<mouseY && mouseY<750+100){
      //判定圖片範圍,xy座標(1000,600),1000+200就是判定範圍有多寬,600+100就是判定範圍有多高
      pressed_start=true;//如果按壓開始遊戲鍵成立
      stage=2;//切換到場景2,介紹遊戲
      pressed_start=false;//關閉按下開始鍵
    }
  }
  if(stage==2){//當被切換到舞台2
    if(860<mouseX && mouseX < 860+150 && 750<mouseY && mouseY<750+80){
      //判定圖片範圍,xy座標(1000,600),1000+200就是判定範圍有多寬,750+100就是判定範圍有多高
      pressed_go=true;//如果按壓開始遊戲鍵成立
      stage=3;//切換到場景3,開始遊戲
      pressed_go=false;//關閉按下go鍵
    }
  }
  if(stage==3){//當被切換到舞台3
    len0 = dist(ballX,ballY,mouseX,mouseY);//計算白色母球和鼠標(X,Y)座標的距離向量
  }
}
void mouseReleased(){//放開滑鼠時
  if(stage==3){//當切換到舞台3時
    len1 = dist(ballX,ballY,mouseX,mouseY);//計算白色母球和鼠標(X,Y)座標的距離向量
    float v = len1-len0;//計算兩者向量相減後的力矩
    ballVX = -v * cos(angle);//COS角度
    ballVY = -v * sin(angle);//SIN角度
    shooting=true;//打開布林變數,球可以被射出
  }
}


程式分頁(stage3)
float [] holeX={50,600,1148,50,600,1151};//48,600,1150,65,600,1150
float [] holeY={52,46,57,692,703,695};//50,50,60,690,700,700
float ballX=180,ballY=200,ballVX=0,ballVY=0,angle=0;//設定球一開始出現的xy位置,以及角度初始化
float score=0;//將成績初始化歸0
float len0=0,len1=0;//距離向量歸0
boolean shooting=false;//射擊的布林變數預設關閉
int startTime;//遊戲開始時間
int Time;//計時
void draw2(){
  //場景地圖
  image(table_img,0,0,1200,750);//可以調整圖片大小,table圖片的x,y座標(0,0),(1200,750)是圖片寬高
  fill(#2B793A);//綠色的長方形
  rect(47,47,1110,660);//測試畫長方(47,47是x,y座標/1110,660是長寬
  
  fill(#A76565);//棕色的長方形
  rect(0,750,1200,300);//測試畫長方(47,47是x,y座標/1110,660是長寬
  
  //計時器
  int m = (150-((millis()/1000)-(startTime/1000)))/60%60;//計時器,毫秒是千分之一秒,150秒約2:30,因為要倒數就要%60,設定分鐘
  int s = (150-((millis()/1000)-(startTime/1000)))%60;//計時器,毫秒是千分之一秒,150秒約2:30,因為要倒數就要%60,設定秒鐘
  String mm = nf(m, 2);//00,ex:01分鐘
  String ss = nf(s, 2);//00,ex:01秒鐘
  String time = "剩下"+":"+mm+":"+ss;//顯示剩餘的時間
  if(millis()-startTime>=150000){//如果時間超過或剛好等於兩分半,切換到場景4
    stage=4;
  }else if(millis()-startTime<=150000){//如果時間還沒超過兩分半,就還在倒數
    fill(#FFFFFF);//剩餘時間的白色字體顏色
    textSize(40);//字體大小
    text(time,20,830);//時間,X座標20,Y座標830
  }
  
  //母球相關
  fill(#FFFFFF);//白色的球
  ellipse(ballX,ballY,30,30);//畫個20*20圓形
  angle = atan2(mouseY-ballY,mouseX-ballX);//算出角度的tan2(),這裡是公式
  
  if(shooting==false){//如果布林變數為關閉
    strokeWeight(10);//粗度為10的直線
    stroke(#FFFF00);//直線顏色是黃色
    line(ballX,ballY,ballX+cos(angle)*100,ballY+sin(angle)*100);//x,y座標固定,
    
    strokeWeight(5);//粗度為5的直線
    stroke(#0000FF);//直線顏色是藍色
    line(ballX,ballY,ballX+cos(angle)*len0,ballY+sin(angle)*len0);//x,y座標固定,
    
    strokeWeight(3);//粗度為3的直線
    stroke(#00FF00);//直線顏色是綠色
    line(ballX,ballY,ballX+cos(angle)*len0,ballY+sin(angle)*len0);//x,y座標固定,
    
    strokeWeight(1);//粗度為1的直線
    stroke(0);//直線顏色是黑色
    line(ballX,ballY,mouseX,mouseY);//x,y座標固定,mouse會隨著滑鼠移動而改變線的長度
  }
  if(ballX+ballVX>1200-5 || ballX+ballVX<10){//ballX+vx>1200控制右邊x邊界,ballX+vx<10控制左邊x邊界
    ballVX=-ballVX;//會反彈
  }
  if(ballY+ballVY>720-5 || ballY+ballVY<25){//ballY+vy>720控制下面y邊界,ballY+vy<10控制上面y邊界
    ballVY=-ballVY;//會反彈
  }
  for(int i=0;i<6;i++){//繪製六個球袋
    fill(#000000);//黑色的球袋
    ellipse(holeX[i],holeY[i],50,50);//最後面兩個數字是桌面六個圓形洞大小
    if(shooting && dist(ballX,ballY,holeX[i],holeY[i])<30){//計算白色母球和球袋的XY座標距離是否小於30
     score++;//如果母球射入球袋就會扣分
     reset();//隨機復活
     println(score);//顯示成績
    }
    ballX += ballVX/10;
    ballY += ballVY/10;
    ballVX*=0.99;//替球增加摩擦力
    ballVY*=0.99;//替球增加摩擦力
  }
}
void reset(){//隨機生成在場地上
  ballX=random(1100);//隨機X座標
  ballY=random(750);//隨機Y座標
  shooting=false;//關閉布林函數,預設非射擊狀態
  ballVX=0;//X方向的速度歸0
  ballVY=0;//Y方向的速度歸0
}







成績的顯示也是依樣畫葫蘆
加在draw2()的函式內
  //成績顯示
  fill(#FFFFFF);//白色字體顏色
  textSize(40);//字體大小
  text(score,300,830);//成績




以及設置了從頭到尾都會出現的障礙物(紅球),還有不同時間會持續存在並干擾玩家的其他色球
首先都要先宣告變數
float ballX2=200,ballY2=300,ballVX2=0,ballVY2=0;//設定球一開始出現的XY位置
float ballX3=300,ballY3=400,ballVX3=0,ballVY3=0;//設定球一開始出現的XY位置
float ballX4=400,ballY4=500,ballVX4=0,ballVY4=0;//設定球一開始出現的XY位置
float ballX5=400,ballY5=500,ballVX5=0,ballVY5=0;//設定球一開始出現的XY位置
float ballX6=200,ballY6=300,ballVX6=0,ballVY6=0;//設定球一開始出現的XY位置

然後在draw2()函式中寫出對應條件
  //一直在場上的紅球
  fill(#FF6A6A);//粉色的球
  ellipse(random(1100),random(750),20,20);//畫個20*20圓形
  //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
  if(shooting && dist(ballX,ballY,ballX2,ballY2)<15){//計算白色母球和橘球的XY座標距離是否小於15
     score--;//如果母球射入球袋就會扣分
     reset();//隨機復活
     println(score);//顯示成績
  }
  

    //不同時間會跑出來干擾的色球
   if(m==2 && s>0 && s<15){//在2:00~2:15秒時,會有橘色球來搗亂
    fill(#FFCB1C);//橘色的球
    ellipse(random(500),random(600),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX6,ballY6)<20){//計算白色母球和橘球的XY座標距離是否小於20
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
   }
  
  if(m==1 && s>0 && s<59){//在1:00~1:59秒時,會有藍色球來搗亂
    fill(#93B9EA);//藍色的球
    ellipse(random(900),random(600),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX3,ballY3)<15){//計算白色母球和藍球的XY座標距離是否小於15
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
   }
   
    if(m==1 && s>0 && s<30){//在1:00~1:30秒時,會有綠色球來搗亂
    fill(#3BB281);//綠色的球
    ellipse(random(900),random(600),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX5,ballY5)<20){//計算白色母球和綠球的XY座標距離是否小於20
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
   }
   
   if(m==0 && s>0 && s<59){//在0:00~0:59秒時,會有藍色球來搗亂
    fill(#93B9EA);//藍色的球
    ellipse(random(800),random(300),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX3,ballY3)<20){//計算白色母球和藍球的XY座標距離是否小於20
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
  }
 
    if(m==0 && s>0 && s<59){//在0:00~0:59秒時,會有黃色球來搗亂
    fill(#FFFCA7);//黃色的球
    ellipse(random(1000),random(800),20,20);//畫個20*20圓形
    //frameRate(3);//每秒刷新多少幀數,一秒鐘刷新10幀
    if(shooting && dist(ballX,ballY,ballX4,ballY4)<30){//計算白色母球和黃球的XY座標距離是否小於30
       score--;//如果碰到就會扣分
       reset();//隨機復活
       println(score);//顯示成績
    }
  }




為哥互動技術week16

 

#2022互動技術


加入button 






加入遊戲說明





為哥互動技術week15

 

#2022互動技術


加入食譜

加入食譜背景圖





為哥互動技術week14

 

#2022互動技術



先使用函式庫下載sound相關的




加入聲音


load 音樂並設定為loop循環播放








week15_新手上碌

  1.優化球的軌跡

1-1.斜率判斷方向:

        /*

        p2.x>p1.x&&p2.y<p1.y//向右上/

         p2.x<p1.x&&p2.y>p1.y//向左下

         slop<=0


         p2.x>p1.x&&p2.y>p1.y//向右下\

         p2.x<p1.x&&p2.y<p1.y//向左上

        slop>=0

         */

1-2.第一版:

void collision(){

    for (int i=0; i< curves.size(); i++) {

      Curve p = curves.get(i);

      for (int j =0; j< p.pts.size()-5; j++) {

        PVector p1 = p.pts.get(j);

        bombing(bomb_1.x, bomb_1.y, x, y);

        PVector p4= p.pts.get(j+5);    //取第5個點

        PVector p2 = p.pts.get(j+1);    //取下一個點

        float d_p1_p2=dist(p1.x, p1.y, p2.x, p2.y);

        float slop=(p2.x-p1.x)*(p2.y-p1.y);    //現在的點與下一個點

        float slop2=(p4.x-p1.x)*(p4.y-p1.y);

        if ((x>=p1.x-19.9&&x<=p1.x+19.9)&&(y>=p1.y-20.5&&y<=p1.y-19.5)) {

          vx=0;

          vy=0;

          println("+++++", slop, "+++", d_p1_p2, "++++", slop2, "H =", H, "U =", U);

          if (slop>=0&&slop2>0) {

            vx=1;

            vy=0.8;

            H=H-vy/10;        //位能

          }

          if (slop<=0&&slop2<0) {

            vx=-1;

            vy=0.5;

            H=H-vy/10;

          }

          if (slop==0&&slop2==0) {

            moving =false;

          }

        }

      }

    }

  }

1-3.第二版:

                    

>>>不會從線中滑落了,但常常會卡住

當斜率很小趨近於0時,要怎麼判斷方向?

2.炸彈

因為炸彈不只一顆>>用class寫

2-1.物件宣告:

Bomb bomb_1;                //宣告

bomb_1=new Bomb();    //new方法創建實體

2-2.定義class:

class Bomb {

  int x, y;

  void draw(int x, int y) {    //一開始就做的事

    fill(#761007);

    ellipse(x, y, 30, 30);

  }

}

void bombing(int x,int y,float ballx, float bally) {

    if (ballx<=(x+15)&&bally<=(y+15)&&ballx>(x-15)&&bally>(y-15)) {//碰撞

      println("Game Over!!!!!");

      ball.vx=0;

      ball.vy=0;

      moving=false;

    }

  }

2-3.使用: