期末專題:打殭屍
- 使用sound函式庫加入了音樂,使按按鍵時會有槍聲,以及遊玩時會有背景音樂
- 加入了能量條,將能量條放在下方,成功得分時會上漲一格,失敗會下降,總共有20格
- 能量滿了之後可發動技能(左邊x鍵、右邊m鍵),使對手的分數下降100分
- Youtube影片連結:
(可觀察影片中的0:09~0:10秒雙方的分數,這時我們剛好都有放招 )
- 最後的程式介紹:
打殭屍遊戲,我們使用綠色和紫色殭屍,綠色代表正常行動(不會亂動)的殭屍,紫色則代表會隨機行動的殭屍,且只有1/5的機率會生成紫色,紫色殭屍跑到最下面時會隨機變動X座標。
在開頭畫面點擊開始後即可進入遊戲畫面,我們將遊戲時間的倒數計時設為30秒,當殭屍移動到最下面時,玩家即可點擊鍵盤按鍵來遊玩遊戲,如果按錯按鍵導致沒打到殭屍就會額外再扣1秒,左右雙方不受對方影響,其中一方結束時,另一方若時間尚未結束,則沒結束的那一方還可以繼續遊玩,直到雙方結束才會跳到結尾畫面。
分數計算方面,綠色殭屍為10分、紫色殭屍為20分。底下有一個能量條,成功得分時會上漲一格,總共有20格,能量滿了之後可發動技能使對手的分數下降100。
- 操作方式說明:
左邊玩家按下鍵盤的'A'、'S'、'D'即可打擊畫面左邊最下方的殭屍;右邊玩家按下鍵盤的'J'、'K'、'L'即可打擊畫面右邊最下方的殭屍。左邊玩家按'X'可清空能量條,發動技能造成右邊玩家扣100分;右邊玩家按'M'可清空能量條,發動技能造成右邊玩家扣100分。
- 最後的完整程式碼
import processing.sound.*;SoundFile file, da;class Player {ArrayList<Ball> balls;String name;int windowShift = 0; // right: 600float[] xPositions = {100, 300, 500}; // Left player's X-axis intersection pointsfloat[] yPositions = {50, 150, 250, 350, 450, 550, 650, 750}; // Y-axis positionsfloat timer = 30.0;int removedBallsCount = 0; // Records the number of removed red and purple balls on the leftint score = 0;boolean GameIsOver = false; // Whether the left player's game is overfloat energy = 0; // Energy variable for the energy barfloat maxEnergy = 20; // Maximum energy capacityboolean 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 playerif (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 barfill(0, 255, 0); // Green color for energy barrect(windowShift + 0, height - 20, energy * 30, 20); // Adjust the position and size as needed}void testGameOver() {// Check if the game time is overif (timer > 0 && !GameIsOver) {timer -= 1.0 / frameRate; // Decrease by one second per frame} else if (!GameIsOver) {// Game over handlingfill(255, 0, 0);textSize(40);GameIsOver = true;}}}Player leftPlayer, rightPlayer;int rowCount = 8; // Number of rowsint columnCount = 3; // Number of columnsint ballSize = 90; // Ball sizePImage img1, img2, img3, img4, img5, img6;boolean gameStarted = false;void setup() {size(1200, 800); // Adjust canvas sizeimg1 = 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);}}}
沒有留言:
張貼留言