AuthorTopic: making video games, where do you start?, how do you stay focus?  (Read 29060 times)

Offline Beoran

  • 0010
  • *
  • Posts: 112
  • Karma: +1/-0
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #50 on: August 28, 2008, 08:42:00 pm
Gaminjustin, I agree with your saying. Thanks for the tip on cave story, I must say it is *very nice*, and it even has a Linux version. This game also uses SDL. 

Atna, if you can't get Rubygame installed, perhaps you could try Ruby SDL in stead ? It's slightly more difficult to use, but the available functionality is even better than that of Rubygame. I'm in the process of switching to rubysdl myself, because I need those extras that Rubygame doesn't have yet. You can read more about how to install it here:

http://www.kmc.gr.jp/~ohai/rubysdl_download.en.html

Look for ruby/SDL version 2.0.1

You may need to install a different ruby or this though, the mswin32 ruby.
I'm sorry I can't be more helpful with a windows install, I use Linux at home.
Kind Regards, Beoran.

Offline Beoran

  • 0010
  • *
  • Posts: 112
  • Karma: +1/-0
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #51 on: August 28, 2008, 09:50:36 pm
Ok, the next step in my tutorial, drawing something to the screen. I'll be using Ruby SDL this time, so sorry if anyone already installed Rubygames (it's not that different).

But first, something new about programming in Ruby.
When programing, you are writing in a language that is made to be easy to understand by the computer,
but which may sometimes be less clear to a human later on. That's why it's important to "document"
your programs. To document your programs simply means, to add a human-readable text
to the program that explains what you are doing. Such human-readable texts are called comments.
The programming language will ignore the contents of the comments, but humans can read them,
and certain tools can be used to extract them from the program for further documentation.

Now, how to add comments to your program?  In Ruby there are two ways to write coments.
The first one is like this:
Code: [Select]
=begin
 This is a comment. It can consist of many lines.
 Note that both = signs have to be at the very beginning of the line,
 so you can't put anything before them
=end

The second way to write comments is like this
Code: [Select]
# This is a one line comment. It begins with a hash sigh. You cannot write it over many lines,
# unless if you write another # sign in front of  the comment for the next line.
puts "Hello"  # This is another comment. You are allowed to put non-comment stuff in front of this comment.

From now on, I'll explain what I am doing in my ruby program inside the program itself, using comments.
That way, it's more easy for me to explain, and I hope, more easy to understand what each step does,
and also, you can copy the program as a whole and run it easily.

So, let's begin and draw something on the screen already!

Code: [Select]
require 'rubygems'
# Load the rubygems library. Most Ruby programs need the functionality of this library.
require 'sdl'
# Load the SDL library. We'll use it for accessing the screen.

screen = SDL::Screen.open(640, 480, 0, 0)
# With this, we open the screen in a 640 pixels wide by 480 pixels high.
# For now you should just get a window. I'll explain how to make a full-screen apllication later.
# Hint: it has to do with the last two zeroes.  ^_~
# As you may know, a computer screen has many very small points on it, each of them called "pixels".
# A computer can only draw on the screen by changing the color of a pixel.
# When drawing to the screen in 2D, you have to decide how many pixels you want for your screen or window.
# How many pixels a screen has is the "resolution" of that screen.
# A high resolution allows you to draw very finely, because the pixels are "smaller", but it is slower.
# For a modern computer 640x480 pixels should get very nice speeds without being too coarse.
yellow = screen.map_rgb(255,255,0)
red       = screen.map_rgb(255, 0,0)
# Create some colors from their RGB values. You're pixel artists, so you should know RGB already. ^_^
# Why do we need to make colours like this? Because the way the screen uses colours is different,
# and may be different for different people and different screens.
# from how humans use them. you need to "map" the rgb value to something the screen will understand.
screen.fill_rect(10, 20, 110, 120, yellow )
# Now, we draw a filled rectangle on the screen, using the yellow color
# What's are the numbers before the color? Well, the first two are the x and y coordinates of the
# rectangle that is drawn. A coordinate is a way to describe the position of a pixel or
# another object on the screen using numbers. The pixel in the top left corner of our screen has
# the coordinates x = 0 and y = 0. The pixel on the bottom left is at x = 0 and y = 479 (that is 480 - 1).
# The pixel on the top right is at x = 639 and y = 0.  The pixel on the bottom right is at x = 639 and y = 479.
# This all assuming our screen is 640 by 480. As you can see. x increases from left to right,
# and y increases from top to bottom.
# What are the next tow numbers? Well, they are simply the width and height of the rectangle in pixels.
screen.fill_rect(50, 50, 150, 150, red)
# And now draw a red rectangle. 
screen.fill_rect(-10, -10, 50, 50, red)
# Can you guess what this will do? If you youse negative coordinates, the rectangle will be partially outside the window.
screen.flip
# Finally, show on the screen what we have been drawing.
# Any changes to the screen will not be shown until you "flip" the screen, that is , display the changes.
# This is so because, it would be very slow to always change the screen for every time we are drawing.
# Like this, you can do all your drawing first, and then show the result when you are finished.
sleep(10)
# Finally wait 10 seconds, so we have the time to see what was drawn, because after this the program will end
# and the screen will be closed automatically.

