2023年10月26日 星期四

Jia的互動技術日誌 Week07

👻🎃👻
因為萬聖節要到了

今天老師想教我們 google 2016年的萬聖節小遊戲

💾 程式碼存檔區
void setup(){
  size(400,400);
}
void draw(){
  if(mousePressed){
    line(mouseX,mouseY,pmouseX,pmouseY);
  }
}
小畫家畫線 但不好不能清除
💾 程式碼存檔區
void setup(){
  size(400,400);
  background(255);
}
void draw(){
  if(mousePressed){
    line(mouseX,mouseY,pmouseX,pmouseY);
  }
}
void mouseReleased(){
  background(255);
}
稍微更改一下 當滑鼠放開便會清空畫面

但這不是我們要的效果
💾 程式碼存檔區
void setup(){
  size(400,400);
  background(255);
}
float ghostX=400,ghostY=20;
void draw(){
  ellipse(200,200,15,15);
  if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  ellipse(ghostX,ghostY,15,15);
  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  background(255);
}
我們剛才可以畫線了(雖然非最終效果)
用圓圈代替小鬼 向中間移動
但 鬼走路有殘影耶
希望畫線有殘影 鬼就會有殘影
所以這個程式要修正
所以 資料結構 就來啦
💾 程式碼存檔區
ArrayList<PVector>pt;

void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  ellipse(200,200,15,15);
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  for(int i=0; i<pt.size(); i++){
    PVector p = pt.get(i);
    ellipse(p.x,p.y,3,3);
  }
  ellipse(ghostX,ghostY,15,15);
  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  background(255);
}
用資料結構
厲害的for迴圈
讓我們清背景不讓小鬼下降有殘影的同時
畫的線不會消失
但現在我們用的是點 一直增加 效果不太對要更改
點點不好看 想變成好看的直線
💾 程式碼存檔區
ArrayList<PVector>pt;

void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  ellipse(200,200,15,15);
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  for(int i=0; i<pt.size(); i++){
    PVector p = pt.get(i);
    ellipse(p.x,p.y,3,3);
  }
  ellipse(ghostX,ghostY,15,15);
  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  for(int i=pt.size()-1;i>=0;i--){ //倒過來的for迴圈
    pt.remove(i);
  }
}
為什麼倒過來刪? 如果正的 迴圈從左往右刪 需要一個個搬家,移動很沒有效率
倒過來刪只要刪最後 很快
💾 程式碼存檔區
ArrayList<PVector>pt;

void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  ellipse(200,200,15,15);
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    line(p.x,p.y,p2.x,p2.y);//ellipse(p.x,p.y,3,3);
  }
  ellipse(ghostX,ghostY,15,15);
  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  for(int i=pt.size()-1;i>=0;i--){ //倒過來的for迴圈
    pt.remove(i);
  }
}
從圓圈變成畫線
for(int i=0; i<pt.size()-1; i++){  為什麼要-1呢
    PVector p = pt.get(i),p2 = pt.get(i+1); 這裡+1了 要對消 不然陣列會超出範圍
    line(p.x,p.y,p2.x,p2.y);//ellipse(p.x,p.y,3,3);
  }

