Showing posts with label tutorial. Show all posts
Showing posts with label tutorial. Show all posts

Monday, 20 May 2019

Easy Maths: Vectors

Hello there!

Today's blog is about maths, more specifically - the rather interesting side of it and what I have learned. Keep in mind that I am not an expert in the subject, so any kind of criticism is more than welcome. With that being said, let's get into the maths.

Preface

This post will cover the topic of vectors, a topic I really enjoy since I use it a lot in game development. I will show you what they are, how they can be used to draw shapes, finding out the length of them and why multiplying them together gives pretty cool results.

How to think of Vectors

I tend to think of vectors as a point in space away from the centre, think of a line that goes from the centre to that specific point. In terms of adding vectors, you could think of it as taking one string and adding it to the position at the end of the string. Or you could just quite literally add the two x's and y's together. Subtracting the two is quite self-explanatory. That is it. They are just points in space.





The power of Pythagoras'

Anyone who has ever heard of that maths question where you need to find the hypotenuse of a triangle, has probably heard of the term Pythagoras' theorem (or the 'Pythagorean theorem' if you have lived in the United States). The way they do it in school is so impractical and shoe-horned that it would put anyone off the whole thing, couldn't one just use a ruler to measure the hypotenuse? Not all triangles are right angled in the real world, in fact very few of them are.

With that being said, it can be very useful in terms of finding the magnitude of a vector (length of the vector), you plug in the X and the Y (if either are negative, make them positive) into Pythagoras' theorem and you have your magnitude!
Now that we have established that, I'll introduce you to another type of vector which is a unit vector, it has a magnitude of 1 and is useful for wanting to move in a certain direction. The way that this is calculated is by dividing both x and y by the magnitude of the non-unit vector. The result is that the two points would either be no more less than -1 or 1.

If you tested this in a game however, the movement speed would be very slow, therefore you would need to multiply it by a single number i.e. (0.5, 0.9) x 20 = (10, 18).

Geometry

Vectors can also be used to make shapes that have vertices, a good example is a triangle or a polygon. More complex examples can include 3d shapes where each vertex is a point that has variables x,y and z. The way that you can turn a bunch of points into a shape is by drawing a line from one point to another much like those drawing books which have you connecting the dots together. You can scale these if you want by multiplying the vectors by one number (similar to increasing the speed of movement). Multiplying a vector by another vector is not what I mean here, but would nicely lead into the next section.

Dot product


When I first heard of this, it was a seemingly simple idea, multiply 2 vectors together.
The formula for this is:
(X1 x X2) + (Y1 x Y2) = Dot product of V1 and V2. 

It doesn't seem too practical. How can I ever use that for anything useful? That kind of thinking is very mistaken, namely because it can be used for a lot like collision detection. A good analogy I came up with is a rod. A pretty long one, in fact one that stretches to infinity in both negative and positive direction. The direction of the rod is determined by a directional vector, ideally a unit vector, since it is very easy to measure. And there are points around it.




Here's where the interesting stuff comes in, imagine that the points fire lasers perpendicular to the rod and they are so hot it leaves a mark on the rod. To make things simpler, lets rotate this whole rod (along with the points) so they all sit in a line.
Let's get rid of the lasers and just focus on the rod.
All that is there is a rod and the red marks. The very useful thing about this is that you can compare where the 'lasers' are relative to that point using these red marks. You could use this to project a shadow from a shape to the rod using said shapes' vertices.




Conclusion

Vectors are pretty cool in my opinion, in fact they are one of my favorite parts of maths (that was, after I stopped doing compulsory maths and actually learned it 'on my own'), it makes me think about how objects are moved or what causes them to move in the first place.
Even if you never use it, just remember that you can at least view the world in a more interesting way if you know vectors.
That's all from me!

Sunday, 14 April 2019

How to save and load levels

Hello there!
This blog will be about one of the most important aspects of a game's architecture, or perhaps even any kind of system (beyond gaming): loading an managing data i.e. levels!

Preface