There you have it! the first rectangles are on the screen. You can already start making Atari 2600-style drawings
on the screen using rectangles. ^_^ In the next installment, at how to handle keyboard input

(Edit: Used code tags for for Ruby program. Scroll down to read it at your own pace.)
« Last Edit: August 29, 2008, 06:41:38 am by Beoran »
Kind Regards, Beoran.

Offline Atnas

  • Moderator
  • 0100
  • *
  • Posts: 1074
  • Karma: +2/-0
  • very daijōbs
    • paintbread
    • paintbread
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #52 on: August 29, 2008, 06:46:56 pm
Ah lovely computers. I managed to install rubygame with a simple 'gem install rubygame' command, but upon trying it with rubysdl I get:

Code: [Select]
Building native extensions.  This could take a while...
ERROR:  Error installing rubysdl:
        ERROR: Failed to build gem native extension.

c:/ruby/bin/ruby.exe extconf.rb install rubysdl
checking for main() in SDL.lib... no
checking for SMPEG_new() in smpeg.lib... no
checking for Mix_OpenAudio() in SDL_mixer.lib... no
checking for sge_Line() in SGE.lib... no
checking for IMG_Load() in SDL_image.lib... no
checking for TTF_Init() in SDL_ttf.lib... no
checking for TTF_OpenFontIndex()... no
checking for TTF_FontFaces()... no
checking for TTF_FontFaceIsFixedWidth()... no
checking for TTF_FontFaceFamilyName()... no
checking for TTF_FontFaceStyleName()... no
checking for Mix_LoadMUS_RW()... no
checking for SDLSKK_Context_new() in SDLSKK.lib... no
creating Makefile

nmake
'nmake' is not recognized as an internal or external command,
operable program or batch file.


Gem files will remain installed in c:/ruby/lib/ruby/gems/1.8/gems/rubysdl-2.0.1
for inspection.
Results logged to c:/ruby/lib/ruby/gems/1.8/gems/rubysdl-2.0.1/gem_make.out

lovely! So all that's stopping me is nmake... whatever that is. I looked it up, downloaded nmake, and tried to run it on the makefile. Nothing.  :)

I'm still following along with your tutorials though, even if sdl isn't working at the moment. I really appreciate what you're doing. I'll hop into some ruby IRC channel to see if I can get some help.  ;D

Offline Beoran

  • 0010
  • *
  • Posts: 112
  • Karma: +1/-0
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #53 on: August 29, 2008, 09:04:24 pm
Atnas, if you want to install rubysdl like that, you need a C compiler (for the C programming language, probably visual C++ or MinGW comes together with nmake or make respectively), and the SDL, SDL_image, SDL_ttf, SDL_mixer and   libraries too, so that is the hard way. There are windows binaries on the Ruby SDL homepage, although you have to look for them a bit and install them in the right place.