畫不一樣的線
💾 程式碼存檔區
ArrayList<PVector>pt;
PImage hi; 
void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
  hi = loadImage("hi.PNG"); 
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  image(hi,125,120,150,150);
  //ellipse(200,200,15,15);
  
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  
  strokeWeight(4);
  float dpx=0,dpy=0; //要看 p.x p2.x 的差距, p.y p2.y的差距
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    dpx += abs(p2.x-p.x); //累積x的移動量
    dpy += abs(p2.y-p.y); //累積y的移動量
  }
  if(dpx>100 && dpy<40) stroke(255,0,0);  //type1 紅色的橫線
  else stroke(0); // 不是就黑色
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    line(p.x,p.y,p2.x,p2.y);//ellipse(p.x,p.y,3,3);
  }
  ellipse(ghostX,ghostY,15,15);
  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  for(int i=pt.size()-1;i>=0;i--){ //倒過來的for迴圈
    pt.remove(i);
  }
}
線段判斷
if(dpx>100 && dpy<40) stroke(255,0,0);
如果 x 位移>100 且 y 位移<40(怕手抖設大一些)
就會判定為畫橫線 呈現紅色
否則黑色 
💾 程式碼存檔區
ArrayList<PVector>pt;
PImage hi; 
void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
  hi = loadImage("hi.PNG"); 
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  image(hi,125,120,150,150);
  //ellipse(200,200,15,15);
  
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  strokeWeight(1);
  stroke(0);
  ellipse(ghostX,ghostY,15,15);
  
  strokeWeight(4);
  float dpx=0,dpy=0; //要看 p.x p2.x 的差距, p.y p2.y的差距
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    dpx += abs(p2.x-p.x); //累積x的移動量
    dpy += abs(p2.y-p.y); //累積y的移動量
  }
  if(dpx>100 && dpy<40) stroke(255,0,0);  //type1 紅色的橫線
  //else stroke(0); // 不是就黑色  
  else if(dpy>100 && dpx<40) stroke(0,0,255);  //type2 藍色的直線
  else stroke(0); // 不是就黑色
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    line(p.x,p.y,p2.x,p2.y);//ellipse(p.x,p.y,3,3);
  }

  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  for(int i=pt.size()-1;i>=0;i--){ //倒過來的for迴圈
    pt.remove(i);
  }
}
橫線 直線 可以判斷了
把圈圈鬼移動到上面 並設置顏色與粗細 才不會受影響
那打勾勾怎麼判斷? V
如果 x 往右 y 往下 就是往右下
💾 程式碼存檔區
ArrayList<PVector>pt;
PImage hi; 
void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
  hi = loadImage("hi.PNG"); 
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  image(hi,125,120,150,150);
  //ellipse(200,200,15,15);
  
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  strokeWeight(1);
  stroke(0);
  ellipse(ghostX,ghostY,15,15);
  
  strokeWeight(4);
  float dpx=0,dpy=0; //要看 p.x p2.x 的差距, p.y p2.y的差距
  int rightdown = 0; //往右下
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    dpx += abs(p2.x-p.x); //累積x的移動量
    dpy += abs(p2.y-p.y); //累積y的移動量
    if( p2.x - p.x > 0 && p2.y - p.y > 0 )rightdown++;
  }
  if(dpx>100 && dpy<40) stroke(255,0,0);  //type1 紅色的橫線
  //else stroke(0); // 不是就黑色  
  else if(dpy>100 && dpx<40) stroke(0,0,255);  //type2 藍色的直線
  else if(rightdown>20) stroke(0,255,0);  //type3 綠的 打勾前半段 往右下
  else stroke(0); // 不是就黑色
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    line(p.x,p.y,p2.x,p2.y);//ellipse(p.x,p.y,3,3);
  }

  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  for(int i=pt.size()-1;i>=0;i--){ //倒過來的for迴圈
    pt.remove(i);
  }
}
往右下 打勾的前半段 綠線
但是這個寫法不夠好
💾 程式碼存檔區
ArrayList<PVector>pt;
PImage hi; 
void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
  hi = loadImage("hi.PNG"); 
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  image(hi,125,120,150,150);
  //ellipse(200,200,15,15);
  
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  strokeWeight(1);
  stroke(0);
  ellipse(ghostX,ghostY,15,15);
  
  strokeWeight(4);
  float dpx=0,dpy=0; //要看 p.x p2.x 的差距, p.y p2.y的差距
  float rightdown = 0; //往右下
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    dpx += abs(p2.x-p.x); //累積x的移動量
    dpy += abs(p2.y-p.y); //累積y的移動量
    if( p2.x - p.x > 0 && p2.y - p.y > 0 )rightdown+=sqrt(dpx*dpx+dpy*dpy);
    ellipse(p.x,p.y,10,10);
  }
  if(dpx>100 && dpy<40) stroke(255,0,0);  //type1 紅色的橫線
  //else stroke(0); // 不是就黑色  
  else if(dpy>100 && dpx<40) stroke(0,0,255);  //type2 藍色的直線
  else if(rightdown>150) stroke(0,255,0);  //type3 綠的 打勾前半段 往右下
  else stroke(0); // 不是就黑色
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    line(p.x,p.y,p2.x,p2.y);//ellipse(p.x,p.y,3,3);
  }

  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  for(int i=pt.size()-1;i>=0;i--){ //倒過來的for迴圈
    pt.remove(i);
  }
}
改用 float 可以精確到小數點
💾 程式碼存檔區
ArrayList<PVector>pt;
PImage hi; 
void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
  hi = loadImage("hi.PNG"); 
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  image(hi,125,120,150,150);
  //ellipse(200,200,15,15);
  
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  strokeWeight(1);
  stroke(0);
  ellipse(ghostX,ghostY,15,15);
  
  strokeWeight(4);
  float dpx=0,dpy=0; //要看 p.x p2.x 的差距, p.y p2.y的差距
  float rightdown = 0,rightup = 0; //往右下 往右上
  boolean green_part1 = false, green_ok = false;
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    dpx += abs(p2.x-p.x); //累積x的移動量
    dpy += abs(p2.y-p.y); //累積y的移動量
    if( p2.x - p.x > 0 && p2.y - p.y > 0 )rightdown+=sqrt(dpx*dpx+dpy*dpy);
    if( p2.x - p.x > 0 && p2.y - p.y < 0 )rightup  +=sqrt(dpx*dpx+dpy*dpy);
    ellipse(p.x,p.y,10,10);
    if(green_part1==false && rightdown>100)green_part1 = true;
    else if(green_part1==true && rightup>100)green_ok  = true;
  }
  if(dpx>100 && dpy<40) stroke(255,0,0);  //type1 紅色的橫線
  //else stroke(0); // 不是就黑色  
  else if(dpy>100 && dpx<40) stroke(0,0,255);  //type2 藍色的直線
  else if(green_ok) stroke(0,255,0);  //type3 綠的 打勾
  else stroke(0); // 不是就黑色
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    line(p.x,p.y,p2.x,p2.y);//ellipse(p.x,p.y,3,3);
  }

  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  for(int i=pt.size()-1;i>=0;i--){ //倒過來的for迴圈
    pt.remove(i);
  }
}
rightdown 剛才判斷了 右下現在判斷右上
if(green_part1==false && rightdown>100)green_part1 = true;
一開始不成立 -> 一開始沒有畫右下
右下成立後 -> green_part1 變成 true
else if(green_part1==true && rightup>100)green_ok  = true;
當 green_part1成立後 有右上 -> green_ok 成立
但..會有小問題喔不只 ν 成立 ∧ 也會被觸發

