XNA F# Breakout Clone - Model Tutorials

Thursday, May 7, 2009 by gradbot

I'm impressed by how easy it is to use Models in XNA and because of this I'm demoting my render engine to line drawing only. Here is how I went about getting Models into my game.

  1. First you will need software to create models and Autodesk has a free version of just that. Autodesk Softimage Mod Tool 7.5
  2. Watch this video so you can create and export your 3D models correctly. The video series and blog post can be found here.
  3. Third you can follow the Microsoft tutorials to get your models in game Microsoft Tutorial on displaying a 3D Model or you can continue the blog from the previous step.
  4. Finally you will need some video tutorials on how to use Autodesk to create more complex models. XSI Video Tutorials


Filed under , , , , having  

Breakout Clone - Added Physics Engine and Sound - F# XNA

Sunday, May 3, 2009 by gradbot

I added the Farseer Physics Engine to my game along with XNA sound effects. I'm amazed by how easy it was to use this physics engine. Collisions are handled by Delegates which you create in F# by passing a function to the delegate constructor.


ball.Geometry.OnCollision <-
Geom.CollisionEventHandler(
fun geom1 geom2 contactList -> true)

My current plan is to add different shapes to the blocks, different masses, and maybe events such as an explosion.


Filed under , , , having  

Knockout Clone - Discriminated Unions with F#

Monday, April 27, 2009 by gradbot

F# supports discriminated unions. This along with pattern matching makes for some short and elegant code which quite frankly is awesome. Here's a small example.

type PieceType = Breakable | Solid

member this.needsDisposing() =
match pieceType with
| Breakable -> (life <= 0)
| Solid -> false

member this.points() =
match pieceType with
| Breakable -> 1
| Solid -> 0
Here I use a property of type PieceType to both define when a piece on the board needs to be removed and if the piece returns a point when it is hit. The calling class has no knowledge of this state and filters out pieces based on the returned bool flag needsDisposing() along with adding whatever is returned by points() to the total point score.





Breakout Clone - Line Segment Intersection Algorithm

Sunday, April 19, 2009 by gradbot

For my next game Breakout, I need to detect collisions for a moving object. I choose line segments to represent object borders and motion. Calculating line segment intersections is a simple and fast algorithm and there are more advanced scan line algorithms to speed it up if needed. In order to use it, I take the ball's position and old position as the line segment for the ball.

The hard part of any collision algorithm is of course dealing with the collision. Detection is always easy because it's been done before. I'm doing collision with a simple reflection of the velocity off of the line segment it's intersecting. This works great until you collide close to another line segment and you happen to reflect to the other side of it. To fix this, I made the intersection and reflection algorithm recursive. This works great except for possible race conditions. Also, you no longer have a constant speed for your ball. A quick fix for the race condition is to check to make sure you can't intersect with the same line segment twice in a row. Having the ball move a little faster is acceptable.

Project Homepage

Here's a burn test where I had set the ball to a very high speed to see if it could escape it's enclosure or enter one of the other objects. In order to make any errors apparent, I added a line trail of a random colors behind the ball. This ends up filling in all of the movable area.

I must say it's pretty cool to see the ball travel to every little nook and cranny of the board. This must be how particle chaos works. Like a fragrance filling the room.

Filed under , , , having  

Tetris in XNA with F#

Saturday, April 11, 2009 by gradbot

I learned a few things on this project. One is that arrays are not the end all of data structures. My first instinct from my C++ background was to make a 2D array for the tetris game board. After wasting an hour or two I realized that it was over complicated and that a Set would work really well.

Basically each piece in the game is a set of tuple points. The game board boarder is a set of tuple points and the already fallen pieces is a set of pieces. I had to keep the concept of a piece in order to keep the color associated with each tuple point. This setup made collision detection simple. It was just a matter of Seq.union_all and Set.intersect

I'm pretty amazed by the relatively few lines of code it took me to recreate the game. The main game logic is incredibly small. Most of the code is spent setting up the system and handling user input/graphics.

Project Time: 13 hours
Project - Source Code

The game is played with the DPad and A/B buttons.

Filed under , , having  

Learning from the Classics

Tuesday, March 10, 2009 by gradbot

So I decided while working on my platformer that I need to reduce the number of jobs I'm undertaking while I program. In order to do that I'm dropping creative director and am instead recreating classic titles. I'm still project manager since I need to manage my time and my development goal has to be playability if I'm ever going to get anything playable.


The below list contains all the 2D video game genres I can think of. I'm going to pick a game and spend a few weeks recreating it and then move on to another game in a different genre. I hope to learn the different challenges associated with each genre and what game mechanics cross genres. I have other long term goals but i'll worry more about those once I have a few games playable.

