期中作業:方塊射擊
因為臨時改變遊戲玩法有改
所以題目也有變化
上課的 Demo 影片
問題解決後的 Demo 影片
影片的音樂在錄製的時候有點兒奇怪
我們是從這段影片截取一段音樂使用 ( 從 2 分 42 秒開始 )
點我點我
想聽音樂可以來這裡聽哦 :D
程式碼
int i=0,j=0,k=0; int [][]grid=new int [10][20]; // 這是一開始俄羅斯方塊的背景陣列 int mapw=20; int score=0; int nowX=5,nowY=0; int backgrounds=1; PImage startbackground; PImage tetrisbackground; PImage endbackground; PImage pig; int mx=0,my=0,mxb=0,myb=0; int angle=0; int shootx=-25; int shooty=0; boolean ctl=true; int ctl2=0; int gameTime,s; int lastTime; int count; import ddf.minim.*; Minim minim; AudioPlayer player; void setup(){ size(500,400); startbackground = loadImage("sb.jpg"); tetrisbackground = loadImage("200.jpg"); endbackground = loadImage("end.JPG"); pig = loadImage("13771.png"); image(startbackground,0,0); s= millis()/1000; minim = new Minim(this); player = minim.loadFile("abdc.mp3"); player.play(); } void draw(){ if( mousePressed && mouseX&rt;180 && mouseX<300 && mouseY&rt;280 && mouseY<350 && ctl) ctl=false; if(ctl==true){ image(startbackground,0,0); } else if(ctl==false){{ image(tetrisbackground,0,0); int m=grid[i][j]; for(int i=0;i<mapw*20;i+=mapw){ for(int j=0;j<mapw*10;j+=mapw){ fill(70,70,70,10); stroke(175,175,175); rect(j+50,i,mapw,mapw); } } Tt(nowX,nowY,20,20); fill(0,255,255); shooty=340+count--; rec(shootx,shooty); if(shooty == (myb)+19 || shootx+10&rt;(mxb+500) && shootx+10< 46+(mxb+500)){ score+=10; } image(pig,mxb+50,myb); } s= millis()/1000; fill(255,0,0); textSize(30); text(score,440,127); lastTime = millis()- s; gameTime = 30-lastTime/1000; text(gameTime,400,70); if (gameTime<0){ image(endbackground,0,0,500,400); text("Your score is: " +score,120,350); } } } void rec(int x,int y){ rect(x,y,20,20); } void Lt(int c, int d,int r, int e){ int lts[][]={{0,0,0,0}, {1,1,1,0}, {0,0,1,0}, {0,0,0,0}}; for(int a=0;a<4;a++){ for(int b=0;b<4;b++) if(lts[a][b]==1){ fill(255,0,0); rect(a*20,b*20,20,20); } } } void It(int x, int y,int r, int e){ int its[][]={{1,0,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0}}; for(int a=0;a<4;a++){ for(int b=0;b<4;b++) if(its[a][b]==1){ fill(255,119,53); rect(a*20,b*20+80,20,20); // 為了確認方塊有出現先移動 y 軸 +80 } } } void Jt(int x, int y,int r, int e){ int jts[][]={{0,0,0,0}, {0,0,1,0}, {1,1,1,0}, {0,0,0,0}}; for(int a=0;a<4;a++){ for(int b=0;b<4;b++) if(jts[a][b]==1){ fill(255,255,0); rect(a*20,b*20+120,20,20); // 為了確認方塊有出現先移動 y 軸 +120 } } } void Wt(int x, int y,int r, int e){ int wts[][]={{0,0,0,0}, {0,1,1,0}, {0,1,1,0}, {0,0,0,0}}; for(int a=0;a<4;a++){ for(int b=0;b<4;b++) if(wts[a][b]==1){ fill(0,128,64); rect(a*20,b*20+180,20,20); // 為了確認方塊有出現先移動 y 軸 +180 } } } void Tt(int x, int y,int r, int e){ int tts[][]={{0,0,1,0}, {0,1,1,0}, {0,0,1,0}, {0,0,0,0}}; for(int a=0;a<4;a++){ for(int b=0;b<4;b++) if(tts[a][b]==1){ fill(0,0,255); rect(a*20+50+mx,b*20+340,20,20); // 為了確認方塊有出現先移動 y 軸 +240 } } } void Zt(int x, int y,int r, int e){ int zts[][]={{0,1,0,0}, {0,1,1,0}, {0,0,1,0}, {0,0,0,0}}; for(int a=0;a<4;a++){ for(int b=0;b<4;b++) if(zts[a][b]==1){ fill(26,133,221); rect(a*20,b*20+300,20,20); // 為了確認方塊有出現先移動 y 軸 +300 } } } void Nt(int x, int y,int r, int e){ int nts[][]={{0,0,1,0}, {0,1,1,0}, {0,1,0,0}, {0,0,0,0}}; for(int a=0;a<4;a++){ for(int b=0;b<4;b++) if(nts[a][b]==1){ fill(91,0,183); rect(a*20+320,b*20,20,20); // 為了確認方塊有出現先移動 y 軸 +300 } } } void keyPressed(){ if(key==CODED && keyCode==LEFT){ mx-=20; if(mx<0)mx=0; } if(key==CODED && keyCode==RIGHT){ mx+=20; if(mx&rt;140)mx=140; } if(key==CODED && keyCode==DOWN){ my+=20; if(my&rt;340)my=340; } if(key=='a'){ mxb-=1; if(mxb<0)mxb=0; } if(key=='d'){ mxb+=1; if(mxb&rt;160)mxb=160; } if(key==CODED && keyCode==UP){ count-=20; shootx = mx+70; } } void keyReleased(){ if(key==CODED && keyCode==UP){ count=0; } }
這是遊戲開始畫面
這是遊戲進行畫面
這是結束畫面
遊戲玩法:
這個遊戲可以兩個人玩
我方砲台控制分別是
左 :← 右:→ 發射 : ↑
敵方物體控制分別是
左 :A 右:D
當我方子彈射擊到敵方物體,則得 10 分
在 30秒 內看我玩家可得到多少分
敵方玩家就只能閃躲,沒辦法射擊子彈
這是我們原本俄羅斯方塊進行的階段
在一開始的程式碼中
我們已成功寫出了 7 種方塊
以及利用陣列畫出背景方格
但後續要考慮到的狀有點多且複雜
例如:方塊旋轉,位置需對應到正確的背景陣列
或是方塊旋轉時,碰到已堆疊好的方塊,該如何調整位置等等
所以我們後來決定改變遊戲的進行方式
心得感想
在一開始決定作俄羅斯方塊時,壓根的沒想過他會這麼難,要考慮到很多條件聽老師說夢想中的遊戲都可能實現,讓我們更確定了我們的目標,所以在開始期中作品一開始,我們先討論要先解決甚麼事情。
介面的設計是我們最一開始的小目標把俄羅斯遊戲畫面的map網格畫出來,在這介面設計上,原本想說單純利用雙層for迴圈來解決,但是我們考慮到後來方塊必須在map網格上判斷是否存在,所以必須將以設定的map網格每一格初始化一個值,雖然我們遊戲邏輯在ㄧ開始有想出來,但是在程式的編寫方面就遇上了難題,我們有到處去問人及上網找解決的方法,但是後來還是老師的初始化方法比較佳且易懂,所以在這初始化map網格上的問題就暫時解決了。
再來就是方格種類的設定,依照我們的思考後的遊戲邏輯,必須將每一個種類的俄羅斯方塊用二維陣列的方式加他寫出來,並且以布林值去做畫方格設定,在這裡也遇到相同的問題,就是知道目的是要做什麼,但是程式不知該如何撰寫會比較佳對於之後的遊戲流程,所以我們在寫俄羅斯方塊時,都是以當出假設概念一邊實驗一邊修改,在這邊徐修謙同學幫了我們很多的忙,這裡的概念是他建議我們的,之後我們自己去試且成功的利用二維與布林值畫出油四格方型排成的7種類型的俄羅斯方塊。在來就是應用在map中,當初我們試想用亂數呼叫的方式,把7種類型的俄羅斯方塊放入map中,可是在這上面頻頻出現問題,在亂數呼叫時,我們運用了random + swich-cace的概念,這個問題我們還沒有解決,因為亂數值會一直跳,停不下來,所以我們的7種方塊在遊戲畫面中,全部出現並一直閃,我們猜想是亂數值停不了,所以在這上面還有問題沒解決,之後我們問題接二連三的出現,讓我們原本的計畫都被不能執行的程式給打亂了,說真的在這邊我們有點挫折感,這時我們才發現在著手寫程式之前概念必須是正確的才會比較順。
後來聽了小葉老師的建議,在短時間內我們無法debug完寫出完整的俄羅斯方塊,或許可以以俄羅斯方快轉個彎,加一點小巧思去改變玩法,變成是屬於我們的簡易式的俄羅斯方塊,後來我們想了一下子,利用之前已完成的7種方塊去做變化,一開始想到的改良版是小蜜蜂,但後來發現其實我們可以更簡單一點,而且可以加入兩個人玩的樂趣,就利用之前作的map網格作為我們的砲台面,我的方塊變成檯面中的砲台可以方射方格砲彈,並且將對手變成一隻豬,而上方的豬可以依照2P玩家控制閃躲,而1P玩家則是下方的方塊砲台並可以發射砲彈,而在限時內砲彈碰到豬時分數就會加10分,這是我們在短時間內不斷想以及改造後的結果。然而在改造的過程中也遇到了其他麻煩,像是砲彈發射的位置以及單按鍵觸發後子彈的反應、砲彈碰到豬的觸發分數加分、畫面的更新、開始畫面進入到遊戲畫面、時間結束跳到結束畫面...等,以上都是我們在短時間內克服的問題。
最後雖然我們做的期中作品不是如預期的那樣,但是我們知道在做一個遊戲時,必須遇到的問題與狀況,在當初評估時並不會想到這麼多問題,所以我們認為我們都經歷了一個很好的學習經驗,在這次的期中作品中我們獲益良多。
沒有留言:
張貼留言