需要一些关于bitblit如何工作的建议

时间:2009-10-12 03:20:17

标签: pygame

我正在使用pygame创建我的第一个游戏,我发现为了制作动画,最流行的方法是使用位blit。
不过我对此有几个问题:

  1. 根据我的理解,当您使用位blit时,您必须在屏幕上“重绘”之前存在的每个对象才能使其正常工作。这是对的吗?

  2. 如果是这样的话...我正在使用rects(矩形)绘制建筑物的“场景”(每个建筑物都有不同的颜色(随机生成),不同的高度(随机),它们也有窗户2种不同的交替颜色)。什么是我的建筑类最好的方法来记住它对建筑物及其窗户的每种颜色,以便当我咬住建筑物时不会得到不同的颜色以使其更逼真?

4 个答案:

答案 0 :(得分:3)

你可以有一个简单的建筑类:

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

关于windows,您可以为每个建筑物指定像[(x,y,w,h)]这样的列表中的每一个,或者只是建立一个如下所示的建筑类:

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

另一种方法是你将你的建筑物“预呈现”成一幅图像,然后再展示一下(如果你有很多建筑物,也可以更快)。

然后你的游戏循环看起来像这样

  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

这几乎是绘制任何东西的最基本方法,你可以用这种方式绘制字符,键或甚至是应该在你上面的字符,例如像Tuff这样的平台游戏中的水瓦片。这里的树也在一个大的列表中(好吧,实际上我保留了一个较小的列表,其中有出于性能原因的1 1/2环绕屏幕上的树。有超过1500个“树”)。

编辑: 在不同窗口颜色的情况下,有两种可能的解决方案。

每个建筑物使用不同的窗口颜色:

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

可能性2,每个窗口有不同的颜色:

   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)])

答案 1 :(得分:1)

是的,请将屏幕视为您绘制的画布。场景结束并向观众展示后,您可以通过在其上方绘画来替换那里的所有内容来开始下一个场景(也称为“帧”)。通过在略微不同的地方反复绘制相同的东西来表示运动。这很像电影中的传统动画 - 展示一系列微妙不同的图片来呈现运动的幻觉。你通常每秒做几十次。

这种方式不仅仅是pygame / SDL的位blit - 几乎所有的实时计算机图形都以这种方式工作。但是,某些系统可能会隐藏此信息并将其隐藏起来。

对于您的建筑物及其颜色,您希望屏幕上的内容代表您的游戏对象。你不想画一些东西,然后试着“记住”你画的东西。渲染应该只是对象的视图,而不是权威的东西。因此,当您生成这些随机高度和颜色时,这将在绘制阶段之前很久完成。可以在创建时将这些值存储为构建对象的一部分。然后,当你来到每个框架绘制建筑物时,你需要的所有信息就在那里,每次绘制时都会保持一致。

答案 2 :(得分:0)

您可以在此处找到第一个问题的答案:
http://en.wikipedia.org/wiki/Bit_blit

答案 3 :(得分:0)

  1. 是。您需要使用“painter's algorithm”从后向前绘制场景。

  2. 因此,对于每一帧动画,您首先绘制背景,然后绘制建筑物,然后绘制建筑物前面的任何内容。如果背景覆盖整个屏幕,则无需“清除”屏幕。