2017-06-19 36 views
0

我已經創建了一個非常簡單的遊戲,用於模擬在Gamemaker Studio中「滾球迷宮」式遊戲中滾動球的非常簡單的遊戲。它僅由玩家對象和無法穿過的牆壁組成。玩家對象在簡單的物理模擬中移動不正確GMS

玩家對象有一個垂直速度和一個水平速度,當你按下移動鍵時增加/減少,然後它的位置每步移動一次這些速度(直到碰到牆壁)。當沒有按鈕被按下時,我還添加了基本減速。

它主要工作,但我有一個非常具體的錯誤。當非常迅速和+正(唐氏; 小號dWASD而言)移動沿着x或y軸,如果我在相反的方向上提供的輸入(交換到W¯¯當拿着S等),當非常接近牆壁時,玩家對象立即眨眼,直到它可以沿着相反的方向行進。

應該發生什麼事情是物體在開始減速前不可避免地碰撞到它正在注意的那堵牆,這是在相反的情況下做同樣的事情時會發生的事情;即沿着Y軸在負極方向上快速移動,方法是保持W然後切換到S就在撞擊牆壁之前。

我並不確定,但我非常肯定它發生在物體朝向牆壁快速向+正方向行進時,它沒有足夠的時間減速到停止之前通過向相反的方向施加力來擊打牆壁。

這裏是不正確的行爲的short clip

這裏是正確的行爲在其他方向上工作的short clip

這裏是簡單的步驟腳本:

// determine which input keys are being pressed and 
// increment/decrement vspd and hspd respectively 
if (vspd < 0 || keyboard_check(ord('W'))){ 
    if place_meeting(x, y+vspd, block_obj) 
    { 
     // pixel-perfect collision resolution 
     while(!place_meeting(x, y-1, block_obj)) 
     { 
      y -= 1; 
     } 
     vspd = 0; 
    } 
    else if keyboard_check(ord('W')) 
    { 
     if(!place_meeting(x, y-1, block_obj)) 
      vspd -= 2; 
    } 
    else 
    { 
     if(vspd < -2) 
     { 
      vspd += 1; 
     } 
     else 
     { 
      vspd = 0; 
     } 
    } 
} 
if (vspd > 0 || keyboard_check(ord('S'))){ 
    if place_meeting(x, y+vspd, block_obj) 
    { 
     // pixel-perfect collision resolution 
     while(!place_meeting(x, y+1, block_obj)) 
     { 
      y += 1; 
     } 
     vspd = 0; 
    } 
    else if keyboard_check(ord('S')) 
    { 
     if(!place_meeting(x, y+1, block_obj)) 
      vspd += 2; 
    } 
    else 
    { 
     if(vspd > 2) 
     { 
      vspd -= 1; 
     } 
     else 
     { 
      vspd = 0; 
     } 
    } 
} 

if (hspd < 0 || keyboard_check(ord('A'))){ 
    if place_meeting(x+hspd, y, block_obj) 
    { 
     // pixel-perfect collision resolution 
     while(!place_meeting(x-1, y, block_obj)) 
     { 
      x -= 1; 
     } 
     hspd = 0; 
    } 
    else if keyboard_check(ord('A')) 
    { 
     if(!place_meeting(x-1, y, block_obj)) 
      hspd -= 2; 
    } 
    else 
    { 
     if(hspd < -2) 
     { 
      hspd += 1; 
     } 
     else 
     { 
      hspd = 0; 
     } 
    } 
} 
if (hspd > 0 || keyboard_check(ord('D'))){ 
    if place_meeting(x+hspd, y, block_obj) 
    { 
     // pixel-perfect collision resolution 
     while(!place_meeting(x+1, y, block_obj)) 
     { 
      x += 1; 
     } 
     hspd = 0; 
    } 
    else if keyboard_check(ord('D')) 
    { 
     if(!place_meeting(x+1, y, block_obj)) 
      hspd += 2; 
    } 
    else 
    { 
     if(hspd > 2) 
     { 
      hspd -= 1; 
     } 
     else 
     { 
      hspd = 0; 
     } 
    } 
} 

x += hspd; 
y += vspd; 

我似乎無法找到我的步驟代碼,造成問題的一部分。

回答

1

如果我這樣做,我會通過使用else if語句使每個控件相互分離。僞代碼如:

if (w) { 
//code 
} else if (a) { 
//code 
} else if (s) { 
//code 
} else if (d) { 
//code 
} 

這應該防止/幫助你的問題,因爲你不能再一次提供多個方向的加速度,如果完全不起作用,可能是因爲您遞增軸運動進入牆,當你改變方向時,你正朝着這個方向加速,因爲碰撞檢查不再是問題,因爲你在按鍵內部進行了碰撞檢查,當你碰到牆時不應該因爲這個原因而加速,只會讓玩家反彈回來。 我有一個項目從幾年前就做了你想做的事,生病試圖找到它不起作用,讓我知道。

+0

我實際上發現了這個問題,我需要爲動量的每個方向做一個單獨的變量,vNegSpd vPosSpd等,所以當檢查碰撞時,我只使用該方向的變量。 問題是,當我說舉行「D」和vspd超高,我交換了「A」,「A」分支將檢查使用相同的超高vspd碰撞,並將觸發「抓到最近牆「解決方案,將其一直捕捉到屏幕的另一側。 – user3776749

+0

儘管打破輸入可能是一個有用的補充,無論。雖然我可能只會把它分成兩個(WA和SD),因爲我想支持對角線移動。 – user3776749