Simple projectile calculations in 2D with your own movement code

So last time we did a simple projectile calculation by using Unity’s rigid bodies by calculating velocity vector and applying a force to the projectile rigid body. Now we do the same without rigid body but doing a calculation based on updating the position manually.

Remember this was the sketch of what we have:

projectile_2d_001

For updating the position we need to know the angle, distance, amount of gravity and time of flight. We also need to calculate the velocity which we need to do other calculations. The distance as you remember from the last time we get by: d = sqrt(pow((x2 – x1)) + pow(y2 – y1)), or Vector3.Distance(start, end) or (start,end).magnitude (where start and end are Vector3 objects).

So in our example: d = 15.0, a = 66.0, g = 9.81, replacing the variables in the equation give us v = 14.0716. Now we are interested how long the projectile will stay in the air. This is because we need to interpolate the position between the start and end positions. We could use some a fixed value for time but this will create unrealistic result since the actual time spent in the air depends on the angle and distance (and gravity).

So how we get the time? You can calculate the time the projectile is airborn in two ways. Either you can use the Y component (eventually gravity pulls the projectile back to ground) or X component. If you want to use Y, the formula is time t = (velocityY * 2) / gravity. So y velocity times 2 over gravity. If you remember from the last time we used the velocity and direction to get the horizontal velocity and sin(angle) * velocity to get Y vertical velocity? We use the same method like this:


var direction = (target.transform.position - start).normalized;
var horizontal = Mathf.Cos(angle * Mathf.Deg2Rad) * velocity;
var vertical = Mathf.Sin(angle * Mathf.Deg2Rad) * velocity;

Finally we can calculate time: t = (vertical * 2) / g. So in our example it is: 2.62s This means that the projectile will stay in the air 2.62 seconds without hitting the target. So bigger the angle more velocity we need to hit the target thus longer the projectile will stay in the air. You could also use t = distance / horizontal, which by the way also gives the same 2.62. (which is a good thing!)

Ok, we have now all the components needed for our calculation. We are using Update() function which Unity will call every frame. This makes the function frame rate dependent, e.g. with 30 fps Update will get called on average by every 33.33 ms. So we know that we should get from start to the end in 2.62s. I said we need to interpolate the position based on the time. This can be done in several ways.

Unity has a Vector3.Lerp -function what is very handy what we can use e.q. Vector3 currentPos = Vector3.Lerp(start, end, time / duration); If the use this helper inside Update() -function we need to increment time variable by the difference of the previous call and Time.deltaTime is exactly for this. This way you make sure your stuff is not frame rate dependent. So a small example:

private float time = 0.0f;

private void Update()
{
time+=Time.deltaTime;
var currenPos = Vector3.Lerp(start, end, time/duration);
}

Duration you need to be calculate somewhere outside Update and start and end are positions as Vector3 type.

If you update your projectile currentPos, it will fly from start to end in given duration, but since it’s a linear interpolation between the values it do not have the projectile trajectory yet. We actually use only the x component to update the x position but we also use it to calculate y position. So how it’s calculated? We go back to the original Wikipedia page and see that height at arbitrary distance x has a formula:

height y = start.y + x * tan(angle) – (gravity * pow(x) / 2 * pow((velocity * cos(angle))))

so when in our Update() function we apply the x from current position to the formula, we have the height at distance x. The update function is going to need something more than that, for example you don’t want to update the position unless the projectile has been launched and you don’t want to update the position after time > duration. But that’s easy stuff after all this.

Neat, now you can hit the target by any angle and distance and you are doing it all by yourself! What do you think? Do you have any suggestions or improvements? Leave comments!

Falling collectible bonus on Unity, part 2: The animation

In the last post we created the asset for the animated falling collectible bonus. In case you missed the post read it first here. In this post we use the images and create an animation in Unity for the collectible.

