2015年5月4日 星期一

期中作品

期中作品 打磚塊




利用Leap Motion實作一個小遊戲
手的擺動可以使得下面的狗狗去移動
然後去碰觸到彈力球使其反彈去撞上面的方塊(狗骨頭)
利用FOR迴圈第一關是一排磚塊 到了第二關變成兩排
以此類推...
有背景音樂搭配背景還有把原本沉悶的打磚塊
變成了狗狗要去吃骨頭的感覺

最困難的地方應該就是反彈跟碰撞偵測
這邊想了很久也參考了很多網路上的資料

以下是程式碼
--------------------------------------------------------------------------------------------------------
import de.voidplus.leapmotion.*; //leapmotion
LeapMotion leap; //leapmotion

int sensorValue;

//音樂
import ddf.minim.*;
Minim m;
AudioPlayer player;

float x = 300;
float y = 300;
float dx = 3;
float dy = -5;
int t;
int bloom=3;
int n=0;
int count=0;
int points=0; //得分
PImage bone; //骨頭的圖
PImage dog; //狗的圖
PImage back; //背景圖
PImage heart; //生命值
PImage imgBG;

float heightbounce=450;

//層級
boolean[][] inside=new boolean[1][11];

void setup()
{
  noStroke();
  leap = new LeapMotion(this);
  size(600, 600,P3D); //視窗尺寸
  frameRate(60);
  smooth();

  m = new Minim(this);

  player=m.loadFile("Sleep Away.mp3");
  player.play(); 

  dog=loadImage("dog.jpg"); //讀入狗圖
  bone=loadImage("bone.png"); //讀入骨頭圖
  back=loadImage("back.jpg"); //讀入背景圖
  heart=loadImage("heart.jpg"); //讀入愛心
  imgBG = loadImage("background.jpg");
  imgBG.resize(600,600);
}

void draw()
{

  
  
  if (t==0) //新級別
  {

    background(imgBG); //背景

    stroke(0);

    if (count<120) //前兩秒顯示第幾關
    {
      fill(0); //填入黑色
      textAlign(CENTER);
      text("LEVEL " + inside.length, 300, 400); //顯示第幾關
    }

    strokeWeight(10); //球的大小
    point(x, y); //顯示球球
    strokeWeight(1); //打擊框框大小

    randomSeed(1); //隨機

    //打骨頭
    for (int j=0;j<inside.length;j++)
    {
      for (int k=0;k<inside[0].length;k++)
      {
        //狗及骨頭的距離
        float dx2=50+50*k-x;
        float dy2=50+50*j-y;
        float dis2=sqrt(pow(dx2, 2)+pow(dy2, 2));

        if (dis2>=25. && inside[j][k]==false) //畫骨頭
        {
          image(bone, 25+50*k, 50+50*j, 50, 50); //被打的骨頭
        }

        //關於反彈
        else if (dx2<=(dis2*cos(PI/4))&& dy2<=-(dis2*sin(PI/4)) && inside[j][k]==false)
        {
          dy*=-1;
          inside[j][k]=true;
          points++;
        }
        else if (dx2<=(dis2*cos(PI/4)) && dy2>=(dis2*sin(PI/4)) && inside[j][k]==false)
        {
          dy*=-1;
          inside[j][k]=true;
          points++;
        }
        else if (dy2<=(dis2*sin(PI/4)) && dx2<=-(dis2*cos(PI/4)) && inside[j][k]==false)
        {
          dx*=-1;
          inside[j][k]=true;
          points++;
        }
        else if (dy2<=(dis2*sin(PI/4)) && dx2>=(dis2*cos(PI/4)) && inside[j][k]==false)
        {
          dx*=-1;
          inside[j][k]=true;
          points++;
        }
      }
    }

    float barsize=50;
    strokeWeight(3);

    /*
      sensorValue = serial.read();
      println(sensorValue);
    }*/
    
      for(Hand hand : leap.getHands())
  {

     hand.draw();
     int     hand_id          = hand.getId();
     PVector hand_position    = hand.getPosition();
     println("pos_x"+hand_position.x);
     image(dog, (hand_position.x)-barsize, heightbounce-50, 150, 100);
  
    
    strokeWeight(1);

    // 打到邊界的話
    if (x>=width || x<=0)
    {
      dx*=-1;
    }
    if (y<=0)
    {
      dy*=-1;
    }

    // 設定方位
    if (y>=heightbounce && y<heightbounce+10)
    {
      if (x>((hand_position.x)-barsize) && x< ((hand_position.x)-(1./3)*barsize) && dx>0 && dy>0)
      {
        dy*=-0.95;
        dx*=-1.05;
      }
      else if (x>((hand_position.x)-barsize) && x< ((hand_position.x)-(1./3)*barsize) && dx<0 && dy>0)
      {
        dy*=-0.95;
        dx*=1.05;
      }
      else if (x>((hand_position.x)+(1./3)*barsize) && x< ((hand_position.x)+barsize) && dx>0 && dy>0)
      {
        dy*=-0.95;
        dx*=1.05;
      }
      else if (x>((hand_position.x)+(1./3)*barsize) && x< ((hand_position.x)+barsize) && dx<0 && dy>0)
      {
        dy*=-0.95;
        dx*=-1.05;
      }
      else if (x>((hand_position.x)-(1./3)*barsize) && x< ((hand_position.x)+(1./3)*barsize) && dy>0) {
        dy*=-1.05;
        dx*=0.95;
      }
    }
  }

    //顯示分數
    textAlign(RIGHT);
    fill(0);
    text(points, 300, 350);

    //遊戲結束
    if (y>height)
    {
      if (bloom>1) //生命值
      {
        t=1;
        fill(0);
        textAlign(CENTER);
        text("CLICK TO RESTART GAME", 300, 400);
        text("PRESS SPACE TO RESTART LEVEL", 300, 500);
        bloom--;
      }
      else
      {
        text("GAME OVER", 300, 300);
      }
    }

    //完成關卡
    if (checkinside()) {
      t=2;
      fill(0);
      textAlign(CENTER);
      text("FINISHED", 300, 300);
      text("CLICK FOR NEXT LEVEL", 300, 400);
    }

    x=x+dx;
    y=y+dy;

    count++;
  }

  //遊戲結束
  else if (t==1)
  {
    x = 300;
    y = 300;
    dx = 3;
    dy = -5;
    count=0;
    points=0;
    if (mousePressed==true)
    {
      t=0;
      inside=new boolean[inside.length][inside[0].length];
    }
    if (keyPressed)
    {
      if (key == ' ')
      {
        t=0;
        inside=new boolean[1][11];
      }
    }
  }

  //關卡完成
  else
  {
    x = 300;
    y = 300;
    dx = 3;
    dy = -5;
    count=0;
    if (mousePressed==true)
    {
      t=0;
      inside=new boolean[inside.length+1][inside[0].length];
    }
  }

  //生命值
  if (bloom==3)
  {
    image(heart, 10, 500, 50, 50);
    image(heart, 70, 500, 50, 50);
  }
  else if (bloom==2)
  {
    image(heart, 10, 500, 50, 50);
  }
  else if (bloom==1)
  {
  }
}

boolean checkinside()
{
  for (int j=0;j<inside.length;j++)
  {
    for (int k=0;k<inside[0].length;k++)
    {
      if (inside[j][k] == false)
      {
        return false;
      }
    }
  }
  return true;
}

沒有留言:

張貼留言