天天看點

Day09_OpenTTD的Viewport介紹

傳回目錄

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.滑鼠左鍵擡起,完成修建動作;

Day09_OpenTTD的Viewport介紹

以上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----

  1. StartSpriteCombine() <- *_cmd.cpp 一般是draw操作前調用

    : Starts a block of sprites, which are “combined” into a single bounding box.

  2. EndSpriteCombine() <- *_cmd.cpp 與上面成對出現

    : Terminates a block of sprites started by #StartSpriteCombine.

    *3. ViewportDoDraw() <- screenshot.cpp LargeWorldCallback() & this.ViewportDraw()

    : 調用 ViewportDraw 開頭的幾個私有函數完成ViewPort的繪制

  3. DrawViewport() <- widget.cpp NWidgetViewport::Draw()

    : Draw the viewport of this window.

    : 在視窗的小元件widget繪制的時候,直接調用 ViewportDraw() 間接調用 ViewportDoDraw()

  4. ViewportAddString() <- texteff.cpp DrawTextEffects() & this.ViewportAddKdtreeSigns()

    : Add a string to draw in the viewport

    : 界面上增加字元串

    ------六個Make開頭的函數 被 cmd類程式發起

  5. MakeStation() <- station_map.h 建立車站、碼頭、機場等Tile & this.RebuildViewportKdtree()
  6. MakeWaypoint() <- waypoint_cmd.cpp Waypoint::UpdateVirtCoord() & this.RebuildViewportKdtree()
  7. MakeTown() <- town_cmd.cpp Town::UpdateVirtCoord() & this.RebuildViewportKdtree()
  8. MakeSign() <- signs.cpp Sign::UpdateVirtCoord() & this.RebuildViewportKdtree()

    ------

  9. RebuildViewportKdtree() <- afterload.cpp AfterLoadGame() UpdateAllVirtCoords() & misc.cpp InitializeGame()
  10. ScrollWindowTo() <- main_gui.cpp ZoomInOrOutToCursorWindow() & smallmap_gui.cpp ScrollMainWindowTo()

    : Scrolls the viewport in a window to a given location.

  11. ScrollWindowToTile() <- *_gui.cpp OnResize() 包括 industry/town/waypoint

    : Scrolls the viewport in a window to a given location.

  12. ScrollMainWindowToTile() <- *_gui.cpp 大量調用這個方法 跳轉視角

    : Scrolls the viewport of the main window to a given location.

  13. UpdateTileSelection() <- window.cpp MouseLoop() & station_gui.cpp StationJoinerNeeded()

    : Updates tile highlighting for all cases.

  14. VpSelectTilesWithMethod() <- *_gui.cpp OnPlaceDrag()

    : Selects tiles while dragging

  15. VpHandlePlaceSizingDrag() <- window.cpp MouseLoop()

    : Handle the mouse while dragging for placement/resizing.

  16. SetObjectToPlaceWnd() <- *_gui.cpp OnClick()

    : 調用SetObjectToPlace()

  17. SetObjectToPlace() <- genworld.cpp GenerateWorld() & *_gui.cpp OnClick()

    : Change the cursor and mouse click/drag handling

  18. ResetObjectToPlace()

    : Reset the cursor and mouse mode handling back to default

    : 調用SetObjectToPlace()

  19. GetViewportStationMiddle() <- linkgraph_gui.cpp GetStationMiddle()
  20. CmdScrollViewport(): Scroll players main viewport.
  21. SetViewportCatchmentStation():
  22. SetViewportCatchmentTown(): Town’s coverage set dirty

----init----

  1. InitializeSpriteSorter() <- openttd.cpp main()
  2. InitializeWindowViewport() <- widget.cpp NWidgetViewport::InitializeViewport()

    : 很多 gui 建立新視窗的時候調用

----private----

  1. MarkCatchmentTilesDirty() <- SetViewportCatchmentStation()
  2. CalcRaildirsDrawstyle() <- VpSelectTilesWithMethod()

    : while dragging

  3. DoSetViewportPosition() <- SetViewportPosition()
  4. SetViewportPosition() <- UpdateViewportPosition()

    *5. TranslateXYToTileCoord() <- GetTileFromScreenXY() & CheckClickOnLandscape()

    : Translate screen coordinate in a viewport to underlying tile coordinate.

    : x,y的坐标轉換為3D的透視圖,調用 landscape.cpp InverseRemapCoords2() 完成轉換

  5. GetTileFromScreenXY() <- GetTileBelowCursor() & GetTileZoomCenterWindow()

    : When used for zooming, check area below current coordinates (x,y)

  6. AddTileSpriteToDraw() <- DrawGroundSpriteAt() & DrawSelectionSprite()

    : Schedules a tile sprite for drawing.

  7. AddChildSpriteToFoundation() <- DrawGroundSpriteAt() & DrawSelectionSprite()

    : Adds a child sprite to the active foundation.

  8. AddCombinedSprite() <- AddSortableSpriteToDraw()

    : Draw a (transparent) sprite at given coordinates with a given bounding box.

  9. AddStringToDraw() <- ViewportAddString()
  10. ViewportSortParentSprites() <- InitializeSpriteSorter()

    ------下面這一堆函數都被ViewportDoDraw()調用

  11. ViewportAddLandscape() <- ViewportDoDraw()
  12. ViewportDrawTileSprites() <- ViewportDoDraw()
  13. ViewportDrawParentSprites() <- ViewportDoDraw()
  14. ViewportDrawBoundingBoxes() <- ViewportDoDraw()
  15. ViewportDrawDirtyBlocks() <- ViewportDoDraw()

    : Draw/colour the blocks that have been redrawn.

  16. ViewportDrawStrings() <- ViewportDoDraw()

    ------上面這一堆函數都被ViewportDoDraw()調用

  17. ClampViewportToMap() <- UpdateViewportPosition()

    : Ensure that a given viewport has a valid scroll position.

  18. SetSelectionTilesDirty() <- SetSelectionRed() & UpdateTileSelection() & SetObjectToPlace()

    : Marks the selected tiles as dirty.

  19. UpdateViewportPosition() <- window.cpp UpdateWindows()

    : Update the viewport position being displayed.

  20. CheckClickOnViewportSign() <- HandleViewportClicked()

    : Check whether any viewport sign was clicked, and dispatch the click.

  21. CheckClickOnLandscape() <- HandleViewportClicked()
  22. PlaceObject() <- HandleViewportClicked()
  23. HandleViewportClicked() <- window.cpp MouseLoop()

    : 點選滑鼠左鍵的事件響應

  24. ViewportDraw() <- Window::DrawViewport()

    : Draw the viewport of this window.

  25. RebuildViewportOverlay() <- ScrollWindowTo()

    : 區域 SetDirty()

繼續閱讀