views:

107

answers:

4

Hi,

I am creating my first game ever using pygame and i've found that in order to animate things the most popular method is to use bit blit. However I have a few questions regarding this:

  1. From what I understood, when you use bit blit you have to "redraw" on the screen every single object that was present before in order for it to work correctly. Is this correct?

  2. If so... i am drawing a "scene" of buildings using rects (rectangles) (the buildings have each a different colors (randomly geneated), different heights (random) and they also have windows which are of 2 different colors alternating). What would be the best way for my Building class to remember every color it had for the building and its windows so that when i bit blit the building dont get different colors to make it more realistic?

Thanks in advance for pointing me in the right direction!

A: 

You may find the answer to your first question here:
http://en.wikipedia.org/wiki/Bit_blit

transmogrify
A: 
  1. Yes. You need to use "painter's algorithm" to draw your scene from back to front.

  2. So, for each frame of animation, you'd draw the background first, then the buildings, and then anything in front of the buildings. You don't need to "clear" the screen if the background covers the whole screen.

Justicle
+1  A: 

Yes, consider the screen to be like a canvas you paint onto. Once the scene is finished and shown to the viewer, you start the next scene (aka 'frame') by painting over the top of it, replacing everything that was there. Movement is represented by repeatedly painting the same thing at slightly different places. It's much like traditional animation in film - show a series of subtly different pictures to present the illusion of motion. You typically do this several tens of times per second.

It's not just pygame/SDL's bit blit that works this way - pretty much all real time computer graphics for work this way. However some systems may hide this from you and do it under the covers.

For your buildings and their colours, you want what goes to the screen to be a representation of your game objects. You don't want to draw something and then try to 'remember' what you drew. The rendering should just be a view of the objects and never something authoritative. So when you generate these random heights and colours, that would be done long before the drawing phase. Store these values as part of your building objects, probably at creation time. Then when you come to draw the building each frame, all the information you need is right there and will remain consistent each time you draw it.

Kylotan
Thank you for your very detailed answer. I now understand much beter how bit blit works :)What do you mean by when i generate the random heights and colors should be done before the drawing phase? Basically what happens is as soon as the game starts i draw this scene, and later on the game based on turns, i need to start animating things. i am not exactly sure how am i supposed to redraw the exact same screen i had before. all my attempts end up with different colors and heights
Between starting the game and drawing the scene, you'd create the buildings. You would typically have an initialisation phase before you do any rendering or enter a main loop, so do it in there. The graphics are only a visual representation of your logic - they're not the logic itself. So set up the logic by creating the buildings once with the properties you require. Then you render them correctly later by referring to those properties. Redrawing the scene won't change colours or heights because you create those values just once, at the start.
Kylotan
+3  A: 

You could have a simple Building class:

class Building:
  def __init__(self, x, y, w, h, color):
    self.x = x
    self.y = y
    self.w = w
    self.h = h
    self.color = color


  def draw(self):
    // code for drawing the rect at self.x,self.y 
    // which is self.w wide and self.h high with self.color here

Concerning the windows, you could specify each one in a list like [(x, y, w, h)] for each building or simply make a building class that looks like this:

class Building:
  def __init__(self, x, y, w, h, color, wx, wy):
    self.x = x
    self.y = y
    self.w = w
    self.h = h
    self.color = color
    self.wx = wx
    self.wy = wy


  def draw(self):
    // code for drawing the rect at self.x,self.y 
    // which is w wide and h high with self.color here

    // Draw wx windows horizontally and wy windows vertically
    for y in range(0, self.wy):
      for x in range(0, self.wx):
        // draw Window code here

Another approach would be that you "prerender" your buildings into an image an then just display that afterwards(that could also be faster if you have a lot of buildings).

And your gameloop could then look something like this

  buildingList = [Building(0, 0, 15, 50, RED), Building(0, 0, 40, 30, BLUE)]
  while gameIsRunning:
        // Clear screen code here

        // Show Building
        for b in buildingList:
          b.draw()

        // More stuff

That is pretty much the most basic approach for drawing anything, you could draw characters this way, keys or even tiles that are supposed to be above you character, e.g. water tiles in a platformer like Tuff. The trees here are also in one big list(ok actually i maintain a smaller list with the trees that are on the 1 1/2 sourrounding screens for performance reasons. there are over 1500 "trees").

EDIT: In the case of different window colors, there two possible solutions.

Using different window colors per building:

class Building:
  def __init__(self, x, y, w, h, color, wx, wy, windowColor):
    self.x = x
    self.y = y
    self.w = w
    self.h = h
    self.color = color
    self.wx = wx
    self.wy = wy
    self.windowColor = windowColor


  def draw(self):
    // code for drawing the rect at self.x,self.y 
    // which is self.w wide and self.h high with self.color here

    // Draw wx windows horizontally and wy windows vertically
    for y in range(0, self.wy):
      for x in range(0, self.wx):
        // draw Window code here using self.windowColor

Possibility 2, with different colors per window:

   class Building:
      def __init__(self, x, y, w, h, color, windows):
        self.x = x
        self.y = y
    self.w = w
    self.h = h
        self.color = color
        self.wx = wx
        self.wy = wy
        self.windows = windows


      def draw(self):
        // code for drawing the rect at self.x,self.y 
        // which is self.w wide and self.h high with self.color here

        // Draw all windows
        for w in windows:
          // draw Window at w[0] as x, w[1] as y with w[2] as color

// Create a building at 0,0 that is 20 wide and 80 high with GRAY color and two windows, one at 2,2 which is yellow and one at 4, 4 that's DARKBLUE.
b = Building(0, 0, 20, 80, GRAY, [(2, 2, YELLOW), (4, 4, DARKBLUE)])
Ivo Wetzel
using the Building class method, I am curious to know how do you pass those arguments to the draw function? from where is it going to get the x,y and color arguments if im not using some sort of list that has this info?
Opps :) Actually i made a mistake there the class instance itself already has all the values it needs.
Ivo Wetzel
ahhh now it makes more sense ! :) one more detail: windows have different colors (it picks a random color from a list of two colors) . how is it going to know which color to use for the draw function? i assume from your example you meant draw to use self.color but self.color is the color of the actual building. how do i pass the current window color? thank you for your help and very detailed answer. everything is making more sense now
Are the colors different for each window on each building or are they just different so that building A has windows with color 1 and building B has windows with color 2. If the later one is the case you can just add another variable to the building class, something like self.windowColor and then paint the window rects with that color. In the other case your window list per building needs another value for each windows color, I'll edit this into my answer.
Ivo Wetzel
its the first one. windows can be yellow or grey and they are randomly picked. all buildings have this windows with these two colors.