寫在正題之前,說一說我的一些想法。

1 sdlpal既然使用了c了,那麼就很難從面向對象角度來思考問題了,很像零散的碎片,需要一個個的去理解。

2sdlpal版的仙劍,是如何完成一個事件的呢,就比如開局這場上菜的對話。 3sdlpal里如何,添加自己的人物,

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)

end

這段代碼的主要用途,就是不停地查詢所有事件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,來顯示我想要輸出的數據。當然了,時下也正在研究,怎麼發送數據包,能夠更好的形式來顯示內存中的流程。

這個要是做好了,區域網的對戰,基本就在醞釀之中了。

推薦閱讀:

相关文章