[STEEM ROGUE LIKE]: Developing a Rogue Like using Unity and Free Assets [004]

in #freeroguelike6 years ago (edited)

This is a continuation of a tutorial that began in post [001]. The post before this one [003] gives you an indication of what this present tutorial post will be about. It will be heavy code/scripting. It will not be for the faint of heart. I will post images of code in segments and will talk about it as I think of additional things I may feel worthy of sharing.

SteemRogueLikeData

We now need to create a script called SteemRogueLikeData it will contain enumerators and structures for data types that the other scripts will use. It will not have a class and none of it will actually be executable itself.

The initial part will link to the necessary using (includes, libraries) as usual. Here we will define three enumerators.

The RL_SPRITE_TYPE is the type of sprite which was explained in some detail in the past two posts.

The RL_SPRITE_DRAW_METHOD is the method used to display these sprites. I also explain these in the previous post.

The third is RL_TILE_VISIBILITY_BITS and it is something I plan to use in the future, but actually has no useful implementation at this point.

We define two different structs here. I have a lot of the elements as private and accessed through methods though that may not be completely necessary. It is easier to tweak a method later than it is to retrofit a bunch of other scripts to use a method after the fact. It is also easier to setup some of the things I'd like to be read only some of the time, but not all of the time.

RL_TILE_DEF is where we define the actual details about a tile. It can support an arbitrary number of sprite identifiers and is used to make instances of sprite based tiles. Think of this sort of like a Prefab for our Rogue Like.

RL_TILE_INSTANCE is used to represent specific occurrences of the previously defined sprites above. In unity terms RL_TILE_DEF is like the Prefab, and RL_TILE_INSTANCE is what you get when you instantiate a tile.

You may be wondering why I use ushorts and bytes? You are welcome to make them all ints if you prefer, I am just aiming for small memory footprints where possible. I find it easier to optimize for low foot print at the beginning than it is to decide to optimize for that after the fact. Old habits. I started programming on 2K RAM computers and then for years was coding on 64K RAM computers so making careful use of space became a practice since way back then.

There is one draw back to the ushort for the Tile Definition number. This means we are limited to just over 65000 unique tile definitions. I thought that was likely sufficient. If you think you need more then consider replacing it with an int or uint.

The interesting thing about the RL_TILE_DEF is I designed it's constructor to accept an input string which you use to pass the definition data. It can be easily human readable from a file, a string array, or whatever.

I explain the parameters and what they are for in the previous post.

RLSprites

We created the RLSprites script initially in post [002]. We now are going to extend it by a little bit. It is a small but important script. I essentially consider this the heart of the process. I picture it much like a library. Though it is possible to have more than one library. You do an internal, and external, etc and have it so only certain sprites are in certain libraries or you could have a big single version.

It has a spot for putting string definitions of tiles as used to construct RL_TILE_DEF. It now also has a Start() method which is instructed to process those definitions.

SteemRogueLikeTile


This a simple script with a specific purpose in giving us ways to cache SpriteRenderer handles and be able to access specific sprites and objects on a tile by tile basis as a GameObject. This will be attached to prefabs that are instantiated.

SteemRogueLikeLevel


This is a large and involved script. It takes all of the above scripts and provides all the tools we need to instantiate maps with both animated and not animated sprites. It will support handling the animations in a more process efficient manner than simply using Update(). It will only be used as needed.

This provides all the tools needed to start building maps. It doesn't dictate how those maps should look, it simply provides the tools so we can do that. This one is large. It will take several screen posts to go over it.

As you can tell since everything is private and not public all interfacing and interacting with the data in this script is via the methods.

This technically is not a constructor. I had a constructor, but I needed something I could call later, so since it does a lot of similar tasks you'd expect from a constructor I called it Construct. This is the first method that should be used before trying to do anything else. It will size the arrays and setup some initial values.

These are the majority of the remaining public methods. They enable interfacing with the data above. As you can see a lot of that data is treated as read only outside of the Construct() method.

The InitializeLevel() method is something you'll want to run before going further. It also allows you to parent the map to a specific object. I'll give you an example of that in the next tutorial.

Animated tiles are maintained in a list. Rather than polling through all the tiles each frame of animation the code only looks at ones that have been flagged as animated. If they are no longer animated it will also clean up the list.

If the SetIsPaused is used to pause the game that will also pause the animating.

SetTile() is overloaded and can be referenced by a single dimensional array address if you know it, or via X,Y coordinates in the map. It allows you to set what a tile is. This will instantiate the tile, set it's appearance, launch the animator if necessary and do that manner of details.

GetTile() allows you to grab the RL_TILE_INSTANCE of a given tile.

SetDetail() allows you to set a second level of sprite on the object. Say you want to make a ground tile, but you also want an animated fountain on top of the ground. SetTile() would be used for the ground and SetDetail() for the fountain. They functionally work the same, but each focuses on a different layer.

I usually code with a little more spacing between methods. I purposefully did not in this for convenience of being able to screenshot them.

This method is the LAST thing that should be called after all tiles are set. Currently it's job is to go an enable appropriate shadow sprites in relation to the presence of walls next to floors. In the future it may be extended to handle additional visibility touch up tasks.

That is the end of the public methods for the SteemRogueLikeLevel script. Now we dive into the private methods that those methods use to accomplish their tasks.

That method does the actual work of setting the tile, activating animation, changing appearances, positioning, etc. This is the method that the SetTile() methods reach out to.

This is the method for the detail layer and it works the same as the SetTile private method before it but this one focuses on the Detail layer and it is coded a bit different in some places.

We wrap this script up with a final private method. It is actually a coroutine.

This is the actual animator for this system. I currently have it running 5 times per second. For these types of games, and the number of animation frames that is fast enough. We can play around with this later if need be.

To speed it up and slow it down you need only modify a single line.

Change the 0.2f to another value to speed it up or slow it down.

There is another script that I wrote to test all of this, but it is not critical to the system. It is just an example. I will go over it in the next post.

If you like these tutorials and would like to encourage me to continue, please up vote. I will continue to make them as long as I am interested or there is interest and up votes. Making things like this takes a considerable amount of time.

To go to the next post in this series click here [005].

Sort:  

Hi! This is jlk.news intelligent bot. I just upvoted your post based on my criteria for quality. Keep on writing nice posts on Steemit and follow me @jlkreiss to get premium world news updates round the clock! 🦄🦄🦄

that's pretty cool to know

Coin Marketplace

STEEM 0.25
TRX 0.11
JST 0.032
BTC 61041.41
ETH 2947.17
USDT 1.00
SBD 3.85