2023年1月6日 星期五

week18(儲存用)

今日進度

色表



老師教的自繪拼圖加移動
```c
PImage imgEmpty,img;
int[]mask1 =new int[1600*1000];
PImage []puzzle;
void setup(){
  size(1600,1000);
  imgEmpty=loadImage("empty.png");
  img = loadImage("1.jpg");
  puzzle = new PImage[4];
   for(int i=0;i<4;i++)
   {
     findPuzzle(i);
     img.mask(mask1);
     puzzle[i]=img.get();
   }
   shift = new PVector[4];
   coord = new PVector[4];
   for(int i=0;i<4;i++){
     int x = -i,y=0;
     shift[i] = new PVector(x*125,y*125);
     coord[i] = new PVector(i*125,y*125);
     println(x,y);
   }
   for(int k=0;k<10;k++){
     int r1=int(random(4));
     int r2=int(random(4));
     PVector temp=coord[r1];
     coord[r1]=coord[r2];
     coord[r2]=temp;
   }
}
void findPuzzle(int k){
  color []cc={#FF0000,#00FF00,#0000FF,#FFFF00};
  imgEmpty.loadPixels();
  for(int i=0;i<500*500;i++){
    color c =imgEmpty.pixels[i];
    if(imgEmpty.pixels[i]==cc[k]){
        mask1[i]=255;
    }else{mask1[i]=0; }
  }
  coord = new PVector[4];
  for(int i=0;i<4;i++){
    int x=(int)random(-4,0), y=(int)random(-4,0);
    coord[i]= new PVector(x*125,y*125);
  }
}
PVector[] shift;
PVector[] coord;
void draw(){
  //background(255);
  for(int i=0;i<8;i++){
    for(int j=0;j<5;j++)
    {
      rect(j*width/8,i*height/5,width/8,height/5);
    }
  }
  /*image(puzzle[0],0,0);
  image(puzzle[1],0,0);
  image(puzzle[2],0,0);
  image(puzzle[3],px,py);*/
  for(int i=0;i<4;i++){
    image(puzzle[i],coord[i].x+shift[i].x,coord[i].y+shift[i].y);
    //將每個卡片分別往右-125
  }
}
float px=0,py=0;
void mouseDragged(){
  float min=99999;
  int selectI=0;
  for(int i=0;i<4;i++){
    float d= dist(coord[i].x+125/2,coord[i].y+125/2,mouseX,mouseY);
    if(d<min){
      min=d;
      selectI=i;
    }
  }
  coord[selectI].x += mouseX-pmouseX;
  coord[selectI].y += mouseY-pmouseY;
}
```

1/7 進度

備份用程式碼