First you need to create a folder under “Assets” in which you will have the images. I have created a folder called “Sprites” and under “Sprites” I have a “Bonus” folder. The structure is up to you but creating a organized structure will help you later when you have more than just few assets (and asset types). Copy the images you created to the Bonus folder. You can import them by using Unity too but I don’t know how to import several images at one command so for me it was easier to use the file system copy.

When files are copied go to the folder and select all the images and drag them to the scene. Dragging the images to scene causes Unity to create an animation to the same folder the images are dragged from, in my case, folder named “Bonus”. You can rename the animation i.e. bonus. At the same time Unity creates a game object with:

  • Sprite Renderer, in which one of the images selected as Sprite (I don’t know is it random or how Unity decides this?)
  • Animator, in which the controller is newly created controller in the same folder. This also seems to have a random name but you can rename it to i.e. bonus. More about the Animator here.

We are going to need also some extra components. We are going to use BoxCollider2D so that we can check if player is colliding with the bonus. Add the BoxCollider2D component to the game object and check the “Is Trigger” check box. This way the bonus only causes trigger when colliding but do not actually collide (interfere with the physics). We don’t want the bonus to bounce or anything from the other game objects. Set the X and Y size so that it matches the sprite boundaries (for me X=0,7 and Y=0,33).

We are going to need also a Rigidbody2D component. You can leave the default values for this component. If the game object do not have Rigidbody2D component it will be ignored by the physics engine. If you are not having this component you need to take care of the movement of the bonus in the scene, plus I think you need to check the collision manually. In my game I wanted the bonus to “fall” so I use gravity to move the object. Your case might be different and require other type of approach.

Now you should have an animation called bonus and controller named bonus in your bonus folder along the sprites and a game object with Sprite Rendered and Animator in which the controller is the “bonus” -controller. You should also have a BoxCollider2D and Rigidbody2D components.

We are also going to add a Script. Add component and select “New Script”, type the name i.e BonusScript and select the type CSharp. This script is going to have the code which is triggered when bonus is collected. The Rigidbody2d has a method:

void OnTriggerEnter2D(Collider2D other) {

// write your bonus handling here or send message to appropriate game object

}

If you are familiar with the tag concept you can check if the object the bonus is colliding with is a player with this type of clause:

if(other.gameObject.tag == “Player”){

}

Using gravity increases the speed of the bonus so it’s more realistic, but if you want to move the bonus object same speed all the time then you can use the following script:

void Update () {
gameObject.transform.Translate (Vector3.down * Time.deltaTime);
}

When you are done with the game object in the scene, drag it from the hierarchy to the folder where you store your prefabs and delete the game object from the scene. This way you can use the prefab to instantiate the actual bonus object in your game.

Until next time, happy coding!

Falling collectible bonus on Unity, part 1: The asset

I thought writing this down already a month ago when I was playing around with Unity and I wanted to create an animated collectible bonus which is instantiated at the certain coordinates at the screen and it starts then to fall “down” (usually Y axis). Now I will create a blog post about the whole thing so I will remember how to do it and maybe help someone else too.

Bonus itself will be a simple small block, a sort of a tile with a letter so that the player can decide if he/she wants to collect the bonus or just let it drop out of the screen. So the bonus tile looks something like this:

r001

This is a simple PNG sized 77 x 38 created with GIMP. The trickier part is the letter and the animation. I want the bonus to be without the letter at the first frame and then frame by frame the letter should be revealed from top of the block so that it will look that it’s kind of rolling down. This means that the letter rendered on the tile should be transformed just a little bit “roundy” so that it would have an illusion of 3rd dimension.

