Python游戏编程(十)Animation

我们将编写一个程序来实现积木在窗口中弹跳的效果。这些积木具有不同的颜色和大小,并且只在对角线上移动。为了让积木有动画的效果,我们将在游戏循环的每一次迭代中,让这些积木移动一些像素。这就会使得积木看上去像是在屏幕上移动。

(一)游戏说明

这个程序称不上是一个游戏,只是通过一些细微的改变实现一个积木的移动。程序中的积木就是用pygame.draw.rect()函数绘制的矩形。在这个程序中,我们有三个不同颜色的积木来回移动,并且从窗口的墙壁弹回。每个积木将在4条对角线方向中的一条上移动。当积木碰到了窗口,它就会从边缘上弹回来,并在一条新的对角线上移动。

所谓积木的移动,就是快速的绘制一个新的矩形,只不过是速度很快,我们看起来就像是在移动一样。

(二)代码分析

1)设置常量变量

import pygame, sys, time
from pygame.locals import *

# Set up pygame.
pygame.init()

# Set up the window.
WINDOWWIDTH = 400
WINDOWHEIGHT = 400
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Animation')

首先是导入模块,然后对pygame模块进行初始化。

这里我们将使用常量变量,以便我们想要修改窗口大小的时候,只需要修改WINDOWWIDTH和WINDOWHEIGHT即可。当然,如果窗口的宽度和高度从不改变,那么使用常量也可。

2)用于方向、速度、颜色的常量变量

# Set up direction variables.
DOWNLEFT = 'downleft'
DOWNRIGHT = 'downright'
UPLEFT = 'upleft'
UPRIGHT = 'upright'

MOVESPEED = 4

# Set up the colors.
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

对于方向,我们也可以不使用常量,而是将这些方向常量赋值给变量,使用这些变量表示。两者的区别是:

  • 如果直接使用字符串“downlwft”表示左下对角线方向,当字符串输入错误的时候,最终会得到一个bug,将会导致程序行为异常,即便程序还不会崩溃。
  • 如果使用变量,当不小心输入了错误的变量名,Python就会报错导致程序崩溃。这仍然很糟糕,但是我们将立刻发现它并且修改它。

对于速度,我们定义了MOVESPEED = 4常量变量,这告诉程序,在游戏循环的每一次迭代中,每个积木应该移动多少个像素。

对于颜色,pygame使用3个整数值的一个元组,来表示红色、绿色和蓝色数量的RGB值。整数值从0到255.

使用常量是为了有更好的可读性。

3)设置积木 数据结构

# Set up the box data structure.
b1 = {'rect':pygame.Rect(300, 80, 50, 100), 'color':RED, 'dir':UPRIGHT}
b2 = {'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPLEFT}
b3 = {'rect':pygame.Rect(100, 150, 60, 60), 'color':BLUE, 'dir':DOWNLEFT}
boxes = [b1, b2, b3]

这里使用字典来表示三个积木,并且将这三个积木放到boxes列表中,这样输入boxes[0]就可以访问b1中的字典数据结构,输入boxes[0]['color']就可以访问b1中的‘color’键的值。

4)游戏循环

游戏循环负责实现移动积木的动画。

动画是这样实现的:绘制一系列略微不同的图像,这些图像一个接着一个地显示。在我们的动画中,图像都是移动的积木,略微不同的是每一个积木的位置。在每一个图像中,积木都会移动4个像素。图像显示得如此之快,以至于积木看上去就像是在屏幕上平滑地移动。如果一个积木碰到了窗口的边缘,游戏循环将会通过改变该积木的方向而令其弹回。

1.处理玩家退出的情况

当玩家通过关闭窗口而退出的时候,我们需要停止游戏。我们需要在游戏循环中做到这一点,以便程序持续地检查受否有一个QUIT事件。

# Run the game loop.
while True:
    # Check for the QUIT event.
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

为了使窗口出现运动轨迹,需要在每一次图形改变之后清楚整个窗口:

    # Draw the white background onto the surface.
    windowSurface.fill(WHITE)

