2023年11月23日 星期四

Jia的互動技術日誌 Week11

📋📋📋

有個老師在網路上詢問點名系統問題,

今天希望可以解決這個老師的疑問

首先畫出學生座位格子

💾 程式碼存檔區
void setup(){
  size(600,500);
}
void draw(){
  background(255);
  for(int i=0;i<4;i++){
    for (int j=0;j<6;j++){
      rect(j*100,i*100,100,100);
    }
  }
}

上色並嘗試印出文字
💾 程式碼存檔區
void setup(){
  size(600,500);
}
void draw(){
  background(255);
  for(int i=0;i<4;i++){
    for (int j=0;j<6;j++){
      fill(#F5B4B4); rect(j*100,i*100,100,100);
      fill(0); text("Hello",j*100+25,i*100+50);
    }
  }
}

💾 程式碼存檔區
void setup(){
  size(600,500);
  for(int i=0;i<4;i++){
    for (int j=0;j<6;j++){
      value[i][j] = int(random(40));
    }
  }
}

int [][] value = new int[4][6];

void draw(){
  background(255);
  for(int i=0;i<4;i++){
    for (int j=0;j<6;j++){
      fill(#F5B4B4); rect(j*100,i*100,100,100);
      fill(0); text(value[i][j],j*100+25,i*100+50);
    }
  }
}
用亂數決定每個座位上的數字
因為random(40)出來的值會是浮點數 會出錯
所以我們強制轉換成整數 int(random(40))

但...亂數決定有可能遇到重複的數字


所以用左手i 右手j 來交換 運用temp
💾 程式碼存檔區
void setup(){
  size(600,500);
  for(int i=0;i<4;i++){
    for (int j=0;j<6;j++){
      value[i][j] = i*6+j +10; //從10開始,數字不重複
    }
  }
  int i=int(random(4)), j=int(random(6));
  int i2=int(random(4)), j2=int(random(6));
  int temp = value[i][j];
  value [i][j] = value[i2][j2];
  value[i2][j2] = temp;
}

int [][] value = new int[4][6];

void draw(){
  background(255);
  for(int i=0;i<4;i++){ //y
    for (int j=0;j<6;j++){  //x
      fill(#F5B4B4); rect(j*100,i*100,100,100);
      fill(0); text(value[i][j],j*100+25,i*100+50);
    }
  }
}
可以看到 10和21做了交換

只交換一次不夠明顯,兩次試試看
💾 程式碼存檔區
void setup(){
  size(600,500);
  for(int i=0;i<4;i++){
    for (int j=0;j<6;j++){
      value[i][j] = i*6+j +10; //從10開始,數字不重複
    }
  }
  for(int k=0;k<2;k++){
    int i=int(random(4)), j=int(random(6));
    int i2=int(random(4)), j2=int(random(6));
    int temp = value[i][j];
    value [i][j] = value[i2][j2];
    value[i2][j2] = temp;
  }
}

int [][] value = new int[4][6];

void draw(){
  background(255);
  for(int i=0;i<4;i++){ //y
    for (int j=0;j<6;j++){  //x
      fill(#F5B4B4); rect(j*100,i*100,100,100);
      fill(0); text(value[i][j],j*100+25,i*100+50);
    }
  }
}
兩次 看到 23 25 和 31 33做了交換

可以將數字設大 交換很多次 就能正確打亂數字啦
💾 程式碼存檔區
void setup(){
  size(600,500);
  for(int i=0;i<4;i++){
    for (int j=0;j<6;j++){
      value[i][j] = i*6+j +10; //從10開始,數字不重複
    }
  }
  for(int k=0;k<200;k++){
    int i=int(random(4)), j=int(random(6));
    int i2=int(random(4)), j2=int(random(6));
    int temp = value[i][j];
    value [i][j] = value[i2][j2];
    value[i2][j2] = temp;
  }
}

int [][] value = new int[4][6];

void draw(){
  background(255);
  for(int i=0;i<4;i++){ //y
    for (int j=0;j<6;j++){  //x
      fill(#F5B4B4); rect(j*100,i*100,100,100);
      fill(0); text(value[i][j],j*100+25,i*100+50);
    }
  }
}

🎆🎇🎑
今天想解決的第二個問題
有同學詢問,如何切換場景或關卡呢?
💾 程式碼存檔區
int state = 0; // 0: white, 1: red, 2: blue
void setup(){
  size(400,400);
}
void draw(){
  if(state==0){ //第0關,白色
    background(255);
  }else if(state==1){ //第1關,紅色
    background(255,0,0);
  }else if(state==2){ //第2關,藍色
    background(0,0,255);
  }
}
現在執行時只有白色,後面會加上切換條件
💾 程式碼存檔區
int state = 0; // 0: white, 1: red, 2: blue
void setup(){
  size(400,400);
  textSize(50);
}
void draw(){
  if(state==0){ //第0關,白色
    background(255);
    fill(0);text("Click to Start",80,200);
  }else if(state==1){ //第1關,紅色
    background(255,0,0);
  }else if(state==2){ //第2關,藍色
    background(0,0,255);
  }
}
void mousePressed(){
  if(state==0)state=1;
}
如果滑鼠按下 從第0關 to 第1關
白色背景變紅色
剛才透過點擊,切換第0關到第1關
現在要用鍵盤移動,當方塊重合時,切換到第2關藍色背景
💾 程式碼存檔區
int state = 0; // 0: white, 1: red, 2: blue
void setup(){
  size(400,400);
  textSize(50);
}
int x = 50, y = 50;
void draw(){
  if(state==0){ //第0關,白色
    background(255);
    fill(0);text("Click to Start",80,200);
  }else if(state==1){ //第1關,紅色
    background(255,0,0);
    fill(255);rect(300,50,50,50);
    fill(128);rect(x,y,50,50);
  }else if(state==2){ //第2關,藍色
    background(0,0,255);
    
  }
}
void mousePressed(){
  if(state==0)state=1;
}
void keyPressed(){
  if(state==1 && keyCode==RIGHT){
    x += 10;
    if(x==300)state=2;
  }
}
💾 程式碼存檔區
int state = 0; // 0: white, 1: red, 2: blue
void setup(){
  size(400,400);
  textSize(50);
}
int x = 50, y = 50, t = 100;
void draw(){
  if(state==0){ //第0關,白色
    background(255);
    fill(0);text("Click to Start",80,200);
    x = 50;
  }else if(state==1){ //第1關,紅色
    background(255,0,0);
    fill(255);rect(300,50,50,50);
    fill(128);rect(x,y,50,50);
    t = 100;
  }else if(state==2){ //第2關,藍色 (倒數10秒)
    background(0,0,255);
    fill(255,255,0); text("Wait "+t,80,200);
    t--;
    if(t==0)state = 0;
  }
}
void mousePressed(){
  if(state==0)state=1;
}
void keyPressed(){
  if(state==1 && keyCode==RIGHT){
    x += 10;
    if(x==300)state=2;
  }
}
t設100 不斷--等於0時切第0關
程式碼不斷循環 0關 -> 1關 -> 2關 -> 0關 -> 1關 ......
為什麼要加上 x=50,t=100呢? 
因為達到切換關卡的條件時 數值已經改變了
需要重置數值關卡才能繼續運行

🏀🏀🏀
💾 程式碼存檔區
PImage imgRack;
void setup(){
  size(300,330);
  imgRack = loadImage("rack.jpg");
}
void draw(){
  background(255);
  image(imgRack,0,0);
  if(mousePressed){
    fill(255);ellipse(posX,posY,20,20);
    line(posX,posY,mouseX,mouseY,20,20);
  }
  fill(#FFA652);ellipse(mouseX,mouseY,20,20);
}
float posX = -100, posY = -100;
void mousePressed(){
  posX = mouseX;
  posY = mouseY;
}
先找一張籃球機的圖片,posX posY 起始投球位置
想要做出投球的拋物線
💾 程式碼存檔區
PImage imgRack;
void setup(){
  size(300,330);
  imgRack = loadImage("rack.jpg");
}
void draw(){
  background(255);
  image(imgRack,0,0);
  if(flying){
    x += vx;
    y += vy;
    vy += 0.98;
    }else{
      x = mouseX;
      y = mouseY;
      if(mousePressed){
        fill(255);ellipse(posX,posY,20,20);
        line(posX,posY,x,y);
      }
    }
    fill(#FFA652);ellipse(x,y,20,20);
}
boolean flying = false;
float x, y, vx, vy;
float posX = -100, posY = -100;
void mousePressed(){
  x = posX = mouseX;
  y = posY = mouseY;
  flying = false;
}
void mouseReleased(){
 vx = posX - mouseX;  vy = posY - mouseY;  flying = true; }
用 boolean 來控制 如果flying 開始以重力飛行
else flying = false 拉滑鼠的 x y值
拉完滑鼠放開 flying 變 true
所以籃球就會飛啦

怎麼gameOver
💾 程式碼存檔區
PImage imgRack;
void setup(){
  size(300,330);
  imgRack = loadImage("rack.jpg");
}
boolean gameOver = false;
void keyPressed(){
  gameOver = true; //在某個狀態下 game over 要暫停
}
void draw(){
  background(255);
  image(imgRack,0,0);
  if(flying){
    if(! gameOver){
      x += vx;
      y += vy;
      vy += 0.98;
    }
  }else{
    x = mouseX;
    y = mouseY;
    if(mousePressed){
      fill(255);ellipse(posX,posY,20,20);
      line(posX,posY,x,y);
    }
  }
  fill(#FFA652);ellipse(x,y,20,20);
}
boolean flying = false;
float x, y, vx, vy;
float posX = -100, posY = -100;
void mousePressed(){
  x = posX = mouseX;
  y = posY = mouseY;
  flying = false;
}
void mouseReleased(){
 vx = posX - mouseX;
 vy = posY - mouseY;
 flying = true;
}
滑鼠按下任意鍵 遊戲會停下來
💣💣💣
踩地雷
💾 程式碼存檔區
int [][]mine = new int[9][9];
void setup(){
  size(450, 450);
  for (int i=0; i<9; i++) mine[i][0]=9;
  for (int k=0; k<1000; k++){
    int i = int(random(9)), j = int(random(9));
    int i2 = int(random(9)), j2 = int(random(9));
    int tmp = mine[i][j];
    mine[i][j] = mine[i2][j2];
    mine[i2][j2] = tmp;
  }
  for (int i=0; i<9; i++){
    for (int j=0; j<9; j++){ // 遇到紅色的地雷附近要+1
      if (mine[i][j]==9){
        addNumber(i-1, j-1);
        addNumber(i-1, j);
        addNumber(i-1, j+1);
        addNumber(i, j-1);
        addNumber(i, j); // 自己本身
        addNumber(i, j+1);
        addNumber(i+1, j-1);
        addNumber(i+1, j);
        addNumber(i+1, j+1);
      }
    }
  }
}
void addNumber(int i, int j){
  if (i<0 || j<0 || i>=9 || j>=9) return; // 超過範圍不做事
  if (mine[i][j]!=9) mine[i][j]++; // 不是地雷就可以+1
}
void draw(){
  for (int i=0; i<9; i++){
    for (int j=0; j<9; j++){
      if (mine[i][j]==9) fill(255, 128, 128);
      else fill(255);
      rect(j*50, i*50, 45, 45);
      
      if (mine[i][j]!=0){
        fill(0); text(" "+mine[i][j], j*50+23, i*50+23, 45, 45);
      }
    }
  }
}
隨機產生地雷









沒有留言:

張貼留言