```c
PImage imgEmpty,img;
int[]mask1 =new int[1200*600];
PImage []puzzle;

void setup(){
  size(1600,1000);
  imgEmpty=loadImage("empty.png");
  img = loadImage("1.jpg");
  puzzle = new PImage[40];
   for(int i=0;i<40;i++)
   {
     findPuzzle(i);
     img.mask(mask1);
     puzzle[i]=img.get();
   }
   shift = new PVector[40];
   coord = new PVector[40];
   for(int i=0;i<40;i++){
     int x = -i,y=0;
     shift[i] = new PVector(x*85,y*85);
     coord[i] = new PVector(i*85,y*85);
     println(x,y);
   }
   for(int k=0;k<40;k++){
     int r1=int(random(40));
     int r2=int(random(4));
     PVector temp=coord[r1];
     coord[r1]=coord[r2];
     coord[r2]=temp;
   }
}
void findPuzzle(int k){
  color []cc={#FF0000,#00FF00,#0000FF,#FFFF00,#00FFFF,#FF00FF,#7D0000,#007D00
             ,#00007D,#7D7D00,#7D007D,#007D7D,#7D7D7D,#FF8080,#FFFF80,#80FF80
             ,#00FF80,#80FFFF,#0080FF,#FF8000,#008080,#0080C0,#8080C0,#804040
             ,#FF8040,#004080,#8080FF,#800040,#FF0080,#008040,#0000A0,#400040
             ,#FF9B64,#FF9B9B,#9B9BFF,#B9E1E1,#E1B9E1,#E1E1B9,#FFFFFF,#00E17D};
  imgEmpty.loadPixels();
  for(int i=0;i<1200*600;i++){
    color c =imgEmpty.pixels[i];
    if(imgEmpty.pixels[i]==cc[k]){
        mask1[i]=255;
    }else{mask1[i]=0; }
  }
  coord = new PVector[40];
  for(int i=0;i<40;i++){
    int x=(int)random(-40,0), y=(int)random(-40,0);
    coord[i]= new PVector(x*125,y*125);
  }
}
PVector[] shift;
PVector[] coord;
void draw(){
  //background(255);
  for(int i=0;i<5;i++){
    for(int j=0;j<8;j++){ 
      /*image(puzzle[i][j],coord[i][j].x,coord[i][j].y,80,80);    //此數字代表拼圖框框的大小,寫80的緣故是為了容易分辨    
      noFill();    //保證每個位置都有圖片*/
      rect(j*width/8,i*height/5,width/8,height/5);
    }
  }
  /*image(puzzle[0],0,0);
  image(puzzle[1],0,0);
  image(puzzle[2],0,0);
  image(puzzle[3],px,py);*/
  for(int i=0;i<40;i++){
    image(puzzle[i],coord[i].x+shift[i].x,coord[i].y+shift[i].y);
    //將每個卡片分別往右-125
  }
}
float px=0,py=0;
void mouseDragged(){
  float min=99999;
  int selectI=0;
  for(int i=0;i<4.;i++){
    float d= dist(coord[i].x+85/2,coord[i].y+85/2,mouseX,mouseY);
    if(d<min){
      min=d;
      selectI=i;
    }
  }
  coord[selectI].x += mouseX-pmouseX;
  coord[selectI].y += mouseY-pmouseY;
}
```


無法讀入mask