To create the letters (by using GIMP):

  1. Create a new layer of the same size as the original layer (77 x 38 in my case). Have the background as white. This is needed because when mapping the layer we don’t want it to be transparent.
  2. By using the text tool create a letter of size 24 px (size 24 looks balanced in the tile) . I will be using letter M in this example.
  3. Rotate the layer 90 degrees clockwise (layer -> transform -> rotate). We need to do this because the GIMP map object filter cannot (at least I don’t know how) map layer to horizontally aligned cylinder aka pipe.
  4. Center the rotated layer by using the alignment tool.
  5. Merge letter layer to the white background layer of the same size as original.
  6. Take the filters -> map -> map object filter up.
  7. Options: map to cylinder, create new layer check box on, transparent background off, no light. In the orientation tab: set the Z rotation to -90 degrees. This now rotates the cylinder horizontally. Leave X and Y to 0 degrees. On the Cylinder tab: images can be what ever, we don’t use them. IMPORTANT: the radius of the cylinder should be a little bigger what your layer is, mine is 0,42 pixels I presume. Check the length so that the letter looks good. (for me 0,65)
  8. Try creating the new layer and check the result. It should look somewhat normal letter M with a little bit of “rounding”, that meaning it do not look completely flat. You can delete the layer and adjust the parameters and create new if it do not look good.
  9. When the letter looks good, you need to start creating the frames. This is done by adjusting the X rotation on the Orientation tab. Start from somewhere -100. It should rotate the letter almost hidden in the top only the bottom of the letter should be visible in the top. Most of the letter is hidden behind the camera and this is why we didn’t want the transparency.
  10. Hide the original layer of the rotated letter (this is done to prevent the export render it as part of the final image)
  11. Select the created frame with the letter just barely showing on the top and select colors -> color to alpha. And select white. If done correctly now the tile and letter should be aligned correctly and look something like this: r002
  12. Export the image in PNG format and name the image something you are comfortable with. I named all my images xxx001.png, xxx002.png and so on so that the numbering is the frame order. For me the first frame was the clear one.
  13. Now increment the X rotation by 10 degrees (this depends how many frames you want to have and how big steps the letter should be rolling). Hide the layers not needed and go to step 11.

In the end of the process you have something like 22 images / frames. The result should be something like this if exported as an animated GIF:

bonus_animated

 

When this is animated so that it moves along the Y axis it looks like it’s falling and rolling at the same time. In the next post I will explain how to use this in Unity. Until next time!

Recent progress with LibGDX version of Word Slinger

I decided to rewrite my game with LibGDX to help me focus more on the actual game and features rather than splitting my time enhancing the engine AND the game.

Word Slinger consist of several screens: Menu Screen, Play Screen, Options Screen, Help Screen, High Score Screen and few extras for handling high score user input etc. Since I am new to LibGDX I thought it would be wise to start to rewrite the game from the simplest possible screen. In my mind this could have been the Help Screen. In Help Screen there’s actually just a little bit text explaining what to do in the game plus some credits and one button.

I knew there was going to be a lot of implications if I just copy & paste the classes I used with my original engine. And there was, a lot. Luckily I used a bit similar abstraction in my own game called Screen which LibGDX has but there was a plenty of things that I have thought very differently. One thing that didn’t make the Help Screen the most easiest one was the fact that I created my own Font class with font metrics and stuff. This is all neat but unfortunately there’s no easy way to use this in LibGDX. To get forward I created a temporary font with Hiero so I can have fancy font of my own.

One nice thing about the LibGDX is the Scene2d. This is a object graph for handling different “things” on the Scene (screen). These object are Actors, objects / entities that compose the Scene (with few other things). Scene2d can use Tables and other widgets for creating UI elements and help positioning the stuff on the screen. I wont go now into detail of all that, it can be read here. Nevertheless, there’s a lot of things to read and learn.

After few (plenty!) bumps and moments of frustration I have managed to create the Help Screen and part of the initial Play Screen. Here are few screenshots which look the same like I was having already last autumn. 🙂 🙂 Hopefully when I get some of the infrastructure ready things will speed up !!

 

ws_help001ws_play001

LibGDX projects

I started a new game project some time ago and now I am happy to say it has moved a bit forward. I have been very busy lately due to my other obligations (read: work) so I haven’t had the time.