Anwyay, for educational purposes, I'll show you how to do about the same with Rubygame as with Ruby SDL. Here goes:

Code: [Select]
require 'rubygems'
require 'rubygame'
# Load Rubygame in stead of SDL

screen = Rubygame::Screen.new([640, 480], 0, 0)
# With this, we open the screen in a 640 pixels wide by 480 pixels high.
yellow  = [255,255,0]
red       = [255, 0,0]
# Create some colors from their RGB values.
screen.fill(yellow, [10, 20, 120, 140] )
# Now, we draw a filled rectangle on the screen, using the yellow color
# What's are the numbers after the color? Well, the first two are the x and y coordinates of the
# top left corner of the rectangle that is drawn. And the second two are the x and y coordinates
# of that same rectangle
screen.fill(red, [50, 50, 200, 200])
# And now draw a red rectangle. 
screen.fill(red, [-10, -10, 40, 40])
# Again, if you use negative coordinates, the rectangle will be partially outside the window.
screen.flip
# Finally, show on the screen what we have been drawing. Also in Rubygame we need Screeen.flip
sleep(10)
# Finally wait 10 seconds, so we have the time to see what was drawn, because after this the program will end
# and the screen will be closed automatically.

Most of this should look familiar. But wait, what' up with the stuff between square brackets?
Well, they are something called "Array"s. Now, what's an array? Well, it's basically an ordered list that contains other
objects like strings, numbers, etc, inside itself. You can get those individual objects ot of the array again by asking fro thm by their position in the array, which is a number. Here are some examples to make it more clear.

Code: [Select]
a = [10, 20, 30]
# Make an array that contains the numbers 10, 20 and 30
b = a[1]
puts b
# This will get the second number that is in the array namely 20, and print it.
# now you may say, "WTF!" why do we have to say 1 when we want to get the /second/ nuumber? Why isn't it 2?
# Well, this is because in many programming languages, when you use an array, you have to substract 1 from the
# position of the obect you want. So, this is a bit of a "programmer's tradition" that we have to get used to.
# So the first number inside a, you will get like this: a[0], the second one is a[1]
# and the third one is a[2] .
puts a[0]
# See, this is 10
puts a[2]
#
puts a.length
# You can see how many objects are inside the array like this
sa = [ "I", "like", "to", "program"] 
# You can also put strings inside an array
puts sa[3]
# And get a string out of the array again.
aa = [a, sa]
# You can even put arrays inside of arrays
puts aa[1][2]
# An get the third string out of the second array again
ma = [ a, 1 , 3 ]
# In Ruby you are allowed to mix all kinds of things together in an array.

Rubygame likes to use arrays for many things, for colors, for rectangles, and for the x and y position of a point.
This may seem complicated, but it also has some advantages.

Anyway, that's it for this episode, I really have to talk more amout input now, but that's for later. Hope you enjoyed this one. :)

Kind Regards, Beoran.

Offline Ai

  • 0100
  • ***
  • Posts: 1057
  • Karma: +2/-0
  • finti
    • http://pixeljoint.com/pixels/profile.asp?id=1996
    • finticemo
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #54 on: August 30, 2008, 02:47:18 pm
Speaking as both a hobbyist and a professional, I have 3 pieces of advice.

Before you do anything else I would write a design doc and lock down every feature, enemy, weapon, character, level, etc. that you want in the game. If you start a project and just keep adding stuff until it's "done" it will never be finished, you may never even get past the first level! Of course you can make changes as you see the need but the Design Doc will keep you focused and on a steady course.

Set deadlines. Even if they don't mean anything. And don't use vague deadlines like "before the end of the year" or "mid-summer". Make them concrete: November 12th. February 6th, etc. If deadlines weren't used by professionals we would never finish anything.

Finally, ambition is good but it must be kept focused. If you have many ideas, make many games. Find a "hook" for your project - one or two things that make it fun to play over and over - and focus on those. The more precision you use, the harder it is to miss your target. Observe that the best games don't attempt to do everything, but rather succeed in doing a few things very very well, in a way that's fun over and over again. Portal is a prime example of this philosophy. On the other hand games like Daiketana or Advent Rising are horror stories about games that tried to do everything and succeeded at nothing. Always keep in mind that If you can save those unused ideas for your next game!

