Thursday, March 20, 2014

Project Aurora, post 10, (Blog Assignment 6) Lighting up the dark waters

One of the things I have done this week is adding plants that the player can light up using his fishingrod with the light bulb, like so:



First I thought about adding a special class for these types of plants called interactive objects but since they will differ so little from normal game objects I decided to keep them in the basic game object class for now, the biggest reason being lack of time.

I have already added earlier in code that game objects can hold a light so all I had to do was to enable this light and then use it. It was fairly easy to add and makes a huge different in the feeling of how the world looks. The plan is also to add AI to the other fish that make them attracted to these lights but I'm not sure we will have time to implement that.













So the circle for the plant light is cut out of the dark surroundings the same way as the player light circle mentioned in earlier posts but then I also added a sprite for the yellow light you see in the screenshot for both the player and the plants to make the illusion that the light bulbs actually emits light. It's hard coded?? (It's coded in a non-dynamic way) So the position for these sprites is fixed with numeric values, which is not that good but at this point it's all about getting our features into the game before time runs out.

Then I started adding collider boxes for the plant light bulbs so the program would know when to turn them on or off. For example when the player light bulb is close in range it would light up the plant.
It caused a few minor problems with the player vibrating when near the lights because our collision detection gives off an offset on both objects colliding and it caused the player to bump and move in an illogical way.

Instead of changing how our collision is handled. Changes that can cause our other objects to behave differently I decided to look for another solution. I found one in SFML. SFML have a built in function that checks if a sprite box intersects with another sprite box. It's called Intersects() and since I now use a sprite for the yellow light on both the player and the plants I could simply just check if these intersects and if they do light up the plants light bulb for a set amount of seconds. Here is some code of it:







First I check if the game object has a light. If it has I check the status of the players light bulb (on or off). I then check if the player light sprite intersects with the game object light sprite and if they do the game object light is toggled on.

Right now the timer is on 10 seconds. After 10 seconds the light on the game object goes out. This feature isn't a "game changer" but it adds a lot to the atmosphere and feeling of the game world making it feel more alive.

The feedback I got from testing this feature was really good by the people who tried it so I'm quite happy with it.

Wednesday, March 12, 2014

Project Aurora, post 9, (Blog Assignment 5) Darkness in the deep

In our game it gets darker the deeper you go in the ocean and I was tasked to implement this feature because I had already worked with the camera and the black filter that covers the view (see earlier posts).

My first thought was to implement this so the changes of opacity are only happening where the camera is but I started with asking my fellow group mates and class mates how they would go about doing this. All of them basiclly said why not cover the whole world with a black filter with a gradient that starts at a certain position / depth on the Y-axis and that covers the whole X-axis. (see picture)

I thought, sure that might work. I just have to do some changes to how the sf::RenderTexure works with the camera (again earlier posts) I then went on to try to make the RenderTexure as big as half our game world and it ended with a size of 22.000 pixels in X-axis and around 8000 pixels in Y-axis. considering our game world will probably grow to the double of this size it's going to be HUGE! 

Since RenderTexture don't load a texture from a file I thought it would be fine but it seems like there is a limit of some sort. When I made it too big, the RenderTexture / Black filter wasn't drawn at all. If i made it too big in Y-axis it crashed our animations in some way I don't yet understand.

So I went back to my earlier thought to only make the changes where the camera is. I found the solution to be fairly simple actually. Since the sf::RenderTexture work similar like a sf::RenderWindow with a clear(), draw() and a display() funtion I came up with an idea to try.

The clear()- function works like this. It clears the window or in this case RenderTexture with a RGB color and a Alpha value.


So I though why not just manipulate this alpha value the deeper I go? So thats what I did.
I started thinking I need to know how deep the player is so I took the players Y-position for that. Then I also need a position where the darkness start to kick in. because we don't want our game to start getting darker until the player reach a certain depth. and Then I need to determine how fast it gets darker.



So first I use the clear() function with zero alpha so everything is seen. Then when you reach a certain depth it starts getting darker. I added a constant called OPACITYSTART to keep track of that position.

Since the alpha value can only be 0-255 I thought if every pixel movement in Y-axis the player makes increase the alpha by 1 then it gets dark very fast. So I increased this value and called the constant OPACITYDEPTH and set a fixed value of 1000 pixels. so this gives 1000 / 256 so basicly the alpha value/opacity is increased by 1 every 4 pixels. (still very fast but all these numbers are only for testing and the final game will have different values.)

