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.