Thursday 24 October 2013

Hypochondria Update #4 - Shaders

So for the past while I've been trying to dip my toes into the vast ocean that is HLSL shader programming....and oh my is it a vast ocean. But after some initial terror I've had some success :-) The two main things I was trying to achieve were some simple lighting (for starters) and textured polygons. I haven't even attempted shadow casting yet because I may end up bald if I try (from tearing my hair out in frustration), but I would like to give it a try at some point because it's something that I think adds a certain level of polish and proffessionalism to any game if done well.

So here's an example of what I've managed to hack together so far:

As you can see, I just have some point lights at the moment that simply light up everything underneath them (foreground and background). I'm not sure yet if I will leave it like that or if I will make layer specific lighting. Maybe it would be best to add it in as an option. I aslo changed the stomach acid shader to make it glow. Super realistic eh? ;-) I'm quite happy with the overall effect for now. I think it's a nice step up from what I had before. This doesn't represent the final look of the game though. It's just a start.

The other big change I made (as you may have noticed) is the terrain. After discussing with a friend of mine I decided that the terrain I had looked too flat and rigid. It didn't really suit the setting (inside a living human). So I'm redesigning everything to have curvy terrain :-) I made a bezier curve editor (basically the pen tool from photoshop) for my level editor so that I can quickly build these shapes. These are then triangulated (I think I'll do a seperate blog post on that) in order to give me a filled polygon which can then be textured and highlighted/shaded using shaders. This should hopefully speed up the development process beacuse I can now just build my terrain using the curve editor and the game will take care of all the drawing for me. All I have to do is make some nice textures in photoshop instead of hand-drawing loads of images. The texture in the image above is just for test purposes and won't actually be used in the final game.

In terms of collision detection and player movement for the curvy terrain I'm still using a path system similar to the one described in the last post for the "sticky" surfaces. But I scrapped that one and re-wrote it from scratch again becuase I noticed it was a bit crap. Works pretty nicely now apart from a few little bugs that still need to be squashed.

Here's a short video I made showing the first few levels with the above mentioned improvements:


So that's it in a nutshell for this post.
Take it easy ;-)

Thursday 29 August 2013

Hypochondria Update #3

Ok so it's well past time for another update on Hypochondria. And as I suspected from the start, the project is snowballing...like crazy. So that October release date is out the window and I'm probably going to be looking at early next year (I hope). Right, so as mentioned before I made and uploaded a demo a while back showcasing some very early gameplay and I'm fairly happy with it. Got some good feedback off my friends, and one very kind youtuber by the name of johnyliltoe (check out his channel here) made some awesome lets play videos as well. Go watch!

So since the last post I've been working o the lung section of the game. The two main things I've gotten done are "sticky" surfaces and the new player ability. The sticky surfaces allow the cells to run vertically/upside down etc due to being covered in sticky cigarette tar. I implemented this by using box2d edgeShapes combined with a path system. The edgeShapes are used to detect when a cell collides with the sticky surface and they each have a start and finish way point as well. So once the cell is "sticking" I simply switch off the gravity for it's body and move it along the path if the player is pressing the move buttons. The way points can be used to determine the draw angle too.


In the picture above you can see a simple example of the sticky edges. The yellow line is made up of multiple edgeShapes and the green dots represent the way points. These are generated automatically when I draw the curved surface. Here's an ingame look (ignore the crappy graphics)


The other thing I've been working on is the player ability for the lungs. In the stomach section of the game the cells can turn into little spheres and roll around. In the lungs the main cell can inflate himself into a bubble ,with the other cells inside it, and float around. While in bubble form the main guy can't move...but the others can! So they can roll around inside him to get him moving. Here's a look at that.


That's kind of it anyway for now. Take it easy ;-)

Friday 12 July 2013

Hypochondria Update #2

Ok so I've finally gotten that demo up on IndieDB. It includes 25 levels + 2 unlockable levels. These represent the early levels of the game where the controls and basic mechanics are introduced to the player, so there's nothing too complicated or difficult here. Graphics and sound are not in their final form, and the menus are just placeholder for the moment.

Xbox360 pad Controls:
movement - left stick
run - right trigger
jump - A
roll - B
re-group - X
pause - start
re-start level - back

Keyboard Controls:
movement - A + D
run - Left Shift
jump - W
roll - Down Arrow
re-group - Up Arrow
pause - escape
re-start level - backspcace

keyboard controls aren't bindable at the moment.

Here's the link to go download it.

