Wed
Apr 15th

Beautiful Algorithms 1: Fire Part 2

Yesterday I introduced Processing and Ruby Processing in Part 1.  This part is the meat and potatoes of the tutorial: the fire algorithm and the Ruby that generates it.

The Algorithm

You can watch a screencast of the fire algorithm in action here: fire-processing-rb.  It looks like a sophisticated animation: waves of fire rise up from the bottom of the window at different angles and gradually get thinner, moving through red, orange and yellow until they fade away.  Modelling this using shapes would be incredibly complicated.  Fortunately, creating this illusion is deceptively simple.

To make fire, generate random colours at the bottom of the screen:  a row of pixels of red, orange and yellow.  Then move up a row and take the pixels to the left and right, and the original pixel below, and average the colours for each of them.

For each frame of the animation (so 30 times a second), repeat this process for every row on the screen.

The Algorithm Again in a Numbered List

Just in case that was confusing, here’s the fire algorithm again in a list:

  1. Create a row of pixels at the bottom of the screen that are random shades of red, orange and yellow
  2. Move up a line
  3. Loop through each pixel on this line averaging the pixels around the current pixel
  4. Once the top of the screen is reached, draw the results and go to 1

Colours

The colours in this algorithm are important: red, orange and yellow banded shades must be created so the algorithm will appear to blend between them.  I’ve stored the colours in an array like this:

Although this doesn’t look too exciting, it’s a major part of creating the fire illusion.

Averaging Pixels

The pixel colours are averaged, but a cap on their maximum brightness is used, along with a gradual reduction in brightness.  I’ve set a variable that controls the intensity of the flame so you can experiment with it.

The Result

Here is the result in my fire-p5r repository: fire.rb — you can run this with rp5 run fire.rb.

If you’d like to improve on my algorithm, try making it work with Processing’s pixels array rather than rect, and drawing rectangles of pixels.  This should work faster than using rect.

Comments (View)
Tue
Apr 14th

Beautiful Algorithms 1: Fire

In this two-part article we’re going to use Ruby to make a fire animation.  It’ll look like this:

In my previous Ruby tutorial, Let’s Make a Game, I explained how to use Ruby and Shoes to make a game.  Another way to get graphics on the screen in Ruby is to use Processing.

Note: Code examples require JavaScript to run, so please view this article in your browser rather than a feed reader.

Processing

Processing is a Java-based system for creating interactive art.  It’s fast too, so you can create pretty complex graphical effects and scenes, even using 3D graphics.  The processing site has lots of examples which will run in your browser.

Like Shoes, Processing gives you a simple toolkit for working with graphics.  Take a look at the Processing reference to see how simple the API is: shapes can be made with rect(), triangle(), ellipse(); stroke and fill colours can be set with stroke() and fill().

Try downloading Processing and run a few examples.

Ruby Processing

The Processing API might be simple, but learning Java to use it is not.  It requires relatively strict syntax, and you need to pay attention to types.  Ruby Processing is a way of using Processing from a Ruby script, and takes some of the pain out of the Processing experience.

To install Ruby Processing you need rubygems installed.  If you’ve got Mac OS Leopard, you’ve probably got it.  If you’re using an older Mac OS (or Linux), it’s best to download it from the rubygems site and install it manually.

Then use either gem1.8 or the gem command to install (it was gem1.8 for me in Ubuntu):

sudo gem install processing

This will make the rp5 command available.

Ruby Processing Basics

Start a project (Processing calls projects sketches) like this:

rp5 create fire

Next, edit the fire.rb file so it looks like this:

This will draw a white rectangle.  The setup and draw methods are automatically added by Ruby Prototype;  setup is called when the sketch is started, and draw is called every frame.

To run the sketch, type this:

rp5 run fire.rb

Next Part

Now you’ve got Ruby Processing going, you can try out the full fire example.  The code is in my GitHub repository: fire-p5r.  I’ll explain how it works in the next part.

Windows Users: If you use Windows and get Ruby Processing running, please leave a comment for Windows users and I’ll include it in the article.

Comments (View)
Sat
Apr 11th

Quite Useful Weekly Roundup

This week I concluded the Let’s Make a Game Series.  I also announced the start of a new series, Beautiful Algorithms, in which I’ll discuss beginner-friendly graphical algorithms alongside examples from the history of computer graphics.

I’m going to take Monday off, so you’ll see Beautiful Algorithms start on Tuesday.

Twitter Summary

Developer

cdargs has made a big difference to the way I work.  It’s a little thing: bookmarks for cd in the command line.  Despite being a simple tool it makes it easier for me to switch between projects; which I need to do a lot in an average day.