Then in our game we don't want it pitch black except maybe for the deepest levels of the ocean so I put in another constant called OPACITYMAX. This is the darkest it can get.

So if the Player position is higher than OPACITYSTART it starts getting darker.
I added a while loop that checks if the player is within the limit OPACITYSTART and a check that the OpacityCounter is within the maximum limit OPACITYMAX.

The variable called OpacityLevel gets the value of 1000/ 256 that I mentioned. This is added for every iteration creating a leveled layer, like 4, 8, 12 ,16 and so on.(not exakt numbers) An OpacityCounter counts what level you are in and it's this counters value that then determine how high the alpha value/ opacity will be seen in the last line of code.

Then I call the draw() function and display() function to draw /cut the light circle out from the black filter like I mentioned in earlier posts, and now with a gradient darkness depending on position instead of completely black as it was before.

The result is shown below, the deeper the player is the darker it gets. The last picture look pitch black but it isnt.











Monday, March 3, 2014

Project Aurora, post 8, Solving problems

Last week I still had problems with light circles overlapping so I booked a private time with my teacher Tommi to see if he could help me solve this problem. We sat down and I explained the problem to him. I wanted to get rid of the black border when two lightcircles overlap. (See picture) 


He came up with a solution where I could try using sf::Image to manipulate the pixels to get rid of the borders. It sounded like a good idea. I was about to get started and Tommi about to leave when I asked if maybe sf::BlendMode could be used. We checked what kind of blendmodes SFML had and he told me to try BlendMultiply and it worked great! 
It  saved me atleast a days work.


(the light is not centered around the player for testing)

Another thing happened today when I sat with my groupmate Oscar and the problems he had with getting collisions to work. He had som collision check code that worked perfectly in a prototype but for some reason it didn't work in our project. I looked at it and it looked good and because the collision behaved so strange I told him to try to limit the collision area by adding more walls just to try to narrow the problem down. Something I have learned with many days of problems with my light circle. He tried it and we figured out what the problem was within 5 minutes.

Conclusion:
Bouncing Idea's with people really help getting to a solution when the solution is unknown.

Friday, February 28, 2014

Project Aurora, post 7, (Blog Assignment 4) Camera problem

Ok, following up on previous post, I had a lot of problems getting the light circle to work as I wanted and all the problems basicly led back to how the view or camera of the game was updated and the position of everything. So this post will be about the camera and maybe some light circle stuff.

At first we didn't have a camera class to handle the camera. We used SFML's built in sf::view which handle what the player can see and moved it around when the player moved. But as soon as I added the black filter I mentioned in my last blog post I thought why not add that functionally into a camera class? In the future we might want to use another filter or other effects not thought of right now like stopping the camera at certain positions but the player can for example keep moving with the camera locked in place and not always center on the player.


First lets explain how the coordinates work. When we draw something to the screen the upper left corner has the coordinate 0,0 and the X-value increase every step to the right and the Y-value every step downwards. Like the picture to the right:









But the sf::view use another coordinate system that have the position 0,0 in the middle and is increased to the left and upwards like the picture to the left:












If you combine that you get something looking like the picture to the right.













As you see it can be very confusing, There are alof of positions to keep track of. And to add to this problem all our positions for our sprites we draw out on the screen is calculated from the middle of the sprite and not the upper left corner.
So the biggest problems I had was keeping track of all positions and understanding how they all work together. This created some strange behaviours and effects like the light being drawn infront of or behind the player and not centered on the players position like the picture show below.



I went through all the sprites and all positions of camera and even the windows position checking so all positions was correct but I still got wrong positions of the light effect and the light also move twice as fast as the player. It has been driving me crazy for about a week. There was absolutely nothing wrong with my code or logical reasoning!.....or so I thought. Some position errors I got was because there are some hardcoded numeric values but I found those fairly easy and adjusted my code to fit those values. But it wasn't enough!

So last night I finally solved it. But before I go into the solution I will break down how a sprite is loaded.
When you create a sprite it's created from a texture that is loaded into the program. Like a photo or a picture drawn in paint. SFML has a Texture load from file funtion that can be used. so sf::Texture.loadfromfile("filename") and then sf::Sprite( create from sf::Texture)