Also I made a quick little video showing a few levels being played. Nothing fancy just some raw gameplay footage. It's a little bit laggy cause fraps was being a bit dickish (it's really time I get that ssd) but you get the idea.



Monday 1 July 2013

Hypochondria Update #1

So this update is a bit delayed due to a random holiday and some forgetfulness on my part. Anyways I'm currently working away on preparing a demo version of the game in the hopes of getting some early feedback. I wanted to have it ready last week but I didn't get as much done as I would have liked. But I should have it ready this week. I just need to do a bit more work on the menus and art, and I thought I might as well make some unlockable levels and character skins as well to give a better impression of what the final game will be like...and what's the point of trying to high score the levels if you get nothing for it anyway?... ;-)

Here take this screenshot:


Tuesday 11 June 2013

New Project - Hypochondria

So I think it's time to slowly start introducing my newest project. It's a 2D twitch platformer called  Hypochondria that I am developing using XNA. In the game you control a group of 20 white blood cells who must kill bacteria/viruses etc. Each level will require the player to navigate the hazards and reach the end with enough cells left to kill the enemy bacteria/virus. The player controls the "main cell" who is in charge of the group. All other cells blindly follow his actions. But you have the limited ability to "draw" them towards you if they start going astray or if you need to navigate through a tight spot/ dodge something etc. The player is rated at the end of each level based on time and number of remaining cells.

Some screenshots:




Planned features:
  • 100+ levels set in 4 organs. At the moment my ideas are, stomach, lungs, heart and brain.
  • bonus levels to be unlocked in each organ by getting high scores in all the levels
  • collectables that can be found in each level. These will unlock outfits for your cells. One outfit per organ. For example a viking outfit that would have your cells running around in viking helmets and wearing big beards :)
  • possibly a level editor. I will probably release the game without one first and if there is some demand for one I will put in the time and make one then. I have a simple one for my own use at the moment, but it's terribly unpolished and has a good few bugs that I haven't bothered to fix cause I know how to avoid them...
Current State of Progress:
So far I have made all the core functionality for the game and about 45 levels. The graphics and sound for the first organ (stomach) are almost complete and I hope to have a demo out soon! I still need to add a few more hazards and proper menu functionality. Then it'll just be a matter of working on the rest of the content. Levels, graphics, music, sounds etc.  My plan is have the game done in October, but we'll see ;)

I plan to update this blog with progress every week. Even if it's only minor stuff. So check back every now and again if you are interested :)

Thursday 30 May 2013

Some Code Snippets

Here I'm going to add some little bits of code that I find handy. Might be some use to somebody.

Desaturate a Colour in C#/XNA

 

//c = the colour to desaturate
//amount = the amount of desaturation between 0 and 1
Color desaturate(Color c, float amount)>
{
     Color gray = new Color((c.G * 0.59f), (c.R * 0.3f), (c.B * 0.11f));
     Color newC = Color.Lerp(gray, c, amount);

     return new Color(newC.R, newC.G, newC.B, 255); //the extra 255 is the alpha value. include this to make sure the color is fully opaque
}

Get Angle Between Two points in C#/XNA

 

//p1 = start point
//p2 = end/destination point
public float getAngleFromPoints(Vector2 p1, Vector2 p2)
{
    float angle = (float)Math.Atan2(p2.Y - p1.Y, p2.X - p1.X);

    if (angle < 0)
    {
        angle += (float)(2 * Math.PI);
    }

    return angle;
}

Convert Between Degrees and Radians in C#/XNA

 

//r = the angle in radians to convert
public float RadiansToDegrees(float r)
{
    return (float)(r * 180 / Math.PI);
}

//d = the angle in degrees to convert
public float DegreesToRadians(float d)
{
    return (float)(Math.PI * d / 180);
}

Detect keyboard and controller input in C#/XNA

 

public class MyKeyboard
{
    private KeyboardState oldState;
    private KeyboardState newState;

    public MyKeyboard()
    {
        oldState = Keyboard.GetState();
    }
        
    //call this at the start of your game loop
    public void init()
    {
        newState = Keyboard.GetState();
    }

    //call this at the end of your game loop
    public void reset()
    {
        oldState = newState;
    }
    /////////////////////////////////////////////////////////////////////////////////
    //check if a key is being held down
    public bool keyDown(Keys k)
    {
        if (newState.IsKeyDown(k))
        {
            return true;
        }

        return false;
    }