Hope this helps!

Thank you for making this post Ben, it helped me considerably.
If you insist on being pessimistic about your own abilities, consider also being pessimistic about the accuracy of that pessimistic judgement.

Offline Beoran

  • 0010
  • *
  • Posts: 112
  • Karma: +1/-0
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #55 on: August 30, 2008, 08:33:15 pm
In this next installment, let's see how to handle keyboard input!
We'll draw a littbe yellow square and make it move to the left or
right if the player presses the left or right arrow keys.
Let's dive right in!

Code: [Select]
require 'rubygems'
require 'sdl'
# Load the libraries we need.

screen = SDL::Screen.open(640, 480, 0, 0)
# Open the screen, like usually.

yellow = screen.map_rgb(255,255,0)
green  = screen.map_rgb(0  ,255,0)
cyan   = screen.map_rgb(0, 255, 255)
# Make come colors

grass_h  = 40
player_w = 40
player_h = 40
player_v = 0
player_x = screen.w  / 2
player_y = screen.h - player_h - grass_h

done     = false
# It ain't overr 'till it's over.

while not done
# Keep doing the next lines while done is not true
  input = SDL::Event.poll
  # We ask SDL to get the input event that is occuring
  intype= input.class
  # Intype now contains what class, that is what kind of input we got
  if intype == SDL::Event::Quit
    # Clicked the close window icon.
    done = true
    # Now, it's over.
  elsif intype == SDL::Event::KeyDown
    # Someone pressed a key.
    key = input.sym
    # We get 'te "sum", that is the key sumbol for this input
    if key == SDL::Key::ESCAPE
      # If someone presses the escape key, we're also done.
      done = true
    elsif key == SDL::Key::LEFT
      player_v = -1
      # Pressing left arrow key, so the player should move to the left
      # For that, we make the speed of the player negative
    elsif key == SDL::Key::RIGHT
      player_v = 1
      # Pressing right arrow key, so the player should move to the right
      # For that, we make the speed of the player positive
    end 
  elsif intype == SDL::Event::KeyUp
    # A key was released
    key = input.sym
    # Get what key was released
    if key == SDL::Key::LEFT
      # If the left key was released, the player should stop moving.
      player_v = 0
    elsif key == SDL::Key::RIGHT
      # If the right key was released, the player should also stop moving.
      player_v = 0
    end
  end 
 
  player_x = player_x + player_v
  # Update the player's position based upon the player's speed.
  screen.fill_rect(0, 0, screen.w, screen.h, cyan)
  # Draw the sky on the background.
  screen.fill_rect(0, screen.h - grass_h, screen.w, screen.h, green)
  # Draw the grassy floor
  screen.fill_rect(player_x, player_y, player_w, player_h, yellow)
  # Draw the player as a square
  screen.flip
  # And display the screen.

end
# End of the while "loop". Everything from while to this end
# will be repeated until the variable done becomes true


You will probably notice there are quite a few new things in there.
The first thing is the use of "false" an "true". False and true are special values that indicate if something
is, well, false or true. Such values are called boolean values. The second new thing is the use of "=="
With "==" you can check if two values are the same or not, like in this example:

Code: [Select]
a = 2
puts a == 2 # Writes out true
puts a == 3 # Writes out false

Then there is the use of a whole lot of if, elsif, end  stuff. What's that for? Well, it allows you to do different
things depending on the value inside a varable.

Code: [Select]
a = 2
if a == 2
  puts  "a is equal to 2"
else
  puts  "a is not equal to 2"
end
This code writes out "a is equal to 2" What will happen if you say a = 3 at the top in stead of a = 2? Right, it will write out "a is not equal to 2" . So you can see that with if, you can make your program do different things depending on what's going on.
If the player presses the left key, something else should happen then when she presses the right key,
so you'll need an "if" to deal with that. You can put "if" inside other ifs, as long as you take care of putting the "end" in the right place,
otherwise you might get an error from ruby. To make putting several ifs into each other simpler, you can use elsif in some cases like this:

