=========================================================================
SIXTEENTH
加了下落的聲音,並且在暫停畫面多了可以回主頁跟重新開始的按鈕
其他就是努力的修Bug
import processing.sound.*; SoundFile Down; SoundFile BackgroundMusic; PImage Tetris;//要將背景換掉 //字型 PFont TextFont, ChFont; //true false狀態:gameStarted、gameOver、showHelp、showSettings boolean gameStarted = false;//遊戲開始畫面 boolean gameOver = false;//結束 boolean showHelp = false;//說明 boolean isPaused = false;//遊戲中暫停 //boolean gamePlay = false;//遊戲進行中 boolean showSettings = false;//設定 int elapsedTime = 0; int seconds = 0; int score = 0; // 分數 int volume1 = 50;//初始音量值(0 到 100 之間) int volume2 = 50; int startTime; // 遊戲開始時間 int CurrentPos[] = new int[2];//當前的形狀 void setup(){ Tetris = loadImage("Tetris.jpg"); size(600, 750); Down = new SoundFile(this, "Down.mp3"); BackgroundMusic = new SoundFile(this, "BackgroundMusic.mp3"); //BackgroundMusic.loop(); //background(0); Current = new Shapes(); CurrentPos[0] = 4;//左右,方塊的起始位置 CurrentPos[1] = 0;//下降,方塊的起始位置 } int down = 0; void draw() { background(0); if(showSettings){ drawSettings(); } else if(!gameStarted) {//開始畫面 if(showHelp) {//按下就是true,顯示說明畫面 drawHelpScreen(); } else{ drawStartScreen(); } } else if(gameOver) {//結束畫面 if(BackgroundMusic.isPlaying()) { BackgroundMusic.pause(); // 確保遊戲結束時音樂暫停 } drawGameOverScreen(); } else if(isPaused) { // 在暫停狀態下繪製暫停畫面或顯示暫停信息 showHelp = false; drawPausedScreen(); } else {//遊戲進行中 if(!BackgroundMusic.isPlaying()) { BackgroundMusic.play(); // 確保遊戲進行中時音樂播放 BackgroundMusic.amp(volume1 / 100.0); // 確保音量正確設置 } gamePlaying(); } } int StopShapes[][] = new int[10][20]; public void Grid(){ for(int x = 0; x < 10; x++) { for(int y = 0; y < 20; y++) { //停下來的Tetris if(StopShapes[x][y] == 0) fill(100); else if(StopShapes[x][y] == 1) fill(#AE5FE0);//紫 else if(StopShapes[x][y] == 2) fill(#FA980F);//橘 else if(StopShapes[x][y] == 3) fill(#E7F000);//黃 else if(StopShapes[x][y] == 4) fill(#4FC104);//綠 else if(StopShapes[x][y] == 5) fill(#258BF5);//藍 else if(StopShapes[x][y] == 6) fill(#E30000);//紅 else fill(#FA65C6);//粉 rect(x*30+165, y*30+50, 26, 26, 5); } } } void displayCurrent() { //正在下落的Tetris if(Current.getColor() == 0) fill(100); else if (Current.getColor() == 1) fill(#D7A7F7);//淺紫 else if (Current.getColor() == 2) fill(#F5C56A);//淺橘 else if (Current.getColor() == 3) fill(#F7FAB1);//淺黃 else if (Current.getColor() == 4) fill(#95E584);//淺綠 else if (Current.getColor() == 5) fill(#B8CBFA);//淺藍 else if (Current.getColor() == 6) fill(#FAB8B8);//淺紅 else fill(#FFDBF2);//淺粉 for(int i = 0; i < 4; i++) { if((Current.getShapeY(i)+CurrentPos[1]) >= 0) { //目前要下降所以先用getShapeY+CurrentPos[1] 因為CurrentPos[1]是跟著down一起++ rect((Current.getShapeX(i)+CurrentPos[0])*30+165, (Current.getShapeY(i)+CurrentPos[1])*30+50, 26, 26, 5); // getShapeX,CurrentPos[0]一組 getShapeY,CurrentPos[1]一組 //跟著Grid的rect同樣參數 } } } Shapes Current = new Shapes(); class Shapes {//形狀 int [][] shape = new int[4][2]; int tetris = 0; public Shapes() { tetris = int(random(1, 8));//random 選擇狀態來隨機選擇圖形 //先選擇圖形 if(tetris == 1) {//直線 每個都以座標來做 shape[0][0] = 0;//(0,0) shape[0][1] = 0; shape[1][0] = 1;//(1,0) shape[1][1] = 0; shape[2][0] = -1;//(-1,0) shape[2][1] = 0; shape[3][0] = -2;//(-2,0) shape[3][1] = 0; } else if(tetris == 2) {//方塊 shape[0][0] = 0; shape[0][1] = 0; shape[1][0] = 1; shape[1][1] = 0; shape[2][0] = 0; shape[2][1] = 1; shape[3][0] = 1; shape[3][1] = 1; } else if(tetris == 3) {//右L shape[1][0] = 1; shape[2][0] = -1; shape[3][0] = 1; shape[3][1] = -1; } else if(tetris == 4) {//左L shape[1][0] = 1; shape[2][0] = -1; shape[3][0] = -1; shape[3][1] = -1; } else if(tetris == 5) {//左閃電 shape[1][0] = -1; shape[2][1] = -1; shape[3][0] = 1; shape[3][1] = -1; } else if(tetris == 6) {//右閃電 shape[1][0] = 1; shape[2][1] = -1; shape[3][0] = -1; shape[3][1] = -1; } else{//小T shape[1][0] = 1; shape[2][0] = -1; shape[3][1] = -1; } } //後來做旋轉 public void Rotate() { for(int i = 0; i < 4; i++) { if(tetris==2) break;//正方形方塊不做旋轉,會往上跑 int temp = shape[i][0]; shape[i][0] = shape[i][1]; shape[i][1] = -temp; } } public int getShapeX(int i) { return shape[i][0]; } public int getShapeY(int i) { return shape[i][1]; } public int MaxRight() { int i = 0; for(int j = 0; j < 4; j++) { if(shape[j][0] > shape[i][0]) i = j; } return shape[i][0]; } public int MinLeft() { int i = 0; for(int j = 0; j < 4; j++) { if(shape[j][0] < shape[i][0]) i = j; } return shape[i][0]; } public int MaxUp() { int i = 0; for(int j = 0; j < 4; j++) { if(shape[j][1] > shape[i][1]) i = j; } return shape[i][1]; } public int MinDown() { int i = 0; for(int j = 0; j < 4; j++) { if(shape[j][1] < shape[i][1]) i = j; } return shape[i][1]; } public int getColor() { return tetris; } } void gamePlaying(){ Grid(); displayCurrent(); down++; if (down > 20) { down = 0; CurrentPos[1]++; StopEmpty(); } StopEmpty(); showScoreAndTimer(); // 顯示分數計時器 } void showScoreAndTimer() { displayScore(); displayTimer(); // 顯示計時器 fill(255); textAlign(RIGHT, TOP); rect(520, 55, 100, 50, 5); TextFont = createFont("Algerian", 150); textFont(TextFont); fill(0); textSize(15); if (!isPaused) { elapsedTime = millis() - startTime; seconds = int(elapsedTime / 1000); text("Time: " + seconds, width - 60, 50);//右邊顯示計時器 } else { text("Time: " + seconds, width - 60, 50); // 當遊戲暫停時顯示暫停的時間 } } void displayScore() {//分數 fill(255); textAlign(LEFT, TOP); fill(255); rect(80,55,100,50,5); TextFont = createFont("Algerian",100);//字型 textFont(TextFont); fill(0); textSize(15); text("Score: " + score, 40, 50);//左邊顯示分數 } void displayTimer() {//計時器 int elapsedTime = millis() - startTime; int seconds = int(elapsedTime / 1000); fill(255); textAlign(RIGHT, TOP); fill(255); rect(520,55,100,50,5); TextFont = createFont("Algerian",150);//字型 textFont(TextFont); fill(0); textSize(15); text("Time: " + seconds, width-60, 50);//右邊顯示計時器 } void drawStartScreen() {//開始畫面 BackgroundMusic = new SoundFile(this, "BackgroundMusic.mp3"); background(Tetris);//背景黑 TextFont = createFont("Algerian",150);//字型 textFont(TextFont); fill(255); textAlign(CENTER, CENTER); textSize(80); text("Tetris Game", width/2, height/2-200); rectMode(CENTER);//將rect置中 //開始遊戲按鈕 Start fill(150); rect(width/2, height/2, 300, 50, 10); fill(255); textSize(40); text("Start Game", width/2, height/2); // 說明按鈕 Help fill(150); rect(width/2, height/2+100, 300, 50, 10); fill(255); textAlign(CENTER, CENTER); textSize(40); text("Help", width/2, height/2+100); // 設定按鈕 Settings fill(150); rect(width / 2, height / 2 + 200, 300, 50, 10); fill(255); textSize(40); text("Settings", width / 2, height / 2 + 200); } void drawHelpScreen() {//說明畫面 // 標題 TextFont = createFont("Algerian",150); textFont(TextFont); fill(255); textAlign(CENTER, CENTER); textSize(50); text("Tetris Instructions", width/2, height/2-150); //說明細項 ChFont = createFont("微軟正黑體",100); textFont(ChFont); fill(255); textSize(25); textAlign(LEFT,CENTER); String S = "使用下左右鍵可以移動方塊 上鍵可以轉動方塊 空白鍵可以立即將方塊下降"; text(S, width/2+58,height/2-50,400,400); TextFont = createFont("Algerian",100); textFont(TextFont); //主頁按鈕 rectMode(CENTER); textAlign(CENTER, CENTER); fill(150); rect(75, 50, 100, 50, 10); fill(255); textSize(25); text("Main", 75, 50); //Start按鈕 rectMode(CENTER); textAlign(CENTER, CENTER); fill(150); rect(width-75, 50, 100, 50, 10); fill(255); textSize(25); text("Start", width-75, 50); } void drawSettings() { background(0); textAlign(CENTER, CENTER); fill(255); textSize(70); text("Settings", width/2, 150); // 顯示音量調整條 textSize(30); text("Music Volume:", width/2, height/2-100); drawVolumeSlider1(); textSize(30); text("FX Volume:", width/2, height/2+50); drawVolumeSlider2(); // 返回按鈕 fill(150); rect(width/2, height-100, 200, 50, 10); fill(255); textSize(30); text("Back", width/2, height-100); } void drawVolumeSlider1() { // 音量調整條 float sliderPosX = map(volume1, 0, 100, 120, width-120);//將音量值映射到水平位置 float sliderWidth = width-240;//調整條寬度 float sliderHeight = 20;//調整條高度 int numSegments = 10;//段數1-10 float segmentWidth = sliderWidth/numSegments;//每段寬度 for (int i = 0; i < numSegments; i++) { // 設定每個格子的顏色 float segmentValue = map(i, 0, numSegments-1, 0, 100);//每段對應的值 color segmentColor = (segmentValue <= volume1) ? color(0, 255, 0) : color(255); //小於等於音量值為綠色,其他白色 // 繪製每個格子 float x = 120 + i * segmentWidth;//格子的 x 座標 float y = height/2-50;//格子的 y 座標 fill(segmentColor); rect(x, y, segmentWidth, sliderHeight, 5);//畫出方塊條 } //滑動方塊 fill(255); rect(sliderPosX-20, height/2-60, 20, 40, 5); } void drawVolumeSlider2() {//從drawVolumeSlider1複製(兩個slider能各別調整) // 設定音量調整條的基本參數 float sliderPosX = map(volume2, 0, 100, 120, width-120);//將音量值映射到水平位置 float sliderWidth = width-240;//調整條寬度 float sliderHeight = 20;//調整條高度 int numSegments = 10;//段數1-10 float segmentWidth = sliderWidth / numSegments; for (int i = 0; i < numSegments; i++) { //設定每個格子的顏色 float segmentValue = map(i, 0, numSegments-1, 0, 100); color segmentColor = (segmentValue <= volume2) ? color(0, 255, 0) : color(255); //小於等於音量值為綠色,其他白色 //繪製每個格子 float x = 120 + i * segmentWidth;//格子的 x 座標 float y = height/2+100;//格子的 y 座標 fill(segmentColor); rect(x, y, segmentWidth, sliderHeight, 5);//畫出方塊條 } //滑動方塊 fill(255); rect(sliderPosX-20, height/2+90, 20, 40, 5); } void drawPausedScreen() { //繪製暫停畫面 fill(255); textAlign(CENTER, CENTER); textSize(80); text("Paused", width/2, height/2-150); //繼續按鈕 rectMode(CENTER); fill(150); rect(width/2, height/2-50, 200, 50, 10); fill(255); textSize(40); text("Resume", width/2, height/2-50); //返回主頁按鈕 rectMode(CENTER); fill(150); rect(width/2, height/2+50, 200, 50, 10); fill(255); textSize(40); text("Main", width/2, height/2+50); //返回主頁按鈕 rectMode(CENTER); fill(150); rect(width/2, height/2+150, 200, 50, 10); fill(255); textSize(40); text("Restart", width/2, height/2+150); //在這裡停止計時器 if(!isPaused) { // 在這裡暫停計時器 elapsedTime = millis() - startTime; seconds = int(elapsedTime / 1000); } } void drawGameOverScreen() {//結束畫面 fill(255); textAlign(CENTER, CENTER); textSize(70); text("Game Over", width/2, height/2-100); //重新開始按鈕 rectMode(CENTER); fill(150); rect(width/2, height/2, 200, 50, 10); fill(255); textSize(40); text("Restart", width/2, height/2); // 返回主頁按鈕 rectMode(CENTER); fill(150); rect(width/2, height/2+100, 200, 50, 10); fill(255); textSize(40); text("Main", width/2, height/2+100); } void keyPressed() {//控制 上(旋轉)下左右 if (keyCode == DOWN) { CurrentPos[1]++;//下落++ StopEmpty(); } if (keyCode == LEFT) { boolean stop = false; for (int i = 0; i < 4; i++) { if ((Current.getShapeX(i)+CurrentPos[0]) >=1) {//判斷到左邊界 //目前要左橫移所以先用getShapeX+CurrentPos[0] 移動最少就是到1 if ((Current.getShapeX(i)+CurrentPos[0]) <=8 && (Current.getShapeY(i)+CurrentPos[1]) <=18 && (Current.getShapeY(i)+CurrentPos[1]) >=1) { //下降最多到18 最少1 if (StopShapes[Current.getShapeX(i)+CurrentPos[0]-1][Current.getShapeY(i)+CurrentPos[1]] !=0){ // StopShapes[x][y] stop = true; } } } else stop = true; } if (!stop) CurrentPos[0]--;//持續判斷是否stop是true 不是的話就可-- 往左邊移動 } if (keyCode == RIGHT) { boolean stop = false; for (int i = 0; i < 4; i++) { if ((Current.getShapeX(i)+CurrentPos[0]) <= 8) {//判斷到右邊界 //目前要右橫移所以先用getShapeX+CurrentPos[0] 右邊移動最多就是到8 if ((Current.getShapeX(i)+CurrentPos[0]) >= 1 && (Current.getShapeY(i)+CurrentPos[1]) <=18 && (Current.getShapeY(i)+CurrentPos[1]) >=1) { //下降最多到18 最少1 if (StopShapes[Current.getShapeX(i)+CurrentPos[0]][Current.getShapeY(i)+CurrentPos[1]] != 0){ // StopShapes[x][y] stop = true; } } } else stop = true; } if (!stop) CurrentPos[0]++;//持續判斷是否stop是true 不是的話就可++ 往右邊移動 } if (keyCode == UP) {//旋轉 Current.Rotate();//呼叫Shapes裡的Rotate //防止旋轉時會超出邊框 if(Current.MinLeft()+CurrentPos[0] < 0){ CurrentPos[0]=-Current.MinLeft();//目前想法,超出就回到原來的 } if(Current.MaxRight()+CurrentPos[0] > 9){ CurrentPos[0]=-Current.MaxRight()+9;//目前想法,超出就回到原來的然後加回去 } if(Current.MinDown()+CurrentPos[1] < 0){ CurrentPos[1]=-Current.MinDown(); } if(Current.MaxUp()+CurrentPos[1] > 19){ CurrentPos[1]=-Current.MaxUp()+19; } } if (key == ' ') { //這裡的if可以讓在結束畫面時按下空白鍵不會有方塊下落 if(!gameOver){ while (!reachedBottom()) {//持續做直到到底 CurrentPos[1]++; // 持續下落直到到達底部 } StopEmpty(); // 停止後處理 } else { CurrentPos[1] = 0; } } if(key == 'p' || key == 'P') { isPaused = !isPaused; // 切換暫停狀態 if(isPaused) { BackgroundMusic.pause(); // 如果計時器被暫停,記錄暫停時的時間 elapsedTime = millis() - startTime; } else{ BackgroundMusic.loop(); // 確保遊戲未暫停時音樂繼續播放 // 如果暫停被解除,更新開始時間以維持計時器連續性 startTime = millis() - elapsedTime; } } } boolean reachedBottom() { for(int i = 0; i < 4; i++) { if(Current.getShapeY(i) + CurrentPos[1] >= 19) { return true; // 已經到達底部 } if(StopShapes[Current.getShapeX(i) + CurrentPos[0]][Current.getShapeY(i) + CurrentPos[1] + 1] != 0) { return true; // 下方有方塊阻擋 } } return false; } void mousePressed() { if(!gameStarted && mouseX > width/2-175 && mouseX < width/2+175 && mouseY > height/2-25 && mouseY < height/2+25) { gameStarted = true;//按下按鈕,開始遊戲 startTime = millis();//設置遊戲開始時間 } if(!gameStarted && mouseX > width/2-100 && mouseX < width/2+100 && mouseY > height/2+75 && mouseY < height/2+125) { // 操作說明按鈕 showHelp = true;//true,顯示說明畫面 } else if(showHelp && mouseX > 25 && mouseX < 125 && mouseY > 25 && mouseY < 75) { // 點擊回主頁按鈕 showHelp = false;//false,關閉說明畫面 } else if(showHelp && mouseX > width-125 && mouseX < width-25 && mouseY > 25 && mouseY < 75) { // 點擊遊戲開始按鈕 gameStarted = true;//開始遊戲 startTime = millis();//設置遊戲開始時間,不重置會一進Help就計算 showHelp = false;//關閉說明畫面 } if(mouseX > width/2-100 && mouseX < width/2+100 && mouseY > height/2+150 && mouseY < height/2+250) { // 顯示設定畫面 showSettings = true; } else if(showSettings && mouseX > width/2-100 && mouseX < width/2+100 && mouseY > height-150 && mouseY < height-75) { // 返回按鈕 showSettings = false; } // 調整音量 else if(showSettings && mouseY > height/2-60 && mouseY < height/2-40) { volume1 = int(constrain(map(mouseX, 100, width-150, 0, 100), 0, 100)); BackgroundMusic.amp(volume1/100.0); // 更新背景音樂音量 } else if(showSettings && mouseY > height/2+90 && mouseY < height/2+110) { volume2 = int(constrain(map(mouseX, 100, width-150, 0, 100), 0, 100)); Down.amp(volume2/100.0); // 更新背景音樂音量 } if(gameOver && mouseX > width/2-100 && mouseX < width/2+100 && mouseY > height/2-25 && mouseY < height/2+25) { //重新開始遊戲 BackgroundMusic = new SoundFile(this, "BackgroundMusic.mp3"); gameOver = false; startTime = millis();//設置遊戲開始時間 for(int i = 0; i < 10; i++) { for(int j = 0; j < 20; j++) { StopShapes[i][j] = 0; } } } else if(gameOver && mouseX > width/2-100 && mouseX < width/2+100 && mouseY > height/2+75 && mouseY < height/2+125) { //反回主頁 gameStarted = false;//停止遊戲 gameOver = false;//遊戲未結束 showHelp = false;//關閉說明畫面 score = 0;//重置分數 seconds = 0;//重置時間 elapsedTime = 0; for(int i = 0; i < 10; i++) { for(int j = 0; j < 20; j++) { StopShapes[i][j] = 0; } } } if(isPaused && mouseX > width/2-100 && mouseX < width/2+100 && mouseY > height/2-100 && mouseY < height/2-50) { isPaused = false;//繼續遊戲 BackgroundMusic.loop();//確保遊戲未暫停時音樂繼續播放 startTime = millis() - elapsedTime; } else if(isPaused && mouseX > width/2-100 && mouseX < width/2+100 && mouseY > height/2+25 && mouseY < height/2+75) { //回主頁 isPaused = false; // 取消暫停狀態 gameStarted = false; // 回到主頁 gameOver = false; // 遊戲未結束 showHelp = false; // 關閉說明畫面 score = 0; // 重置分數 seconds = 0; // 重置時間 elapsedTime = 0; CurrentPos[1] = 0; for(int i = 0; i < 10; i++) { for(int j = 0; j < 20; j++) { StopShapes[i][j] = 0; } } } else if(isPaused && mouseX > width/2-100 && mouseX < width/2+100 && mouseY > height/2+125 && mouseY < height/2+175) { //重新開始遊戲 BackgroundMusic = new SoundFile(this, "BackgroundMusic.mp3"); isPaused = false; CurrentPos[1] = 0; startTime = millis();//設置遊戲開始時間 for(int i = 0; i < 10; i++) { for(int j = 0; j < 20; j++) { StopShapes[i][j] = 0; } } } } public void StopEmpty() { boolean stop = false; for(int i = 0; i < 4; i++) { if(Current.getShapeY(i)+CurrentPos[1] < 19) { if(StopShapes[Current.getShapeX(i)+CurrentPos[0]][Current.getShapeY(i)+CurrentPos[1]+1] != 0) { //StopShapes[x][y] i=3,ShapeY(i)=-1, 所以至少要+1變回0 stop = true; if(stop==true) Down.play(); } } } if(Current.MaxUp()+CurrentPos[1] == 19 || stop) { //上限+目前 for(int i = 0; i < 4; i++) { if((Current.getShapeY(i)+CurrentPos[1])<0){ gameOver = true; }// else { Down.play(); StopShapes[(Current.getShapeX(i)+CurrentPos[0])][(Current.getShapeY(i)+CurrentPos[1])] = Current.getColor(); } } for(int y = 0; y < 20; y++) { boolean empty = true; for(int x = 0; x < 10; x++) { if(StopShapes[x][y] == 0){ empty = false; } } if(empty){ for(int y2 = y-1; y2 > -1; y2--) { for(int x = 0; x < 10; x++) { StopShapes[x][y2+1] = StopShapes[x][y2]; } } score+=10; } } Current = new Shapes(); CurrentPos[0] = 4; CurrentPos[1] = 0; displayCurrent(); //state=true; } }
沒有留言:
張貼留言