My new game is going to be something a little bit different from Word Slinger. Game doesn’t have an official name yet but I have named the project Bouncy. The name might change if I come up with something better but for now it will do.

Bouncy_title_land

Bouncy will be more like a action game with a hero / heroine and some balls that are making the life difficult. How balls make life difficult? Well, if they are many, they are bouncy and will knock you unconscious, they can be!

I am not sure on what platform (desktop or mobile) the game will be released but I have selected LibGDX to be the library I will be using. There are several reasons for this. The main reason would be that I am planning to rewrite Word Slinger on LibGDX.

Yes, you read it correctly! I am ditching my own engine I created with all pain and sweat to be replaced with something more common and more easy to extend. Also I want to concentrate on the actual game not the engine 😉  LibGDX is also more flexible on platforms, it will allow me to create a desktop game along with a Android version if choose to. That way I don’t need to decide yet the platform.

I will be doing the both project at the same time, hoping they will gradually get finished eventually. No release date yet! Heheheh 😉 Stay tuned for updates!

Retrospective and statistics on Word Slinger

My game (Word Slinger) has been now for a little over three months in the Play store. It has now reached over 1000 (yes, you read correctly!) downloads. I think it’s pretty remarkable in the context what I had originally expected and hoped for.

My original goal was to learn to create an Android Game and upload it to Play store to have it available for anyone who would find it entertaining and interesting.

When I was creating the game I decided to push the goal a little bit further. I added some features like high scores, ads and eventually in app purchases. The idea was not to make money with it rather learn how to do it and _maybe_ cover some of the development expenses.

I am gonna analyze how it has succeeded so far. Here are some graphs about the progress.

Progress of downloads:

WS_installs_1Q2014

There’s nothing remarkable here really. The spikes in daily installs are due to the marketing campaigns I have run on FB.

Admob requests / clicks:

WS_admob_1Q2014

This chart boils down into few things. Clicks are very few, 62 total so far. Yes, people probably doesn’t like ads and are not clicking unless something very interesting comes up. I hope irritation (or should I say attitude?) doesn’t prevent from clicking something interesting. One thing that is not showing here is that almost all clicks are from the USA, almost 95%. Maybe the ads culture is developed further there than in EU?

It’s interesting how little revenue this creates. My game should have 1000 times more active users and if the clicks (and revenue) scale linearly then this could cover some of the costs, now it really doesn’t.

Income from the in app purchases:

WS_earnings_1Q2014

 

I have smudged the actual amounts but make no mistake about it, the total revenue is very very low. I barely got to the target of getting purchases so I could buy myself a cold beer. This is the scale of things 🙂 Nevertheless, at the start there was some action in IAP side but lately it’s next to none, like you can see it’s gone down by 75%.

This is the statistics (or some of it) for the first quarter for my game. One of the blog visitors said wisely that do games for fun, not for money. It has certain wisdom in it. Of course, by looking the numbers provided doesn’t proof anything else but having the money factor in place it causes more anxiety and maybe empty hopes.

Unfortunately I haven’t got any feedback how people like my game (or if they don’t). No feature requests or not even a single bug report. Maybe 1000 is a little too few to get to there? Anyways, inspired by the statistics I am planning to update the game and hopefully this yields more downloads and happy gamers.

Word Slinger released!!

So the day finally came. My game is released in Google Play Store. This is absolutely a great day!

Those who have been following my blog know that I am moving to France and I just wanted to get this done before I leave. I will be developing the game while in France but the this was more like a mental deadline that I wanted to achieve.

I was quite long looking for an appropriate background image to the play screen but I didn’t find one and specially I didn’t find any free ones. I sent few email to few artist but unfortunately I didn’t get any response. So I had to draw myself and I am pretty content with the outcome.

Here’s the final version of the play screen:

Image

So, what are you waiting for? If you are an Android phone or tablet owner, please, do me a favor and download, try and rate my game! Thank you!