But when I created my light circle I loaded the texture from sf::RenderTexture. I thought it worked the same way but I was wrong. The difference is that a sf::RenderTexture is like a drawing board and when I moved the camera the drawing board stayed put where the starting position of the camera and player was.
I moved the black filter I created from the sf::RenderTexure but not the drawing board itself and it was this that caused so many strange behaviours.

To explain. Se the picture below. The red rectangle is the starting view / position and the green rectangle is what I see right now. As you see the original light circles followed me even though I moved and if I bumped into new circles they weren't drawn. And to add to my headache the circles could move themself also.
So if a circle moved into what is shown as the red rectangle they would show up in my current view in the green rectangle.
This was very confusing and hard to understand why it happened.  I have gone through the code over and over again and nothing was wrong but...it was ofcourse wrong.
Only after I started to understand what the problem could be by printing out the position of the camera, the player position, the light position and the black filter position I could see that I got some strange numbers.

The positions of everything didn't match as it should. so slowly I started realizing it was something wrong with the filter or how its drawn and I started testing different things. I got the filter in the right position but the position of the lights was showing position numbers from an area located where the red square is located but should have shown position numbers where the green rectangle is and that got me thinking it had something to do with the sf::RenderTexture and thats when i found the problem.


All I had to do was add one line of code!!!

m_FilterTexture->setView(m_CameraView);

This code updates the position of the sf::RenderTexture to that of the camera. Problem solved and I could sleep well last night.











Thursday, February 27, 2014

Project Aurora, post 6, (Blog Assignment 3) Light / Fog of war around the player

So the feature I have been working on this week is the light effect for our light bulb/Fishing rod that light up an area around the player.

This was something I never done before so first I broke down the problem to the basics.
I need a black filter to make everything on screen black and I need to be able to cut through it somehow to show what's under it.

So I draw out the filter as a sprite that covers the whole screen, Done!
Then I read up on SFML to see if there was some information there abouthow to cut through other sprites and I found some people with similar problems and they had solved it in many different ways. One guy had a flashlight solution that seemed simple enough so I went ahead with trying to implement some of what he done into our game.  The reason I went with his example is because it was fairly easy to understand and wouldn't take a lot of time to code.

He used something called sf::RenderTexture. With it you can "draw" stuff without showing it on the screen. like a secret drawing. If you give that drawn stuff to a sprite you can then draw the sprite out on screen using our normal DrawManager..

So first I need a circle that will be the ring of light that cuts through the darkness.
I don't want a clear cut. I want you to see most in the middle and then it gets darker towards the edges of the circle. So when I created the circle I draw it out on another of these sf::RenderTextures one circle after another, each new circle smaller and with different Alpha value than the previous circle. With this way I created the layered circle I wanted.

I then draw this layered circle on to the drawing / sf::RenderTexture that holds the black filter. After that the black filter sprite gets that sf::RenderTexture/secret drawing loaded into it and is then drawn out on the window.

GetFilterTexture()->clear();
if(p_GameObjMgr->m_pxPlayer->GetLightSource()->GetLightStatus() == true )
{
GetFilterTexture()->draw(*p_GameObjMgr->m_pxPlayer->GetLightSource()->GetLightCircle(), sf::BlendNone );
}
GetFilterTexture()->display();

In this code example I clear my secret drawing. draw out my layered circle and the "save" that.
The "GetFilterTexture()->display();"  don't draw it out on screen but only draw it out on the texture surface.
See it as saving your picture or something. Drawing it out on the screeen is done later in the code.


As you can see on the screenshot the other fish has a light around them as well. That's only for testing at the moment and work in progress, I want to be able to merge two light circles if they overlap for other game features that will let us light up some areas of the game world.

This feature was easy enough to understand but I bumped into so many problems adapting this code into our game due to much code we have is hard coded with numeric limits. And with that there was a problem when moving around on the screen because the world limits was hard coded this way and so was some starting positions and sizes of the player and whatnot. The black filter was the easiest to add to the game but the hardest to understand( because of how the camera is handled).

The black filter can be made really big to cover the whole world or just follow the camera. I chose the solution making it big as the screen and follow the camera because that's more dynamic and can be used if the game world is made bigger or smaller. With my solution we don't have to resize the filter all the time. It does that automatic after the screen resolution.
Since all the problems I had was because of the camera and how moving around works in our game I will cover that in another post about the camera and not go deeper into those problems here.


Thursday, February 20, 2014

