Choosing SkiaControls to display a game that is mainly a "Game Level" map plus HUD overlay with interactive elements. #90
Replies: 9 comments 20 replies
-
Hey, Way 1. Reuse your existing rendering code to go along with drawnui HUD and other layout stuff. This is easy, just need to create a custom SkiaControl-subclassed control that would wrap your existing rendering logic. Examples of that are:
Here we have an existing code that was using SkiaSharp that integrates into drawnui layout system with minimal effort. Way 2. Create an optimized drawnui game with custom controls appropriate for a specific game. Actually thinking of the following:
Sandbox_yCQH7mUbIS.webmIt supports also zooming (gestures and mousewheel) and we know that canvas works fine with keyboard for desktop. When using a preview skiasharp3 version you can already have hardware acceleration for WinUI, it makes a huge difference if you need Windows.
Didn't totally catch if you had an existing code already or building from zero.. I you have existing code you could start with path Nb1 for a fast proof of concept. Then when you could spend more time optimizing on the path Nb2. So in path nb 1: can take spasehooter code, delete content inside the canvas and place a custom control wrapper for the existing code. Could help with the wrapper np. For the path nb 2: Almost same, just instead of the wrapper would come: <draw:Canvas>
<game:MauiGame>
<skiascroll>
<myworld/>
</skiascroll>
<myhudwhatever/>
</game:MauiGame>
</draw:Canvas> That A very important point is that drawnui already comes with a caching system, that has to be used for scrolling to be smooth while content is animated and avoid using usual gavedev tech like "save background" "blit", "restore background" "blit elsewhere".. Might have not much time this month, but still could help: only use-cases make this engine develop and get rid of bugs so I'll follow :) |
Beta Was this translation helpful? Give feedback.
-
Way 1 sounds like what I had in mind to start. Benefits I seek ASAP:
FUTURE: I see how to do infinite map scrolling using a single bitmap. Ignore below description; I just don't want to delete it completely:
|
Beta Was this translation helpful? Give feedback.
-
Hey,
Normally if you override a skiacontrol in a usual way your drawing logic must reside inside the |
Beta Was this translation helpful? Give feedback.
-
I have mentioned a couple of examples of wrappers for maps and skiagraphs, look how its basically done:
example maps:
and example 2:
So for your case the wrapper might look similar for your own game code drawing over drawnui canvas |
Beta Was this translation helpful? Give feedback.
-
Draw is framework-tenchnical if i may say, used for creating deeply customized controls, while Paint (called by Draw) is acting purely for the drawing logic, "paint and forget", its result will be cached, transformed (and more) by the engine. |
Beta Was this translation helpful? Give feedback.
-
Yeah basically speaking inside Draw you have the caching and transform system, so controls that want to change cache themself etc would need to override this, while the total majority of custom control, like labels, images just override Paint. An example of Draw override, SkiaDecoratedGrid (subclassed SkiaLayout Type=Grid):
|
Beta Was this translation helpful? Give feedback.
-
What is the correct way to dynamically tell SkiaScroll how big my content is? It is larger than the viewport. Equivalent of setting The map size will vary. So is not known until after game is initialized. UPDATE I have UPDATE #2 Never mind - MyWorld.DrawUsingRenderObject results in call to Measure. |
Beta Was this translation helpful? Give feedback.
-
I made good progress in using DrawnUI. My game runs steadily at 30 fps now. On a good pc, without hardware acceleration. Watching the really dumb AI play itself. Can scroll around wildly. Zoom in, scroll some more. Zoom out, see the whole game level. While the AI plays. Cached the base map, which is stable. Everything overlaid on the map, that could change or move, rendering only for tiles that are visible. I have an Not currently being smart about how many tiles are needed. I pre-allocate them to cover the entire game map. Improve that later. I do know which ones are visible, so will be easy to fix. And from what you've said about improvements coming, this should work well even on weaker devices. I won't put any more into performance until much later in development. I removed my MAUi widget panel to avoid interfering with performance. Next, I do what I came to DrawnUI for: implement HUD layer with DrawnUI controls. |
Beta Was this translation helpful? Give feedback.
-
Hey sounds godly, glad to hear about the progress! |
Beta Was this translation helpful? Give feedback.
-
Most of game takes place on a Bird's-Eye View scrollable and zoomable map. Orthographic "Fake 3D" composed of many small images.
Most user actions are by touching something on the map.
But also, along the bottom, top, and sometimes popping in from corners or edges, are various interactive UI. Think "HUD overlay".
These interactive widgets I currently draw with Maui (all in c# markup - no XAML).
I decided to eliminate the use of Maui rendering; do everything in SkiaSharp.
I didn't want to reinvent the wheel; searched for SkiaSharp-based interactive widgets.
I found nothing even remotely decent. Until I saw the youtube of DrawnUI.
This is way more than I dreamed of. Simply Awesome.
I have a rough idea of how to architect this in DrawnUI. Seeking feedback.
Think of the map as tile-based, though the tiles overlap, and are not on a rectangular grid.
The map will be a custom control. Most of the game logic revolves around user touching somewhere on the map, resulting in feedback directly on the map, followed by movement of player-controlled units (game pieces) and AI-controlled units.
In addition to these units, there are many small features that are part of the map world, that may appear or disappear.
I'll treat both the units and the changeable features as sprites.
There may be hundreds of small sprites on the map. Most of the time, most will not be moving. But sometimes there are many moving at once. Movement is slow; sprites are generally just moving from one tile to the next, or perhaps battling at edge between two tile-centers. Or appearing/disappearing with some animation.
For performance, I plan to "snapshot" sprites that rarely appear/move/disappear, along with the dynamically composed map behind them.
Moving sprites may need to visually move behind snapshotted sprites; because many sprites might move at same time, I'll likely just redraw any snapshotted sprites that overlap any of the moving sprites.
The back-to-front rendering while sprites are moving is:
If HUD blocks anything user wants to see, they can pan the map a bit.
Primary target: lightweight tablet.
But I'll make it work everywhere else also. Thus, .Net 8+ as platform.
SkiaSharp, to "render everywhere".
Maximizing battery life is important.
But maximizing developer productivity, and minimizing time to market, are more important.
After spending a day looking at code and demos, this is my best guess at how to structure this:
Some questions:
draw:Canvas
element? Or is that handled by some other DrawnUI class? In my previous approach, I have anSKCanvasView
for Skia PaintSurface and Touch.MyGameMap
, which is my screen-filling custom control, be aSkiaControl
,SkiaLayout
, or something else?MyGame : MauiGame
andMyGameMap
. CurrentlyMyGame
is an invisible wrapper, to hold theActionOnTickAnimator
andGameLoop
-related stuff. Should I try to minimize the number of levels in the hierarchy, incorporate that into MyGameMap somehow?All feedback and suggestions welcome :)
Beta Was this translation helpful? Give feedback.
All reactions