💾 程式碼存檔區
ArrayList<PVector>pt;
PImage hi; 
void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
  hi = loadImage("hi.PNG"); 
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  image(hi,125,120,150,150);
  //ellipse(200,200,15,15);
  
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  strokeWeight(1);
  stroke(0);
  ellipse(ghostX,ghostY,15,15);
  
  strokeWeight(4);
  float dpx=0,dpy=0; //要看 p.x p2.x 的差距, p.y p2.y的差距
  float rightdown = 0,rightup = 0; //往右下 往右上
  boolean green_part1 = false, green_ok = false;
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    dpx += abs(p2.x-p.x); //累積x的移動量
    dpy += abs(p2.y-p.y); //累積y的移動量
    if( p2.x - p.x > 0 && p2.y - p.y > 0 )rightdown+=sqrt(dpx*dpx+dpy*dpy);
    if( green_part1 && p2.x - p.x > 0 && p2.y - p.y < 0 )rightup+=sqrt(dpx*dpx+dpy*dpy);
    ellipse(p.x,p.y,10,10);
    if(green_part1==false && rightdown>100)green_part1 = true;
    else if(green_part1==true && rightup>100)green_ok  = true;
  }
  if(dpx>100 && dpy<40) stroke(255,0,0);  //type1 紅色的橫線
  //else stroke(0); // 不是就黑色  
  else if(dpy>100 && dpx<40) stroke(0,0,255);  //type2 藍色的直線
  else if(green_ok) stroke(0,255,0);  //type3 綠的 打勾
  else if(green_part1) stroke(0,150,0);  //暗暗的綠 type3 前半段
  else stroke(0); // 不是就黑色
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    line(p.x,p.y,p2.x,p2.y);//ellipse(p.x,p.y,3,3);
  }

  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  for(int i=pt.size()-1;i>=0;i--){ //倒過來的for迴圈
    pt.remove(i);
  }
}
用暗綠色來發現問題