If you've ever programmed any kind of system which manages and loads data, you may have at some point tried to figure out how to load the data from somewhere that isn't the program. Say you are making a program where you are trying to find the price of a book, you have programmed functions for adding to cart, checking the price etc, but now you need to actually have the data there. The first thing you would do is fill the data by hard-coding a bunch of values and pushing them into something like a list and run the program to see if you can check things or add them to the cart. Then once this all works neatly you would probably wonder "Hmm... how can I add items without hard-coding them in to the program"

This may not seem related to gaming at first, but it's more similar than you think.


The magic of binary

I've been dabbling around with the 65c186 assembly which was used to program Super Nintendo games (sadly I've only gone as far to make a single coloured background as of writing this). I did wonder how they included level files, did they write some kind of asset packing program to store everything into the game? Was everything all hard-coded into the game? Did the game have to access resources from outside?
It turns out that the assembly language (and other assemblers too) had a secret weapon called ".incbin". This made the question of writing asset packing programs or loading things from outside completely moot. The reason why is that the assembler did the asset packing itself, specifically when it compiles everything into one read-only memory image (basically the whole game itself). It all gets packed into one space, which makes it easy to load everything into the game, since it already has pointers to certain bits of memory like levels.
The memory is stored as a bunch of characters which may mean gibberish on first glance, but if you know what you are doing, then you will know exactly what they mean. The SNES game "Legend of Zelda: A link to the past" has a clever way of loading dialogue: instead of loading each individual word, it checks a single character and writes a combination of words based on it, for example a character with the hexadecimal value DE is "with" and E3 "you". When combined together you could write "With you" with almost a quarter of the characters needed to even write these words!

Know your files

However in something like a higher level language like C# this is more difficult. For example in Unity, you can't just have all your game in a single .exe file. There are other things that will be alongside the exe file. These may be things that Unity require to run, the part that is most relevant to this post is a strange file named "assets", this pretty much stores all the game's objects and files. Thankfully this is done when you build the game so you don't need to worry too much about it. But the difficult thing about this is that you need to tell the program where the file is and how to convert it into something that can be read, again Unity does this for you so need not worry.

Actually saving the data

What should one save data into? There are multiple answers to this question, there is the aforementioned binary conversion. One way is making an interpreter that turns level data into a text file and making a custom parser, one game of mine I'm working on at the moment uses this method. For reasons explained later, the interpreter would write the text "level:", following a series of characters. As it goes through every single object in the level, it writes to a text file each character at a time. Each character represents a different object. I also store data for the timer which writes the string "data:" right before it shows the time to set the timer. Information about the custom parser will be explained later on in this post.
Or you could use a JSON converter (Unity has this built-in to the program) which does all this work for you. First you would need to write some data structures to tell which object/data is which so you can use them later on to load into a level. You would then need to gather all the data from all of the objects so they can fill in these data structures with things like positions, type and the such like. Unity would then get to work converting all of that into a single JSON text file. Unity compiles this JSON file into that 'assets' file I was mentioning about when you build the game (turn it into an EXE file) so the engine knows where to find the file.

Unloading the data cargo

So now you've come up with a way to save data, now we need to unload it. Firstly we would need to make a content loader which checks to see any level files we have saved. Then we unload the files from binary into something we can read. Perhaps it could be a JSON file, we could write a system to convert from JSON into whatever format it was. Like how Unity has a way to convert data structures into JSON files, it can do the reverse. So we convert a text file into data that can be loaded. Great. So now what?
We would need to read from the data itself and arrange everything together based on what it says. For example if there was a list of tile data from the JSON file, we would iterate through all of them and create new tiles based on these data structures.
Or if you are writing your own custom parser, it would be a bit trickier. You would need to write a state machine so the loader would know what it is doing. For example I mentioned writing "level:" and "data:" somewhere in the text file. This is not just for show, this is so that the parser can know what section they are doing, for example when it encounters the "data:" string, it realizes "I'm now going to read the next 3 characters and convert them into an integer" so it reads for instance "015" and converts that into an integer. Before that though it would encounter the "level:" string and then would know that it is now converting every character it comes across into a block depending on which character it is.

Conclusion

