[請益] 整個遊戲設計結構

看板GameDesign作者 (522)時間11年前 (2012/12/26 12:18), 編輯推噓11(11033)
留言44則, 11人參與, 最新討論串1/3 (看更多)
各位高手好,最近我設計的遊戲已經完成一小部分了 其中包含角色移動、攻擊、跳躍等基本功能, 敵人也可以移動、攻擊被打到也會扣血 可是我設計的結構可能太差了,因為如果怪物一次出現10隻 我遊戲就會開始頓頓的,我本來以為這很正常,因為數量太多 不過我想想不對,我之前玩過別人設計的直向飛行遊戲, 敵人加上自身的子彈近百顆,那些子彈每次都要計算 『下一步要移動到哪裡、有沒有撞到東西、是否超出遊戲視窗外』 可是她的遊戲卻不會LAG,所以一定是我的設計結構有問題 想請教一下我設計的方式有沒有問題 我遊戲的主迴圈大概如下 while(quit!=ture){ if( SDL_PollEvent( &event ) ) //判斷使用者是否有操作鍵盤 role.handle_input(); //去判斷使用者有沒有按到移動、攻擊、防禦、跳 //的按鍵 role.move(); //計算角色移動的距離,如果上面的if不成立等於不會移動 //也會判斷主角是否有踩空地板導致開始下降 role.show(); //將角色相應的圖片貼上,移動貼移動,攻擊貼攻擊 bat.action(); //敵人的移動、攻擊、是否被打、貼圖全部都在這函式一次完成 SDL_Flip( screen ) //更新視窗 } 其實這樣還好,但如果敵人有10隻,那bat.action()會修改成如下 for(int i=0 ; i<have_enemy_count ; ++i ) bat[i].action(); 主要就是改成這樣之後當敵人數量一多,就開始頓頓的了 因為這迴圈跑的時間有稍微延遲到,造成畫面更新的速度下降 我遊戲現在完全沒有使用任何多執行緒, 我本來想說敵人的部份改成讓執行緒去跑,可是這樣有一個大問題 我畫面更新時有時候敵人的圖片還沒貼上就更新畫面了, 有時候一隻怪物反而會貼兩次才更新畫面 是否有辦法說執行緒完成怪物的判斷且貼一次圖之後,先暫停 等到畫面更新了才繼續跑一次判斷? 當然主程式的畫面更新也要先等所有的怪物都貼好圖了才更新畫面, 如果還沒貼好圖就暫停等怪物貼好 想請教一下我整個遊戲架構該怎麼設計才會更好? 謝謝 我本來想說要貼上move()、show()、action()等函式的內容 可是實在是太多太雜了@@ 當然也有可能是我那些函式的內容設計的不夠好才會造成延遲 @@ 不好意思麻煩各位高手給點意見,謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.134.49.54 ※ 編輯: yoll522 來自: 220.134.49.54 (12/26 12:22)

12/26 12:28, , 1F
語言?
12/26 12:28, 1F

12/26 12:35, , 2F
不好意思忘記說了,我是用sdl寫的
12/26 12:35, 2F

12/26 12:39, , 3F
關於碰撞是怎麼刻的呢?
12/26 12:39, 3F
我碰撞是用矩陣的方式,主角有一個隱藏的矩陣會跟著主角移動 怪物也有怪物的矩陣,當主角攻擊時會出現攻擊的矩陣 如果怪物的矩陣碰到了攻擊的矩陣那就算攻擊到了

12/26 12:40, , 4F
一般問題應該比較容易出在碰撞判斷上、場景太大之類的
12/26 12:40, 4F
對吼@@ 我想到我的遊戲視窗是1024*768,我現在有弄一個測試的背景是3000*900 我就直接把這3000*900整張貼上去, 然後再用一個攝影機的變數去判斷角色應該要在3000*900這張背景上的哪個位置出現 有可能是因為這張圖太大張的關係嗎? 請問圖片的大小張在貼的時候會影響效能嗎?

12/26 12:41, , 5F
如果是碰撞問題的話..... 可以切場景來判斷說
12/26 12:41, 5F

12/26 12:41, , 6F
先把物件分區,分區完後再計算碰撞
12/26 12:41, 6F
請問什麼是物件分區?

12/26 12:50, , 7F
"所有的子彈都要判斷有沒有撞到東西"?
12/26 12:50, 7F

12/26 12:51, , 8F
除了主角還會撞到什麼東西嗎,只要計算主角那區附近的子彈
12/26 12:51, 8F

12/26 12:52, , 9F
就好了吧,如果有特殊的再一個一個加進去,然後兩個物件在
12/26 12:52, 9F

12/26 12:52, , 10F
一個區域也只需計算一次
12/26 12:52, 10F
因為我看有些遊戲敵方的某些子彈再跟玩家的子彈相撞後會消失, 所以我以為敵方的每顆子彈隨時都在判斷有沒有撞到任何東西@@

12/26 12:56, , 11F
你在遊戲中有設定延遲嗎?
12/26 12:56, 11F

12/26 12:57, , 12F
應該說你怎麼控制遊戲的FPS?
12/26 12:57, 12F
其實我現在沒有設置FPS,因為我當初在學LAZY FOO到16課時 網址:http://ppt.cc/tKgh 裡面有提到用FPS的方式去移動那個圓點 可是當我學到第32課的時候:http://ppt.cc/DJzD 裡面用的卻不是用FPS去控制,而是用delta timer去判斷 而且這種移動方法讓畫面更順,所以我就把cap the frame rate的方法全部刪掉了

12/26 13:29, , 13F
10隻就lag感覺是繪圖方面的問題
12/26 13:29, 13F

12/26 13:31, , 14F
參考看看 i3+內顯 8000子彈@60FPS
12/26 13:31, 14F
請問這是PTT的文章嗎? 我剛剛GOOGLE了一下查不到關鍵字@@

12/26 13:31, , 15F
線性移動+對一個角色做圓形碰撞判定
12/26 13:31, 15F
請問意思是用圓形的矩陣來做判斷嗎? 可是我是用rect來做長方形的矩陣,這些會有影響到嗎?

12/26 13:32, , 16F
建議你做做看profiling
12/26 13:32, 16F

12/26 13:34, , 17F
VerySleepy或是CodeAnalyst都是免費的
12/26 13:34, 17F

12/26 13:34, , 18F
他可以幫你看每個function花了多少時間
12/26 13:34, 18F
好的謝謝你,我會去查看看我哪個函式跑太久了

12/26 16:06, , 19F
我覺得問題出在bat.action()
12/26 16:06, 19F

12/26 16:07, , 20F
你把move show action都做個計時器看看跑一次需時多少
12/26 16:07, 20F

12/26 16:07, , 21F
這樣比較清楚
12/26 16:07, 21F

12/26 16:08, , 22F
你畫面更新率若是60 那麼全部的計算需要在16毫秒內完成
12/26 16:08, 22F
了解,我晚點來查查看是什麼函式卡太久,可是我遊戲並沒有設定畫面更新率 原因跟我上面提到的一樣,會不會是我對這部分的觀念出錯了@@

12/26 16:47, , 23F
Google broadphase
12/26 16:47, 23F
謝謝你,我等等來看一下查到的資料 ※ 編輯: yoll522 來自: 220.134.49.54 (12/26 17:22)

12/26 16:57, , 24F
10隻broadphase應該沒什麼幫助就是了
12/26 16:57, 24F
※ 編輯: yoll522 來自: 220.134.49.54 (12/26 17:24) ※ 編輯: yoll522 來自: 220.134.49.54 (12/26 17:25)

12/26 18:01, , 25F
我說的參考看看是我以前遊戲的效能
12/26 18:01, 25F

12/26 18:02, , 26F
圓形碰撞判定是直接判斷兩者之間的距離
12/26 18:02, 26F

12/26 18:02, , 27F
方形判定沒有寫錯理論上會快一點
12/26 18:02, 27F

12/26 18:03, , 28F
可是碰撞判定就算一個像素一個像素檢查
12/26 18:03, 28F

12/26 18:03, , 29F
應該也不會到10隻就不行
12/26 18:03, 29F

12/26 18:04, , 30F
所以你目前應該先做profile
12/26 18:04, 30F
我剛剛用內建的方法測試了一次,我的方法如下 Timer test; test.start(); //裡面會取得目前時間的變數startTicks = SDL_GetTicks(); role.show(); test.get_ticks();//這裡會取得扣掉時間後的費時 SDL_GetTicks()-startTicks; 可是測出來的結果有點出乎我意料, 當只有一隻怪物的時候的執行時間:http://ppt.cc/WsRY 當有10隻怪物的時候:http://ppt.cc/L6Il bat_action();執行出來居然只有5毫秒@@ 可是不知道為什麼我人物在移動的時候就真的會有點卡卡的 沒有像一隻怪物的時候那麼順 好奇怪@@ ※ 編輯: yoll522 來自: 220.134.49.54 (12/26 18:30)

12/26 19:04, , 31F
12/26 19:04, 31F

12/26 19:05, , 32F
另外你的delta time是怎麼設定的?
12/26 19:05, 32F
不好意思我網址沒複製好,我已經修正了 delta time其實也沒有設定什麼, int xVel=400; Timer delta; delta.start() while(1){ .... .... role.move(delta.get_ticks()); delta.start(); .... .... } move(Uint32 deltaTicks){ x += xVel * ( deltaTicks / 1000.f ); } 這種公式可以讓角色每次移動的距離都跟上一次移動的時間差而改變 可能這一次是 x += 400 * ( 50 / 1000.f ); 然後下一次突然系統很頓,所以造成遊戲也LAG了一下 因此變成x += 400 * ( 300 / 1000.f ); 我全部就只有玩家、敵人的移動會用到這公式,其他都沒有再用了@@

12/26 19:25, , 33F
12/26 19:25, 33F
我原本也以為要用double-buffer,可是SDL的畫面更新好像比較不一樣 再貼圖上去的時候畫面並不會顯示,她好像會先貼到某張看不到的畫布 接著我用SDL_Flip( screen )更新視窗時才會一次更新畫面 所以我再猜SDL應該不會用到double-buffer ※ 編輯: yoll522 來自: 220.134.49.54 (12/26 20:46) ※ 編輯: yoll522 來自: 220.134.49.54 (12/26 20:46)

12/26 21:05, , 34F
有試過紀錄整個迴圈跑一次的時間嗎 還有噸的感覺
12/26 21:05, 34F

12/26 21:05, , 35F
是FPS太低的那種頓 還是輸入會延遲的噸?
12/26 21:05, 35F
噸的感覺是像fps太低的那種,就是畫面感覺會小小的跳一格跳一格的顯示 然後我剛剛測試了整個迴圈跑完的時間,卻奇怪的數字滿大的 而且我發現更奇怪的是當我站在怪物的右邊數字會在2x,而這時候才會開始噸 當我再怪物的左邊數字會是18左右,這時候就不會噸 站在怪物左邊:http://ppt.cc/FOJC 站在怪物右邊:http://ppt.cc/aY61 哇哩勒這是什麼奇怪的現象@@ ※ 編輯: yoll522 來自: 220.134.49.54 (12/26 21:56)

12/26 23:16, , 36F
時間檢查多一點 看看是哪邊的問題 另外就算平均為25ms
12/26 23:16, 36F

12/26 23:16, , 37F
那你每秒也還有40FPS 應該不至於太頓才對
12/26 23:16, 37F

12/26 23:17, , 38F
但每秒LOOP只跑40次 反而你的輸入可能會稍微有點延遲感?
12/26 23:17, 38F
的確是不會太頓,只是前面順順的,中間卻突然頓頓的感覺有點奇怪 然後我輸入延遲是沒什麼感覺@@ 我剛剛照你說的到處檢查,結果出來了,超無言的 原來我寫的函式幾乎都不會噸, 真的就是我背景那張delay到了,我背景3000*900 大概就是因為一次貼太大張了才造成這種問題 難怪我之前看一本書,在教寫類似楓之谷的遊戲,在貼地圖的時候 他遊戲視窗假設800*600,地圖假設8000*600這麼長 他卻把它截圖拆成(800*600)*10張,我還想說他幹嘛沒是要拆成這麼多張 直接一張貼上去不就好了@@ 大概就是因為太大張的圖會造成lag吧 學到了一課@@ 真的很謝謝各位的幫忙 感恩 不過我就算把地圖改成跟視窗同樣大小的1024*768 貼背景還是花了13、14左右 再一次感謝各位 ※ 編輯: yoll522 來自: 220.134.49.54 (12/27 00:29)

12/27 00:40, , 39F
可是還有一個無解的就是不曉得為什麼我站在怪物右邊會
12/27 00:40, 39F

12/27 00:40, , 40F
比左邊頓,我可能還得查查
12/27 00:40, 40F
我查到原因了,不是什麼左邊右邊的關係,而是敵方角色圖片的問題 我怪物的圖檔原本就是面向右邊的,然後我利用程式翻轉 這樣我就有了向左、右邊的圖, 可是當我貼原本的向右的圖案時會delay大概5、6左右 我貼用程式翻轉的向左的圖案反而不會delay到@@ 我一開始讀檔的時候就沒有釋放過,所以應該不會是因為重複讀圖檔的關係 請問有人知道為什麼嗎?謝謝 ※ 編輯: yoll522 來自: 220.134.49.54 (12/27 00:53)

12/27 01:09, , 41F
你的向左向右的圖片是否屬於顯示用的?
12/27 01:09, 41F

12/27 01:09, , 42F
不屬於顯示用的圖片在貼圖時由於要多一次轉換所以會變慢
12/27 01:09, 42F
感謝你,我剛剛測試了一下,我發現是因為去背的關係@@ SDL_SetColorKey( Image, SDL_SRCCOLORKEY, SDL_MapRGB(Image->format, 0, 255, 0 ) ); 我如果用了去背的功能,每次貼圖的時後都會LAG 可是如果把去背拿掉,那貼圖的時候非常順暢@@ 連背景圖也是很順 不過我角色不管怎樣都要去背才行 可是請問為什麼去背在每次貼圖的時候都會造成LAG? 謝謝你們 ※ 編輯: yoll522 來自: 220.134.49.54 (12/27 07:35)

12/27 07:38, , 43F
不然我就是在複製一次圖片吧,把原本右邊的圖去背後
12/27 07:38, 43F

12/27 07:39, , 44F
再複製到另外一個變數,然後把原本去背的給釋放
12/27 07:39, 44F
我找到了一個函式,關鍵就是 SDL_SetColorKey( optimizedImage,SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB( optimizedImage->format, 0, 255, 0x00 ) ); 在第二個引數多加一個SDL_RLEACCEL就可以告之SDL我要重複使用 這樣就沒問題了~ ※ 編輯: yoll522 來自: 220.134.49.54 (12/27 09:39)
文章代碼(AID): #1GsdgUn5 (GameDesign)
文章代碼(AID): #1GsdgUn5 (GameDesign)