```c
PImage imgBig,img,imgEmpty;    //印出圖片
PImage [][]imgSmall;    //代表會有幾乘幾的拼圖框架出現
PVector [][]coord;    //拼圖的座標,用來移動拼圖
int[]mask1 =new int[1200*600];
PImage []puzzle;

void setup(){
  size(1200,600);
  imgEmpty=loadImage("empty.png");
  img = loadImage("1.jpg");
  readFile("1.jpg");
   puzzle = new PImage[40];
   for(int i=0;i<40;i++)
   {
     findPuzzle(i);
     img.mask(mask1);
     puzzle[i]=img.get();
   }
   shift = new PVector[40];
   coord1 = new PVector[40];
   for(int i=0;i<40;i++){
     int x = -i,y=0;
     shift[i] = new PVector(x*85,y*85);
     coord1[i] = new PVector(i*85,y*85);
     println(x,y);
   }
}
void findPuzzle(int k){
  color []cc={#FF0000,#00FF00,#0000FF,#FFFF00,#00FFFF,#FF00FF,#7D0000,#007D00
             ,#00007D,#7D7D00,#7D007D,#007D7D,#7D7D7D,#FF8080,#FFFF80,#80FF80
             ,#00FF80,#80FFFF,#0080FF,#FF8000,#008080,#0080C0,#8080C0,#804040
             ,#FF8040,#004080,#8080FF,#800040,#FF0080,#008040,#0000A0,#400040
             ,#FF9B64,#FF9B9B,#9B9BFF,#B9E1E1,#E1B9E1,#E1E1B9,#FFFFFF,#00E17D};
  imgEmpty.loadPixels();
  for(int i=0;i<1200*600;i++){
    color c =imgEmpty.pixels[i];
    if(imgEmpty.pixels[i]==cc[k]){
        mask1[i]=255;
    }else{mask1[i]=0; }
  }
  coord1 = new PVector[40];
  for(int i=0;i<40;i++){
    int x=(int)random(-40,0), y=(int)random(-40,0);
    coord1[i]= new PVector(x*125,y*125);
  }
}
PVector[] shift;
PVector[] coord1;
void readFile(String filename){
  imgBig = loadImage(filename);
  imgSmall = new PImage[6][8];    //因為圖片太大,所以陣列內數字增加
  coord = new PVector[6][8];
  for(int i=0;i<6;i++){
    for(int j=0;j<8;j++){
      imgSmall[i][j] =imgBig.get(150*j,150*i,150,150);    //前者兩個數字圖片視角遠近,數字越大視角越遠,前後數字要一樣
      coord[i][j]=new PVector(85*j,85*i);    //這兩個數字代表拼圖間的間隔,數字越大間距越大,數字越小間距越小
    }
  }
  for(int k=0;k<10;k++){    //此迴圈能隨機改變拼圖位置,而k所寫的數字代表拼圖交換幾次
    int i1=int(random(6)),i2=int(random(6));
    int j1=int(random(8)),j2=int(random(8));
    PVector temp = coord[i1][j1];//new PVector(coord[i1][j1].x,coord[i1][j1].y);
    coord[i1][j1]=coord[i2][j2];
    coord[i2][j2]=temp;
  }  
}
void draw(){
  background(#F1FFB2);    //背景顏色改黑,否則要是背景為白的情況下,移動會出現殘影
  image(imgBig,700,90,480,330);  //前兩個數字是座標,後面則是圖片大小
  fill(#25E539);
  rect(700,430,450,120);  //告示牌
  PFont font = createFont("標楷體",40);  //文字字體,大小
  textFont(font);
  fill(#2C1C76);  
  text("拼圖遊戲",850,60);
  PFont font1 = createFont("宋體",30);  //文字字體,大小
  textFont(font1);
  fill(#2C1C76);  
  text("上一張圖請按1",800,520);
  text("下一張圖請按2",800,480);
  for(int i=0;i<6;i++){
    for(int j=0;j<8;j++){
      image(imgSmall[i][j],coord[i][j].x,coord[i][j].y,80,80);    //此數字代表拼圖框框的大小,寫80的緣故是為了容易分辨    
      noFill();    //保證每個位置都有圖片
      //rect(200*j,200*i,200,200);
    }
  }
}
int selectedI=-1,selectedJ=-1;
void mousePressed(){    //點擊
  int selectI=-1,selectJ=-1;
  for(int i=0;i<6;i++){
    for(int j=0;j<8;j++){
      if(coord[i][j].x<mouseX && mouseX<coord[i][j].x+80 && coord[i][j].y<mouseY && mouseY<coord[i][j].y+80){    //不太理解,只知道x、x+80是指拼圖在該圖片的位置
      selectI =i; selectJ=j;
      }
    }
  }
  if(selectI!=-1){
    selectedI=selectI;
    selectedJ=selectJ;
  }
}
void mouseDragged(){    //拖曳
  if(selectedI!=-1){
    coord[selectedI][selectedJ].add(new PVector(mouseX-pmouseX,mouseY-pmouseY));
  }
}
void mouseReleased(){
  PVector now = coord[selectedI][selectedJ];
  int II=0, JJ=0;
  float min=9999999;
  for(int i=0;i<=6;i++){
    for(int j=0;j<=8;j++){
      float len = dist(now.x, now.y, 85.0*j, 85.0*i);  //數字代表拼圖間的吸附距離
      if(len<min){
        min = len;
        II = i;
        JJ = j;
      }
    }
  }
  now.x = 85.0*JJ;
  now.y = 85.0*II;
  selectedI=-1;
  selectedJ=-1;
}
void keyPressed(){
  if(key=='1') readFile("1.jpg");
  if(key=='2') readFile("2.jpg");
  if(key=='3') readFile("3.jpg");
}
```

1/8進度

今天發現mask random 必須是滿版才能隨機交換,也就是說我們無法像期中一樣放示意圖和告示牌了,這也代表我們前面所計畫的方案全要改動,只好臨時先做好備案,將期中程式碼加上主畫面和背景音樂。



