Cow Pong: A simple Xna game in F#

F# is akin of melting pot language, including some interesting features from various functional languages like Haskell, OCaml and so on. It is very succint, readable and it is ML-based.
I’ve realized a simple Pong-clone game using the XNA framework in F#, and this is the result:

// A semiserious game // Learn more about F# at http://fsharp.net open System open Microsoft.Xna.Framework open Microsoft.Xna.Framework.Graphics open Microsoft.Xna.Framework.Input open Microsoft.Xna.Framework.Content type Paddle(posX : int, posY : int) =     let speed = 10     let x = posX     let mutable y = posY     static member W = 50     static member H = 80     member this.X with get() = x     member this.Y with get() = y and set v = y <- v     member this.Bounds         with get() = new Rectangle(x - 100, y - Paddle.H / 2, Paddle.W, Paddle.H)     member this.Move (keyUp : Keys) (keyDown : Keys) =         let ks = Keyboard.GetState()         if ks.IsKeyDown(keyUp)             then y <- y - speed         if ks.IsKeyDown(keyDown)             then y <- y + speed type Ball() =     let mutable x = 0     let mutable y = 0     let mutable vx = 0     let mutable vy = 0     let mutable number_of_bounce = 10     static member W = 20     static member H = 20     member this.Number_of_bounce         with get() = number_of_bounce and set v = number_of_bounce <- v     member this.X with get() = x and set v = x <- v     member this.Y with get() = y and set v = y <- v     member this.Bounds         with get() = new Rectangle(x - Ball.W / 2, y - Ball.H / 2, Ball.W, Ball.H)     member this.BounceX() =         this.Number_of_bounce <- this.Number_of_bounce + 1         vx <- -vx     member this.BounceY() = vy <- -vy     member this.Start (velX : int) (velY : int) =         vx <- velX         vy <- velY     member this.Update() =         x <- x + (int (this.Number_of_bounce/10))*vx         y <- y + (int (this.Number_of_bounce/10))*vy     member this.Collide (p : Paddle) = this.Bounds.Intersects(p.Bounds) type Game1() as this =     inherit Game()     let graphics = new GraphicsDeviceManager(this)     let contentManager = new ContentManager(this.Services)     let mutable spriteBatch = null     let mutable texture = null     let mutable left_paddle = null     let mutable background = null     let mutable ball_texture = null     let left = new Paddle(Paddle.W * 2, 300)     let right = new Paddle(820, 300)     let ball = new Ball()     let rand = new Random()     let mutable leftScore = 0     let mutable rightScore = 0     let clampY x : int =         if x < Paddle.H / 2 then Paddle.H / 2         else if x > 600 - (Paddle.H / 2) then 600 - (Paddle.H / 2)         else x     let reset (b : Ball) =         let mutable x = 0         let mutable y = 0         if rand.Next() % 2 = 0 then x <- -3 else x <- 3         if rand.Next() % 2 = 0 then y <- -3 else y <- 3         b.X <- 400         b.Y <- 300         b.Number_of_bounce <- 10         b.Start x y     let bounce (b : Ball) =         if b.X < Ball.W / 2 then             rightScore <- rightScore + 1             reset b         else if b.X > 800 - Ball.W / 2 then             leftScore <- leftScore + 1             reset b         if b.Y < Ball.H / 2 then             b.Y <- Ball.H / 2             b.BounceY()         else if b.Y > 480 - Ball.H / 2 then             b.Y <- 480 - Ball.H / 2             b.BounceY()     override Game.LoadContent() =         spriteBatch <- new SpriteBatch(this.GraphicsDevice)         background <- contentManager.Load<Texture2D>("xnb/green-field")         left_paddle <- contentManager.Load<Texture2D>("xnb/cow")         ball_texture <- contentManager.Load<Texture2D>("xnb/sheep")         texture <- new Texture2D(this.GraphicsDevice, 1, 1);         texture.SetData([| Color.White |])         reset ball     override Game.Update gameTime =         left.Move Keys.W Keys.S         right.Move Keys.Up Keys.Down         ball.Update()         bounce ball         left.Y <- clampY left.Y         right.Y <- clampY right.Y         if ball.Collide(left) || ball.Collide(right) then             ball.BounceX()     override Game.Draw gameTime =         this.GraphicsDevice.Clear(Color.Beige)         spriteBatch.Begin()         spriteBatch.Draw(background, new Vector2(0.0f, 0.0f), Color.White)         spriteBatch.Draw(left_paddle, left.Bounds, Color.White)         spriteBatch.Draw(left_paddle, right.Bounds, Color.White)         spriteBatch.Draw(ball_texture, ball.Bounds, Color.White)         for i in 1 .. leftScore do             let r = new Rectangle(50 + i * 10, 5, 5, 5)             spriteBatch.Draw(texture, r, Color.Black);         for i in 1 .. rightScore do             let r = new Rectangle(750 - i * 10 - 5, 5, 5, 5)             spriteBatch.Draw(texture, r, Color.Black);         spriteBatch.End()         base.Draw(gameTime) let g = new Game1() try g.Run() finally g.Dispose()

At the end of the post I will link the entire project as well. As you can see it’s very easy to create a game from scratch, thanks to the support of the XNA Framework. The only tangible problem is related to the creation of the sprites file, due to the lack of support for Contents creation in Visual Studio F#.
A possible workaround is to create a dummy C# project, load all your images there and then compile. You will find all the created .xnb files inside the project directory. Finally, you need to copy the generated files into your bin directory. Here is a screenshot:

And there you can download the entire project:

CowPong.zip

Enjoy!

Annunci

Fixing Slime’s “connection broken by the peer” with Lispbuilder-sdl

Something more than a mental note.
While programming with Common Lisp using the Lispbuilder-sdl library probably you want to evaluate your programs within Emacs and Slime (as usual.)
By the way, even with the simplest SDL program on slime-eval-region (or whatever else) Slime terminate in an expected way with this message:

[…]Connection broken by the peer[…]

Googling hard, I’ve found a solution that works like a charm!
First of all, open your swank.lisp file (you can find it inside your Slime installation), then add this line:

(setf swank:*communication-style* :fd-handler)

Done! It was simple enough, wasn’t it?
Now you can evaluate your lisp game within Emacs!
Enjoy!

2010 in review

The stats helper monkeys at WordPress.com mulled over how this blog did in 2010, and here’s a high level summary of its overall blog health:

Healthy blog!

The Blog-Health-o-Meter™ reads Fresher than ever.

Crunchy numbers

Featured image

A helper monkey made this abstract painting, inspired by your stats.

A Boeing 747-400 passenger jet can hold 416 passengers. This blog was viewed about 3,000 times in 2010. That’s about 7 full 747s.

 

In 2010, there were 16 new posts, growing the total archive of this blog to 30 posts. There was 1 picture uploaded, taking a total of 14kb.

The busiest day of the year was October 13th with 143 views. The most popular post that day was Introduction to Leiningen.

Where did they come from?

The top referring sites in 2010 were python-it.org, reddit.com, enrico-franchi.org, facebook.com, and davidcramer.net.

Some visitors came searching, mostly for public static void main string args, public static void main, python vs c, python vs java, and public static void main(string[] args).

Attractions in 2010

These are the posts and pages that got the most views in 2010.

1

Introduction to Leiningen October 2010
1 comment

2

C vs Python vs Java December 2008
3 comments

3

Crittografia pure-python? Si, grazie! January 2009
2 comments

4

About me December 2008
11 comments

5

How to finally fix that damned MySQLdb module on Leopard January 2009
1 comment