    //check if a key has just been pressed
    public bool keyPressed(Keys k)
    {
        if (newState.IsKeyDown(k) && oldState.IsKeyDown(k) == false)
        {
            return true;
        }

        return false;
    }

    //check if a key has just been released
    public bool keyReleased(Keys k)
    {
        if (newState.IsKeyDown(k) == false && oldState.IsKeyDown(k))
        {
            return true;
        }

        return false;
    }
}

public class MyController
{
    private GamePadState oldState;
    private GamePadState newState;

    public MyController()
    {
        oldState = GamePad.GetState(PlayerIndex.One);
    }
    
    //call this at the start of your game loop
    public void init()
    {
        newState = GamePad.GetState(PlayerIndex.One);
    }

    //call this at the end of your game loop
    public void reset()
    {
        oldState = newState;
    }
    /////////////////////////////////////////////////////////////////////////////////
    //check if a button is being held down
    public bool buttonDown(Buttons b)
    {
        if (newState.IsButtonDown(b))
        {
            return true;
        }

        return false;
    }

    //check if a button has just been pressed
    public bool buttonPressed(Buttons b)
    {
        if (newState.IsButtonDown(b) && oldState.IsButtonDown(b) == false)
        {
            return true;
        }

        return false;
    }

    //check if a button has just been released
    public bool buttonReleased(Buttons b)
    {
        if (newState.IsButtonDown(b) == false && oldState.IsButtonDown(b))
        {
            return true;
        }

        return false;
    }
    ////////////////////////////////////////////////////////////////////////////////////
    //get the value of the left thumb stick
    public Vector2 leftStick()
    {
        return (new Vector2(newState.ThumbSticks.Left.X, newState.ThumbSticks.Left.Y));
    }

    //get the value of the right thumb stick
    public Vector2 rightStick()
    {
        return (new Vector2(newState.ThumbSticks.Right.X, newState.ThumbSticks.Right.Y));
    }

    //get the value of the left trigger
    public float leftTrigger()
    {
        return newState.Triggers.Left;
    }

    //get the value of the right trigger
    public float rightTrigger()
    {
        return newState.Triggers.Right;
    }
}

Wednesday 22 May 2013

Easing/Tweening

So a useful tool for game development is a technique called "easing" or "tweening". This is often used for skeletal animation, but is also useful for other tasks. Basically what it involves is updating a value between a start and end point over time. So for example if I wanted to move a sprite across the screen along the x axis starting at x = 200 and ending at x = 1000 for a duration of 1.5 seconds, then the x position of the sprite could be tweened between these two values.

Below I will show you four quadratic easing functions (language is C#, but you can adapt these functions to whatever language you are using):

All the functions will have the same parameters:
currentTime: this is the current time of the tween
start: this is the start value of the tween
diff: this is the difference between the end and start value
length: this is the total time of the tween

Linear (the value will be changed at a constant rate):



public float Linear(float currentTime, float start, float diff, float length)
{
     return diff * currentTime / length + start;
}



Ease Out (the value will change quickly at first and then slow down)



















public float EaseOut(float currentTime, float start, float diff, float length)
{
      currentTime /= length;
      return -diff * currentTime*(currentTime-2) + start;
}



Ease In (the value will change slowly at first and then speed up)




















public float EaseIn(float currentTime, float start, float diff, float length)
{
     currentTime /= length;
     return diff*currentTime*currentTime + start;
}



Ease In Ease Out(the value will change slowly at the beginning and end, and change quickly in the middle)





















public float EaseInOut(float currentTime, float start, float diff, float length)
{
     if ((currentTime /= length / 2) < 1)
     {
         return diff / 2 * currentTime * currentTime + start;
     }

     return -diff / 2 * ((--currentTime) * (currentTime - 2) - 1) + start;
}


Example:
So let's use the example from above. We want to move a sprite along the x axis between x = 200 and x =  1000 for a duration of 1.5 seconds. We would set up the parameters like this:

currentTime: you'd need to set up a timer for the tween and update it using your game engine/framework's delta time (time between last frame and current frame)
start: in this case 200
diff: in this case 1000 - 200 = 800
length: in this case 1.5

so call this line every frame:
spriteX = Linear(timer, 200, 800, 1.5);


Tuesday 21 May 2013

New Blog

So in the interest of letting people know what I'm doing on a (hopefully) regular basis instead of hiding in my cave and then pouncing on the internet with a finished game that no one has ever heard of, I'm setting up this blog where I will post updates on project progress and other random gamedev stuff.

Enjoy :)