傳回目錄
OpenTTD的視覺系統2.5D形式展現,素材都是圖檔,通過螢幕貼圖的方式生成界面元素,是以不能像真3D遊戲那樣在遊戲過程中旋轉視角,看到3D模型側面或者背面的情況。這種2.5D的展示方式對顯示卡要求較低,大量使用在手機遊戲裡面,比如 王者榮耀、部落沖突、三國志政策版的界面,我們都能看到這種顯示模式的身影。Openttd.cpp 代碼量不大(行數 3000+),函數數量多(50+),其中對外服務函數26個,私有服務 27個。上層調用者主要包括 gui類、cmd類以及遊戲初始化階段的各種類,向下調用 gfx.cpp set dirty(把螢幕部分或者全部設定重新整理) , Draw開頭的繪制等操作,下面是整理出來的主要函數調用關系及說明。
viewport是遊戲進行中的主界面,我們以鋪設鐵軌為例,修建鐵路相關的界面在rail_gui.cpp定義,操作流程:
1.點開toolbar的鐵路菜單欄;
2.選擇修建鐵路圖示;
3.滑鼠左鍵拖動修建鐵路;
4.滑鼠拖動過程中,界面對應Tile對應顯示鐵軌;
5.滑鼠左鍵擡起,完成修建動作;
以上3-5步驟分别由 viewport.cpp的三個函數實作
VpStartPlaceSizing() 開始拖動
<- rail_gui.cpp OnPlaceObject()
<- viewport.cpp PlaceObject()
<- viewport.cpp VpStartDragging() 拖動中
VpHandlePlaceSizingDrag() 拖動完成
<- rail_gui.cpp OnPlaceMouseUp()
通過上面的分析,我們可以看到,實作拖動架設鐵路的操作是由 viewport.cpp 與 rail_gui.cpp 幾個函數之間互相調用實作
鋪設鐵路調用鍊
說明:
a<-b 表示函數a被函數b調用
<= 後面是這個函數的說明
格式:<-(第一行沒有) 源碼檔案名 函數名 <= 函數說明
rail_gui.cpp DoRailroadTrack() <= 調用DoCommandP()
<- HandleAutodirPlacement() <= select_proc=DDSP_PLACE_RAIL
<- OnPlaceMouseUp() <= select_proc=DDSP_PLACE_RAIL
<- PlaceRail_Bridge() <= Start placing a rail bridge.
<- OnPlaceObject() <= this->last_user_action=WID_RAT_BUILD_BRIDGE
<- viewport.cpp <= PlaceObject()
<- HandleViewportClicked()
<- window.cpp MouseLoop() <= 每一個tick
<- HandleMouseEvents()
<- sdl2_v.cpp VideoDriver_SDL_Base::PollEvent()
<- video_driver.cpp VideoDriver::Tick()
最後,是viewport.cpp的函數清單
說明:
a() <- b() 表示函數a被 函數b調用
: 後面是這個函數的中英文說明
*3 表示這是需要重要關注的函數
----public----
-
StartSpriteCombine() <- *_cmd.cpp 一般是draw操作前調用
: Starts a block of sprites, which are “combined” into a single bounding box.
-
EndSpriteCombine() <- *_cmd.cpp 與上面成對出現
: Terminates a block of sprites started by #StartSpriteCombine.
*3. ViewportDoDraw() <- screenshot.cpp LargeWorldCallback() & this.ViewportDraw()
: 調用 ViewportDraw 開頭的幾個私有函數完成ViewPort的繪制
-
DrawViewport() <- widget.cpp NWidgetViewport::Draw()
: Draw the viewport of this window.
: 在視窗的小元件widget繪制的時候,直接調用 ViewportDraw() 間接調用 ViewportDoDraw()
-
ViewportAddString() <- texteff.cpp DrawTextEffects() & this.ViewportAddKdtreeSigns()
: Add a string to draw in the viewport
: 界面上增加字元串
------六個Make開頭的函數 被 cmd類程式發起
- MakeStation() <- station_map.h 建立車站、碼頭、機場等Tile & this.RebuildViewportKdtree()
- MakeWaypoint() <- waypoint_cmd.cpp Waypoint::UpdateVirtCoord() & this.RebuildViewportKdtree()
- MakeTown() <- town_cmd.cpp Town::UpdateVirtCoord() & this.RebuildViewportKdtree()
-
MakeSign() <- signs.cpp Sign::UpdateVirtCoord() & this.RebuildViewportKdtree()
------
- RebuildViewportKdtree() <- afterload.cpp AfterLoadGame() UpdateAllVirtCoords() & misc.cpp InitializeGame()
-
ScrollWindowTo() <- main_gui.cpp ZoomInOrOutToCursorWindow() & smallmap_gui.cpp ScrollMainWindowTo()
: Scrolls the viewport in a window to a given location.
-
ScrollWindowToTile() <- *_gui.cpp OnResize() 包括 industry/town/waypoint
: Scrolls the viewport in a window to a given location.
-
ScrollMainWindowToTile() <- *_gui.cpp 大量調用這個方法 跳轉視角
: Scrolls the viewport of the main window to a given location.
-
UpdateTileSelection() <- window.cpp MouseLoop() & station_gui.cpp StationJoinerNeeded()
: Updates tile highlighting for all cases.
-
VpSelectTilesWithMethod() <- *_gui.cpp OnPlaceDrag()
: Selects tiles while dragging
-
VpHandlePlaceSizingDrag() <- window.cpp MouseLoop()
: Handle the mouse while dragging for placement/resizing.
-
SetObjectToPlaceWnd() <- *_gui.cpp OnClick()
: 調用SetObjectToPlace()
-
SetObjectToPlace() <- genworld.cpp GenerateWorld() & *_gui.cpp OnClick()
: Change the cursor and mouse click/drag handling
-
ResetObjectToPlace()
: Reset the cursor and mouse mode handling back to default
: 調用SetObjectToPlace()
- GetViewportStationMiddle() <- linkgraph_gui.cpp GetStationMiddle()
- CmdScrollViewport(): Scroll players main viewport.
- SetViewportCatchmentStation():
- SetViewportCatchmentTown(): Town’s coverage set dirty
----init----
- InitializeSpriteSorter() <- openttd.cpp main()
-
InitializeWindowViewport() <- widget.cpp NWidgetViewport::InitializeViewport()
: 很多 gui 建立新視窗的時候調用
----private----
- MarkCatchmentTilesDirty() <- SetViewportCatchmentStation()
-
CalcRaildirsDrawstyle() <- VpSelectTilesWithMethod()
: while dragging
- DoSetViewportPosition() <- SetViewportPosition()
-
SetViewportPosition() <- UpdateViewportPosition()
*5. TranslateXYToTileCoord() <- GetTileFromScreenXY() & CheckClickOnLandscape()
: Translate screen coordinate in a viewport to underlying tile coordinate.
: x,y的坐标轉換為3D的透視圖,調用 landscape.cpp InverseRemapCoords2() 完成轉換
-
GetTileFromScreenXY() <- GetTileBelowCursor() & GetTileZoomCenterWindow()
: When used for zooming, check area below current coordinates (x,y)
-
AddTileSpriteToDraw() <- DrawGroundSpriteAt() & DrawSelectionSprite()
: Schedules a tile sprite for drawing.
-
AddChildSpriteToFoundation() <- DrawGroundSpriteAt() & DrawSelectionSprite()
: Adds a child sprite to the active foundation.
-
AddCombinedSprite() <- AddSortableSpriteToDraw()
: Draw a (transparent) sprite at given coordinates with a given bounding box.
- AddStringToDraw() <- ViewportAddString()
-
ViewportSortParentSprites() <- InitializeSpriteSorter()
------下面這一堆函數都被ViewportDoDraw()調用
- ViewportAddLandscape() <- ViewportDoDraw()
- ViewportDrawTileSprites() <- ViewportDoDraw()
- ViewportDrawParentSprites() <- ViewportDoDraw()
- ViewportDrawBoundingBoxes() <- ViewportDoDraw()
-
ViewportDrawDirtyBlocks() <- ViewportDoDraw()
: Draw/colour the blocks that have been redrawn.
-
ViewportDrawStrings() <- ViewportDoDraw()
------上面這一堆函數都被ViewportDoDraw()調用
-
ClampViewportToMap() <- UpdateViewportPosition()
: Ensure that a given viewport has a valid scroll position.
-
SetSelectionTilesDirty() <- SetSelectionRed() & UpdateTileSelection() & SetObjectToPlace()
: Marks the selected tiles as dirty.
-
UpdateViewportPosition() <- window.cpp UpdateWindows()
: Update the viewport position being displayed.
-
CheckClickOnViewportSign() <- HandleViewportClicked()
: Check whether any viewport sign was clicked, and dispatch the click.
- CheckClickOnLandscape() <- HandleViewportClicked()
- PlaceObject() <- HandleViewportClicked()
-
HandleViewportClicked() <- window.cpp MouseLoop()
: 點選滑鼠左鍵的事件響應
-
ViewportDraw() <- Window::DrawViewport()
: Draw the viewport of this window.
-
RebuildViewportOverlay() <- ScrollWindowTo()
: 區域 SetDirty()