22 Jun 2019 @ 8:34 AM 

For some time now, I’ve occasionally created a relatively simple game and typically I’m not bothered to get into fancy “game engines” or using special rendering. usually I just have a Windows Form Application, a Game loop, and paint routines working with the System.Drawing.Graphics canvas. “BASeTris”, a Tetris clone, was my latest effort using this technique.

While much maligned, it is indeed possible to make that work and maintain fairly high framerates; one has to be careful what and when things get drawn, and eliminate unnecessary operations. By way of example, within my Tetris implementation, the blocks that are “set” on the field are drawn onto a separate bitmap only when they change; For the main paint routine, that bitmap get’s drawn in one go, instead of individually drawing each block, which involves bitmap scaling and such each time. Effectively I attack the problem by using separate “layers” which get rendered to individually and then those layers are painted unscaled each “frame”.

Nonetheless, it is a rather outdated approach. Because of that I decided I’d give SkiaSharp a go. SkiaSharp is a cross-platform implementation that is a wrapper around the Skia Graphics Library. This is used in many programs, such as Google Chrome. For the most part, the featureset is very similar conceptually to GDI+, though it tends to be more powerful, reliable, and, of course, portable, since it runs across different systems as well as other languages. It’s also hardware accelerated which is a nice-to-have.

The first problem, of course, was that much of the project was tightly coupled to GDI+. For example, elements that appear within the game will typically have a routine to Perform a Frame of animation and a routine that is capable of drawing to a System.Drawing.Graphics. Now, it would be possible to amend the interface such that there is an added Draw routine for each implementation, But this would clog up a lot of the internals of the logic classes.

Render Providers

I hit upon the idea, which is obviously not original, to separate the rendering logic into separate classes. I came up with this basic interface for those definitions:

The idea being that implementations would implement the appropriate generic interface for the class they can draw, the “Canvas” object they are able to draw onto (the target) and additional information which can vary based on said implementation. I also expanded things to create an interface specific to “Game States”; The game, of course, would be in one state at a time, which is represented by an abstract class implementation for the Menu, the gameplay itself, the pause screen, as well as the pause transitions and so on.

Even at this point I can already observe many issues with the design. The biggest one is that all the details of drawing each object and each state would effectively need to be duplicated. The alternative it seems would be to construct a “wrapper” that is for example able to handle various operations, in a generic but still powerful way, to paint on both SKCanvas as well as System.Drawing.Graphics. I’ve decided against this approach because realistically once a SkiaSharp implementation is working, GDI+ is pretty much just legacy stuff that I could arguably remove altogether anyway. Furthermore, that sort of abstraction would prevent or at least make more difficult utilization of features specific to one implementation or another within the client code doing the drawing, and would just mean that now the drawing logic is coupled to whatever abstraction I created.

There is still the problem of Game Elements using data types such as PointF or RectangleF and so forth, and particularly Image and Bitmap to represent positions, bounds, and loaded images, so I suspect things outside the game “engine” will require modification, but it has provided a scaffolding upon which I can build the new implementations. Seeing working code, I find, tends to motivate further changes. Sort of a tame form of Test Driven Development, I suppose.

I have managed to implement some basic handlers so hopefully I can get a SkiaSharp implementation utilizing a SKControl as the drawing surface sorted out. I decided to implement this stuff before for example trying to create a title screen menu because that would be yet another state and drawing code I’d need to port over.

Some of the direct translations were interesting. They also gave peripheral exposure to what looks like very powerful features that are available in SkiaSharp that would give a lot of power in terms of drawing special effects compared to GDI+. For example, using BlendFilters, it appears it would be fairly straightforward to apply a blur effect to the play field while the game is paused, which I think would look pretty cool.

Posted By: BC_Programming
Last Edit: 22 Jun 2019 @ 08:40 AM

EmailPermalinkComments (0)
Tags
Tags: , ,
Categories: .NET, C#, Programming
 03 Jun 2017 @ 3:00 AM 

