2024年1月4日 星期四

學校滑鼠有夠爛 - Week17 - 互動技術🦆

Week17

影片連結:點這裡

使用鍵盤 W、A、S、D 控制警察補捉小偷。成功捕捉一名小偷或誤捕一名民眾後,小偷及民眾會隨機重新生成在不同座標位置,在時間內捕捉越多小偷,分數越高。

(1)在遊戲開始前增加三張圖片,表示倒數三秒遊戲即開始。

(2)玩家實際遊玩後會發現,警察誤捕民眾的錯誤訊息不明顯,故新增"警察觸碰到民眾時顯示一秒紅色畫面"

(3)覺得遊戲還是太單調,想讓小偷及民眾會自由四處移動

(4)另外,在結束顯示分數框增加一些小裝飾。



int x = 500, y = 500;  // 警察初始座標
float thief_x = 150, thief_y = 300;  // 小偷初始座標
float thief_speedX = 3.0;  // 小偷的水平速度
float thief_speedY = 1.5;  // 小偷的垂直速度

float people_x = 500, people_y = 300;  // 民眾初始座標
float people_speedX = -2.0;  // 民眾的水平速度
float people_speedY = 2.0;   // 民眾的垂直速度

int a = 0;  // 初始分數
int b;  //剩餘遊戲時間
int c = 900; // 900豪秒=15s
PImage road, thief, police, people;
PImage background1, background2, background3;


int frameCounter = 0;
int currentBackground = 0;  // 0表示第一張背景,1表示第二張,2表示第三張
int flashDuration = 30;  // 紅色畫面持續的幀數
int flashTimer = 0;      // 控制紅色畫面持續時間的計時器
boolean flashActive = false;  // 標誌,表示紅色畫面是否啟用

void setup() {
  size(800, 800);
  background1 = loadImage("1.jpg");
  background2 = loadImage("2.jpg");
  background3 = loadImage("3.jpg");
  road = loadImage("road.jpg");
  thief = loadImage("thief.png");
  police = loadImage("police.png");
  people = loadImage("people.png");
}

void draw() {
  frameRate(35);
  background(road);//設置畫布背景色

  if (flashActive) {
    // 顯示紅色畫面
    fill(255, 0, 0, 150);  // 使用半透明的紅色
    noStroke();
    rect(0, 0, width, height);
    flashTimer--;

    // 檢查紅色畫面是否持續時間結束
    if (flashTimer <= 0) {
      flashActive = false;
      flashTimer = flashDuration;
    }
  }
  if (frameCounter < 35 * 3) {  // 切換圖片的總幀數,這裡假設每張圖片顯示1秒
    if (frameCounter < 35) {
      image(background3, 0, 0, width, height);
    } else if (frameCounter < 35 * 2) {
      image(background2, 0, 0, width, height);
    } else {
      image(background1, 0, 0, width, height);
    }
    frameCounter++;
  } else {
    // 開始遊戲的邏輯
    move();
    image(police, x, y);
    moveThief();
    image(thief, thief_x, thief_y);
    movePeople();
    image(people, people_x, people_y);
    over();
    font();

    if (sqrt((thief_x - x) * (thief_x - x) + (thief_y - y) * (thief_y - y)) < 25) {
      thief();
      people();
      a += 20;
    }
    if (sqrt((people_x - x) * (people_x - x) + (people_y - y) * (people_y - y)) < 25) {
      thief();
      people();
      a -= 50;
      flashActive = true;
    }
  }
}

void move() {
  if (keyPressed) {
    if (key == 'a' && x != 0) {
      x -= 10;
    }
    if (key == 'd' && x != 600) {
      x += 10;
    }
    if (key == 'w' && y != 0) {
      y -= 10;
    }
    if (key == 's' && y != 600) {
      y += 10;
    }
  }
}

void moveThief() {
  thief_x += thief_speedX;
  thief_y += thief_speedY;

  // 檢查小偷是否超出畫面範圍,如果是,則反向移動
  if (thief_x < 0 || thief_x > width - thief.width) {
    thief_speedX *= -1;
  }

  if (thief_y < 0 || thief_y > height - thief.height) {
    thief_speedY *= -1;
  }
}
void movePeople() {
  people_x += people_speedX;
  people_y += people_speedY;

  // 檢查民眾是否超出畫面範圍,如果是,則反向移動
  if (people_x < 0 || people_x > width - people.width) {
    people_speedX *= -1;
  }

  if (people_y < 0 || people_y > height - people.height) {
    people_speedY *= -1;
  }
}


void thief() {
  // 隨機刷新小偷位置
  thief_x = random(50, 600);
  thief_y = random(50, 350);
}

void people() {
  // 隨機刷新民眾位置
  people_x = random(150, 600);
  people_y = random(50, 400);
}

void font() {
  fill(0);
  textSize(24);
  text("Score: " + a, 50, 50);
  text("Time: " + b + "s", 600, 50);
}


void over() {
  c -= 1;
  b = c / 60;
  if (c == 0) {
    // 使用淡綠色填充圓角矩形
    fill(144, 238, 144);
    noStroke();
    int rectX = 200, rectY = 400, rectWidth = 450, rectHeight = 100;  // 矩形左上角X,Y座標;矩形寬度、高度
    int cornerRadius = 10;  // 圓角的半徑

    // 繪製圓角矩形
    rect(rectX, rectY, rectWidth, rectHeight, cornerRadius);

    // 在矩形中心顯示分數相關的文字
    fill(0);
    String s = "Your score is: ";
    textSize(20);
    textAlign(CENTER, CENTER);
    text(s, rectX + rectWidth / 2, rectY + rectHeight / 2 - 10);
    textSize(30);
    text(a, rectX + rectWidth / 2, rectY + rectHeight / 2 + 20);

    // 繪製一些裝飾
    fill(255, 255, 0);  // 黃色
    drawStars(rectX + 30, rectY + 30, 3, 10);
    drawStars(rectX + rectWidth - 30, rectY + 30, 3, 10);

    // 停止 draw() 的執行,即停止遊戲的更新和繪製
    noLoop();
  }
}

void drawStars(float x, float y, int num, float size) {
  // 繪製星星的函數
  for (int i = 0; i < num; i++) {
    float angle = TWO_PI / num * i;
    float starX = x + cos(angle) * size;
    float starY = y + sin(angle) * size;
    ellipse(starX, starY, 5, 5);  // 假設星星是小圓點
  }
}




沒有留言:

張貼留言