Chartbeat looks like a friendly way of keeping track of service outages and page load times.  I don’t like the use of speedometers on their dashboard, they take up a lot of space that could be used for other information, but it’s worth checking out.

Designer

The Tools Artists Use is an interesting blog.  Hearing about the tools artists use is fascinating, yet something not usually discussed in detail.

Boks is a way to explore CSS: it’s an Air app that provides an interface for Blueprint CSS.

Smarthistory is an alternative to art history text books.  I actually love reading art history books, as dry as they are.  Smarthistory’s clever use of modern web design techniques, videos, audio and short text will definitely appeal to students.

iPhone

iPhone Mobile Air Mouse turns your iPhone into a mouse.  This makes using your computer from a couch easier, or might be cool for presentations.

Comments (View)
Fri
Apr 10th

Beautiful Algorithms

I enjoyed writing the Let’s Make a Game Series, so I’m thinking about a followup with a guide for writing Pacman or Space Invaders.  In the meantime, I’d like to start a new recurring series called Beautiful Algorithms.

This new series will explain how to write graphical effects.  I’m going to stick to Ruby or possibly JavaScript — languages with simple syntax that won’t scare off newcomers.  I’m researching old school demo scene graphics, because that’s what got me into programming in the first place (back on the Sinclair and then Amiga computers).

Here’s a preview:

The Demo Scene

Demos and intros were big in the 90s in Europe.  Programmers, artists and musicians collaborated to create audio visual experiences, pushing hardware to the limit.  They coaxed realtime raytracing (glossy 3D graphics) out of Amigas — machines many times less powerful than your iPhone.

Fortunately, you don’t need old computers to appreciate demos, people post them to YouTube all the time.

Desert Dream

Desert Dream Part 1, Desert Dream Part 2

This demo is one of my favourites.  It ran on Amigas and was release in 1993.  The music in this demo is still amazing.  It’s pretty typical: effects are showcased with ridiculous showboating, barely knit together into a narrative, complete with mockery of other demo groups.  The dot effects haunted me for years, I couldn’t figure out how they drew so many with such a good framerate.

Jesus on E’s

YouTube Playlist for Jesus on E’s

This is another Amiga demo, released in 1992.  More famous for its music than graphics, but slickly put together.  It’ll probably remind you of acid house if nothing else.  It features an effect where curves are plotted and the colour is increased as they overlap (screenshot above), which is the first effect I figured out in my early programming days.

The Black Lotus

The Black Lotus

This was made in 2005 — people still make Amiga demos, and they’re still getting new things out of the hardware.  The 3D dancer is particularly impressive.  This demo is a good example of how (in some areas) the scene has matured.  To see another example of this shift in culture, get Linger In Shadows off PSN for PlayStation 3.

Demos are what got me into programming: I used to spend hours studying C and trying to recreate the effects on my Amiga 500.  It was probably a tough introduction to programming, but it made me realise that making and experimenting with cool graphical algorithms was a great place to start: it was far less boring than studying gigantic books with examples about businesses and databases.  So please forward Beautiful Algorithms links on to anyone who you know who wants to learn programming.

Comments (View)
Thu
Apr 9th

Let’s Make a Game: Wrap Up

In this tutorial series I explained how to build a version of the game Snake.

  • Part 1: Covers installation of Shoes and explains how the snake moves and how to control it with the keyboard
  • Part 2: Basic collision detection, eating food to make the snake longer
  • Part 3: Collision detection for bricks and the snake, stopping the main animation when the snake crashes
  • Part 4: Handling scores, game over screen and restarting the game.  This part also shows how to draw a border around the level, and explains how to use Git to get my code
  • Part 5: Sounds and ideas for better sound support

Making games with Shoes and Ruby is fun and relatively easy.  You could use the same approach to make any classic game, from Space Invaders to Pacman — the algorithms are similar for any programming language, so using Ruby is a gentle introduction and a great way to experiment.  Shoes even has examples of games like Minesweeper and Pong here: Shoes samples.

Comments (View)
Wed
Apr 8th

Let’s Make a Game 5: Sounds

Shoes doesn’t have great audio support right now, but it ships with multimedia capabilities provided by the VideoLAN and ffmpeg libraries.

To use audio, use the video keyword with a wav or mp3.  You can hide the resulting video object so it won’t take up layout space.  One limitation of audio playback is you only have a single stereo channel, which means you can’t multiplex audio (I might be wrong, but I haven’t found a way to do this).  This is usually required in a game, so our audio will be fairly limited, but good enough to get things going.