2.移动、弹跳积木

    for b in boxes:
        # Move the box data structure.
        if b['dir'] == DOWNLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == DOWNRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == UPLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top -= MOVESPEED
        if b['dir'] == UPRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top -= MOVESPEED

        # Check whether the box has moved out of the window.
        if b['rect'].top < 0:
            # The box has moved past the top.
            if b['dir'] == UPLEFT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = DOWNRIGHT
                
        if b['rect'].bottom > WINDOWHEIGHT:
            # The box has moved past the bottom.
            if b['dir'] == DOWNLEFT:
                b['dir'] = UPLEFT
            if b['dir'] == DOWNRIGHT:
                b['dir'] = UPRIGHT
        if b['rect'].left < 0:
            # The box has moved past the left side.
            if b['dir'] == DOWNLEFT:
                b['dir'] = DOWNRIGHT
            if b['dir'] == UPLEFT:
                b['dir'] = UPRIGHT
        if b['rect'].right > WINDOWWIDTH:
            # The box has moved past the right side.
            if b['dir'] == DOWNRIGHT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = UPLEFT

3.绘制窗口

        # Draw the box onto the surface.
        pygame.draw.rect(windowSurface, b['color'], b['rect'])

    # Draw the window onto the screen.
    pygame.display.update()
    time.sleep(0.02)

源代码:

import pygame, sys, time
from pygame.locals import *

# Set up pygame.
pygame.init()

# Set up the window.
WINDOWWIDTH = 400
WINDOWHEIGHT = 400
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Animation')

# Set up direction variables.
DOWNLEFT = 'downleft'
DOWNRIGHT = 'downright'
UPLEFT = 'upleft'
UPRIGHT = 'upright'

MOVESPEED = 4

# Set up the colors.
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# Set up the box data structure.
b1 = {'rect':pygame.Rect(300, 80, 50, 100), 'color':RED, 'dir':UPRIGHT}
b2 = {'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPLEFT}
b3 = {'rect':pygame.Rect(100, 150, 60, 60), 'color':BLUE, 'dir':DOWNLEFT}
boxes = [b1, b2, b3]

# Run the game loop.
while True:
    # Check for the QUIT event.
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    # Draw the white background onto the surface.
    windowSurface.fill(WHITE)
    for b in boxes:
        # Move the box data structure.
        if b['dir'] == DOWNLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == DOWNRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top += MOVESPEED
        if b['dir'] == UPLEFT:
            b['rect'].left -= MOVESPEED
            b['rect'].top -= MOVESPEED
        if b['dir'] == UPRIGHT:
            b['rect'].left += MOVESPEED
            b['rect'].top -= MOVESPEED

        # Check whether the box has moved out of the window.
        if b['rect'].top < 0:
            # The box has moved past the top.
            if b['dir'] == UPLEFT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = DOWNRIGHT
                
        if b['rect'].bottom > WINDOWHEIGHT:
            # The box has moved past the bottom.
            if b['dir'] == DOWNLEFT:
                b['dir'] = UPLEFT
            if b['dir'] == DOWNRIGHT:
                b['dir'] = UPRIGHT
        if b['rect'].left < 0:
            # The box has moved past the left side.
            if b['dir'] == DOWNLEFT:
                b['dir'] = DOWNRIGHT
            if b['dir'] == UPLEFT:
                b['dir'] = UPRIGHT
        if b['rect'].right > WINDOWWIDTH:
            # The box has moved past the right side.
            if b['dir'] == DOWNRIGHT:
                b['dir'] = DOWNLEFT
            if b['dir'] == UPRIGHT:
                b['dir'] = UPLEFT

        # Draw the box onto the surface.
        pygame.draw.rect(windowSurface, b['color'], b['rect'])

    # Draw the window onto the screen.
    pygame.display.update()
    time.sleep(0.02)

参考:

  1. Python游戏编程快速上手
发布了10 篇原创文章 · 获赞 1 · 访问量 1964

猜你喜欢

转载自blog.csdn.net/weixin_45755966/article/details/104435464