```c
PImage imgBig,imgStart;    //印出圖片
PImage [][]imgSmall;    //代表會有幾乘幾的拼圖框架出現
PVector [][]coord;    //拼圖的座標,用來移動拼圖
import ddf.minim.*;
Minim minim;
AudioPlayer player;

int stage=1;
void setup(){
  size(1200,600);
  readFile("1.jpg");
  imgStart = loadImage("start.png");
  minim = new Minim(this);
  player = minim.loadFile("music.mp3");
  player.play();
}
void readFile(String filename){
  imgBig = loadImage(filename);
  imgSmall = new PImage[6][8];    //因為圖片太大,所以陣列內數字增加
  coord = new PVector[6][8];
  for(int i=0;i<6;i++){
    for(int j=0;j<8;j++){
      imgSmall[i][j] =imgBig.get(150*j,150*i,150,150);    //前者兩個數字圖片視角遠近,數字越大視角越遠,前後數字要一樣
      coord[i][j]=new PVector(85*j,85*i);    //這兩個數字代表拼圖間的間隔,數字越大間距越大,數字越小間距越小
    }
  }
  for(int k=0;k<10;k++){    //此迴圈能隨機改變拼圖位置,而k所寫的數字代表拼圖交換幾次
    int i1=int(random(6)),i2=int(random(6));
    int j1=int(random(8)),j2=int(random(8));
    PVector temp = coord[i1][j1];//new PVector(coord[i1][j1].x,coord[i1][j1].y);
    coord[i1][j1]=coord[i2][j2];
    coord[i2][j2]=temp;
  }  
}
void draw(){
  if(stage==1){
    background(imgStart);
  }
   if(stage==2){
    background(#F1FFB2);    //背景顏色改黑,否則要是背景為白的情況下,移動會出現殘影
    image(imgBig,700,90,480,330);  //前兩個數字是座標,後面則是圖片大小
    fill(#25E539);
    rect(720,430,450,120);  //告示牌
    PFont font = createFont("標楷體",40);  //文字字體,大小
    textFont(font);
    fill(#2C1C76);  
    text("拼圖遊戲",850,60);
    PFont font1 = createFont("宋體",30);  //文字字體,大小
    textFont(font1);
    fill(#2C1C76);  
    text("上一張圖請按1",850,480);
    text("下一張圖請按2",850,520);
    for(int i=0;i<6;i++){
      for(int j=0;j<8;j++){
        image(imgSmall[i][j],coord[i][j].x,coord[i][j].y,80,80);    //此數字代表拼圖框框的大小,寫80的緣故是為了容易分辨    
        noFill();    //保證每個位置都有圖片
        //rect(200*j,200*i,200,200);
      }
    }
   }
}
int selectedI=-1,selectedJ=-1;
void mousePressed(){    //點擊
  if(stage==1)stage=2;
  int selectI=-1,selectJ=-1;
  for(int i=0;i<6;i++){
    for(int j=0;j<8;j++){
      if(coord[i][j].x<mouseX && mouseX<coord[i][j].x+80 && coord[i][j].y<mouseY && mouseY<coord[i][j].y+80){    //不太理解,只知道x、x+80是指拼圖在該圖片的位置
      selectI =i; selectJ=j;
      }
    }
  }
  if(selectI!=-1){
    selectedI=selectI;
    selectedJ=selectJ;
  }
}
void mouseDragged(){    //拖曳
  if(selectedI!=-1){
    coord[selectedI][selectedJ].add(new PVector(mouseX-pmouseX,mouseY-pmouseY));
  }
}
void mouseReleased(){
  PVector now = coord[selectedI][selectedJ];
  int II=0, JJ=0;
  float min=9999999;
  for(int i=0;i<=6;i++){
    for(int j=0;j<=8;j++){
      float len = dist(now.x, now.y, 85.0*j, 85.0*i);  //數字代表拼圖間的吸附距離
      if(len<min){
        min = len;
        II = i;
        JJ = j;
      }
    }
  }
  now.x = 85.0*JJ;
  now.y = 85.0*II;
  selectedI=-1;
  selectedJ=-1;
}
void keyPressed(){
  if(key=='1') readFile("1.jpg");
  if(key=='2') readFile("2.jpg");
  if(key=='3') readFile("3.jpg");
}
```

做到這裡時又發現一個問題,因為我們mouseReleased()函式已經設定好範圍
PVector now = coord[selectedI][selectedJ];
所以要是我們點拼圖以外的區域程式便會值將當掉。

點擊的範圍
點範圍外卡住畫面
簡直是多災多難...

沒有留言:

張貼留言