TönnenKlapps – not entirely unlike a virtual piñata beating game for XBOX controllers

March 17th, 2011

TonnenKlapps_Title_500

A couple of weeks ago some friends and I competed in the very cozy Indie9000 game jam in Aalborg, Denmark. The theme was Fastelavn, a celebration where danish kids beat innocent barrels to pieces with sticks.

We figured it would be fun to make a virtual edition of this custom – so we did! :)

In this version up to four players use an Xbox controller and try to beat the colored staves in the barrel using the button on the controller in the corresponding color. The timing must be right too, as the bat can only hit a single position.

ingame_2

Highlights of the code are:

- dynamic detection of new controllers added and existing ones removed
- simple emulation of a spinning 3D barrel by drawing single staves back to front using individual colors

Here you can see the 36 different transparent PNGs used to simulate rotation:

rotating_barrel_160 

Here you see Lars trying to get a feel for where the bat would hit the barrel while learning 3D modelling:

Lars

Here you see the team (myself excluded) and a group of playtesters:

playtesting

It was fun to make, and we were nominated in Best game, Best graphics and Best sound – yay!

The game is published to Codeplex on http://tonnenklapps.codeplex.com/, so head there for sourcecode and a game of barrelwhooppin’ TönnenKlapps! :)

Empty folder deleter – cleanup tool

December 28th, 2010

Since I often download pdfs, sourcecode and other files from the web, I often end up with my downloads folder being cluttered with full and empty folders between each other.

emptyfolderdeleter_screenshot

For that reason I made a little commandline tool to delete empty folders. I have it in my downloads folder, so I can doubleclick it whenever I’ve been sorting stuff, and want the empty folders deleted. To be sure that you meant to run the program it asks you to press D(elete) on the keyboard to continue. You can run it from a batch file with the parameter "-quiet" to make it run without confirmation.
You can download the application CommandPrompt (zip), or the source code floppy .

An interesting code snippet is the Options class. Earlier I've been using Plossum, but I didn't want to include referenced DLLs in my app, so I made the Options class as an alternative. It is a class which parses the command line and stores the options in public properties, so the logic in the command line version could easily be changed to accept input from for example an xml file. The main logic is in the constructor which receives the string[] sent from the Main() method of the program.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace EmptyFolderDeleter
{

// ****************************************************************
// Jakob Krarup - December 2010
// http://www.xnafan.net
// Distributed under Creative Commons Attribution license:
// http://creativecommons.org/licenses/by/3.0/
// Short version: use it how you wish, just leave my name on it :)
// ****************************************************************

///

/// Class to parse commandline options for the EmptyFolderDeleter program
///

public class Options
{

#region Properties

///

/// The folder to delete files in
///

public string Folder { get; set; }

///

/// Whether to refrain from writing status to the console
///

public bool Quiet { get; set; }

///

/// Whether to display the program help for the user
///

public bool Help { get; set; }

///

/// Whether there was an error parsing the arguments in the constructor
///

public bool ParseError { get; set; }

///

/// What the error was, when parsing the arguments in the constructor
///

public string ParseErrorMessage { get; set; }

#endregion

///

/// Parses the commandline arguments and saves them in an Options object
///

/// A string[] containing the arguments /// An Options object containing the parsed values
public Options(string[] args)
{
if (args.Length == 0)
{
return;
}
else
{
//convert the argument array to list to be able to use LINQ and to remove items
List argList = args.ToList();

//create a stringbuilder for the errormessages
StringBuilder error = new StringBuilder();

try
{
//if "help" is one of the arguments, set the help property of options to true
if (argList.Any(arg => arg.ToLower() == "-help"))
{
this.Help = true;
argList.Remove("-help");
}

//if "help" is one of the arguments, set the help property of options to true
if (argList.Any(arg => arg.ToLower() == "/?"))
{
this.Help = true;
argList.Remove("/?");
}

//if "quiet" is one of the arguments, set the verbose property to false
this.Quiet = argList.Any(arg => arg.ToLower() == "-quiet");
argList.Remove("-quiet");

if (argList.Any(arg => arg.StartsWith("-path")))
{
//find the first argument that begins with "-path"
string folderArgument = argList.First(arg => arg.StartsWith("-path"));

string folderPath = folderArgument.Split('=')[1].Trim();
//remove quotationmarks
this.Folder = folderPath.Replace("\"", "");
if (!Directory.Exists(this.Folder))
{
this.ParseError = true;
error.Append("The path '" + this.Folder + "' is not a valid folder.\r\n");
}
argList.Remove(folderArgument);
}

//if there are still arguments left, the user has entered an invalid argument
if (argList.Count > 0)
{
this.ParseError = true;
argList.ForEach(arg => error.Append("Unknown argument: '" + arg + "'.\r\n"));

}

}
catch (Exception ex)
{
this.ParseError = true;
error.Append("Error while trying to parse arguments.\r\n The error message is '" + ex.Message + "'.");
}
//save the collected errormessages
this.ParseErrorMessage = error.ToString();

}
}

///

/// The folder the user wants to delete, as a DirectoryInfo
///

/// The folder the user wants to delete, as a DirectoryInfo
public DirectoryInfo GetFolder()
{
DirectoryInfo folderDir = null;

//if no parameter was given or ".", then we use the current folder
if (string.IsNullOrEmpty(Folder) || Folder == ".")
{
folderDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
}

else if (!Directory.Exists(Folder))
{
//if a folder parameter was given, but it doesn't exist, we throw an exception
throw new ArgumentException("The path '" + folderDir + "'is not a valid folder");
}
else
{
folderDir = new DirectoryInfo(this.Folder);
}

return folderDir;
}
}
}