Code: [Select]
a = 3
if a == 2
  puts  "a is equal to 2"
elsif a == 3
  puts  "a is equal to 3"
else
  puts  "a is not equal to 2"
end

Finally, something new here is the "when" part. "When" is used for making a "loop" in the program, that is, for doing the same thing over and over again while a certain condition is true.
Code: [Select]
when not done
# All this between here will be repeated until done becomes true.
end

Well, that should cover it for today. I may be going a bit fast, so don't hesitate to ask if anything is unclear. :)
Kind Regards, Beoran.

Offline Atnas

  • Moderator
  • 0100
  • *
  • Posts: 1074
  • Karma: +2/-0
  • very daijōbs
    • paintbread
    • paintbread
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #56 on: August 31, 2008, 12:47:29 am
Oh wow, thanks for that. You explained it perfectly. :)

Offline Beoran

  • 0010
  • *
  • Posts: 112
  • Karma: +1/-0
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #57 on: August 31, 2008, 08:11:57 am
Today, we're going to learn how to improve the structure of our game a bit. You might wonder what's wrong with the structure of the previous program? Well, it's a bit messy really. Especially in side th while loop, many things are going on, and if we are going to make our game better, we'll have to add much more stuff in there, so it will become even more messy. It would be a lot nicer if we could group together certain logically related parts of what is going on in that loop.

How will we do this? Well, do you remember what I wrote about modules and functions or methods before? For example, if you say "puts a" then Ruby will look up in it's libraries what puts means, and then do whatever that is. Puts is an example of a function. But that's not all there is to functions! Actually, we can define our own functions. Like in this example:

Code: [Select]
# DEFine a fuction that simply writes "Hi there!" to the screen.
def hi
  puts "Hi there!"
end

hi # Now it will write Hi There! on the screen. You could also say hi() in Ruby

This is of course a very simple example. You might wonder what the point is of using a function when you can just write the command s immediately. But, the function above is very short. One what you want to do becomes longer, it makes a lot of sense to split up what you want to do over different functions, so your program has a nice structure. Also, you can use functions to do complicates calculations, and then get out the results of that calculations many times later on in one go. For example:

Code: [Select]
# A function that calulates the sum and the absolute difference between two numbers
def sumdiff(a, b)
  sum = a + b
  # Calculate sum
  diff   = (a - b).abs
  # Calculate difference
  return sum, diff
  # Return determines the result of the function. This function returns two values, sum and absolute difference.
end
 
s, d = sumdiff(10, 20)
# Calculate the sum and absolute difference of 10 and 20
puts "The sum is "
puts s
puts "The absolute difference is "
puts d

Sumdiff is an example of a function that "returns" with two results. That is, it calculates to values, based upon what you put inside it. The numbers, strings, or other objects you put inside a function are also called the arguments of that function. All this jargon comes from math, so, by now you should know that as a programmer you should pay (or have paid) attention in math class.

So, now we know the basics, let's try to improve our program by using function. The result is below:

Code: [Select]
require 'rubygems'
require 'sdl'
# Load the libraries we need.

# Define a function to handle the input
def handle_input(input, player_v, done)
  intype= input.class
  # Intype now contains what class, that is what kind of input we got
  if intype == SDL::Event::Quit
    # Clicked the close window icon.
    done = true
    # Now, it's over.
  elsif intype == SDL::Event::KeyDown
    # Someone pressed a key.
    key = input.sym
    # We get 'te "sum", that is the key sumbol for this input
    if key == SDL::Key::ESCAPE
      # If someone presses the escape key, we're also done.
      done = true
    elsif key == SDL::Key::LEFT
      player_v = -1
      # Pressing left arrow key, so the player should move to the left
      # For that, we make the speed of the player negative
    elsif key == SDL::Key::RIGHT
      player_v = 1
      # Pressing right arrow key, so the player should move to the right
      # For that, we make the speed of the player positive
    end 
  elsif intype == SDL::Event::KeyUp
    # A key was released
    key = input.sym
    # Get what key was released
    if key == SDL::Key::LEFT
      # If the left key was released, the player should stop moving.
      player_v = 0
    elsif key == SDL::Key::RIGHT
      # If the right key was released, the player should also stop moving.
      player_v = 0
    end
  end 
  return player_v, done
  # The result of this function will be the speed of the player and
  # whether or not the game is done.
