Sunday, July 28, 2013

Snake : A level of difficulty

Last post we rounded out how hunting the mice would work, and mentioned at the end some problems caused with the changes we've made from the classic version of Snake.  Let's compare these changes now:

Classic:  Food was immobile, there would only be one at a time, hitting yourself causes you to lose.

New: Food moves, as the game progress there will be more which can be chased off if too difficult to get, and you can go over your own body.

We've made the game more exciting by adding a chase element to getting the food and making the mice have variable statistics.  We've also added a level of strategy by allowing you to use your body to trap the mice.  On the other hand, we've removed almost every level of difficulty.  The only loss condition is hitting the wall, which you can easily avoid.  If a mouse is too fast for you to catch, you can chase it off and wait for a respawn.

So there's two things we now need to fix.  We need to add a level of difficulty within the game map itself, and a level of risk to choosing whether or not to chase a mouse off and wait for a respawn.

Fix 1) There are now randomly spawning obstacles on the map field (rocks and bushes).  Keeping with the theme of randomness, the position and size is randomized, as well as when they pop up.  This allows the play area to evolve as the game progresses, and creates a level of risk.  As the game continues, the players movement is more restricted, but at the same point they can push mice into the obstacles, giving a high-risk method of trapping them.

Fix 2) There is now a hunger bar that is constantly decreasing.  If it reaches the bottom, the player will lose, and the only way to fill it is to eat mice!  This will push the player into taking more risk in catching mice, in order to keep their hunger bar topped off.

Fix 3) Less of a fix and more of an added feature, there are now three difficulty settings.  Playing on a higher difficulty simply ups the speed of the game, allowing a higher challenge for those who like reflex-based games.


So gameplay-wise, we're pretty much done.  All that's left is a bunch of polishing and gui work.  Once that's done, I'll do a showcase piece as well as a postmortem discussing some of the programming issues I ran into, and how that's going to inspire my next few projects. 

Friday, July 26, 2013

Showcase : House Wives vs Zombies

House Wives vs Zombies is set in the 1950's, where a sudden zombie virus has spread through your city.  The virus however, only affects men, so it's up to you to take your mighty rolling pin in hand, beat those misogynist zombies, and save the remaining men in the city (though we didn't get around to finishing that last part).



Controls:
Esc: Quit
WASD: Move
1: Switch to Rolling Pin (Default weapon)
2: Switch to pistol
Mouse: Change facing
Left Mouse Button: Fire weapon

Team:
One programmer/Lead designer (Myself)
Three artists
Two composers
Everyone helped with designing and input

It's a game I threw together with a few people for the Iamagamer game jam, with the theme of "Strong Female Protagonists".  We weren't able to participate that week, so we held our own mini-jam the week after.  Though we had good intentions, a bunch of things came up, and we ended up only spending around 16 hours on the project.  Despite this, I'm proud of the work we got done in the short period of time, and though rough, I feel like the finished product is a good proof-of-concept.

Here's a link to the download if you want to give it a go.  (Just run the installer, you can uninstall it once you're done).  Postmortem coming later.
https://dl.dropboxusercontent.com/u/85698531/HouseWifeVsZombies.zip


Wednesday, July 17, 2013

Snake : The Hunt Begins

So, last post we discussed the controls of the snake game.  In response to the post, I received a comment on how to improve the (rather terrible) controller support.  Basically, instead of limiting the controls to four general directions, I've changed it so that the 'target angle' of the snake is whatever angle the thumb pad is currently facing.  Brilliant and simple!

Moving on, I've finished implementing the AI of the mice/food.  "AI?  Why would completely immobile pellets of food need AI?"  You ask?  Well, I felt keeping the food immobile would be a waste of such a fun movement mechanic.  So, the mice move, giving a level of difficulty to the chase.

Each mouse has a list of attributes, being: Speed, RunSpeedMultiplier, AwarenessDistance, AwarenessDropMultiplier, WalkTime, PauseTime.

So, I wanted the natural behavior of the mouse to be 'skittish', so they alternate between two states.  They will first choose a random direction, and move at their Speed in that direction.  They will move this way until their WalkTime is up, and will then not move for . . well, the duration of their PauseTime.  Once that runs up, they'll choose another random direction and repeat the process.

Their behavior changes, however, if the head of the snake gets within a distance less than their "AwarenessDistance".  They immediately move at their Speed times the RunSpeedMultiplier (which will always make them run faster) in a direction directly away from the snake head.  Their direction will constantly update, so they're always running directly away from you.  They will continue like this, until they reach a distance away from you equal to their AwarenessDistance times the DropMultiplier, or are chased out of the map (Mice who are being chased can escape the map.  If they notice a snake is there, they're going to get out of there!).

Now, the values of all these attributes are randomized per mouse, so when mice spawn (more spawn the longer your body is) you'll get fast and slow ones, some stupid (won't run until you're on top of them) or smart (see you coming miles away), which provides an interesting twist to each game.  On top of this, the values scale with the length of the snake, the longer you are, the faster the mice will be.  At the beginning you're much faster than the mice, and can easily out-maneuver them, however as time progresses, it get's impossible to catch them by just chasing.  This brings to light another gameplay element I'm quite proud of.

As seen in the picture from the last post, I've made it so the snake doesn't collide with himself.  This allows you, as you get longer, to trap the mice.  They run directly away from your head . . . so if you loop around before going in to strike them, you can catch them in the curves of your body.

Cool!  And to demonstrate this, I've made a video!  You'll see the three stages of the game here, the beginning, when you easily catch mice, the mid-game, where they're getting hard to chase down but you're not quite long enough to wrap around them, and the late-game, where strategy and planning are needed to capture those tasty mice.