Project Aurora, post 5, (Blog Assignment 2)

This is my second blog post as part of the blog assignment we have in our class.
Today I will go deeper into animations. Earlier we had it so animations could be loaded and played but only one type of animation and animations couldn't be switched.

The player animations is loaded from a .png file then a sprite/picture is cut out using a rectangle in this case sf::intrect. This rectangle is then stored in a vector. So then I had a vector with a number of frames that could be played up with a set duration. So next I had to think of a way of storing multiple animations.
First I thought I would store one animation in a seperate sprite that then is loaded on to a gameobject but that would mean that a gameobject needs multiple sprites and that felt like it would take more resources and could possibly lead to memory leaks if adding/removing sprites isn't handled correctly.

Then I thought, since I already load in a big spritesheet I just re-use that by cutting rectangles out of it. But then I needed a way to keep track of all rectangles positions. So one vector would represent one type of animation. like moving. eating. attacking, etc. and the vector needed to be connected to the frame duration and I also need a tag to know what kind of animation it holds so my choice for storing all this  fell on using std::map< >

I first added so a struct called Anim (top of the picture) is made within the animated class and it holds a float duration and a std::vector <> I then store that anim struct in a map < > together with a string to know what vector/animation it is.(se bottom of picture to the right)

This way I just store a bunch of rects and one float value for duration and I can access it all using a string.


With this in place I had to re-write the code a bit so it fit with what we had. It's still work in progress for when it comes to optimization. Here is a part of the .cpp file. I'm using an iterator to find the animation type I want to update with help of a string that starts at "Idle" as default but that can be updated using the SetActiveAnimation()-method.

Performance is not a big problem here but I think it might become a problem if the number of animations increase in numbers because it checks through the map with every update looking for the right type instead of just updating the current animation without having to look for it first. So we might change it later but it works for now.

I also changed the way the rectangle sizes are read from a text-file. Instead of having to read multiple text files for every type of player animation i have one text file for all player animations like picture to the left.
Numbers and animations are not 100% correct in the screenshot but its just there to show the build up of the txt-file. So I had to do some changes in the spritemanager as well on how all this is read in.

So now we have a good and dynamic way to load future animations into the game and I'm quite happy with the result.

And as always I end the post with the latest screen of the game.
(doors == enemies)

Friday, February 14, 2014

Project Aurora, post 4

Today our group met with our teacher Marcus for a pre-alpha screening and chat how things are going in the project. We didn't get any negative feedback and he thought we were right on track....phew!
After the meeting I went straight to work and now with some more fun stuff. Player mechanics!...I also moved alot of code though.

I started adding some methods for an attack/dash move on the player so it moves more fluently when attacking and not teleports from on spot to another. I will work more on movement, attack and a sneak mode we have to lure in fish. All these are very important to the feeling of the game so they will need alot of attention.

Here is a code snippet of the dash/attack so far:


First I check that we are in the Dash state with help of the enums I created earlier. Then I check what direction the player is facing so the dash will happen in the right direction.

Then the actual movement is set in the velocity variable with a call to the function to SetVelocity();

After that the dashpower is increased until a certain point. then it starts slowing down.

When the dashtimer reach 0 the dash stops. I will add later that it also stops when you hit a target.

So now I can play around with the dash timer and power to change the movement of the attack to for example fast in the begining and then slow in the end or the opposite if i like. This needs alot of testing so it will match the feeling we want to capture in game.
I will probably start making these different player actions to private methods/functions instead that are called in the player update function. I will make them private so they can't be called outside the playerobject somewhere else in our code.

I also brought a class back to life! Our FishObject class Viktor made. I remade the whole thing and made it inherit from our Gameobject class. The PlayerFish and all other fish will then inherit from this FishObject class.

Here is part of the .h file. some things got cut out from the screenshot on top like the 2 enums direction and state I added the other day. This is the basic outline all fish will have. I will build more on this class I will likely add something for animations here as well since all fish will probably be animated.


I also added so the player sprite flips when moving left or right and I had to set the center of the sprite as origin. Otherwise the sprite flipped based on the upper left corner of the sprite creating a fixed flip? like when you flip a domino. but the result we want is like flipping a pancake, does that make sense?

Here is a screen of the latest progress so far:

My groupmate David added the GUI in the top left corner and we also put in the player sprite / Idle animation. Right now its a little too big but it will be resized soon.

Thats it for today.