MineCraft Timer app for Netduino

December 27th, 2010

MinecraftSince my previous post two things have happened...
First I’ve taken a liking to MineCraft, the builder/explorer indiegame that sold over half a million copies.   Secondly – I’ve taken up learning electronics, using Electronics for Dummies, and YouTube ;-).

When I try to learn something new, I always start out with a little project I really want to do. It gives a lot of motivation to get through the ordeal of learning something by yourself.
For a long time, I’ve wanted to be able to program something on the PC which interacts with homemade netduinohardware outside the PC. I had heard about the Arduino (an open source programmable micro computer which interfaces with homemade periferals), but hadn’t gotten so far as to invest in one, when I heard about the netduino. The netduino is an Arduino for .Net coders. It runs the .Net Micro Framework, so you can write code in C# in Visual Studio.Net and then deploy it directly to the USB connected netduino.

minecraft_canary Ever since I downloaded the MineCraft Canary for my Android, which lets me know what time of day it is on the surface, I wanted to make an electronic version using LEDs. I am not yet skilled enough to make a version using just electronic components from scratch (you know – the oldfashioned way with soldering and stuff), so I thought “Why not use the netduino?” :).

After quite a bit of fiddling around, and learning that the .Net Micro Framework doesn’t have Linq, Generics, and a host of other things I take for granted these days – I got a little working solution running.

In the video here I demonstrate the concept, both using the netduino’s built-in LED and button, and using the Seeed Studio Electronic Brick Starter Kit, which adds the possibility of click-on extensions.

There are two sets of code here:

- the really simple, written in one Program.cs file, which only uses the netduino boards button and LED
- a more advanced one which supports any number of inputs and notification components in a class hierarchy which implements interfaces for a code-your-own-extension style app.
They are both available for download here floppy

If you have the Electronic Brick Starter Kit, you need the ?LiquidCrystal library for interfacing with the LCD display.

The netduino is a LOT of fun :).

------------------------

UPDATE 28 December 2010

Yay - my favorite webzine (MakeZine.com) found my project and posted it :D

http://blog.makezine.com/archive/2010/12/minecraft_timer_app_for_netduino.html

EPIC WIN!!!1 :)

And Kotaku as well - yay! http://kotaku.com/5720244/make-your-own-minecraft-alarm-clock

Protect your Carrot

April 30th, 2010

Just finished attending Indie9000 gamejam here in Aalborg. We had a lot of fun. The theme (revealed friday evening) was Rabbits.
We were intent on making a combined "Shoot-the-little-varmints" and Tower Defense game where we would partly shoot the little rodents with a shotgun (instant gratisfaction ;-)) and partly set up traps and obstacles to keep them out of the garden.
In the end we only implemented the shoot-em-up part, but had great fun getting there.
One thing we laughed a lot about was the fact that we had to implement some censorship. We wanted the rabbits to be able to "spawn" new rabbits when amorous feelings arose. But they had very few inhibitions. To begin with we found out that they were jumping members of their own sex. While we have nothing morally against that - it didn't lead to offspring (which was our intention to begin with) so we put a stop to that.
Then we found out that they were copulating with the deceased which we also chose to stop, and finally when all was well and dandy and little rabbitcouples were having rabbit offspring we saw some deviants sexually assaulting the babies. So finally, after three "censorship IF-sentences" we got the game up and running :).

