2024年1月4日 星期四

部落格week17

 

  • 新增函式庫,讓遊戲有背景聲音跟音效,使遊戲更豐富

  • 新增了能量條機制,當成功得分時可以讓能量條上漲一格,能量集滿時可發動能力,讓對手的分數下降100分,如果能量條沒滿,就無法發動能力

  • Youtube影片連結:
https://www.youtube.com/watch?v=29OjO5_AuWI


  • 最後的程式介紹:
  打殭屍遊戲,我們使用綠色和紫色殭屍,綠色代表正常行動(不會亂動)的殭屍,紫色則代表會隨機行動的殭         屍,且只有1/5的機率會生成紫色,紫色殭屍跑到最下面時會隨機變動X座標。

  在開頭畫面點擊開始後即可進入遊戲畫面,我們將遊戲時間的倒數計時設為30秒,當殭屍移動到最下面時,玩         家即可點擊鍵盤按鍵來遊玩遊戲,如果按錯按鍵導致沒打到殭屍就會額外再扣1秒,左右雙方不受對方影響,           其中一方結束時,另一方若時間尚未結束,則沒結束的那一方還可以繼續遊玩,直到雙方結束才會跳到結尾畫         面。

  分數計算方面,綠色殭屍為10分、紫色殭屍為20分。底下有一個能量條,成功得分時會上漲一格,總共有20              格,能量滿了之後可發動技能使對手的分數下降100。 


  • 最終程式碼