end 


# A function to calculate the new player position
def update_player(player_x, player_v)
  new_player_x  = player_x + player_v
  return new_player_x + player_v
  # return the new position of the player
end

# A procedure to draw the screen
def draw_screen(screen, player_x, player_y, player_w, player_h,
                grass_h, cyan, green, yellow)
  screen.fill_rect(0, 0, screen.w, screen.h, cyan)
  # Draw the sky on the background.
  screen.fill_rect(0, screen.h - grass_h, screen.w, screen.h, green)
  # Draw the grassy floor
  screen.fill_rect(player_x, player_y, player_w, player_h, yellow)
  # Draw the player as a square
  screen.flip
  # And display the screen.
end


screen = SDL::Screen.open(640, 480, 0, 0)
# Open the screen, like usually.

yellow = screen.map_rgb(255,255,0)
green  = screen.map_rgb(0  ,255,0)
cyan   = screen.map_rgb(0, 255, 255)
# Make come colors

grass_h  = 40
player_w = 40
player_h = 40
player_v = 0
player_x = screen.w  / 2
player_y = screen.h - player_h - grass_h

done     = false
# It ain't overr 'till it's over.

while not done
# Keep doing the next lines while done is not true
  input          = SDL::Event.poll
  # We ask SDL to get the input event that is occuring
  player_v, done = handle_input(input, player_v, done)
  # Process the input in our own function
  player_x       = update_player(player_x, player_v)
  # Update the player's position based upon the player's speed.
  draw_screen(screen, player_x, player_y, player_w, player_h,
              grass_h, cyan, green, yellow)
  # Display the screen.
end
# End of the while "loop". Everything from while to this end
# will be reprated until the variable done becomes true

Now, one thing you may wonder about is, why do we have to pass so many arguments, for example, to the
draw_screen function? Well , you see, functions create their own little "world", in which only the arguments that
come in to the function, and the variables that you use inside the function are known. The effect that variables
that are used in one part of the program can be hidden from another part of the program is called "scope." Look at this example.

Code: [Select]
a = 10
def scope_example
a = 20
puts a
end

puts a # writes out 10
scope_example()
# will write out 20, not 10, because scope_example uses it's own version of A, not the one outside of it

Why is this useful? Well, it allows you to split up your program in parts that can't mess up each other's variables. That's very useful to allow you to keep your program orderly, and to prevent different parts from the program to interact with each others in ways which you don't want them to do!

So there, that's my installment on how you can make functions yourself. There is more we can do to improve the structure of the program, though, and that I will explain in my next installment! See you then! And remember all questions are welcome. :)
Kind Regards, Beoran.

Offline Emtch

  • 0010
  • *
  • Posts: 157
  • Karma: +0/-0
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #58 on: September 10, 2008, 07:13:37 pm
So does anyone know any good sites with tips and tricks on ruby? I've searched and didn't really find anything relevant
« Last Edit: September 10, 2008, 07:24:45 pm by Emtch »

Offline Beoran

  • 0010
  • *
  • Posts: 112
  • Karma: +1/-0
    • View Profile

Re: making video games, where do you start?, how do you stay focus?

Reply #59 on: September 11, 2008, 05:16:31 pm
First of all, Sorry to stall my tutorial, I wasted a week on getting the collision detection right. But I have it now, I just need to comment it and post it here if I can get off my lazy butt. :p

As for tips on ruby, there are plenty of sites; just like this one:
http://www.rubytips.org/
Found like this:
http://www.google.com/search?q=ruby+programming+tips
Kind Regards, Beoran.