One of the fun parts of personal projects is, well, you can do whatever you want. Come up with a silly or even dumb idea and you can implement it if you want. That is effectively how I’ve approached BASeBlock. Iit’s sort of depressing to play- held back by older technologies like WindowsForms and GDI+, and higher resolution screens make it look quite awful too. Even so, when I fire it up I can’t help but be happy with what I did. Anyway, I had a lot of pretty crazy ideas for things to add into BASeBlock, some fit and were even rather fun to play- like adding a “Snake” boss that was effectively made out of bricks- others were sort of- well, strange, like my Pac man boss which attempts to eat the ball. At some point, I decided that the paddle being able to shoot lightning Palpatine-style wasn’t totally ridiculous.

Which naturally led to the question- how can we implement lightning in a way that sort of kind of looks believable in a mostly low-resolution way such that if you squint at the right angle you go “yeah I can sort of see that possible being lightning?” For that, I basically considered the recursive “tree drawing” concept. One of the common examples of recursionm is drawing a tree; f irst you draw the trunk, then you draw some branches coming out of the trunk, and then branches from those branches, and so on. For lightning, I adopted the same idea. The eesential algorithm I came up with was thus:

  1. From the starting point, Draw a line in the specified direction in that direction at the specified “velocity”
  2. From that end point, choose a random number of forks. For each fork, pick an angle up to 45 degrees of difference from the angle between the starting point and the second point, and take the specified velocity and randomly add or subtract up to a maximum of 25% of it.
  3. If any of the generated forks now have a velocity of 0 or less, ignore them
  4. otherwise, recursively call this same routine and start another “lightning” from this position at the specified velocity from the fork position.
  5. Proceed until there are no forks to draw or a specified maximum number of recursions has been reached

of course as I mentioned this is a very crude approximation; lightning doesn’t just randomly strike and stop short of the ground and this doesn’t really seek out a path to ground or anything along those lines. Again, crude approximation to at least mimic lightning. The result in BASeBlock looked something like this:

BB_lightning

Now, there are a number of other details in the actual implementation- first it is written against the game engine so it “draws” using the game’s particle system, and also uses other engine features to for example stop short on blocks and do “damage” to blocks that are impacted, and there are short delays between each fork (which again is totally not how lightning works but I’m taking creative license). The result does look far more like a tree when you look at it but the animation and how quickly it disappears (paired with the sound effect) is enough, I think, to at least make it “passably” lightning.

But All this talk, and no code, huh? Well, since this starts from the somewhat typical “Draw a shrub” concept applied recursively and with some randomization, let’s just build that- the rest, as they say, will come on their own. And by that, I suppose they mean you can adjust and tweak it as needed until it gets the desired effect. Or maybe you want to draw a shrubbery, I’m not judging. With that in mind here’s a quick little method that does this against a GDI+ Graphics object. Why a GDI+ Graphics Object? Well, there isn’t really any other way of doing standard Bitmap drawing on a Canvas type object as far as I know. Also as usual I just sort of threw this together so I didn’t have time to paint it and it might not be to scale or whatever.

What amazing beautiful output do we get from this? Whatever this is supposed to be:

bluetree

It does sort of look like a shrubbery I suppose. I mean, aside from it being blue, that is. It looks nothing like lightning, mind you. Though in my defense if electricity tunnels through certain things it often leaves tree-like patterns like this. Yeah, so it’s totally electricity related.

 

This is all rather unfulfilling, so as a bonus- how about making lightning in Photoshop:

 

Step 1: Start with a Gradient like so

Next, Apply the “Difference Clouds” filter with White and Black selected as Main and Secondary Colours.

Invert the image colours, then Adjust the levels to get a more pronounced “Beam” as shown.

Finally, add a layer on top and use the Overlay filter to add a vibrant hue- Yellow, Red, Orange, Pink, whatever. I’m not your mom. I made it cyan for some reason here.

Posted By: BC_Programming
Last Edit: 03 Jun 2017 @ 03:00 AM

EmailPermalinkComments Off on Faking “Lightning” in a 2-D game
Tags
Tags: , , ,
Categories: .NET, C#, Programming

 Last 50 Posts
 Back
Change Theme...
  • Users » 47469
  • Posts/Pages » 391
  • Comments » 105

PP



    No Child Pages.

Windows optimization tips



    No Child Pages.

Soft. Picks



    No Child Pages.

VS Fixes



    No Child Pages.

PC Build 1: “FASTLORD”



    No Child Pages.