加黃色 ∧ 模仿綠色寫法
💾 程式碼存檔區
ArrayList<PVector>pt;
PImage hi; 
void setup(){
  size(400,400);
  background(255);
  pt= new ArrayList<PVector>();
  hi = loadImage("hi.PNG"); 
}
float ghostX=400,ghostY=20;
void mouseDragged(){ //按下mouse鍵 再拖他
  pt.add(new PVector(mouseX,mouseY));
}
void draw(){
  background(255);
  image(hi,125,120,150,150);
  //ellipse(200,200,15,15);
  
  //if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
  strokeWeight(1);
  stroke(0);
  ellipse(ghostX,ghostY,15,15);
  
  strokeWeight(4);
  float dpx=0,dpy=0; //要看 p.x p2.x 的差距, p.y p2.y的差距
  float rightdown = 0,green_rightup = 0; //往右下 往右上
  float rightup = 0,yellow_rightdown = 0; //往右下 往右上
  boolean green_part1 = false, green_ok = false;
  boolean yellow_part1 = false,yellow_ok = false;
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    dpx += abs(p2.x-p.x); //累積x的移動量
    dpy += abs(p2.y-p.y); //累積y的移動量
    if( p2.x - p.x > 0 && p2.y - p.y > 0 )rightdown+=sqrt(dpx*dpx+dpy*dpy);
    if( green_part1 && p2.x - p.x > 0 && p2.y - p.y < 0 )green_rightup+=sqrt(dpx*dpx+dpy*dpy);
    if( p2.x - p.x > 0 && p2.y - p.y < 0 )rightup+=sqrt(dpx*dpx+dpy*dpy);
    if( yellow_part1 && p2.x - p.x > 0 && p2.y - p.y > 0 )yellow_rightdown+=sqrt(dpx*dpx+dpy*dpy);
    //ellipse(p.x,p.y,10,10);
    if(green_part1==false && rightdown>100)green_part1 = true;
    else if(green_part1==true && green_rightup>100)green_ok  = true;
    if(yellow_part1==false && rightup>100)yellow_part1 = true;
    else if(yellow_part1==true && yellow_rightdown>100)yellow_ok  = true;
  }
  if(dpx>100 && dpy<40) stroke(255,0,0);  //type1 紅色的橫線
  //else stroke(0); // 不是就黑色  
  else if(dpy>100 && dpx<40) stroke(0,0,255);  //type2 藍色的直線
  else if(green_ok) stroke(0,255,0);  //type3 綠的 打勾
  //else if(green_part1) stroke(0,150,0);  //暗暗的綠 type3 前半段
  else if(yellow_ok) stroke(255,255,0);  //type4 黃
  else stroke(0); // 不是就黑色
  for(int i=0; i<pt.size()-1; i++){
    PVector p = pt.get(i),p2 = pt.get(i+1);
    line(p.x,p.y,p2.x,p2.y);//ellipse(p.x,p.y,3,3);
  }

  float dx = 200-ghostX, dy = 200-ghostY,len = sqrt(dx*dx+dy*dy);
  ghostX += dx / len / 3;
  ghostY += dy / len / 3;
}
void mouseReleased(){
  for(int i=pt.size()-1;i>=0;i--){ //倒過來的for迴圈
    pt.remove(i);
  }
}
今天完成了 — | ∧ v 可以用來消鬼

沒有留言:

張貼留言