I’ve made a small class to manage audio in our snake game.  It makes managing sounds easier:

  • Add sounds with @sounds.add_sound :death, 'death.mp3'
  • Playing a sound will automatically stop other sounds
  • I’ve bundled sounds for collecting items and death

The current version of this tutorial in my snake-shoes git repository is here: snake-shoes-6d88.  You can download the sounds and code there.

The sound class looks like this:

Other Options for Sound

One way of handling audio would be to rely on a library like libSDL.  Rubysql would be a good starting point.

Dependencies

If your Shoes applications start to require libraries, you can manage them with Shoes.setup:

Shoes.setup do
  gem 'library'
end
Comments (View)
Tue
Apr 7th

Let’s Make a Game 4: Scores and Death

Note: Remember to view this article on Quite Useful’s site in case you can’t read the code examples.

The snake game we’ve been building over the last 3 articles is still pretty basic.  The player can’t restart a game, there’s no score, food doesn’t reappear, and the snake can slither off the screen.

If this is the first part you’ve read, check out Part 1 to see how to get started.

In this part we’re going to:

  • Track the snake’s death
  • Track the player’s score
  • Add a border around the game board
  • Allow the player to restart the game after death
  • Introduce source code version control

Here’s what the results will look like:

The Boundaries

The game currently lays out random bricks and food using [rand(50), rand(50)].  Where did 50 come from?  I made it up for testing!  We need to store the boundary of the board so it can be reused by the collision detection methods and for positioning game items.

GameBoard#initialize will be modified to record this:

  @boundary_x = [1, 58]

@boundary_y = [4, 48]

By the way, the ClassName#method_name notation is commonly used by Ruby programmers to refer to “instance methods” — methods that can be run when a class has been instantiated (created, initialized) with new.

Next we need to make the random coordinate code reusable so bricks and food can use it when setting up the game board.  GameBoard needs this method:

  def random_coordinate

[rand(@boundary_x.last - @boundary_x.first - 1) + @boundary_x.first + 1,

rand(@boundary_y.last - @boundary_y.first - 1) + @boundary_y.first + 1]

end

This will return a coordinate within the boundary.  The boundary is now flexible, and can be resized as required.  These variables can be used to draw bricks to represent the boundary:

I use Brick.new here rather than add_brick because I don’t want the collision detection methods to search for boundary collisions.  This is because they add a lot of tiles to the brick array, and we’d have to check for collisions on them every animation loop.  Instead, the crashed_into_brick? method needs to detect boundary collisions:

return true if @snake.x == @boundary_x.first or @snake.x == @boundary_x.last

return true if @snake.y == @boundary_y.first or @snake.y == @boundary_y.last

Splat!

The GameBoard#random_coordinate method can be passed to all methods that take x and y coordinate parameters.  Even though this method returns an array, it can be passed as two parameters to a method using the splat operator:

add_food *random_coordinate

This method is defined as def add_food(x, y), but the splat operator (*) will allow us to pass the array that random_coordinate returns.

Death

We need to track the snake’s death so the game knows when the game can be restarted without losing the player’s progress.  Simply add an instance variable to the Snake class called dead, and set it to false in the initialize method.  Then, when the snake dies in the animation loop, set it to true.

I’ve changed the keypress detection code to respond to ‘r’ only when the snake is dead.  This allows the game to be restarted:

A setup method must also be added so the game board and snake can be reinitialized.  Shoes lets us use clear to clear all objects, which will both clear the display and free up the memory they were using.

Scores

Adding text in Shoes is easy, just write a paragraph with the para method.  Like most methods in Shoes, para will return an object that can be modified later.  Whenever the snake eats food, the score’s text can be updated like this:

@score.text = "Score: #{@board.score}"

Version Control

The code’s actually getting quite long now.  Adding huge examples in a blog post isn’t a great idea, so I’m going to put the code in a version control system.  If you’re a programmer who’s just following this for fun, you’ll know all about version control so you can skip this and get my code at the end.  Otherwise, it’s worth reading just to get the basics.

I’m going to show you how to use Git for version control.  I already have a folder called snake, with snake.rb inside it.  I’ve got an account on GitHub which lets me share code with people.  GitHub will let you download a zip of my code, but you could also install Git and checkout the code yourself.

Windows: Try tortoisegit

Mac: See GitHub’s installation methods

Linux: Most package managers have git as git-core (ubuntu/debian do)

To get my snake code, you need to clone my repository from the public clone URL:

git clone git://github.com/alexyoung/snake-shoes.git

To get subsequent updates, run git pull.  To see changes, run git log.