2d paddle - knockout, pong
2d shooter - galaga, zanak, space invaders
2d platformer - metroid, mario, kurby, castlevania, sonic
2d puzzle - tetris, dr. mario, generic match 3 game
2d maze - pacman, frogger
2d hack & slash - gauntlet, zelda, diablo, crono trigger
2d fighter - street fighter
2d rpg - final fantasy, dragon warrior
2d simulation - simcity, trains
2d strategy - civilization
2d rts - starcraft, red alert, dune 2, lemmings
2d racing - r.c. pro am, excite bike, mario cart
2d board game - chess, checkers, go, othello
2d projectile - gorrila, scorched earth, tank

I'm going to contenue using F# and XNA as they have served me well so far.

Filed under having  

Added runtime fx compilation and lighting

Tuesday, February 17, 2009 by gradbot

I spent some time fighting with matrices to get the lighting correct but I'm happy now that I have a rotating and moving object in XNA that is lit from a single stationary source. I'm using the plastic shader that comes with NVIDIA FX Composer 2.5.




Here's my runtime code that compiles a fx file into an Effect.


let compileEffect(fileName : string)=
let compiledEffect =
Effect.CompileEffectFromFile(
fileName,
null,
null,
CompilerOptions.Debug,
TargetPlatform.Windows)
let effectCode =
compiledEffect.GetEffectCode()
new Effect(
this.graphics.GraphicsDevice,
effectCode,
CompilerOptions.Debug,
null)

source code

Filed under , , having  

Moving along in XNA

Saturday, February 14, 2009 by gradbot

I added a shape class and some basic shapes made out of line segments. Along with this i added collision for the line segments with a player and mapped the first controller pad to control it. Jumping is very basic and gravity is simple.





Images from the project.


source code: github.com/gradbot/xna-f-sharp

Filed under , , having  

Rotating Triangle in F#

Sunday, January 4, 2009 by gradbot

For my first project in F# I ported a simple C# XNA project that draws an rotating triangle. The original C# article can be found here.

I'm using Microsoft F#, September 2008 CTP (Community Technology Preview) and Microsoft XNA 3.0 CTP

You can download the complete solution here.




#I @"C:\Program Files\Microsoft XNA\XNA Game Studio\v3.0\References\Windows\x86";;

#r @"Microsoft.Xna.Framework.dll";;
#r @"Microsoft.Xna.Framework.Game.dll";;

open System
open System.Collections.Generic

open Microsoft.Xna.Framework
open Microsoft.Xna.Framework.Audio
open Microsoft.Xna.Framework.Content
open Microsoft.Xna.Framework.Graphics
open Microsoft.Xna.Framework.Input
open Microsoft.Xna.Framework.Storage

type MyGame =
inherit Game

val mutable graphics : GraphicsDeviceManager
val mutable content : ContentManager
val mutable effect : Effect
val mutable world : Matrix
val mutable view : Matrix
val mutable projection : Matrix

new() as this =
{
graphics = null
content = null
effect = null
world = Matrix.Identity
view = Matrix.Identity
projection = Matrix.Identity
}
then
this.graphics <- new GraphicsDeviceManager(this)
this.content <- new ContentManager(this.Services)
this.view <-
Matrix.CreateLookAt(
new Vector3(0.0f, 0.0f, 3.0f),
Vector3.Zero,
new Vector3(0.0f, 1.0f, 0.0f))
this.projection <-
Matrix.CreatePerspectiveFieldOfView(
MathHelper.Pi / 4.0f,
(float32)this.Window.ClientBounds.Height / (float32)this.Window.ClientBounds.Width * 3.0f / 2.0f,
0.01f,
1000.0f)

override this.Initialize() =
base.Initialize()

override this.LoadContent() =
this.effect <- this.content.Load("colorfill")

override this.Draw(gameTime) =
let gd = this.graphics.GraphicsDevice
gd.Clear(Color.Green)

let vertex = [|
new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.0f), Color.Red);
new VertexPositionColor(new Vector3(0.0f, 0.5f, 0.0f), Color.Blue);
new VertexPositionColor(new Vector3(0.5f, -0.5f, 0.0f), Color.Yellow);
|]

gd.RenderState.CullMode <- CullMode.None
gd.VertexDeclaration <- new VertexDeclaration(gd, VertexPositionColor.VertexElements)

this.effect.Begin()

for pass in this.effect.CurrentTechnique.Passes do
pass.Begin()
gd.DrawUserPrimitives(PrimitiveType.TriangleList, vertex, 0, 1)
pass.End()

this.effect.End()

override this.Update(gameTime) =
if (GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed) then
this.Exit()

this.world <- this.world * Matrix.CreateRotationY(MathHelper.TwoPi / 360.0f)
this.effect.Parameters.Item("WorldViewProj").SetValue(this.world * this.view * this.projection)
base.Update(gameTime)

let game = new MyGame()
game.Run()

Filed under , , having