Data loading is not something you would think about when making something like a game, but it is absolutely necessary (if you want to make something that can be saved, loaded and modified. There are plenty of ways to save and load data which makes it a pretty interesting topic, there are also ways to crunch and compress the way that data is loaded like the Legend of Zelda example.
That's all from me!

Monday, 11 March 2019

Easy maths: Sin and Cosine

Hello there!

Today's blog is about maths, more specifically - the rather interesting side of it and what I have learned. Keep in mind that I am not an expert in the subject, so any kind of criticism is more than welcome. With that being said, let's get into the maths.

Preface

Sin and Cosine are the concepts you may have first heard when you were being taught how to find a certain side/angle of a triangle. The phrase "SOHCAHTOA" often tends to pop up, and a lot of the questions you were given you just had to use this formula to answer them. As well as explaining what this phrase means, I'll also explain why you use this to find sides ,something your maths teacher probably never explained.

Relations with the Axis

Sine = X and Cosine = Y. I've pretty much told you the answer right there. So, next section....
Actually, I jest.
Look at the triangle below:
It has the hypotenuse, adjacent and opposite side labeled for your convenience, so you don't need to crack open your maths book.

If we want to find, for example the adjacent, we will need to use SOH (Sine, Opposite and Hypotenuse). Why?  Because the adjacent is a horizontal line, and Sine is used for working them out (think: the X axis).
Now, we're not going to do a maths question, so don't panic. I'm just telling you a theoretical example. Anyway, Sine is the thing you would use to work out the horizontal parts of the triangle. As you can imagine you would need Cosine for the Vertical axis (or the opposite in this case), therefore you need to use CAH. I'm not going to talk about TOA because I'm not talking about Tangents in this blog, only Sine and Cosine. But hopefully I've made your maths homework a bit easier. Sin for finding out the horizontal side and Cosine for finding the vertical side.

Okay, at this point in time, you may wonder "Right, I know that Sine is used to work out the horizontal and Cosine for the vertical, but why? What is the relationship between these?"
I'll tell you in the next section.

Angles to Vectors

You may have also encountered angles at some point in your maths career, the things you use a protractor to measure or what you have to figure out in a triangle, on the opposite of the right angle, (using Sine and Cosine). I'll tell you why:
As you can see, in Desmos this is what Sine (Red) and Cosine (Blue) looks like in a graph. It produces quite a wavy pattern, which looks quite nice. This wavy pattern is far more than just a beautiful little pattern, it also shows how Sine and Cosine functions, in the graph, Cosine is a little bit more delayed than Sine in terms of reaching its top and bottom, but by how much exactly, and why?
If you look below at the two diagrams, the top point is 1 and the lowest is -1, the more interesting point is the horizontal point, which is half of PI (3.142...). If you multiply this by 57.672 (to convert radians to degrees), you get a number which is ~90. Sounding familiar?


If you quadruple 90 you get 360, which a full circle is 360 degrees (or 2 PI radians). The relation of this to Sine and Cosine is that the distance that they are apart is equivalent to a quarter of a circle. I'll demonstrate what I mean below:
Make sure the setting is in degrees rather than radians.

As shown, B is 90 and the point on the circle is where 90 degrees would be going, and the number '1' is shown again, much like the previous diagrams. The reason that Sine is used for horizontals and Cosine being used for Verticals is shown in the example, due to the aforementioned separation by half a PI. If we swapped Sine for Cosine, then the point would be on the top rather than the right side and that wouldn't look like 90 degrees. Since these two operate in a wavy pattern where the highest value of Sine and Cosine is 1 and the lowest is -1, they can be a useful way of converting angles into a unit Vector. I hope you are starting to see how Cosine and Sin can be used to be turned into vectors.

This is especially handy if you want to simulate rotations via having degrees rather than vectors. 

Conclusion

This is my first time explaining mathematics to you, and I feel a bit nervous doing so, since I don't really have much of a formal background in the subject beyond GCSE. But as I've stated before I welcome any form of criticism.
Sine and Cosine are quite useful things, probably more than you thought - it can be used for things like converting angles into vectors, rotating matrices (which I know the barebones of), items that bob up and down in Minecraft or even chiptune music (stuff you would hear on old game consoles like the Gameboy).

That's all from me!

Saturday, 9 February 2019

How to make pixel-perfect graphics

Hello there!

I have been dabbling around with JavaScript on and off for a year and a half; it was not until mid-December where I decided to start development on a game using the language. I've briefly mentioned about it in my other blog posts but never really went into depth about it; I want to keep it that way until it's release (~20th February), but I will tell you that it is a game much like Prelude of the Chambered (minus the 3d and violence).

The great thing that I've learned from making this game is how to create a custom engine and way of processing logic and rendering images to the screen and the such like. I did all of this without having to use C++; although I'd still love to make a custom engine in that language, I don't think I have the experience to make a fully-fledged game engine in such a language.

What I'll be talking about here is how I've managed to create pixel-perfect graphics within the engine I've created in JavaScript.

Preface

What do I mean by Pixel-perfect graphics?
By that I mean having pixel graphics where every singe pixel is in a consistent order, like a series of tiles, with the same width, height. Usually when it comes to increasing the screen resolution, you need to make the sprites, the world and the graphic user interface bigger so that the player can see more. Many would take the approach of increasing the size everything and increasing the width and height of which the images are drawn. However this approach would produce results like this:

Not too pretty.
You can see here that the pixels of the characters are not in line with each other, there are pixels that partially overlap with other pixels. There is not much depth in that at all, perhaps if this were a game which had less pixel-based graphics like vectors, then that would be completely fine because everything else has vector graphics. But here, the cohesiveness fails miserably. You need not worry though, I have found a solution to this problem.

Drawing with mosaic

I'm pretty sure you may have seen mosaic art before, that art where each tile is placed in a square pattern. Trying to make the world seem bigger would be like trying to put a mosaic art that consist of 3cm tiles into mosaic art that consists of 1cm tiles. This may be fine if the size of the image is being resized for certain effects like this (the map below the 3 characters is being resized to give the illusion of height). However, if you are trying to make the screen resolution larger, trying to resize the images like this would lead to ugly effects like the picture below. 
The character outlines in magenta resemble the size of each pixel.


Rather than trying to force a mosaic image consisting of 3cm tiles on to a pattern of 1cm tiles, how about we shrink the tiles of that image into 1cm tiles and fit it onto the rest of the art. It doesn't have to be 3cm, it could be 7cm or 13cm or even 50cm! It dosen't matter! You can reduce them to 1cm tiles and fit them in.

Real space vs Visual space

Now that I have spent an entire point rambling about mosaic tiles, but now lets put it into practice with pixels. Say we want to put an 32x15 pixel image on to a 150x95 world, but we want to increase the size of the world so the player can see it better.

What I have learned from programming my JavaScript game is that you do not change the world or the objects' real size and position. It's a better idea to keep the two variables constant, I just mentioned the term 'real' size/position - by this I mean that the objects' size relative to the tiny pixels rather than relative to the player's eyes. Instead, you'll need to change the size at which both are being rendered, if you scale the aforementioned object and the world by 3 you will get a 96x75 image. A similar example can be seen below.



Unlike the last image of Bounty Hunter I where the pixel characters look inconsistent when they move, when you move the player in this scenario, all the pixels will be aligned or 'snapped' in place in respect to the real position of the player. The reason this is that, as I said before, despite the render size being changed, the player's real size and position stays the same as if it were if it was a 32x15 pixel image rather than a 96x75. 

With this you can have pixel graphics in a video game where they look all cohesive, much like graphics on a SNES, PS1 or a hand held console, where all pixels are displayed in a consistent manner.

Lower level graphics

If you are making a game where you have control over where the pixels are drawn, that would be even easier because you can just state how large each pixel would be and draw the character in real space and let the engine calculate the character/object's exact pixel size on the screen.

This kind of thing would be useful if you are making a render engine in something like C++, where you do not have to work around any shenanigans that a 3rd party engine may have.

Conclusion

This has been a problem that I've been consistently seeing with pixel games nowadays, and there are rarely any tutorials on these kinds of things. The tutorials I've been seeing on topics like these show things that are way too unnessacarily complicated and conboluted. I'm not sure if this is the completely right way, but I think it works. If that is not the case then please let me know and explain your soloution in the comments.

Through what I have explored here, I would like to help others encountering the same or a similar problem and mention that it does not need to be complicated as it seems. I hope this has been useful to you and will allow you to have pixel graphics that do not look messy and unordered.

That's all from me!