跳躍
開始之前,我們先把視角從俯視改成側(cè)視,這樣英雄才可以跳躍。就像下面的這個(gè),按左右鍵英雄移動(dòng),按空格鍵跳躍:
跳躍基礎(chǔ)
跳躍意味著上升,上升在Flash中意味著_y屬性的減少。所以我們需要計(jì)算這樣的式子: 新的坐標(biāo)=現(xiàn)在的坐標(biāo)-上升速度
如果只計(jì)算一次,坐標(biāo)只改變一次,英雄很快就停止了。因此我們需要持續(xù)不斷的計(jì)算新坐標(biāo)。而且,我們還應(yīng)該改變速度的值,否則英雄就在空中下不來了。 下落和上升一樣,只不過速度值前面加個(gè)負(fù)號(hào)而已。
為了改變速度,我們定義一個(gè)新的變量:重力加速度。重力把英雄拉向地面,學(xué)過物理吧?重力加速度并不直接改變坐標(biāo),他改變的是速度: 速度=速度+加速度
這就是Flash中的表示方法,=可不是表示左右相等,是把右邊計(jì)算的結(jié)果賦給”速度”變量。這個(gè)式子也是需要不停計(jì)算的,以便保持連貫的運(yùn)動(dòng)。你可以改變重力的值,較小的值意味著在空中的時(shí)間更長,較大的值很快就會(huì)把英雄“拉”下來。 從另外的角度看,重力也意味著跳躍能力,我們可以給不同的對(duì)象賦以不同的“重力”屬性,這樣他們跳得就不至于一樣高。
讓我們來看一個(gè)例子。比如剛開始的速度是-10,重力是2。 那么開始的時(shí)候,英雄將會(huì)上移10象素,然后速度降低到8; 接著英雄上移8象素,然后速度又變成了6…… 如此往復(fù),直到速度等于0的時(shí)候,英雄不再上升了。 接著速度成了2,英雄開始下降2象素; 下一步又下降4象素、6象素、8象素……直到落地。
落地后,跳躍自然也應(yīng)該結(jié)束了。但是要是英雄在跳躍過程中頂?shù)秸系K物怎么辦? 很簡單,我們把速度強(qiáng)行改成0就行了,然后英雄就會(huì)落下來。
【注意】在區(qū)塊游戲開發(fā)中,不要讓速度值超過方塊的高度。過大的速度會(huì)導(dǎo)致碰撞檢測跳過某個(gè)方塊,導(dǎo)致英雄“穿過”障礙物。或許有些魔法師可以穿過障礙物,但是在普通的區(qū)塊游戲中,這是個(gè)bug。
跳躍并不影響水平方向的運(yùn)動(dòng),在空中我們還可以用方向鍵控制英雄的水平運(yùn)動(dòng)。我們需要做的是,在左移或右移后,判斷英雄腳下是不是還有東西,如果是空的,跳躍就開始了(這時(shí)候初始速度是0,英雄直接下落)。
會(huì)跳的英雄
我們給英雄再添加一些屬性: char = {xtile:2, ytile:1, speed:4, jumpstart:-18, gravity:2, jump:false}; speed屬性是水平移動(dòng)速度,jumpstart是跳躍的初始速度, granvity是重力值,jump屬性用來表示英雄是不是在跳躍過程中。
下面加一句as到buildMap函數(shù)中: char.y = ((char.ytile + 1) * game.tileW) - char.height;
因?yàn)槲覀兊囊晥D是側(cè)視的,英雄剛開始的位置可能是“漂”在空中的,我們應(yīng)該讓他站到地面上來。
changeMap函數(shù)和getMyCorners函數(shù)不需要任何變動(dòng)。
騰空的感覺
我們先來改造detectKey函數(shù),刪除上下鍵檢測,添加空格鍵檢測:
function detectKeys() { var ob = _root.char; var keyPressed = false; if (Key.isDown(Key.SPACE) and !ob.jump) { ob.jump = true; ob.jumpspeed = ob.jumpstart; } if (Key.isDown(Key.RIGHT)) { keyPressed = _root.moveChar(ob, 1, 0); } else if (Key.isDown(Key.LEFT)) { keyPressed = _root.moveChar(ob, -1, 0); } if (ob.jump) { keyPressed = _root.jump(ob); } if (!keyPressed) { ob.clip.char.gotoAndStop(1); } else { ob.clip.char.play(); } }
注意看我們?cè)趺幢苊馓S過程中空格鍵觸發(fā)新的跳躍(聽起來很拗口,哈哈),實(shí)際上就是當(dāng)處于跳躍中時(shí),忽略空格鍵。如果按了空格鍵,而且英雄沒有處于跳躍過程,那就開始跳吧,把jump屬性改成true,把jumpspeed改成speedstart屬性值。
看一下,在左右方向鍵的檢測語句后面,我們添加了幾句。 if (ob.jump) { keyPressed = _root.jump(ob); }
如果jump屬性為true(正在跳),那么執(zhí)行jump函數(shù)。只要jump屬性為true,jump函數(shù)就會(huì)不斷地被執(zhí)行,直到j(luò)ump屬性變成了false。這個(gè)函數(shù)可以在空格鍵松開后仍然執(zhí)行,只要jump屬性為true。
Jump函數(shù)所做的只是改變jumpspeed的值,給他加上重力值。同時(shí)做一些處理防止速度值過大,讓jumpspeed不會(huì)超過方塊高度。最后調(diào)用moveChar函數(shù)移動(dòng)角色。
function jump (ob) { ob.jumpspeed = ob.jumpspeed + ob.gravity; if (ob.jumpspeed > game.tileH) { ob.jumpspeed = game.tileH; } if (ob.jumpspeed < 0) { moveChar(ob, 0, -1, -1); } else if (ob.jumpspeed > 0) { moveChar(ob, 0, 1, 1); } return (true); }
我們還需要改一下moveChar函數(shù),因?yàn)榧尤肓颂S過程,跳躍時(shí)的速度jumpspeed和水平移動(dòng)的速度speed是不同的:
function moveChar(ob, dirx, diry, jump) { if (Math.abs(jump) == 1) { speed = ob.jumpspeed * jump; } else { speed = ob.speed; } ...
jump參數(shù)是從上面的jump函數(shù)中傳遞過來的,它的取值不是1就是-1。如果jump的絕對(duì)值(Math.abs)是1,移動(dòng)的距離就是jumpspeed*jump,否則就是speed屬性。
如果這一步移動(dòng)結(jié)束后,角色的頂?shù)搅苏系K物,就要把jumpspeed值改成0: ob.y = ob.ytile * game.tileH + ob.height; ob.jumpspeed = 0;
如果這一步移動(dòng)結(jié)束后,角色站到了地面上,跳躍就該結(jié)束了: ob.y = (ob.ytile + 1) * game.tileH - ob.height; ob.jump = false;
在左右移動(dòng)后,我們還要看看角色是不是還站在平臺(tái)上,如果不是,就應(yīng)該落下來: ob.x += speed * dirx; fall (ob);
所以,我們還需要一個(gè)fall函數(shù): function fall (ob) { if (!ob.jump) { getMyCorners (ob.x, ob.y + 1, ob); if (ob.downleft and ob.downright) { ob.jumpspeed = 0; ob.jump = true; } } }
如果角色已經(jīng)處于跳躍過程中,這個(gè)函數(shù)就沒有必要運(yùn)行了,它是用來檢測“踩空”的情況的,只有當(dāng)角色站著(!ob.jump)的時(shí)候才有用。這時(shí)候我們調(diào)用getMycorners函數(shù),如果角色下方的兩個(gè)方塊都是可通行的,那就應(yīng)該落下來了, 起始速度是0,然后把jump屬性改成true。
下載源文件
出處:藍(lán)色理想
責(zé)任編輯:qhwa
上一頁 芝麻開門-地圖切換 下一頁 騰云駕霧
◎進(jìn)入論壇Flash專欄版塊參加討論
|