First thing you might notice, is not terrible graphics!  Thanks to Erika for doing the art.

Another interesting thing to note, is that at almost every stage of the game, mice were still smart/lucky enough to escape, leaving an element of difficulty at all points.

However, the issue still stands that, as is, it's pretty much impossible to lose.  The only obstacles are the walls which, honestly, can be easily avoided.  Mice respawn when chased out of the map, so you'll always be able to get bigger.  There's some level of challenge to chasing the mice, but outside of that it gets boring.  I already have two more mechanics designed to fix this, but that'll have to wait for another time!

Sunday, June 30, 2013

Code Snippet : Angle Facings

So, simple enough concept:  "I have an entity facing a certain direction.  I want to turn him to face a target direction.  I want him to turn on the shortest angle possible".

Despite this being what I consider a simple and common problem, I struggled greatly to find somewhere that adequately described the solution.  So here's how I handled it!

Things to note:  
-Angles are in degrees (Most math libraries use radians, but I find degrees easier to assign initial values to, so we'll assume all Math functions we use take and return degrees)

-0 degrees is straight right, and the range of angles is 180 (counter clockwise) -> -180 (clockwise)

First of all, you'll need a helpful function called WrapAngle.  Monogame has this by default in the MathHelper class, but in essence it does the following:

public float WrapAngle(float angle)
{
   while (angle > 180)
   {
      angle -= 360;
   }
   while (angle < -180)
   {
      angle += 360;
   }
   return angle;
}



Alright, so whenever we modify an angle, we need to feed it through WrapAngle.

Next step, is to get our compared value.  facingAngle is your current facing, and targetAngle is . . . well, the angle you're turning towards.

float compareAngle = WrapAngle(targetAngle - facingAngle);

We now use this, along with the turningSpeed of the entity to update the facing position.  We do a quick check to make sure this direction is actually the shortest.

facingAngle = facingAngle + Math.Min(turningSpeed, Math.Max(-turningSpeed, compareAngle));

Aaaaand done!  Put this in your update loop, and your entity will always turn to a given angle, taking the shortest

Snake : An issue of control

So, take a programmer who wants to make games.  He has to smart small.  A good idea would be to do a remake project of a classic game, in the language/framework he would like to become familiar with.

So, which language?  Having some experience with XNA, I researched the no-longer supported framework and found out about Monogame (http://www.monogame.net/).  A framework that takes all the simplifying goodies of XNA and makes it ridiculously portable?  Yes please!

So, which classic game should I remake?  Well I was in a pet store the other day looking at snakes, and you know what?  Snakes are pretty awesome.  So snake it is!

So we've got a framework, and we've got a game.  I want to make sure to keep it simple, but at the same time I'd like to do a little innovation on the game idea.  Let's start with the most obvious issue you deal with when making a multi-platform title and that's dealing with the issue of different controls.

Now, Monogame does a brilliant job of wrapping similar input modes together.  Programming wise, a gamepad on any device can be treated the same, a touchscreen on any device can be treated the same, etc.  However, we still need to deal with the fact that some devices might only have a gamepad, while some might only have a mouse or touchscreen.  So, we need to think of a control scheme that allows tactile, intuitive input across the following devices:

Keyboard, Mouse, Touchscreen, Gamepad.

With the original snake, Keyboard and Gamepad are fairly simple control inputs.  Up, down, left, right, we're set.  However, the issue comes when you introduce Mouse and Touchscreen.  We could have it so tapping somewhere on the screen, either above, below, left of or right of the snake will cause him to go in that direction.  Though effective, this doesn't feel like it will give you much control, and seems to remove a level of immersion.  That and feels like a poor-mans control port.  We could draw the arrow keys on screen and allow the player to click/tap them, but this seems to carry the same problem as the last idea.  I want my game to feel like it was designed to work naturally with all levels of input, and that seems rather difficult to do with the current way the snake moves.  Luckily enough, I was planning on redesigning how the snake moves anyway.

Rather than having the old-school up, down, left, right movement, I'd like to have more control of my snake. The body parts will still follow the head, but the head will now have a 360 degree 'forward' variable, as well as maximum move and turn speeds.  The snake will be able to curve and wrap around the map, giving the player a more unique control experience, as well as adding other gameplay elements I will discuss later.  So, let's revisit our control schemes:

Mouse/Touch:  Clicking somewhere on the screen will set that as the snake's destination.  The snake will turn and move to take the shortest path possible to reach it, and then circle around it.  For a higher level of control, you can click and drag just in front of the snake, and he will follow your cursor.  I really like this outcome, it really lets you feel like you're in control of the snake and it's fun to have him follow your finger.

Gamepad:  Now that our snake has 360 degrees of movement, we can take advantage of thumb pads.  When pressed in a direction we'll set a 'target angle' for the snake and the snake will move until he's facing that direction and then keep moving straight.  This will give the player the feel of curving around the level/objects and should give a good level of control.

Keyboard:  Oddly enough, is now the least intuitive of controls.  Having only four directions of movement, it should function like a restricted gamepad control.  Tap in a direction, and it'll set the target angle as that direction.  Though functional, this removes a lot of the 'looping' and control found in the other input methods, some of which will be important to some gameplay elements.  Normally I'd be upset about this, but honestly, every device that has a keyboard should also have either mouse or touch, so we should be in the clear.

So, we've got our control worked out, and after performing some Monogame Magic, we come up with this:

So the first thing you might notice is that programmer art is terrible.  That's true!  I'm working on that.  The second thing you might notice is that the snake is wrapping over himself!  Why is he doing that! Doesn't the snake know that he's so ravenous he'll eat his own tail?  Well, that's something we'll address in the next post, which will be dedicated mostly to gameplay.