The beauty of using git is you could fork my snake code on GitHub, then contact me and I could merge your code with the main branch.  That means anyone could contribute code to the snake project.

Putting it All Together

The version of the code I checked in for this tutorial can be viewed and downloaded here: snake.rb

Alternatively, visit my Snake GitHub page (or follow the clone instructions above).

Comments (View)
Mon
Apr 6th

Let’s Make a Game 3: Rules

This is Part 3 of the Let’s Make a Game series.  In Part 1 I explained how to get started with Ruby and Shoes and built a basic snake, and in Part 2 I added food.

Remember to view this on Quite Useful rather than in your feed reader (in case code examples don’t appear!)

This part shows how to add more complex rules to the game using collision detection.  Collision detection is used in almost all games in some form: for any particular state a game engine has to decide the relationship between game items and the logical outcome.

Snake has the following rules:

  • Eating food makes the snake longer and removes the food - done
  • Colliding with a brick kills the snake
  • Colliding with a snake segment kills the sake

Collisions

Collisions for a given x and y co-ordinate can be calculated like this:

item.x == x and item.y == y

Our game only considers items at x and y pixels with a precision of 10 * 10 pixels.  This means collisions are very simple: if a GameItem occupies the same x and y co-ordinate as another one then a collision has occurred.

Ideally, we want the main loop to look like this:

When designing your code it helps to think top-down: think about how your classes should be used to keep the API simple, then worry about the gory details later within the class itself. Method names like crashed_into_brick? are easy to read.  Behind the scenes they’ll all use the same collision methods with different item arrays (food, bricks and snake.segments).

Stopping the Game

The example above stores an instance variable named @anim when setting up the animation.  This variable will be available within the animation loop, so the action can be stopped with @anim.stop.

Most methods in Shoes return an object when called.  This means you can perform operations on that object after you’ve set it up, just like how references to rectangles are stored in our snake game so they can be moved and hidden.

Bricks

The game board also needs bricks.  Bricks are another GameItem.

  • I’ve added a fill colour to GameItem in this version so the bricks will look solid next to other items
  • Bricks are stored in an array within GameBoard
  • A helped method called add_brick has been added
  • collision_with_anything? has been added so bricks aren’t added over food — this is really just because we’re currently adding food and bricks randomly

Putting it Together

Take a look at the full code to see how collision? is reused all over the GameBoard.

Comments (View)
Sat
Apr 4th

Quite Useful Weekly Roundup

This week I started a new series called Let’s Make a Game.  I’ll be continuing this series next week, with posts about how to add rules and maps to the game.

We also published a series on open mapping technology: Introduction, OpenStreetMap and OpenLayers.

Here’s the Twitter roundup.

Social

TweetChat makes Twitter feel more like a chat room, grouping posts based on hashtag.

Hunch.com launched with a closed beta.  It helps you make decisions using an almost 20 Questions-like algorithm.  I’m on the beta and it didn’t take long to get accepted, so it’s worth putting your email in.

BlueBird is a cool new Mac OS Twitter client.  It’s native so the interface feels fast, and looks good too.

Design and Developer

Product Planner looked like an interesting idea.  It helps you design products through “user flows”.

There’s a Palm Pre developer preview out which looks interesting.

Comments (View)
Fri
Apr 3rd

Let’s Make a Game 2: Food

This article is part 2 of our Let’s Make a Game series.  Remember you’ll need to view this on the site rather than your feed reader in case the code examples don’t appear.

Today I’m going to show you how to add a game board and food:

This tutorial is a little bit shorter than the previous one because I’m attending GitLondon!  Message me on Twitter (@alex_young or @quiteuseful) if you’re going.

Snakes Need Food

The core mechanic in Snake is collecting food.  Each piece of food grows the snake, making it more difficult to navigate without crashing.

The code I featured yesterday demonstrated how to extend the length of the snake.  It turns out that growing a snake is very similar to handling movement.  That means most of the work towards handling food is done.

A Game Board

The game board is simply a bag of arrays containing the positions of game items like food.  Eventually I’ll show you how to add maps, but for now let’s just add food:

Food is another use of the GameItems that make up the snake.  The board is also going to handle collision detection by comparing the position of one item with another.

Notice that sneaky remove_food_at method.  This will remove items from the game board.  Removing food will work like this:

  • The item will be deleted from the food items array
  • The item will then be hidden from view

Shoes allows you to hide shapes using the hide method.  That means GameItems now need a remove method, like this:

Putting it Together

I’ll add a random sprinkling of food to the board to give you something to play with.  Next up: snakes need rules!

Comments (View)
Related Posts Widget for Blogs by LinkWithin