NOGDUS

Articles, Tutorials, and other things. => General Game Programming => Topic started by: Richard Marks on July 05, 2008, 11:23:03 AM



Title: RubySDL Introduction II
Post by: Richard Marks on July 05, 2008, 11:23:03 AM
RubySDL Introduction II

(http://www.ccpssolutions.com/nogdus/members/rmarks/rubystuff/HelloRubySDLWorld2.png) (http://www.ccpssolutions.com/nogdus/members/rmarks/rubystuff/HelloRubySDLWorld2.png)

Okay since there is a total lack of documentation on this I figure that it would be nice for me to put this out there.  ;D

I assume only that you have gone through the Ruby Tutorials here (http://www.ruby-lang.org/en/documentation/quickstart/) and here (http://tryruby.hobix.com/) so that you are familiar with the Ruby syntax.

I also assume that you have Ruby installed on your computer and RubySDL properly installed already.
If not get with either Michael or I on IRC and we will explain the process to you. (Linux and Windows support only atm)

I use the text editor SciTE based on the Scintilla syntax-highlighting component for nearly all my programming projects.
I highly recommend it. Get it here (http://scintilla.sourceforge.net/SciTEDownload.html).

Let's get started. Create an "arby" file (a file with the extension .rb on the end) in your project directory.
I called mine rubysdl_helloworld2.rb

The first thing you need is to include the SDL library in your program.
Code:
#!/usr/bin/env ruby
# rubysdl_helloworld.rb
# A RubySDL Hello World program
# by Richard Marks ccpsceo@gmail.com

require "sdl"

That was simple.

The require command simply includes the classes, constants and functions that are contained within the specified "arby" library. Do notice that you do not specify the .rb extension when requiring the library file.

Next we will write a small function for drawing text on a surface that will make our code a little cleaner and easier to understand.
Code:
def DrawText(font, surface, text, x, y, colorArray=[0xff, 0xff, 0xff])
font.drawSolidUTF8(surface, text, x, y, *colorArray)
end # end function DrawText

If any of this does not make sense, I'll try to explain it now.
If you already understand the code, then jump ahead past this section of text.

The function that we just made DrawText takes from 5 to 6 parameters.
The last parameter is optional since we specified a default value for it.

The first parameter is an SDL_TTF font that specifies the font with which we will print our text with.
The second parameter is an SDL Surface that specifies the surface to print out text onto.
The third parameter is a string that we will print onto the surface.
The fourth and fifth parameters specify the x,y position to draw the text.
The fifth parameter specifies the color of the text. It is an Array in Hexadecimal Notation.
You will see how to use the function later.

I like to place my program's main loop in a class called Demo just for kicks I guess.
This is just my particular taste, and you don't have to use this convention, though if you do, its easier for you and I to find bugs in your code.

We will have only two methods in our class for this simple program.
The initialize method is the class constructor that gets called when an instance of the class is created.
The Run method is where I place my main loop of my programs.

Note: I like my methods to be capitalized, but I cannot capitalize the constructor method as it is a built-in requirement of the Ruby language that it be lowercase.

SAVE your file if you haven't now.

Code:
class Demo
def initialize
end # end method initialize
def Run
end # end method Run
end # end class Demo

Now, After our class we will place the code to create an isntance of our Demo class, and the call the Run method.
This code only gets called if the file is being executed by Ruby directly (not being included by another "arby" file).
Code:
if __FILE__ == $0 then
# create an instance of our demo class (calls initialize automatically)
demo = Demo.new
# call the Run method of our class to get this sucker running!
demo.Run
end # end if this file is the running file (not just being required from another file)

That was easy.

Jump back up to our empty Demo class.
Let's fill in the details of the initialize method now.

What do we need to do?

1. initialize SDL
2. create a window to draw on
3. initialize SDL TTF
4. load our fonts that we will use
5. init any member variables that we need

Code:
# init SDL
SDL.init(SDL::INIT_VIDEO)

# init video mode (create a window 640x480 with 16 bpp)
@screen = SDL.setVideoMode(640, 480, 16, SDL::SWSURFACE)

# set the window manager window caption
# SDL::WM.setCaption(windowed_caption, icon_caption)
SDL::WM.setCaption("RubySDL Hello World!", "RubySDL Hello World!")

# init SDL_TTF
SDL::TTF.init

# load a ttf font
@defFont = SDL::TTF.open('astrolyte.ttf', 48)
@defFont.style = SDL::TTF::STYLE_NORMAL

# SDL event handler
@event = SDL::Event.new

SAVE your file if you haven't now. I cannot stress the importance of saving your code after each few lines enough. Nothing worse than your computer dying randomly while typing your code. >_<

All that code should be pretty much easy to understand.
I think that I named it all clear enough, but if not, then just ask me to elaborate on IRC or here.

We now need to handle a few things in our Run method.

1. begin the main loop
2. poll for events such as key presses, mouse actions, window events like resizing and closing etc.
3. handle the events we want to handle
4. update any objects we need to (Note: in this demo we don't have anything to update)
5. render (draw or blit) everything to the screen buffer
6. flip the screen buffer to the physical screen display so we can see it

Whew! How about we do that now?
Code:
# start the infinitely executing main loop
while true
# poll for events
if @event.poll != 0 then
# check for quit and keydown events
case @event.type
when SDL::Event::QUIT
break
when SDL::Event::KEYDOWN
# check for the ESC key
if @event.keySym == SDL::Key::ESCAPE then
break
end # end if ESC pressed
end # end case event.type
end # end event if events in event.poll

# fill the screen buffer with black
@screen.fillRect(0, 0, 640, 480, 0)


DrawText(@defFont, @screen, "Hello RubySDL World!", 50, 198)

# ensure garbage collection
ObjectSpace.garbage_collect

# flip screen buffer contents to visible screen
@screen.flip
end # end main loop
SAVE your file if you haven't now. I'd have saved at least 8 times by now.

download this font (http://www.webpagepublicity.com/free-fonts/a/Astrolyte.ttf) and place it in your project directory before running this.
Note: If you're using linux, rename the file to be all lowercase.

If you're running SciTE, then press F5 and your program will run. Press ESC or close the window using the close-button.

That's it.
Here is the full source in one chunk so that you can see how it all fits together.
Make sure you don't blindly copy/paste this code to your file.
You will not learn that way!

Code:
#!/usr/bin/env ruby
# rubysdl_helloworld2.rb
# A RubySDL Hello World program
# by Richard Marks ccpsceo@gmail.com

require "sdl"

def DrawText(font, surface, text, x, y, colorArray=[0xff, 0xff, 0xff])
font.drawSolidUTF8(surface, text, x, y, *colorArray)
end # end function DrawText

class Demo
def initialize
# init SDL
SDL.init(SDL::INIT_VIDEO)

# init video mode (create a window 640x480 with 16 bpp)
@screen = SDL.setVideoMode(640, 480, 16, SDL::SWSURFACE)

# set the window manager window caption
# SDL::WM.setCaption(windowed_caption, icon_caption)
SDL::WM.setCaption("RubySDL Hello World!", "RubySDL Hello World!")

# init SDL_TTF
SDL::TTF.init

# load a ttf font
@defFont = SDL::TTF.open('astrolyte.ttf', 48)
@defFont.style = SDL::TTF::STYLE_NORMAL

# SDL event handler
@event = SDL::Event.new
end # end method initialize

def Run
# start the infinitely executing main loop
while true
# poll for events
if @event.poll != 0 then
# check for quit and keydown events
case @event.type
when SDL::Event::QUIT
break
when SDL::Event::KEYDOWN
# check for the ESC key
if @event.keySym == SDL::Key::ESCAPE then
break
end # end if ESC pressed
end # end case event.type
end # end event if events in event.poll

# fill the screen buffer with black
@screen.fillRect(0, 0, 640, 480, 0)


DrawText(@defFont, @screen, "Hello RubySDL World!", 50, 198)

# ensure garbage collection
ObjectSpace.garbage_collect

# flip screen buffer contents to visible screen
@screen.flip
end # end main loop
end # end method Run
end # end class Demo

if __FILE__ == $0 then
# create an instance of our demo class (calls initialize automatically)
demo = Demo.new
# call the Run method of our class to get this sucker running!
demo.Run
end # end if this file is the running file (not just being required from another file)

I hope this helped you out.
I'll post more as I figure it out!
I'd love to hear your feedback on this article/ tutorial.