There were a lot of other very well made games and we saw our chances of winning any of the categories as very slim :).
One thing we were very happy about was making a score system to tempt the good gamers into making the game harder for themselves: We awarded the player 1 point for every kill. But if you kept shooting at the rabbitcorpse you got additional points. Two points for the next shot, then three, four, etc. for the entire two seconds before the corpse was removed from the playingfield. this makes it possible to get up around 1+2+3+.....+15+16 points if you go on a splatterspree :). This also lets the other rabbits get closer to your carrot, gives them time to make new rabbits and even more rabbits are spawned from the rabbitholes around the border of the playing board.
The judges apparently thought this was a great balancer for the game - and also liked how easy the game was to learn (and addictive - we had to wait for one of the judges to beat our highscore :)).

If you want to play the game - it's available for download here.

You need the XNA redistributable if you don't already have the XNA framework installed.

The sourcecode will be available soon, it's being beautified *G*.

Enjoy!

Small project to show drawing items with the mouse in XNA

February 3rd, 2010

I saw a post today on the XNA Community Forums asking how to give a player the possibility of adding things to a game, and storing the position of the added images.

I made a Downloadlittle project to show how to do this. Basically it adds a Vector2 to a generic List when the left mouse button is pressed and removes a Vector2 when the right mousebutton is pressed.

Here's a small demo:

using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace SmallXNADrawingGame
{
    /// <summary>
    /// Small class to show how to be able to draw and store objects in XNA.
    /// 
    /// Jakob "XNAFAN" Krarup - February 2010
    /// http://www.xnafan.net
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        //a list to store the dots in
        List<Vector2> positionOfDots = new List<Vector2>();

        //the dot to use for drawing
        Texture2D textureDot;

        //stores half the size of the dot for centering the texture
        Vector2 halfSizeOfDot;

        //stores the current and previous states of the mouse
        //they are used to compare in Update() to make sure
        //a mouseclick is a new one and not just the button being held
        MouseState currentMouse, oldMouse;

        //font for writing instructions
        SpriteFont defaultFont;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            //set size of screen
            graphics.PreferredBackBufferHeight = 600;
            graphics.PreferredBackBufferWidth = 800;
            Content.RootDirectory = "Content";

            //make sure to display mouse cursor
            this.IsMouseVisible = true;
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            textureDot = Content.Load<Texture2D>("dot");
            //calculate half the size of a dot and store it 
            //for drawing the dot centered on the mouseclick (se Draw())
            halfSizeOfDot = new Vector2(textureDot.Width / 2, textureDot.Height / 2);

            //load the font
            defaultFont = Content.Load<SpriteFont>("DefaultFont");
        }

        protected override void Update(GameTime gameTime)
        {
            //store the current state of the mouse (buttons, position, etc.)
            currentMouse = Mouse.GetState();

            //if the mousebutton was pressed between this and last update...
            //this check makes certain that one click doesn't create multiple dots because the button is held down
            if (currentMouse.LeftButton == ButtonState.Pressed && oldMouse.LeftButton == ButtonState.Released)
            {
                positionOfDots.Add(new Vector2(currentMouse.X, currentMouse.Y));
            }

            //if right mousebutton was pressed
            if (currentMouse.RightButton == ButtonState.Pressed && oldMouse.RightButton == ButtonState.Released)
            {
                //and there are still dots left
                if (positionOfDots.Count > 0)
                {
                    //remove the last
                    //"-1" is because the list i zero-indexed,
                    //so a count of 1 would remove the dot at position 1-1 (zero).
                    positionOfDots.RemoveAt(positionOfDots.Count - 1);
                }
            }

            base.Update(gameTime);

            //store the current state in oldMouse 
            //to be able to determine when buttons have JUST been pressed 
            //by comparing the two states in an update
            oldMouse = currentMouse;
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();

            //write instructions
            spriteBatch.DrawString(defaultFont, "Left mousebutton to draw dot", new Vector2(20, 20), Color.White);
            spriteBatch.DrawString(defaultFont, "Right mousebutton to delete dots", new Vector2(20, 40), Color.White);

            foreach (Vector2 position in positionOfDots)
            {
                //draw the dot centered on the position of the mouse
                //by subtracting the Vector 
                //which has half the textures width for X and half the textures height for Y
                //from the position stored.
                spriteBatch.Draw(textureDot, position - halfSizeOfDot, Color.White);

                //draw the dot's position
                spriteBatch.DrawString(defaultFont, position.ToString(), position, Color.White);
            }
            base.Draw(gameTime);
            spriteBatch.End();
        }
    }
}

We won a “Juror’s Special Pick” award!!

February 3rd, 2010

I had to leave Nordic Game Jam before the votes were counted in the semifinals. Apparently we first made it to the finals and then were picked by the juror Thor Frølich (Graphics Designer and Ninja Extraordinaire from IO Interactive). He liked the simplicity - that the game had one core gameconcept chase and the simplistic graphical expression.
Apparently (I wasn't there, but Rasmus was) suddenly everybody could see the benefits in our simple game as opposed to the graphically superior games :)
GREAT :)

Chasing Dots – Our contribution to Global Game Jam 2010

January 31st, 2010


This is the game we created at the Nordic Game Jam 2010.
Finally ... after liters of chocolate milk, coffee and chocolate.
After playtesting, debugging, playtesting, debugging.... etc for 48 hours - we finally have a playable version out.
The theme for this years Game Jam was "Deception" and there was a constraint saying that you had to have a DonKEY, a MonKEY or a KEY in your game.

We chose to make a little player-vs-player maze game. The hunter (black) is faster than the hunted (white) but the hunted can spawn clones of himself.
The KEY is used to unlock the teleports (red squares).

We are considering selling the game on Xbox Live Marketplace, but let's see :)

Here's a demo of the game - have fun and let me know what you think.
You will probably need to install the XNA 3.1 framework redistributable first, if you don't already develop XNA games.
Credits:

Project Manager/Music
Lars Nysom

Audio/Concept/Leveldesign
Rasmus Lønne

Code
Malte Baden Hansen
Jesper Eiby
Jakob Lund Krarup

Fanpic with Peter Molyneux :)

January 30th, 2010

The Legendary Games Creator and a great fan!

I am attending the Nordic Game Jam chapter of the Global Game Jam that is going on this weekend in all timezones.
The keynote speaker is Peter Molyneux - and since I got the chance to meet a legend I just HAD to brag.

To all the Teenage-Game-Tycoons out there :)

January 28th, 2010

Someone posted on the XNA Forums about how all of his projects gradually slowed down and finally ground to a halt far from being finished and far from being anything like what he was striving for.

The original post was deleted while I was responding - but since I know there are many TGT's out there I thought I'd post it here.
If you're a TGT - this one's for you!

"Well if you want to hear my solution:

Do a little and do it well
Start out simple - but finish it!
If you have to create XNA-tic-tac-toe or XNA-Pong for you to finish a complete game including titlescreen, options and help, then by all means DO THAT :)
Better to have a fully finished game to show off, expand and learn from than 20 barely-begun projects laying around.

Be proud of what you do - because YOU did it!
This has worked for me in many endeavors.
Continually praise yourself saying "well done - you finished another sprite/method/class/level" and remind yourself of how far you've gotten on this project.
It is really a benefit to have high thoughts about what YOU produce - even despite what others may think or compare your games to. :)

Join hands - it just makes for better results :)
Only start something by yourself if you are content with failure or another "draft-gone-prealpha-gone-stale" :)
Find someone on the forums to make your first little game with. All gameprogrammers started small, but very few got to where they are today without the moraleboost of being in a group.

Go get'em tiger!

Kind regards - Jakob "xnaFan" Krarup"

Nordic Game Jam this weekend – yay! :)

January 27th, 2010

This weekend a buddy of mine and I are driving to Copenhagen to participate in Nordic Game Jam.
The sign-up closed at 260 participants, that will be my biggest jam yet :).
For those of you who haven't participated in a Game Jam yet - DO IT!
Here's a short excerpt from the NGJ webpage about why you should try it. It sums it up pretty well:

But why participate in a game jam? And why go through 48 hours of: very little sleep, hard work, great ideas, crunching, problem solving & technical issues? Because a game jam encourages innovation and experimentation. It is one of the vehicles behind the new generation of game developers that can experiment with platforms and game ideas in an intense and yet still informal atmosphere. This is the space where the new generation of talents can be found.

If you urge to create a game, collaborate and meet other game developers - then Nordic Game Jam is the perfect place for you. As a participant at the Nordic Game Jam you will be part of a global event of creativity and fun.

The Nordic Game Jam 2010 will follow the same format like previous years, as an event where students, hobbyists and professional game developers, meet up for a weekend to develop and experiment with new and innovative game ideas.

My version of the 10 second pitch sounds like this:
"It's an excellent chance to pick up new skills and friends while doing what you like best - code XNA ;-)."

Nordic Game Jam will be opened by Carina Christensen, Danish Minister of Culture - which I think is a proper recognition for the role games play in the development of a common culture.
But more importantly: Peter Molyneux, yes THE Peter "Populous-DungeonKeeper-Black and White" Molyneux will be doing the Keynote speech.
To me Peter is synonymous with Artificial Intelligence. Like no other he made me believe that the characters you saw on the screen had a life of their own, even after turning off the PC :)

Can hardly wait!