import processing.sound.*;
SoundFile file, da;
class Player {
  ArrayList<Ball> balls;
  String name;
  int windowShift = 0; // right: 600
  float[] xPositions = {100, 300, 500}; // Left player's X-axis intersection points
  float[] yPositions = {50, 150, 250, 350, 450, 550, 650, 750}; // Y-axis positions
  float timer = 30.0;
  int removedBallsCount = 0; // Records the number of removed red and purple balls on the left
  int score = 0;
  boolean GameIsOver = false; // Whether the left player's game is over
  float energy = 0; // Energy variable for the energy bar
  float maxEnergy = 20; // Maximum energy capacity
   boolean canUseEnergy = false; // 是否可以使用能量
   void useEnergy() {
    if (energy >= maxEnergy) {
      // 如果能量條滿了,執行相應的操作
      // 這裡可以根據需要添加你的代碼
      energy = 0; // 清空能量條
      canUseEnergy = false; // 重置使用能量的條件
    }
  }
  Player(String _name, int _windowShift) {
    name = _name;
    windowShift = _windowShift;
    resetGame();
  }
  void resetGame() {
    balls = new ArrayList<Ball>();
    float y = yPositions[0];
    boolean isRed = true;
    boolean isPurple = random(5) < 1;
    float x = xPositions[(int) random(columnCount)];
    Ball ball = new Ball(x + windowShift, y, isRed, isPurple);
    balls.add(ball);
    for (int i = 1; i < yPositions.length; i++) {
      x = xPositions[(int) random(columnCount)];
      y = yPositions[i];
      isRed = true;
      isPurple = false;
      ball = new Ball(x + windowShift, y, isRed, isPurple);
      balls.add(ball);
    }
  }
  void drawBalls() {
    for (Ball ball : balls) {
      if (ball.isRed) {
        image(img1, ball.x - ballSize / 2, ball.y - ballSize / 2, ballSize, ballSize);
      } else if (ball.isPurple) {
        image(img2, ball.x - ballSize / 2, ball.y - ballSize / 2, ballSize, ballSize);
      }
    }
    generateBall();
  }
  void generateBall() {
    // Automatic ball generation mechanism, left player
    if (removedBallsCount > 0) {
      float newX = xPositions[(int) random(xPositions.length)] + windowShift;
      float newY = yPositions[0];
      boolean isPurple = random(5) < 1;
      balls.add(new Ball(newX, newY, !isPurple, isPurple));
      removedBallsCount--;
      for (Ball ball : balls) {
        if (ball.y == 750 && ball.isPurple) {
          ball.x = xPositions[(int) random(xPositions.length)] + windowShift;
        }
      }
    }
  }
  void drawEnergyBar() {
    // Draw energy bar
    fill(0, 255, 0); // Green color for energy bar
    rect(windowShift + 0, height - 20, energy * 30, 20); // Adjust the position and size as needed
  }
  void testGameOver() {
    // Check if the game time is over
    if (timer > 0 && !GameIsOver) {
      timer -= 1.0 / frameRate; // Decrease by one second per frame
    } else if (!GameIsOver) {
      // Game over handling
      fill(255, 0, 0);
      textSize(40);
      GameIsOver = true;
    }
  }
}
Player leftPlayer, rightPlayer;
int rowCount = 8; // Number of rows
int columnCount = 3; // Number of columns
int ballSize = 90; // Ball size
PImage img1, img2, img3, img4, img5, img6;
boolean gameStarted = false;
void setup() {
  size(1200, 800); // Adjust canvas size
  img1 = loadImage("zombie1.png");
  img2 = loadImage("zombie2.png");
  img3 = loadImage("halloween.jpg");
  img4 = loadImage("tt.png");
  img5 = loadImage("H.jpg");
  img6 = loadImage("BG.jpg");
  file = new SoundFile(this, "a.mp3");
  file.play();
  da = new SoundFile(this, "da.mp3");
  leftPlayer = new Player("Left", 0);
  rightPlayer = new Player("Right", 600);
  noLoop(); // Initial stop updating the screen
}
void drawStartScreen() {
  background(0);
  image(img5, 0, 0, 1200, 750);
  textSize(35);
  fill(0);
  textAlign(CENTER, CENTER);
  text("Click to Start", width / 2, height / 2);
}
int startT = -1;
void mouseClicked() {
  gameStarted = true;
  startT = millis();
  loop(); // Start screen updating
}
void draw() {
  if (!gameStarted) {
    drawStartScreen();
    return;
  }
  if (leftPlayer.GameIsOver && rightPlayer.GameIsOver) {
    showEndScreen();
    return;
  }
  background(255);
  image(img3, 0, 0);
  image(img4, 600, 0, 600, 900);
  leftPlayer.drawBalls();
  rightPlayer.drawBalls();
  leftPlayer.drawEnergyBar();
  rightPlayer.drawEnergyBar();
  stroke(0);
  for (float x = 200; x <= 1000; x += 200) {
    line(x, 0, x, height);
  }
  fill(255);
  textSize(20);
  text("Left Time: " + ceil(leftPlayer.timer), 70, 40);
  text("Left Score: " + leftPlayer.score, 70, 60);
  text("Right Time: " + ceil(rightPlayer.timer), 1110, 40);
  text("Right Score: " + rightPlayer.score, 1107, 60);
  leftPlayer.testGameOver();
  rightPlayer.testGameOver();
}
void showEndScreen() {
  background(255);
  image(img6, 0, 0, 1200, 800);
  textSize(50);
  fill(0);
  textAlign(CENTER, CENTER);
  if (leftPlayer.GameIsOver && rightPlayer.GameIsOver) {
    text("Game Over", width / 2, height / 2 - 50);
    text("Left Score: " + leftPlayer.score, width / 2, height / 2);
    text("Right Score: " + rightPlayer.score, width / 2, height / 2 + 50);
  }
  noLoop();
}
class Ball {
  float x;
  float y;
  boolean isRed;
  boolean isPurple;
  Ball(float x, float y, boolean isRed, boolean isPurple) {
    this.x = x;
    this.y = y;
    this.isRed = isRed;
    this.isPurple = isPurple;
  }
}
void keyPressed() {
  if (!rightPlayer.GameIsOver) {
    if (key == 'j' || key == 'J') {
      da.play();
      removeBall(700, rightPlayer.balls);
    } else if (key == 'k' || key == 'K') {
      da.play();
      removeBall(900, rightPlayer.balls);
    } else if (key == 'l' || key == 'L') {
      da.play();
      removeBall(1100, rightPlayer.balls);
    }
  }
  if (!leftPlayer.GameIsOver) {
    if (key == 'a' || key == 'A') {
      da.play();
      removeBall(100, leftPlayer.balls);
    } else if (key == 's' || key == 'S') {
      da.play();
      removeBall(300, leftPlayer.balls);
    } else if (key == 'd' || key == 'D') {
      da.play();
      removeBall(500, leftPlayer.balls);
    } else if (key == 'x' || key == 'X') {
      if (leftPlayer.energy >= leftPlayer.maxEnergy) {
        leftPlayer.energy = 0; // 清空能量條
        leftPlayer.canUseEnergy = false; // 重置使用能量的條件
         rightPlayer.score -= 100;
      }
    }
  }
  if (!rightPlayer.GameIsOver) {
    if (key == 'm' || key == 'M') {
      if (rightPlayer.energy >= rightPlayer.maxEnergy) {
        rightPlayer.energy = 0; // 清空能量條
        rightPlayer.canUseEnergy = false; // 重置使用能量的條件
        leftPlayer.score -= 100;
      }
    }
  }
}
void removeBall(float targetX, ArrayList<Ball> currentBalls) {
  boolean isRemoveValid = false;
  for (int i = currentBalls.size() - 1; i >= 0; i--) {
    Ball ball = currentBalls.get(i);
    if (ball.x == targetX && ball.y == 750) {
      boolean isRed = ball.isRed;
      boolean isPurple = ball.isPurple;
      currentBalls.remove(i);
      for (Ball otherBall : currentBalls) {
        if (otherBall.y < 750) {
          otherBall.y += 100;
        }
      }
      if (isRed) {
        if (currentBalls == leftPlayer.balls) {
          leftPlayer.removedBallsCount++;
          leftPlayer.score += 10;
          leftPlayer.energy = min(leftPlayer.energy + 1, leftPlayer.maxEnergy);
        } else if (currentBalls == rightPlayer.balls) {
          rightPlayer.removedBallsCount++;
          rightPlayer.score += 10;
          rightPlayer.energy = min(rightPlayer.energy + 1, rightPlayer.maxEnergy);
        }
      } else if (isPurple) {
        if (currentBalls == leftPlayer.balls) {
          leftPlayer.removedBallsCount++;
          leftPlayer.score += 20;
          leftPlayer.energy = min(leftPlayer.energy + 2, leftPlayer.maxEnergy);
        } else if (currentBalls == rightPlayer.balls) {
          rightPlayer.removedBallsCount++;
          rightPlayer.score += 20;
          rightPlayer.energy = min(rightPlayer.energy + 2, rightPlayer.maxEnergy);
        }
      }
      isRemoveValid = true;
      break;
    }
  }
  if (!isRemoveValid) {
    if (currentBalls == leftPlayer.balls) {
      leftPlayer.timer -= 1;
      leftPlayer.energy = max(leftPlayer.energy - 1, 0);
    } else if (currentBalls == rightPlayer.balls) {
      rightPlayer.timer -= 1;
      rightPlayer.energy = max(rightPlayer.energy - 1, 0);
    }
  }
}

沒有留言:

張貼留言