寫在正題之前,說一說我的一些想法。
1 sdlpal既然使用了c了,那麼就很難從面向對象角度來思考問題了,很像零散的碎片,需要一個個的去理解。 2sdlpal版的仙劍,是如何完成一個事件的呢,就比如開局這場上菜的對話。 3sdlpal里如何,添加自己的人物, 4sdlpal是如何,觸發場景切換的呢?
1 sdlpal既然使用了c了,那麼就很難從面向對象角度來思考問題了,很像零散的碎片,需要一個個的去理解。
4sdlpal是如何,觸發場景切換的呢?
其實我有很多的疑問,但是沒有辦法,只能慢慢深入了。基調還是順藤摸瓜,在胡思亂想之餘,我想起了行為樹,還有concurrent,還有協程,還有qt的scene 和view,又在想,怎麼把sdl surface怎麼翻譯成qt的qpixmap。又想通過concurrent把調試數據傳遞到另外一台電腦上面,輸出的都是print不能設置坐標,又想造一個可以輸出坐標的print。總之一堆看起來很合理,又不著邊際的想法
上回說到了,要做的3個函數,已經翻譯完畢了
local functionName=PAL_GameUpdateV2 class_t[functionName]=function(self,d,small_env) --print(PAL_GameUpdateV2 00 zero) local item_menu_helper=d.item_menu_helper local palcommon=d.palcommon local menu_helper=d.menu_helper local scene_helper=d.scene_helper local bit=d.bit local util=d.util local gpGlobals=d.gpGlobals local gameData=gpGlobals:getGameData() local rgParty=gpGlobals:getParty() ------------------------------ local t=small_env or {} local fTrigger=t.fTrigger
local wEventObjectID, wDir,p,cnt -- LPEVENTOBJECT p; local curr_scene,next_scene local wNumScene local viewport,partyoffset,dx,dy,px,py local xOffset,yOffset
local pos,x,y
--print(PAL_GameUpdateV2 001) if fTrigger then if gpGlobals.fEnteringScene~=FALSE then gpGlobals.fEnteringScene=FALSE cnt=gpGlobals.wNumScene - 1 curr_scene=gameData:getScene(cnt) curr_scene.wScriptOnEnter=PAL_RunTriggerScript( curr_scene.wScriptOnEnter,0xFFFF) if gpGlobals.fEnteringScene ~=FALSE or gpGlobals.fGameStart ~=FALSE then -- Dont go further as were switching to another scene return end PAL_ClearKeyState() PAL_MakeScene() end --print(PAL_GameUpdateV2 002) -- Update the vanish time for all event objects for wEventObjectID=0,gameData.nEventObject-1 do p=gameData:getLprgEventObject(wEventObjectID) if p.sVanishTime~=0 then if p.sVanishTime<0 then p.sVanishTime=1 else p.sVanishTime=0 end end end --print(PAL_GameUpdateV2 003) -- Loop through all event objects in the current scene wNumScene=gpGlobals.wNumScene curr_scene=gameData:getScene(wNumScene-1) next_scene=gameData:getScene(wNumScene)
--print(PAL_GameUpdateV2 0031) --error before is no +1 for wEventObjectID=curr_scene.wEventObjectIndex+1, next_scene.wEventObjectIndex do -------------------------------------- --error before is no -1 p=gameData:getLprgEventObject(wEventObjectID-1) -- print(PAL_GameUpdateV2 00321) if p.sVanishTime==0 then -- print(PAL_GameUpdateV2 0033)
viewport=gpGlobals.viewport
partyoffset=gpGlobals.partyoffset dx=palcommon:get_X(viewport) dy=palcommon:get_Y(viewport) px=palcommon:get_X(partyoffset) py=palcommon:get_Y(partyoffset) --print(PAL_GameUpdateV2 004)
if p.sState<0 then if p.x<dx or p.x>dx+320 or p.y<dy --error py<dy or p.y>dy+320 then --error py>dy ------------------- p.sState=math.abs(p.sState) p.wCurrentFrameNum=0 --print(PAL_GameUpdateV2 0050000000000000000) end --This event object can be triggered without manually exploring elseif p.sState>0 and p.wTriggerMode>= kTriggerTouchNear then if math.abs(dx+px -p.x) +math.abs(dy+py-p.y)*2 <((p.wTriggerMode-kTriggerTouchNear)* 32 + 16) then --Player is in the trigger zone --print(PAL_GameUpdateV2 006) if p.nSpriteFrames==0 then else p.wCurrentFrameNum=0 xOffset=dx+px-p.x yOffset=dy+py-p.y if xOffset>0 then if yOffset>0 then p.wDirection=kDirEast else p.wDirection=kDirNorth end else if yOffset>0 then p.wDirection=kDirSouth else p.wDirection=kDirWest end end -- Redraw the scene PAL_UpdatePartyGestures(FALSE) PAL_MakeScene() VIDEO_UpdateScreen(nil) -- print(PAL_GameUpdateV2 007) end --Execute the script --print(string.format("%d 0x%x",p.wTriggerScript,wEventObjectID ),p.sState) p.wTriggerScript = PAL_RunTriggerScript(p.wTriggerScript,wEventObjectID) --print(run ------------0001b,p.wTriggerScript,wEventObjectID ,p.sState) PAL_ClearKeyState() -- print(PAL_GameUpdateV2 008)
if gpGlobals.fEnteringScene ~=FALSE or gpGlobals.fGameStart ~=FALSE then -- Dont go further as were switching to another scene return end
end else --if wEventObjectID==16 then -- print(p.sState,p.wTriggerMode>= kTriggerTouchNear) --end --else print( -- wEventObjectID, -- p.sState>0, p.wTriggerMode>= kTriggerTouchNear, -- math.abs(dx+px -p.x) +math.abs(dy+py-p.y)*2 , -- (p.wTriggerMode-kTriggerTouchNear* 32 + 16)
-- ) end
else --continue end
end
end --print(PAL_GameUpdateV2 009) --Run autoscript for each event objects wNumScene=gpGlobals.wNumScene curr_scene=gameData:getScene(wNumScene-1) next_scene=gameData:getScene(wNumScene)
local wScriptOnEnter for wEventObjectID=curr_scene.wEventObjectIndex+1, next_scene.wEventObjectIndex do ----------------------------------------------- p=gameData:getLprgEventObject(wEventObjectID-1) --print(PAL_GameUpdateV2 0010) if p.sState>0 and p.sVanishTime==0 then --print(wEventObjectID,p.x,p.y,p.wAutoScript)
wScriptOnEnter=p.wAutoScript if wScriptOnEnter~=0 then --print(PAL_GameUpdateV2 00102,wScriptOnEnter, wEventObjectID)
--print(run ------------00011,p.wAutoScript) p.wAutoScript = PAL_RunAutoScript(wScriptOnEnter, wEventObjectID) --print(run ------------00012,p.wAutoScript ) --print(PAL_GameUpdateV2 001021) if gpGlobals.fEnteringScene ~=FALSE or gpGlobals.fGameStart ~=FALSE then --print(PAL_GameUpdateV2 00103) -- Dont go further on scene switching ,look this changed word return end end end --print(PAL_GameUpdateV2 0010) --Check if the player is in the way viewport=gpGlobals.viewport partyoffset=gpGlobals.partyoffset dx=palcommon:get_X(viewport) dy=palcommon:get_Y(viewport) px=palcommon:get_X(partyoffset) py=palcommon:get_Y(partyoffset) if fTrigger~=0 and p.sState>=kObjStateBlocker and p.wSpriteNum~=0 and math.abs(p.x -dx -px)+math.abs(p.y-dy-py)*2<=12 then --Player is in the way, try to move a step------------------ wDir=(p.wDirection)%4 --print(PAL_GameUpdateV2 00111k) for i=0,4-1 do x=palcommon:get_X(gpGlobals.viewport)-palcommon:get_X(gpGlobals.partyoffset) y=palcommon:get_Y(gpGlobals.viewport)-palcommon:get_Y(gpGlobals.partyoffset) if wDir ==kDirWest or wDir ==kDirSouth then x=x-16 else x=x+16 end if wDir ==kDirWest or wDir ==kDirNorth then y=y-16 else y=y+16 end pos =palcommon:pal_XY(x,y)
if scene_helper:PAL_CheckObstacleV2(d, {pos,fCheckEventObjects=TRUE,wSelfObject=0})~=0 then --if PAL_CheckObstacle(pos, TRUE, 0) ~=0 then gpGlobals.viewport =palcommon:pal_XY( palcommon:get_X(pos)-palcommon:get_X(gpGlobals.partyoffset), palcommon:get_Y(pos)-palcommon:get_Y(gpGlobals.partyoffset) ) break end wDir=(wDir+1) %4
end end end gpGlobals.dwFrameNum=gpGlobals.dwFrameNum+1
--print(PAL_GameUpdateV2 0012)
這段代碼的主要用途,就是不停地查詢所有事件object,判斷,是否達成事件。
比如靠近某人,某地後就觸發。所有的內容都指向腳本。
先看看下圖
下面再看看 PAL_UpdatePartyV2 的翻譯
local functionName=PAL_UpdatePartyV2 class_t[functionName]=function(self,d,small_env) --print(PAL_GameUpdateV2 00 zero) local item_menu_helper=d.item_menu_helper local palcommon=d.palcommon local menu_helper=d.menu_helper local bit=d.bit local util=d.util local gpGlobals=d.gpGlobals local gameData=gpGlobals:getGameData() local rgParty=gpGlobals:getParty()
local g_InputState=d.g_InputState ------------------------------ local t=small_env or {} --local fTrigger=t.fTrigger -------------------------------------- local xSource, ySource, xTarget, yTarget, xOffset, yOffset local dir =g_InputState.dir --Has user pressed one of the arrow keys? local viewport,partyoffset local curr_trail --print(run 00000000000011) if dir ~=kDirUnknown then if dir ==kDirWest or dir==kDirSouth then xOffset=-16 else xOffset=16 end --------------------- if dir==kDirWest or dir==kDirNorth then yOffset=-8 else yOffset=8 end -- print(run 00000000000012) --------------------- viewport,partyoffset =gpGlobals.viewport,gpGlobals.partyoffset -- print(run 000000000000121) xSource =palcommon:get_X(viewport)+palcommon:get_X(partyoffset) -- print(run 000000000000122) ySource=palcommon:get_Y(viewport)+palcommon:get_Y(partyoffset) -- print(run 00000000000013)
xTarget =xSource+xOffset yTarget =ySource+yOffset
gpGlobals.wPartyDirection=dir --Check for obstacles zhangaiwu on the destination location --print(run 00000000000014) if self:PAL_CheckObstacleV2(d,{ pos=palcommon:pal_XY(xTarget, yTarget),fCheckEventObjects=TRUE,wSelfObject=0 }) ==0 then --if PAL_CheckObstacle(, TRUE, 0) ==0 then --Player will actually be moved. Store trail -- print(run 000000000000141) for i=3,0,-1 do -- print(run 000000000000142) curr_trail=gpGlobals:getTrailItem(i) --print(run 000000000000143,gpGlobals.setTrailItem) gpGlobals:setTrailItem(i+1,curr_trail) --print(run 000000000000144) end --print(run 000000000000145) curr_trail =gpGlobals:getTrailItem(0) --print(run 000000000000146) curr_trail.wDirect=dir curr_trail.x=xSource curr_trail.y=ySource --move the viewport --print(run 000000000000147) gpGlobals.viewport =palcommon:pal_XY( palcommon:get_X(gpGlobals.viewport)+xOffset, palcommon:get_Y(gpGlobals.viewport)+yOffset ) --Update gestures zitai zishi
PAL_UpdatePartyGestures(TRUE)
return -- dont go further end --print(run 00000000000012) end PAL_UpdatePartyGestures(FALSE) end
這個函數,其實很簡單,
就是當玩家,按上下左右之後,調整了主角小隊的移動方向和位置。self:PAL_CheckObstacleV2檢查是否前面是障礙物,
PAL_UpdatePartyGestures(TRUE)這個函數,簡單來講就是計算,主角小隊所有人物的下一幀,
基本上 3個函數的翻譯工作就完成了。至此,主幹的循環參與的函數就做完了。要想明白,這個遊戲是怎麼運作的,個人覺得,必須得做一個雙機互聯顯示遊戲輸出信息的工具。
比如這個,concurrent
ping端的結果
一旦涉及網路,不論是區域網還是什麼網,肯定要用多線程。多線程思路已經在年幼的時候,植入思想。
源碼是這樣的
1 為何要這麼干呢,我個人覺得,將來的程序員,必須懂得聯網和多線程。不論什麼程序員,
2,因為我有一個想法,那就是sdl要想轉換成qt顯示,是不是,我們將內存傳到另外一台電腦上面,那台電腦實時地把這台電腦的內容顯示出來呢,如果能,說明,我們已經消化了這段代碼。
3因為現在就涉及到下一步,該往哪裡走了,直接往腳本里走,還是繼續圖形的部分,但是往場景和地圖,還有各種小精靈上面。但是不論往哪裡走,都不再是流程那麼簡單,全部都是各種細節,想要了解信息,就必須動態修改數據。
那麼試想一下,從另外一台電腦,發個命令過來,這台收到了,就執行對應的操作。那該多好啊。
朝著這個想法,我準備試一試,
雖然小目標達到了,但是本章未完,這兩天會把雙機操作的想法測試完了,把結果貼上了。
如果太難了,還是單機調試來理解代碼了。
說一個非分之想,如果仙劍1,能夠多人聯機打,應該是一個令人期待的方向。
好了,我去測試想法了
4-5個小時過去了。真開心。終於把concurrent排錯給排凈了,
1從根處開始排的,lua重新編譯了。不生成lib,只生成dll,
生成dll和lib了。
2重新開始編譯luasocket,把剛生成的lib拖拽進去。
個人感覺luasocket,似乎不太支持靜態lib的lua51.問題就出在這個庫。
只要 collectgarbage(collect) 立即就崩。重新編譯之後,立馬爽歪歪。已經可以傳遞出去了。
很好坐標已經傳遞出來了,現在只是傳遞主角自己的坐標,希望越傳越多。我覺得,是時候,該多思考一下,聯網排錯,分析源碼的事情了。
幾天沒有更新了,原因很簡單,這次幹了一件大事,那就是,區域網排錯
引入多機調試,可以很好的打開局面。
下面就是糾正林月如走路方向錯誤的問題
利用替換法,發現錯誤還是發生在了。PAL_UpdatePartyGesturesV2
經過修改後,正常了。
為什麼要加入區域網排錯呢?還用的是lua的庫,當然了,我也想用c++的,那麼問題來了,c++的庫,要熟練應用起來,是需要時間的,先用lua的,把流程和用法用熟練了,再轉成c++的,就可以了。c++程序員,多線程,協程,圖形庫2-3個,資料庫1-2個,然後就是跟著時代更新,基本上不用想35歲以後怎麼辦。因為你已經想到60歲的時候,你還要幹什麼。搞編程,一定要往上爬,不能因為眼睛疼,頭疼,各種拒絕的思想,讓我們停滯不前,稍微一懈怠,人就廢了。這一章算是完事了,我不想用舊的方法來解讀源碼了,因為我這5天就是引入了lua的concurrent,signal,還有qt的signal slot thread,還有scene和view。
有了這些東西之後,我可以創建超過500個textitem,來顯示我想要輸出的數據。當然了,時下也正在研究,怎麼發送數據包,能夠更好的形式來顯示內存中的流程。
這個要是做好了,區域網的對戰,基本就在醞釀之中了。
推薦閱讀: