Friday, October 17, 2008

XNA Part 9 - Pixel Based Collisions

Let me start by saying that the XNA Creators Club tutorials on collisions are really good and a lot of what I have learned so far has come from them. Check them out!

So on to pixel based collisions. You can of course collide on any data based in the pixels, but in our case we will look at the "Alpha" value. For those of you who are not familiar with the channels in a color, we represent color values with different components. There are several different ways to represent color, but in our case we will be using ARGB. The 'RGB' part should be familiar, this is the Red Green and Blue components of our color. The 'A' part stands for the Alpha, which is simply how opaque your color is. Where 0 is completely transparent and 255 is completely opaque. Notice that the values are between 0 and 255. This is because the 4 values are represented by the 'byte' data type which is an 8 bit integer type. 8 bits can hold 256 values and therefore in this case represent the numbers 0-255.

So the idea behind our pixel based collision is this: we look at the bounds of the 2 objects that we want to test and if they overlap, we examine the overlapping pixels in each image. If a pixel in both images is not transparent and overlapping, a collision has happened.

Now of course it will be up to you if you test for both pixels being 0 alpha for non-collisions or if you allow partial transparency to equal non-collision (i.e. both pixels have to be 255 alpha to collide rather than both being 0 to not collide).

Lets look at how we do this in our code.

We will store our pixel data in an array of Color objects for ease of use. So I'm going to add a Color[] to my GameObject.
public Color[] pixelData;

and in my constructor I am going to initialize it and load it up with my sprite's data.
pixelData = new Color[sprite.Width * sprite.Height]; 
sprite.GetData<color>(pixelData);


So we create the size of our pixelData array to be the sprite's height times width and then call the sprite's GetData method using the color type template and passing it the pixelData array to receive the data. Now we should have a lovely array filled will the pixel values of our sprite.

Now that we have pixel data to compare, we will rewrite our Intersects function to take it into account. We will take out our reference to the rectangle intersects() method. and start with our empty method.
public bool Intersects(GameObject b) { }


First we need to determine what the bounds of interection are. So we compare the tops and sides of the 2 rectangles. Remember that Y goes the opposite direction then we might think, so the top of a rectangle is a smaller number than the bottom. So we will compare the Top of a and b and see which one has a bigger value, meaning which one is LOWER on the screen. So in this case b's Top is a bigger number than a's Top since b's Top is lower on the screen than a's (confusing isn't it). So to find the lowest object Top on the screen we compare and choose the maximum Top between the 2 objects. You should also see that in this image b.Top is the top of our collision area.
int Top = Math.Max(Bounds.Top, b.Bounds.Top);


We also want the highest bottom on the screen so we look for the minimum value of a and b's Bottom.
int Bottom =  
Math.Min(Bounds.Bottom,
b.Bounds.Bottom);

Left and Right are easier since it moves in a more intuitive way. So we want the biggest Left and the smallest Right.
int Left = Math.Max(Bounds.Left,b.Bounds.Left);
int Right = Math.Min(Bounds.Right, b.Bounds.Right);

Now we can loop though using these values and extract the pixelData from the 2 GameObjects and compare them.
for (int y = Top; y < Bottom; y++)
{
for (int x = Left; x < Right; x++)
{

You will see the the for loops will not execute if top > bottom. That way, if the lowest top on the screen is below the highest bottom (ie the object are completely above and below each other) the loops will not happen. Then if they are vertically able to collide but horizontally not able to collide we don't execute the body of the inner loop. But if both work we get to the meat.

To discover where in the array of pixels we need to calculate where a particular pixel is. The pixels were stored by each row. So in this image we have our GameObjects textures as 8x8 grids. pixelData[0] through pixelData[7] would contain the first row. [8] though [15] would contain the next. So conviently we can do a little math to get us to our pixel. We take the row we want to access (starting at 0) and multiply by the width of the row (in this case 8) to give us the starting pixel in a row. Then we simply add the number of the pixel in the row we want to access (starting at 0) to that number and we have the index of the pixel we are looking for. Therefore our pixel index within a sprite becomes


pixelData [ rowNumber*rowWidth+colNumber ]


Now that we know how to access a given pixel how to we use the data we have to find the overlapping pixels and thier data. As we can see in this image, our x value would be starting at pixel 7 of the screen but only index 5 of object a and index 0 of object b. Since we can get the left value of object a (which is 2), we can subtract that from the value of x (7) and get the horizontal pixel index we need in object a (5). That would become our "colNumber" in our index formula. We determine our rowNumber in the same way with the y value. We get the distance of the y value from the "Top" of a by subtracting a's Top from the value of y. This gives us our rowNumber. We would then take the width of a as the rowWidth; so our formula for finding the pixel in a would be
Color colA = pixelData[(y - Bounds.Top) *
Bounds.Width + (x - Bounds.Left)];
Color colB = b.pixelData[(y - b.Bounds.Top) *
b.Bounds.Width + (x - b.Bounds.Left)];

Then we compare the colors and decide if they are a collision.
if (colA.A != 0 && colB.A != 0) 
{
return true;
}

Since it only takes one pixel for a collision, the first time we hit, we finish. After the loops you will want to add a return false if it makes it all the way through without a collision.

Now if you run this again with some objects that have transparency, you should find that they will only intersect when their pixels line up rather than their bounding boxes.

One caveat, this only applies to non-rotated, non-scaled textures. When we come back to collisions again, we will talk about how to handle those situations. But that will not be for a little while.

Thanks big time to the XNA creators club tutorial on Pixel based collisions, it was my primary learning source while preparing to write this post.

Thursday, October 16, 2008

XNA Part 8 - Simple Collisions

Most games that have any kind of movement need to detect object collision. There are many levels of object collision (as I am learning) that we can detect, but to start, we will look at simple rectangular collisions.

Here is the basic idea: First take 2 objects of type Rectangle which is defined this way

Rectangle a = new Rectangle(10, 10, 100, 100);

where we pass the X and Y coords of the top left corner of the rectangle and then the width and height of the rectangle. Then we create another one

Rectangle b = new Rectangle(20, 15, 100, 100);

Now we can call a member of the Rectangle class called Intersects() that will return a bool to tell us if if the 2 rectangles intersect.

So in this case since a and b do intersect,

a.Intersects(b)

would return true. We can use this type of information to help us out. In determining our game logic and behavior.

Here is an idea I came up with for putting this type of functionality into our GameObject Class. We can implement an Intersects method for our GameObject class that takes a GameObject as a parameter and then do our determining there. Here is the code for a simple GameObject

class GameObject
{
public Texture2D sprite;
public Vector2 position;

public GameObject(Texture2D inSprite,float x, float y)
{
sprite = inSprite;
position = new Vector2(x, y);
}

public Rectangle Bounds
{
get
{
return new Rectangle((int)position.X,
(int)position.Y,
sprite.Width,
sprite.Height);

}
}

public bool Intersects(GameObject b)
{
return Bounds.Intersects(b.Bounds);
}
}

We will hold only the texture and the position for now and we set them both in our constructor. Then we add a read only property called Bounds. This dynamically returns a Rectangle object that has been derived from the position vector and the size of the texture. Then in our Intersects() method we will ask our class for it's bounds and then see if it intersects with the bounds of our GameObject b. That way, we can later run code that looks like this.


GameObject a = new GameObject(Content.Load("test"), 10, 10);
GameObject b = new GameObject(Content.Load("test"), 300, 300);
if(a.Intersects(b)){
//Do something here
}

Now of course in this example, both GameObjects are hard coded to a location, so we would want to add code somewhere to get one of these puppies moving. So in our Update method I will add

a.position.X += 1.0f;
a.position.Y += 1.0f;

and flesh out my Draw method with

if(a.Intersects(b)){
graphics.GraphicsDevice.Clear(Color.Red);
} else {
graphics.GraphicsDevice.Clear(Color.Green);
}
spriteBatch.Begin();
spriteBatch.Draw(a.sprite, a.position, Color.White);
spriteBatch.Draw(b.sprite, b.position, Color.Blue);
spriteBatch.End();

So in the end, if a and b intersect, the background is cleared with red otherwise it is green.

This method works great when our Game Objects are rectangles, but if you recall, we are using PNG images which support transparency, so even the transparent part of your GameObjects would cause a collision since we don't care what is drawn in our GameObject we are just checking the bounds. Next we will be taking a closer look at our image to see if, pixel by pixel, we have collisions.

Wednesday, October 15, 2008

XNA Sidebar - Converting a single index into multiple

I was playing around with some coding ideas and thought about this. Say you have a 5x5 grid defined in a multidimensional array int[5,5] and then you create an array of object that will be placed in that grid. Say you want to refer to those grid entries as 0-24 rather than [0,0][0,1]...[4,3][4,4] a neat way to do it is with a little integer math. Division in integers is whole number division and we use the modulus operator to get remainder. So if we know the width of our grid (in this case 5), we can say

int x = 7;
int wid = 5;
grid[x/wid][x%wid];

would give us

grid[1][2]

which if we line things up

0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24


we see that the index 7 is the second row, 3rd column, which in 0 based notation is 1,2. You may have already known this, but I thought it was pretty handy.

XNA Part 7 - Audio - Sound Effects

In our last installment, we talked a little about the Song object and how to load a music file and play it in our games. In this post we will talk about the SoundEffect Object. From my understanding the difference between these two types is in a. how they are stored and b. how they are played. Sound effects are considered shorter burts of sound that will be played from beginning to end rather than started, paused, stopped, etc. If there is a XNA genius here who wants to add to the finer details of this, please do so in the comments.

So to add a sound effect to our project, we will add it the same way in our content pipeline. We will add a folder under content called sounds and then add our sound file to that folder.

The difference comes in how we access that file. Rather than exposing that sound file with a Song object, we will load it into a SoundEffect object. So at the top of our class we will add a variable of type SoundEffect called fx.

SoundEffect fx;

Then in our LoadContent method, we will call
fx = Content.Load("sounds\\effect");

Now since this sound effect should be triggered by something happening in our game, we want to play it during our update method.

I am going to add it to the block of code that gets executed when we press the spacebar.

if (ks.IsKeyDown(Keys.Space)) { fx.Play(); }

As you can see we do not use the MediaPlayer class to play a SoundEffect file. They have a built in method to play themselves. Now the Play has 3 versions. the first takes no parameters and just plays the sound at the full volume. The second takes a float for volume control (between 0 and 1) and the 3rd takes a float for volume, a float between -1 and 1 for pitch to move the sound down or up an octave, a float for panning (between -1 left and 1 right, 0 center) and a bool to indicate if the sound should just keep looping.

If we just call fx.Play() it is sort of a set it and forget it sort of deal. It plays, ends and that is it. But if you need additional control over the sound effect after it is started, then you need to save the return value of fx.Play() which is an instance of type SoundEffectInstance. So you would do this.

SoundEffectInstance e = fx.Play(.1f, 0.0f, 0.0f, true);

now the variable e can be used to control this instance of the playing sound effect. It has methods such as Stop, Play, Resume and variables like volume, pan, pitch, islooped, and state (which tells us what the sound is currently doing). That way if you created a SoundEffect as looping, you could stop it with e.Stop();

So now as we move along, you can very easily add sound effects to your games and make them a lot more interesting.

One note, as you progress into 3d games, there are ways to place a sound within 3d space and the SoundEffect objects have methods for dealing with this as well.

Tuesday, October 14, 2008

XNA Part 6 - Audio - Music

Today we will take a slight detour from our drawing of textures to another very important part of games. The audio! Music and sound effects are incredibly important parts of games no matter if you are doing a simple pong game to a massively multiplayer online game.

There are 2 basic type of audio that I want to talk about today. Music and Sound Effects. Now please remember what I am going to talk about today is part of XNA Game Studio 3 beta using Visual C# 2008, not XNA Game Studio 2.

Lets start with music. First, just like with textures, we want to add our music to the content pipeline. Depending on how much music and sound you are adding to your project, you may want to create 2 folders under content. One for Music and one for Sound Effects. So right click on content in the solution explorer and add a new folder and call it music. Then right click on the music folder and 'add'->'existing item' change the type to audio files (you will see that you can load xap,wav,wma and mp3 files) and browse to your music file and add it.

In our code, we will add an instance variable to our Game class to hold a reference to a song object. so somewhere after

public class Game1 : Microsoft.Xna.Framework.Game {

add

Song mySong;

and in the LoadContent method, add the line

mySong = Content.Load("music\\musictrack");

where musictrack is the name of your music file. if you want it to start playing immediately, one the next line put

MediaPlayer.Play(mySong);

and that is it, your song will begin playing at the beginning of the program.

Now your mySong object also exposes some info about your song like
Name,Album, Artist, Duration, Genre, etc if they are available, and the MediaPlayer class has several static methods for Playing, Pausing, Changing Volume, Queuing songs, etc. You can set the volume with

MediaPlayer.Volume = 1.0f;

Or in your update call check for certain keys like we did with movement and change the volume based on key presses.

So next time we will look at the equally easy way to cue up sound effects for your game.

XNA - "Always...no, no...Never...forget to check your references"

There is something to be said for really knowing a topic. To be able to have information at your brain's fingertips at all times makes for quick work. But realistically, there is no way for me (rather than becoming a recluse) that I can have a full grasp of everything in XNA. So that being said, I find that gleaning knowledge from people who are smarter than I is a good use of time. Also, having their work/writings as a quick reference is also very handy. So here is a list of references for XNA that I have checked out so far. (Bonus points if you know what movie my post title came from)

The XNA Creator's Club has a LOT of tutorials and samples and videos to get you started and to keep you going. A lot of the information I am presenting to you is my take on what I have learned from this site so far, as well as these following ones.

Here are some blogs that talk about XNA and some of the advanced things you can do with it. Check them out!

Bad Corporate Logo
http://badcorporatelogo.spaces.live.com/

Cornflower Blue
http://blogs.msdn.com/etayrien/default.aspx

Shaw Hargreaves Blog
http://blogs.msdn.com/shawnhar/default.aspx

Michael Klucher's Blog
http://klucher.com/blog/

Ziggyware
http://www.ziggyware.com

These guys are a lot smarter at XNA than I am for sure, so I'm keeping their blogs on my speed dial for when I need some info! I try my hardest to make my tutorials my own and write them in my own conversational style, but sometimes it may seem like my information is VERY close to information posted by these guys. So please check them out too. If you are an XNA blogger/tutorial writer and you feel I have copied you, my apologies, it probably means I got a lot out of your lesson. Just let me know if you feel that I need to give additional credit to you and (if I was inspired by a post of yours) I will gladly give you credit in my post.

Monday, October 13, 2008

XNA Part 5 - Game Object Class

Up until now we have had our sprite be a simple Texture2D object with its position property as a separate Vector2 object. To simplify our coding, we are going to create another class to handle our in game items. First right click on your "Project" in the solution explorer and click add -> Class. Name this class GameObject. A new class will be created in your project within your namespace. You will however want to replace the block of using statements at the top of your new class file with the ones from the Game1.cs file.

Within the class GameObject we will define our basic class members.

class GameObject
{
Texture2D sprite;
Vector2 position;
float rotation;
Color tint;
}

Each game object will contain a Texture2D to hold its image, a position, a rotation and a tint color.

Now for some basic C#. We need to create a constructor to initialize our object;

public GameObject(Texture2D content)
{
sprint = content;
position = Vector2.Zero;
rotation = 0.0f;
tint = Color.White;
}

Our constructor will take a parameter of type Texture2D and we set sprite to it, and then we initialize our other parameters to good basic values;

Now I will add some properties to let the client code update and access our variables.
public Texture2D Sprite
{
get { return sprite; }
set { sprite = value; }
}
public Vector2 Position
{
get { return position; }
}
public float X
{
get { return position.X; }
set { position.X = value; }
}
public float Y
{
get { return position.Y; }
set { position.Y = value; }
}
public float Rotation
{
get { return rotation; }
set { rotation = value; }
}
public Color Tint
{
get { return tint; }
set { tint = value; }
}

Now back in our game code I remove the alien Texture2D object and the position object. and in it's place add

GameObject alien;

I remove the position setting line from Initialize and the change the loading line in LoadContent to the following

alien = new GameObject(Content.Load("sprites\\alien"));

Which creates a reference to a new gameobject passing it a reference to the Texture2D created by the Content.Load call.

In update, I change my references to alien to the following

if (state.IsKeyDown(Keys.Left)) { alien.X -= 5; }
if (state.IsKeyDown(Keys.Right)){ alien.X += 5; }
if (state.IsKeyDown(Keys.Up)) { alien.Y -= 5; }
if (state.IsKeyDown(Keys.Down)) { alien.Y += 5; }

and my draw call to the following

spriteBatch.Draw(alien.Sprite, alien.Position, alien.Tint);

so now all the parameters in the draw call come from an existing object rather than being hard coded into the draw call.

Just for fun, we will return to the update method and add the following check

if (state.IsKeyDown(Keys.Space)){ alien.Rotation += 0.1f; }

and change our draw call to this overloaded method

spriteBatch.Draw(alien.Sprite,
alien.Position,
null,
alien.Tint,
alien.Rotation,
new Vector2(0,0),
1,
SpriteEffects.None,
0);

Which gives 9 parameters rather than 3.
  • The Texture2D,
  • the position,
  • the null is a placeholder for a parameters we are not using at the moment,
  • the tint,
  • the rotation,
  • the "origin" of the texture or point of rotation/position,
  • the scale of the object (how big to draw it),
  • the spriteeffect (if we want to flip the image)
  • the depth to draw the image
Now when you run your program, if you press the spacebar, your image will rotate.

Here is the code from the game file:



using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TutorialGame
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

GameObject alien;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

protected override void Initialize()
{

base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
alien = new GameObject(Content.Load
("sprites\\alien"));
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

KeyboardState state = Keyboard.GetState();

if (state.IsKeyDown(Keys.Left)) { alien.X -= 5; }
if (state.IsKeyDown(Keys.Right)){ alien.X += 5; }
if (state.IsKeyDown(Keys.Up)) { alien.Y -= 5; }
if (state.IsKeyDown(Keys.Down)) { alien.Y += 5; }
if (state.IsKeyDown(Keys.Space)){ alien.Rotation += 0.1f; }

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(alien.Sprite,
alien.Position,
null,
alien.Tint,
alien.Rotation,
new Vector2(0,0),
1,
SpriteEffects.None,
0);
spriteBatch.End();
base.Draw(gameTime);
}
}
}



and the code from the GameObject File (I've made it a little bigger this time):

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TutorialGame
{
class GameObject
{
Texture2D sprite;
Vector2 position;
float rotation;
Color tint;

public GameObject(Texture2D content)
{
sprite = content;
position = Vector2.Zero;
rotation = 0.0f;
tint = Color.White;
}

public Texture2D Sprite
{
get { return sprite; }
set { sprite = value; }
}
public Vector2 Position
{
get { return position; }
}
public float X
{
get { return position.X; }
set { position.X = value; }
}
public float Y
{
get { return position.Y; }
set { position.Y = value; }
}
public float Rotation
{
get { return rotation; }
set { rotation = value; }
}
public Color Tint
{
get { return tint; }
set { tint = value; }
}

}
}

Friday, October 10, 2008

XNA Part 4 - Controls

Now that we have drawn a texture on the screen and made it move on a sine wave, lets make it move in response to our input.

There are 3 basic input devices that you can access. The Keyboard, The Mouse and a Gamepad. The wired XBox 360 controller is USB, so you can plug one straight into your computer. But alas I do not have one (unless someone has one they want to send me), so I'll only mention it here a little bit, if you are writing games for XBox360, you will need to program with it in mind. I'm going to focus on the keyboard, since it ubiquitous on PCs.

We access the keyboard during the update method and look at the keyboard 'state'

KeyboardState state = Keyboard.GetState();

now the object state will contain information about the keyboard at that particular time slice. We can look at that object and based on information in it, make updates to our game. We will pass 4 different keys to the "IsKeyDown" method of the state object which returns true if the key we pass it is indeed pressed at that moment. We pass the IsKeyDown method a variable from the "Keys" enumeration which contains a list of all the keys that we could be pressing. Here is the code for checking and updating.

if (state.IsKeyDown(Keys.Left)) { position.X -= 5; }
if (state.IsKeyDown(Keys.Right)) { position.X += 5; }
if (state.IsKeyDown(Keys.Up)) { position.Y -= 5; }
if (state.IsKeyDown(Keys.Down)) { position.Y += 5; }

So we check each of the 4 keys and update the position accordingly.

Now if we compile and run our game, our arrow keys will move our texture.

To access gamepad information we would do this

GamePadState pad = GamePad.GetState(PlayerIndex.One);
position.X += pad.ThumbSticks.Right.X * 5.0f;
position.Y += pad.ThumbSticks.Right.Y * 5.0f;

pad is a GamePadState object that we get from GamePad.GetState and we give it the player index (One through Four). Then we get the value of the Right thumbstick (which goes from -1 to 1) and use that as a multiplier for the addition to our position. That way the further we press the thumbstick the faster it will move! We do not have that degree of control on a keyboard.

Here is the code:

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TutorialGame
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D alien;
Vector2 position = Vector2.Zero;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

protected override void Initialize()
{
position.Y = graphics.GraphicsDevice.Viewport.Height / 2;
base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
alien = Content.Load
("sprites\\alien");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

KeyboardState state = Keyboard.GetState();

if (state.IsKeyDown(Keys.Left)) { position.X -= 5; }
if (state.IsKeyDown(Keys.Right)) { position.X += 5; }
if (state.IsKeyDown(Keys.Up)) { position.Y -= 5; }
if (state.IsKeyDown(Keys.Down)) { position.Y += 5; }

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(alien, position, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}

Wednesday, October 08, 2008

XNA - A slight adjustment

In researching audio methods for XNA I have discovered that XNA 3.0 has better (and easier) tools for dealing with audio. So before I get into anything that will be made obsolete when XNA 3 comes out of beta, I am upgrading to 3.0 beta now. Everything so far should be uneffected by this change. Just to let you know that is the platform I am now using. In addition, XNA 3.0 required C#2008 so I upgraded that too.

Tuesday, October 07, 2008

XNA Part 3 - Updating an Object

Now that we have put a graphic on the screen, we want to make it do something. Perhaps we want to make it move on the screen. First off, in the last example we created a variable inside the Draw method to hold the position of our image. This wont do, because we need to update that value. If we leave it inside the Draw function, it gets recreated every time draw is called. So instead, lets move it out to be a class member of our game class. Just under our declaration of Texture2D alien, we will add


Vector2 position = Vector2.Zero;

This will create a variable accessible to our game class the can persist through our game. We also need to remove the Vector2 line from the draw function. This will also initialize our position to 0,0.

Now in the initialize method, lets set our initial position.


position.Y = graphics.GraphicsDevice.Viewport.Height / 2;

This sets the Y (vertical component) to 1/2 the height our game's viewport, which we access through the graphics.GraphicsDevice.Viewport object. We will leave the X component alone for now. You can run the program to see what you have accomplished so far. The top left corner of your image should be at (0, 1/2 window height)

Now lets move the image in time. To do this we alter the position variable during the update method call. Lets move our image on a sine wave for kicks. Inside the update method, right above base.Update(gameTime); add some code to update our position

position.X += 0.15f;

position.X is a float so we will add 0.15f to its current value;

position.Y = position.Y + (float)Math.Sin(position.X);

Here we take position.Y and add the Sine of the X component. Sin() returns a double, so we need to cast it to a float and add it to Y so that we end up with a float to assign to position.Y.

Now if you run your program your image should oscillate up and down as it wiggles from left to right.

XNA Part 2 - Some Simple Drawing

Now that we have a very basic understanding of the framework of our game, we will do something equally as simple. Taking an image, bringing it into our content manager and drawing it on the screen.

There are many image formats that you can use in XNA, but I am going to suggest the PNG format for a couple of reasons. The first is that it supports variable transparency. That is parts of the image can be between 0% and 100% transparent. As opposed to GIF which is either 0% or 100% transparent or JPG or BMP which has no transparency. XNA will respect the transparency of your image, so it is a good choice. It is also a lossless format which means that it does not have the same type of artifacts that JPG has from it's compression.

So the image I'll use in today's example is one I whipped up in Blender and saved as an RGBA PNG file.

So, let's draw this guy on the screen.

First we need to add the image file to the project. First, under the content folder in the Solution Explorer, right click and choose Add, then choose "New Folder". We will make a folder called "sprites". Sprites are small graphics elements that we can use/reuse in our game. So we make a folder for them in our "content pipeline". Once we have a folder called sprites, right click on it, and choose Add, then choose Existing Item(since our graphic file already exists). Browse to your image file and double click it. You will then see the image listed in your Solution Explorer under the content->sprites folder. Right click on it and change the name of the file to "alien.png".

When your game is compiled, XNA will take the resources in the content pipeline and put them in a format it can use in your game.

Now for some code. We store an image in a XNA object called Texture2D. So first we will add a private member to our game class called alien. Go to the top of your game class and just below "SpriteBatch spriteBatch;" add the line

Texture2D alien;

This creates a class variable in our game class to hold a 2d texture (an image). Now in our "LoadContent" method we will load content into this "alien" variable. Go to the LoadContent method and just below

spriteBatch = new SpriteBatch(GraphicsDevice);

add the line

alien = Content.Load("sprites\\alien");

"Content" is the content manager, so we are telling it to load the sprites\alien file. (notice we leave off the extention, and have to escape the backslash) This returns a reference to a texture2d object and puts that reference into the alien variable.

So now we have an object containing our image data ready to be drawn.

So if we want to draw something we do it in the draw method. Scroll down to it. After the line

graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

We will add the following code.

Vector2 position = new Vector2(10,10);
spriteBatch.Begin();
spriteBatch.Draw(alien, position, Color.White);
spriteBatch.End();


Line 1 creates a Vector2 object with the coordinates 10,10. We will use this to position our image. Later we will move this code out of the draw method since it really doesn't belong here. All coordinates in XNA are drawn from the upper left hand corner as 0,0. Keep that in mind.

Line 2 takes our spriteBatch object and calls it's begin method. spriteBatch lets us create a batch of graphical elements and write them to the graphics card in an orderly and efficient manner. So this line begins our batch.

Line 3 adds our image drawing to the batch. There are 7 different ways you can call the spriteBatch.Draw method. The one we have used here takes our Texture2D object, a Vector2 for location, and a color from the Color enumeration that acts as a "tint" for our image. If we do not want to tint our image, we choose Color.White.

Line 4 ends our batch so it can be sent to the graphics card.

This is all the code we need to Draw our image to the game. We can compile and run our program to see the results. You should see your image drawn in your game window.


Here is the complete code for the Game1.cs file

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TutorialGame
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D alien;
Vector2 position = Vector2.Zero;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

protected override void Initialize()
{
position.Y = graphics.GraphicsDevice.Viewport.Height / 2;
base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
alien = Content.Load
("sprites\\alien");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
position.X += 0.15f;
position.Y = position.Y + (float)Math.Sin(position.X);
base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(alien, position, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}

Monday, October 06, 2008

XNA Part 1 - Program Structure

To begin, we fire up C# 2005 and choose to create a new project. We will choose a Windows Game 2.0 project.

A new project is created for us with the boilerplate for a basic Windows XNA game. The file Game1.cs is opened for us (dbl click it if it is not already open) you will see at the top a block of using statements

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


These import several namespaces from the XNA framework into our current namespace to make coding a little easier.

Now, lets look at some more code.


public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}


Our primary game class is a derived class of Microsoft.Xna.Framework.Game
We have some private members for our class to work with, a GraphicsDeviceManager called graphics and a SpriteBatch called spriteBatch (imagine that) We will talk about what those are for a little later.

Now we define our default constructor for our Game1 class. The constructor does 2 things, it allocates a GraphicsDeviceManager for our class and sets a root directory for our game assets. You will notice in the "Solution Explorer" a part called
"Content". This is the base folder for our content pipeline. We will talk more about our content pipeline in the future. It makes your life a little easier.


protected override void Initialize()
{
base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
}

protected override void UnloadContent()
{
}

protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
}
}
}


Now for the instance methods of our game class that we override from the base class. There are only 5 of them, not too tough!

Initialize is called once at the beginning after the constructor, but before LoadContent, so we can set stuff up non content stuff if we need to.

LoadContent is called once for loading content of all things

UnloadContent is called once at the end for unloading content

Update is called with a target rate of 60 times per second, we update our game objects here. We check for keyboard, mouse or gamepad state and update our game accordingly.

Draw is called once after the updates, then waits for the next update. So optimally it is called 60 times a second as well.

Now click your compile button to build and run your game, and you should get a little blue screen "CornflowerBlue" to be exact. That is all your game does at the moment. Click the red X to end it.

If you got an error rather than the game, you may not have a graphics card capable of running XNA games. For this I apologize for your wasted time. If your game ran, than you will be ready for our next installment.

Getting Started with XNA

So you want to be a game programmer? Well my answer is yes, so I'm picking up the Microsoft XNA framework for C# as my first step. Some people agree with this and some don't but hey you gotta start somewhere. So I'm gonna take you, my loyal reader on this trip with me.

Right now XNA 2.0 is the current release, but 3.0 is in beta. If you want to use XNA 2.0 you need Visual C# 2005, 3.0 requires Visual C# 2008.

So lets install a couple of things to get going on this...

1. Visual C# 2005 Express

You can pick MS's free version of the visual c# here, get that installed and then get...

2. XNA Game Studio 2.0

Installing XNA will add the XNA classes/framework into Visual C#

Now something to keep in mind is that XNA requires a graphics card that can support shader model v1.1

3. While you are at it, you can visit http://creators.xna.com/ and sign up for an account there. The forums there seem like they are active and people are willing to give tips.

So, do that stuff and we will start looking at some code in our next installment.

How it all started...

What got me "into" computers? I hadn't thought too much about it. It was always something that I was interested in and was drawn towards. But what was it that made it 'click' with me. Well the other night was movie night at our house and there was nothing good on TV. So out of the blue I suggested we watch an old favorite of mine from 1982. TRON. So I dug out my VHS copy and put it in and my kids were amazed by the (now very dated) special effects. They LOVED the light cycles and the tanks and thought 'bit' was hillarious. Then it hit me. This may be it. The movie that convinced me that computers were an exciting area, and that making computer games would be a very cool way to make a living (just like Flynn)

So, here I am 26 years later. I work with computers every day, but am not a game programmer. That brings me to my next series of upcoming posts. I've recently started learning the Microsoft XNA framework. Which is a .NET extension of classes for game programming on the PC, XBOX360 and Zune platforms. I have always found that teaching something helps me learn it better, so I will teach you how to use XNA and take another step closer to my childhood dreams of taking down the MCP with my identity disc.

Thursday, June 26, 2008

Web Programming Toolkit

I am not a "web guru" but I can generally get things done. But I am always on the lookout for tools that will make things easier. Here are some of the tools that I've been using lately in both my primary job and side projects that I work on.



Content Creation - Text Editing

In this area I am 'old school', I'm a text editor kinda guy. Right now my text editor of choice is notepad++. This is a great notepad replacement with line numbering and syntax highlighting and lots of other goodies for a programming editor.

Content Creation - Graphics

As I have mentioned in other posts, I am a big fan of Blender 3d for graphics creation both 3d and 2d. Also Inkscape for vector graphics is another great tool. Paint.Net is also good for getting those 2d images ready for the web.

Database

It is no small suprise that my database of choice would be MySQL. Here is a web standard if I ever saw one. Easy to set up and use and has always been very PHP friendly. I am also doing some looking at SQLite to see if it may hold some possibilities for use in the future for me. Actually I mention this because I've tinkered a little lately with Google Gears which is a component from Google that allows you to create a local site specific database on a client machine (with their permission of course) to let you store relational database information OFFLINE so that they can cache your web based application on their computer and use it while they are disconnected. This is actually how Google Docs and Reader are doing their offline modes. It uses a SQLite engine to accomplish this.

Code

PHP & PEAR

Most of the files you will see coming from my editor are coded in PHP. PHP has become one of the foremost used scripting languages used online these days. It is versatile for mixing dynamic content with static, making it easy to design websites that reuse a lot of code rather than duplicating it page after page. PHP also allows for easy integration with databases. This point brings me to PEAR. PEAR is the PHP Extension and Application Repository. This is a readily available library of tools written to extend the capabilities of PHP. One example is the MDB2 library which allows you to write database applications that don't really care what kind of database is backing it up (as long as the database tables are there) so your application can be just as happy talking to a mysql database as to an mssql or SQLite database. It also allows for "lazy" database connections. You can set up your database connection in a header file then when you code you always have a $db object ready to talk to the database for you. It also makes it easy to get the data back from queries really simple to do in various formats. I'll probably do a example in my next blog post.


JavaScript

I've been using a Javascript Framework called Prototype lately that is really helpful. I've mentioned it before. If all you are looking for is an easy way to get into AJAX, check it out. Also an extention to Prototype called Script.aculo.us makes doing user interfaces easy with JavaScript and AJAX. From animated effects to Edit-In-Place fields to Drag and Drop support it is a great library to get to know.

A recent javascript library that I found for making HTML tables sortable is called Standardista Table Sorting it is very simple to implement in your code and is very fast. I'll have to show you how I added it to a function to take a MDB2 result set and turn it into a sortable database table (based on an idea implemented by a co-worker) in a later post.

So, in short, yes I am firmly planted in the LAMP (Linux Apache Mysql PHP) camp. But I am certainly open to other tools and technologies. Really whatever makes my job easier.

What are your favorite tools, languages, database engines and libraries? Leave a post and let me know!

Thursday, June 19, 2008

Free / Open Source DVD Creation Workflow

Occasionally I will have the need to create a DVD. I'll do slide shows for weddings or special events, videos for family or church. My DVD drive came with it's own burning software but I've been looking for a more portable solution, since I use other computers with DVD burners in them, but no pre-installed burning software. Here is a rundown of how I might put together a slide show DVD with no commercial software.

First I'll need to scan in my images, for this you can use Paint.NET. If you haven't seen Paint.Net yet, it is a great light Photoshop replacement. If all you are doing is scanning, rotating and cropping images and doing minor work on them, it is super. Others would say to use Gimp here, but it has always felt clunky to me. Paint.NET is Windows only, so Mac and Linux users will need to look elsewhere for this part of the chain.

Once you have you images ready, you may need some extra slides as intro or ending slides. For this I go to my old stand by, Blender. Here for instance is a pair of wedding bands that I made for a wedding slide show. I added the text after the fact. You could also use Blender to create menu graphics for your DVD. It has a built in non-linear video editor if you wanted to do any motion video or animation as well. Blender is cross-platform: Windows, Mac and Linux can all use it.

So at this point, I have a folder full of images that I have named numerically in the order I want them (this speeds up the process later) ready to be made into a slide show. Now in the past I have used Windows Movie Maker, but I wanted to get away from that because it really has it's limitations. So in doing a little searching I found SSMM which is a really handy slide show tool. It has a pretty wide selection of transition effects and a pretty simple layout. You can also sync up audio as well (as long as it is in WAV format, see the section on FFMPEG later for help) Once you have all your settings done, it will render an AVI file of your slide show. SSMM is Windows only, so Mac and Linux users will need to look elsewhere. It may run under Wine for you Linux folk, but I don't know.

Now I needed to get this AVI onto a DVD. I found DVDStyler, a Windows/Linux DVD authoring package (Mac users could of course use iDVD). It lets you build your menus and insert movies into your DVD project and burn the DVD as well. There is only one problem with DVDStyler, for videos, it only accepts mpeg and SSMM only outputs AVI. But have no fear, there is always a solution.

If you do any work with video files, FFMPEG can be your best friend. One of the tools in the ffmpeg package is a command line converter. It can convert a TON of formats, including wmv and quicktime. It also does audio formats, so if you have an MP3 file that you want to convert to a WAV so you can use it in SSMM, it'll do that too! So with this simple command I can convert my AVI from SSMM to an mpeg usable by DVDStyler.

ffmpeg -i inputmovie.avi -b 1600kb outputmovie.mpg

Now that it is converted, DVDStyler can add it, I can finish the menus and burn my DVD.

So there you have it it may not be the quickest solution, but if you have a scanner and a DVD burner already, you are good to go. Do you have any suggestions for this production chain? Any tools in your toolbox that you would like to share?

Wednesday, June 04, 2008

Settling In

Well, I'm into my 3rd week at Greenville College. Week one was spent getting re-acclimated to how the IT department was set up, getting my accounts set up as well as my computer and learning that I may well get pegged in the head at any time with a nerf rocket. My second week at the college was not spent there, but in Nashville, TN at the JAM 2008 convention. This is the annual conference for a company called Jenzabar who makes software for higher education. I went with Dan Coulter and Kris Truitt. We went to a lot of sessions about the core software we use at the college, but also spent a bunch of time hanging out. We watched a bunch of RiffTrax and ate ate this a hole in the wall BBQ place called Hog Heaven. So really a great time!
So now the hard work begins, but I'm looking foward to it.

Monday, April 14, 2008

Getting into AJAX with Prototype

I've been working with PHP for about 5 or 6 years. I first got into using it while working as a Database Admin at Greenville College, trying to write a web based reporting interface for the college's student data system. I had previously been using Perl for everything CGI and PHP made working with databases a lot easier. After taking a job as a network admin at a bank, I had a lot less use for PHP. I used it when I could to 'keep my skills up' on freelance work and Bank intranet stuff. Now I had been hearing about AJAX for a couple years and knew it was something I should pick up. I tried reading a few tutorials on it and learned quickly that it was a little different between browsers and took a bunch of code to get working. All the tutorials I found were more about getting it set up rather than what you did with it. They all started with the Asynchronos JavaScript and XML bit, explained the first half and never said what to do with the XML. Well, after a little playing I put it aside for a while. I recent picked it up again and found the same old tutorials and still no luck. I asked an old co-worker of mine Dan Coulter who wrote the phpflickr class if he could give me some assistance. He pointed me to Prototype which is a JavaScript framework that makes dealing with AJAX much nicer. At first I thought it was all about the AJAX, but it isn't. It really makes JavaScript much easier to use cross-platform. First of all there is a utility function for accessing DOM elements. It looks like this

$('myelement')

This returns the element with the ID of myelement. Want to change the content of a DIV called stuff?

$('myelement').update('New Content');

even better the $$() function lets you get lists of objects like

$$('div');

Would return an array of all the div tags in your document or

$('div.myclass');

would return all divs with the class 'myclass'

But what about AJAX?

As I have learned recently AJAX is less about the acronym and more about making calls to other web pages without reloading the current page. This is where PHP & AJAX really make nice friends. With Prototype, making an AJAX call is this simple:

new Ajax.Request('mypage.php',{method:'get'});

This basically opens a call to the mypage.php page and returns the results to the browser. Now this example doesn't do anything with that result. For that you have to extend things a little, and add in the $() stuff

new Ajax.Request('mypage.php',{
method:'get',
onSuccess: function(r){
$('mydiv').update(r.responeText);
}});


This code runs the mypage.php page, takes the results of that page and replaces the contents of the element mydiv with it.

I am still digging into Prototype, and find new things to do with it each time I sit down with it. So, if you are interested in picking up AJAX or just beefing up your JavaScript programming, I would highly recommend it.

Friday, April 11, 2008

Backstage Meetings

I have to say that I am not easily starstruck. My dad was in charge of a lot of conventions when I was young and I met a lot of special guest speakers, in college I was the stage manager or assistant stage manager of the Agape music festival for 3 years and saw and dealt with a lot of artistist there. I ran sound and was stage manager for Nashville North in Taylorville, IL for a couple years, where a lot of big name country acts came through. All that to say I'm generally not impressed by fame. Well, that is until it becomes personal. One of the first cassette tapes I ever owned was Phil Keaggy's Find Me in These Fields and over the years his style has been a major influence of my playing (not that I can play like Phil ) I have seen him in concert a few times. Once on his Crimson and Blue tour back in 1994, on the Keaggy, King, Dente tour, once in a masterclass and concert at Greenville College and last night at Harvester Christian Church. We arrived to find that the "Artist Circle" seating area which we had tickets for was oversold and we had to sit in an "artist circle overflow" area. They were not bad seats, I wasn't really upset by this. At intermission we were told that because of this error, the people who had to sit there would get to have a personal meet and greet with Phil after the show. So after the show we went back and I got to meet Phil. Pretty much a handshake, a couple stupid sounding compliments from me, and a picture. He also gave us all signed copies of his recent CD set, but it was enough. You listen and idolize someone for that long and when you get a chance to meet them face to face, it's pretty cool.

So although I don't easily get starstruck, I do make exceptions.

Monday, November 19, 2007

My Robot has 10,000 Views!

Well, I know it's small change for some, but I was pretty excited to see that my Gibson Robot Guitar Video has over 10,000 views. For those of you who are wondering, I did the animation with Blender. Which is an open source 3d package. Well, Thanks to all who have watched and I'll let you know when you can go vote :)



Sunday, November 18, 2007

Accepting Undeserved Gifts

I recently received a gift. Now mind you, I like gifts, a lot. Who doesn't really? But this was one of those take your breath away sorts of gifts. A gift I did not want to touch in case it was some sort of mistake. But soon it sank in that this brand new guitar in front of me was in fact sent to me by...anonymous. There was no card or tag or from or anything. It did not say who paid the bill or ordered it. It was just sitting there waiting to be picked up, plugged in and played. Being the inquisitive person I am, I immediately called my parents, neither knew a thing about it and so I started trying to figure out who would have done this and WHY! I have ideas of who may have been invovled in this, but I came to a realization. Finding out who sent this gift is not the point. If they wanted a phone call saying thanks, they would have put in a note or called to make sure it arrived intact. Instead, I think the sender of this gift wants me to do what the gift calls for, to be pulled from it's case, tuned up, turned up and played on. To be used in worship is the type of thanks this type of anonymous gift calls for.

Now why has this hit me so hard? I do not deserve this kind of gift. Sure there I days when I feel like I deserve everything I want and then there are days when I know what I have coming and know I deserve every bit of it. Usually the latter is true. But I think that this gift I have received outlines something important. Christ came to earth to die in our place as the biggest undeserved gift ever. We spend so much time trying to figure out why or wrestle with the nuts and bolts of Christian life and forget to just pick up the gift with a greatful heart and use it to the best of our ability. Does Christ expect our thanks? Yes, but I think the thanks he wants is not the thanks that we generally say in our bedtime prayers, but instead using of his gift to glorify his name.

Wednesday, November 14, 2007

Gibson Robot Guitar


Gibson is releasing a self-tuning guitar called the Gibson Robot Guitar. They are having a make your own video contest to win one. So here is my entry....




Hopefully they will add my video to their site soon for voting. I already have over 1000 views on YouTube so at least some people have seen it :) Enjoy.

The Gibson page is here

Wednesday, October 17, 2007

Out with the Old...


So my effects rack of 13 years finally decided to die on me. It was an ART SGX2000 and it just started flaking out. So I have started from the ground up. I have a BOSS volume pedal from many years back that still works great so to that I added a DS-1 Distortion and BD-2 Blues Driver. Also today I got in a CH-1 Chorus pedal. I built a temporary board for them and this is what it looks like. I got the 1-spot 8 pedal power kit and the CoreX2 solderless cable kit. So far I am very happy.

Wednesday, July 11, 2007

The Wishbook

I used to love making wishlists. As a kid I would circle so many things in the Sears "Wishbook", or I would find something I wanted and work hard to save my pennies to get it.

I have kinda gotten out of the habit in recent years, because as a father of 4 I usually do not have any extra cash to spend on myself. But as I go along I have found that day to day life has actually made me stop wishing for things. I don't spend time dreaming of the what ifs. I am not talking about being materialistic, sitting around being jealous of those who have what we want is very unproductive. But I think that wishing for things can be a great motivator for us to tackle new goals, expand our horizons and go after things that may, in our current circumstance, seem unattainable. Things can certainly own us and there ARE wrong reasons for wanting things. To outdo someone or to hoard something, these are not good. On the other hand things can be symbols. Symbols are so important. Take a look at company logos. It is not enough just to have a name, you need a symbol. If we wish for things in our life that are representative symbols of who we want to become, they can not only aid us once we have them, but can motivate us to become that person who 'deserves' that thing, and perhaps help us take our lives in a new direction that we may have only dreamed or wished about.

Recently (as you can see in another blog post of mine) I entered a contest. First place prize is $57,000. I made a decent entry and so I thought "What if I won?" At first my thoughts went to how much debt I could pay off, but then for the first time in a long time I did a little dreaming. My guitar and rig are old, an old rig for a tired guitarist, but then I thought, what if I could spend $$$ on a real setup. So in the spirit of wishing, here is a link to my wishlist of choice.

Guitar Center Wishlist

As you can see, johnnyGizmo wishes to break out of his cubicle and pursue something more. I have a new excitement in my life. I realize that I very well may not win this contest, but the wishing it prompted has given me something that I needed just as much.

Saturday, June 30, 2007

Heinz Ketchup Commercial Entry

I made an entry for the the Heinz "Top This TV Challenge". Check it out. First prize in the contest is $57,000!!! Let me know what you think :)

Download All the Videos from A Given YouTube User with a Simple Script.

I wrote a little Perl script that takes a YouTube username and with the help of FFMPEG, downloads and converts all the public videos that user has posted and converts them to any format FFMPEG supports like mpg or mov.

read more | digg story

Sunday, May 27, 2007

Update and an Observation

Well, its been a while since my last post. We are now very close to completing our paperwork. We have a couple more documents to get and then a lot of photocopying and notorization to get done. The a big chunk of $$$ will get us into the "waiting phase" of the adoption. At that point things will be out of our hands until we get our referal. We are getting closer all the time and it feels like it is taking for ever. I also want to thank the people who have dontated funds either through Chipin or directly to my Paypal account. Your donations certainly have helped us with the costs of this process.

On a different note, I noticed something that I do lately. When I am around my kids, I talk about myself in the 3rd person. Why do I do this? It's not like my kids don't understand the concept of the word "I". But apparently phrases like "Daddy has to go to work" are now how I talk. Well anyway, talk to you all later because Johnny is going crazy :)

Tuesday, March 20, 2007

Our First Donation!!!

Well we had our first donation through ChipIn recently, in response to the getCals program (which is hosted here getCals if you need it) So thanks to your donation (you know who you are!) you have paid for one of our passport photos.

Wednesday, March 07, 2007

Home Study and Ranting about the Child Shopping Network

I am not much of a ranter, but after this short update, I have to vent...

Well, we have made it through the bulk of the dreaded "home study". We have a little more online training to do as well as some infant CPR classes, but it is pretty much done. So now we prepare our final documentation to be notarized, translated, etc. and send off our next big payments to our adoption agency. We were very happy to work with Baptist Children's Home in Mt. Vernon, IL. They were a great organization to work with and were very friendly and helpful.

---BEGIN RANT---

We are hoping within the next few weeks to have our dossier completed and ready to go. Then we wait and save as much money as possible. Visiting El Salvador will not be cheap. We are probably somewhere in the range of $7k - $9k still in fees and travel costs before we can bring our daughter home. It will also take about 10 months for all the paperwork to be processed. It is a long way to go and it really makes me sick when I read about celebrities who jet over to some country pick out a kid and those countries grease the wheels for them like in this case of Angelina Jolie's Vietnam adoption which will only take 3 months. Friends of ours who are adopting from Vietnam who have all their paperwork submitted still plan to wait another full year before they can bring home their child.

These people (Madonna, Angelina, etc) make me sick. They throw their money around, have their lawyers get all their paperwork together, and go get their kid. Then try to look like some sort of humanitarian by bringing home a child that their nanny can take care of. Then there are many people that I know who spend 1-2 years of paperwork, tens of thousands of hard earned dollars, emotionally taxing ages of waiting to do the same process. Do I have sour grapes? Sure. Would I prefer to have millions of dollars to just slap down and bring our little Miley home? Absolutely. But I don't. I just wish more people would be able to see how difficult it is to adopt a child if you are not a 'super-star'. That you have to invest a lot of your time, money, effort, heart and life into bringing this child home. It is certainly not the child-shopping-network that the super-rich get to use when it strikes them that they want a baby without the hassle of that whole getting pregnant thing.

---END RANT---

So anyway, thanks for reading. If you want to make a contribution to our adoption you can of course use the chipin widget on my sidebar.

Thursday, February 15, 2007

The Lost Podcast with Jay and Jack

After the most recent Lost episode "Flashes before your eyes" I called into the Lost Podcast with Jay and Jack and they put my call on the show. Check it out Here and you can check out their website here.

Jay and Jack do 2 podcasts a week, one right after each new episode where they do a rundown of the episode and play listener calls and then a recap show on the following monday. They do give out some spoiler type information, but usually give a good warning to skip ahead when they do. Give them a listen if you like the show Lost on ABC.

johnnygizmo

Wednesday, January 24, 2007

getCals Getting Hosted

I recently got an email offering to host getCals since Google decided I broke their EULA somehow on googlepages. Once I have a new link available, I'll post it here. Also if you have used getCals in the past or get it in the future and want to show your appreciation, you can always use the chipIn box here to make a donation towards our family's adoption of a little girl from El Salvador.

---EDIT---

Well, here it is. Thanks Nick for hosting it for me!

getCals

Adoption Fund Raiser

We have all heard the Internet stories about people posting websites asking for money for this or that, or trading paperclips for mansions or whatever. Well I guess I thought that I would see if I can tap into some of that love to assist in our adoption story. Using a site called Chipin.com, I have set up a fund raiser for our adoption. I put in the most $ we will probably need and gave it a year. If you would like to donate to our cause, please feel free. We will find the funds one way or another to bring little Miley home. Perhaps you can help.


As an update on our process, we are getting done with our paperwork phase and are in the process of doing our 'home study'. Things are moving along. It is hard to think though that we will have to wait for so long after we get the paper and money sent in before we can bring her home.

Thanks for reading
Johnny

Saturday, December 23, 2006

A Simple Juggling Video

I had a little time on my hands and so I grabbed the video camera and did a little juggling so I could see what I looked like. Here is some of that. Some simple diabolo, 4 ball and 5 ball juggling. No tricks to speak of, just basic stuff. So if you are easily bored, don't watch :) And hey I'm even wearing my WJF t-shirt. I'm sure Jason Garfield would be proud (or would hide his head in shame that I am in any way assosicated with the WJF)



Sunday, October 22, 2006

Start of Our Adoption Journey

Well, we got the news last week that we have been accepted by an Adoption agency to begin the process of adopting a child internationally. This is pretty exciting and hopefully in the next 12-18 months we will go to El Salvador and pick up our child. There is lots of paperwork and expenses to the dealt with between now and then and we are trying to get everything in order for it to happen. All told, it will probably end up costing somewhere between $15k-$20k dollars to complete the adoption process, but we are holding fund raisers and are being supported by our family to help cover the costs, but even still it is going to take a lot. If you or anyone you know wants to help by making a donation, send me an email johnny.matthews+adoption@gmail.com. If you can not help financially, that's fine, but we would appreciate your prayers as we follow this path.

Friday, October 20, 2006

Juggling with an Oddball

I've been working on 5 balls for a while now, I don't get as much practice as I would like, so I have been trying to make the most of the few minutes I get here and there. One issue I have with 5 balls is counting throws. I am trying to get certain throw counts solid before moving on.

I have been stuck at 7-8 throws for a while. So last week I picked up 4 balls of one color and 1 of another to act as a sort of "tracer". Now I place the odd ball in the 5th ball position. For me, this is in the palm of my left hand (I start on the left)




Now it is visually very easy to see throw #10 is the 2nd throw of the odd ball. It is also easy to figure other #'s of throws this way. If you wanted 13 throws, put it in the 3rd ball position and it will be the 3rd throw. You just need to know in what order you throw the balls.

Now I'm sure this is not rocket science to anyone, and certainly not a new idea, but I must say in a matter of a couple practices I have gotten to 16 throws after a couple months of only having had qualified a couple of times. Now I can qualify most of the time and am ready to make some upward progress.

I have also thought of a way to introduce an idea that I used to use whe practicing the guitar. I would set my metronome to a tempo where I could accomplish what I wanted to play. Then I gave myself a few tries at that tempo. If I played it to my satisfaction I would bump up a notch, otherwise after a few tries I would go down. So applying this to learning 5 balls. I start with a flash. When I do it well, do 6 throws. Now if I don't get 6 within 3 tries, I go back to 5. If I do get six, I go to seven throws. 3 tries at 7, if I get it I go to eight, otherwise back to six. You get the idea. So using this in conjuction with the oddball, once you learn where to place the oddball for 5-25 throws, it should be an easy game to play to help get the pattern solid without making yourself go insane counting to 8,9,8,9,10,11,10,11,12 etc.

What are your thoughts? How did you work through the initial hump? Let me know what you think.

Tuesday, September 12, 2006

The Happiest Place on Earth

Ok, so Me, my Wife and 4 kids piled into the minivan, drove 1000 miles and spent a week at Disney World. We had a great time. Let me give you the run down on what we did and my recommendations...

Dates

If you ever go to Disney on a non-peak week, you will never go at another time again. We went the week after labor day and never spent more than 15-20 minutes in any given line. Most waits were between 5 and 10 minutes. When you have small kids with you, this is tremendous!

Dining

Since September is a slow month for Disney, they were offering the Disney Dining Plan for free with certain packages. This plan gives each member of your group a Snack, a Counter Service Meal and a Table service meal every day of your visit. We tried our best to keep track and we totaled about $1000 worth of meals. So if you are going, check this out. It saved us a chunk of cash and allowed us to eat some meals that we probably would not have eaten. The $25 Prime Rib at Boatwrights was especially good. :) I also learned not to ask for Ketchup at the Wilderness Lodge resturant.

Magic Kingdom

I don't know how they do it, but the Magic Kingdom never ceases to amaze me. I really think it is Disney's attention to detail that really draws you into their parks. Every waiting queue for every attraction is in some way decorated so that you want to check it out.

Disney / MGM

3 things really stood out to me at MGM:

1: The Lights,Motors, Action Stunt show. This was a really cool car/motorcycle stunt show and was very impressive.

2: The Tower of Terror. I went on the ToT in 1997 and it was fun, but apparently there was an upgrade in 2004 that added random drops. That made it much better!

3: The Rockin' Roller Coaster. Ok, the lamest name ever, but the best thrill ride at Disney. A linear induction coaster goes from 0-70ish in 2.8 seconds, and sends you into 3 inversions including a really nice corkscrew, and all in the dark with some blacklight scenery and Aerosmith blasting in your ears the whole time. mmmm fun!

Animal Kingdom

Animal Kingdom was a nice park. The safari ride was cool, some nice views of the animals. The River Rapids ride was good, but really short. The best ride there is definitely The Everest Expidition. So good drops and some good speed and some backwards coasting as well. I was a little surpised about the "kiddie ride" area it felt almost like a midway at a county fair. Some of the rides seemed like they were assembled that day. Strange for Disney.

Epcot

Epcot was fun as always. They have done a lot of updating. The Test Track ride was pretty good, especially when it goes outside for the banked curves. I took my 7 year old on the tame version of Mission: Space. I would like to go on the intense version next time.

We saw the afternoon main street parade, the Spectralmagic parade, the Illuminations show and the "Wishes" fireworks display. I think sitting in front of the castle watching Wishes was a real high point for everyone.

So all in all, it was a great vacation. I can't wait to go back.

Wednesday, August 30, 2006

New WJF Site

Well, after a lot of tweaking, the WJF is now running its new website design. You can check out the work I did at:

http://www.thewjf.com

Jason had a pretty good idea of what he wanted, so it has been a matter of assembling the site and making it work. It is pretty graphics intensive, so there are still some optimizations to take care of. But at least we got it launched in the timeframe that we had initially wanted.

The site is not completely done yet, there are still some sections to convert from the old site (like the videos) and some new stuff in the wings, but that is for after a well needed vacation.

So go check it out, and while you are there buy some quality juggling balls and learn to juggle :)

For me and my family, it is off to Disney World. We have been planning a vacation there for months and the time has come. We will drive down to FL and spend the week. Wwill have missed Hurricane Ernesto, so I think we just have to deal with the regular Florida weather.

Saturday, August 19, 2006

Movie Review: Snakes on a Plane

I got a call last night at about 8:30pm from some old friends who were going to go see Snakes on a Plane. I hadn't seen them all in a while and thought it would be a fun night out. So we headed up to the Globe Theater in Greenville, IL. Where I shelled out $7 for my ticket and $4.50 for my drink and popcorn, which in my opinion is a bit steep for the size of the theater and non-stadium seating. But hey, it's the only theater within 20 miles.

After a lot of previews the fun began. Since leaving the movie last night, I have been trying to come up with the genre of this film. It is a campy-action-survival horror-horror comedy-thriller-cop movie with an improbable plot and over the top action, it was great. Besides, it's Samuel L Jackson! I do have to warn you that there is a fair amount of profanity, violence, gore and breif nudity. It really took me back to the pointless action movies of the late 80's combined with the tongue in cheek horror films of the same time. Where you can find yourself in one second laughing cause a poisonous snake just bit someone on the bum followed by going ugh when someone get bit right on the eye, or more tender areas. If you get easily squeemish with snakes, don't see this movie. If you get stressed from airplanes in peril, don't see this movie. If you want to go see a movie thats sole purpose is a fun action filled time with no regard for logical plot, this might be a good one for you. So... Check your movie critic attitude at the gate and get on board "Snakes on a Plane".