Pygame(六)动画起步1

Pygame(六)动画起步1

前情提要

image.png

作业示例

image.png

# /usr/bin/python3

# Author: 爱编程的章老师
# @Time: 2021/1/4 0004
# E-mail: [email protected]


import pygame
import sys


def homework():
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    screen.fill((255,255,255))
    # 画房子主体
    rect = pygame.Rect(260,390,280,210)
    c = 102, 204, 255
    pygame.draw.rect(screen, c, rect, 0)

    # 画窗户:边框 加两条张
    rect = pygame.Rect(285,420,70,70)
    c = 102, 204, 153
    BLACK = 0,0,0
    h_line_start = 285, 455
    h_lint_end = 354, 455
    v_line_start = 320, 420
    v_lint_end = 320, 489
    pygame.draw.rect(screen, c, rect, 0)
    pygame.draw.rect(screen, BLACK, rect, 1) # 画黑色边框
    pygame.draw.line(screen, BLACK, h_line_start, h_lint_end, 1)
    pygame.draw.line(screen, BLACK, v_line_start, v_lint_end, 1)


    # 画门
    rect = pygame.Rect(445,520,55,80)
    c = 255, 153, 51
    pygame.draw.rect(screen, c, rect, 0)

    # 画门把手
    pos = 490, 570
    r = 6
    c = 102, 102, 102
    pygame.draw.circle(screen, c, pos, r)

    # 红色屋檐 + 黄色三角形

    pos_list = [(200, 390), (600, 390), (560, 330), (240, 330)]
    c1 = 255, 51,51
    triangle_list = [(355, 390), (445, 390), (400, 330)]
    c2 = 255, 255, 0
    pygame.draw.polygon(screen, c1, pos_list, 0)
    pygame.draw.polygon(screen,c2, triangle_list, 0)

    # 画烟囱
    rect = pygame.Rect(280,290,25,40)
    c = 153, 0, 51
    pygame.draw.rect(screen, c, rect)

    # 画三个黑烟
    pos_list = [(295, 265), (320, 240), (340 ,220)]
    for index, pos  in enumerate(pos_list):
        pygame.draw.circle(screen, BLACK, pos, 12 - index * 2)

    pygame.display.update()
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
    pygame.quit()

if __name__ == '__main__':
    homework()

吐槽一下
这个作业感觉把我自己坑了.数据没凑好.用PS量了半天.读者朋友可以尝试自己作一下图

本节提要

在这里插入图片描述

内容详解

所有我们的看到的动画,其本质就是一幅幅画面快速连续的切换(播放)所形成的视觉效果.
因此,无论是做游戏的动画效果,还是做动画片的动画效果,其本质就是不断的在生成新的图片,以代替原来的图片.
我们先来看以下代码:

def hand_movement():
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    WHITE = 255, 255, 255  # 定义白色
    screen.fill(WHITE)
    GREEN = 0, 255, 0
    dx, dy = 0, 0
    size = width, height = 100, 100
    step = 1  # 定义步长

    pygame.display.update()
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        if dx <= 800 or dy <= 600:
            pygame.draw.rect(screen, GREEN, ((dx, dy), size))
            pygame.display.update()
            dx += step
            dy += step
            time.sleep(0.1)
    pygame.quit()

这断代码的效果如下:
1.gif
通过这个代码,我们可以看到一个不断向左下角移动的正方形.
但是原来的图片,影响了效果.我们可以尝试把画面不断的刷成白纸,再看一下效果
改进后的代码

def hand_movement2():
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    WHITE = 255, 255, 255
    screen.fill(WHITE)

    GREEN = 0, 255, 0
    dx, dy = 0, 0
    size = width, height = 100, 100
    step = 1

    pygame.display.update()
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        if dx <= 800 or dy <= 600:
            screen.fill(WHITE)
            pygame.draw.rect(screen, GREEN, ((dx, dy), size))
            pygame.display.update()
            dx += step
            dy += step
            time.sleep(0.1)

    pygame.quit()

改进后的效果图
6_2.gif

move与move_ip

pygame中有专门的方法来处理这种移动效果.

rect.move(dx,dy)
rect.move_ip(dx, dy)7

参数说明:

  • dx: 左右方向的移动距离
  • dy: 上下方向的移动距离

使用说明

  • 该方法是一个pygame.Rect的对象的方法.
  • move方法将在目标位置生成一个新的rect
  • move_ip方法将原生rect对象的坐标进行了改变

使用举例:


def auto_move():
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    WHITE = 255, 255, 255
    screen.fill(WHITE)
    GREEN = 0, 255, 0
    rect = pygame.draw.rect(screen, GREEN, (0,0, 100, 100))
    dx = dy = 1
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        screen.fill(WHITE)
        rect.move(dx, dy)
        pygame.draw.rect(screen,GREEN, rect)
        pygame.display.update()
        time.sleep(0.1)
    pygame.quit()

可以看到,虽然rect调用了move()方法,但是画出来的图像是静止的.
效果图如下:
image.png

我们要不断的去改变rect的位置
因此,改变后的代码如下:

def auto_move2():
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    WHITE = 255, 255, 255
    screen.fill(WHITE)
    GREEN = 0, 255, 0
    rect = pygame.draw.rect(screen, GREEN, (0,0, 100, 100))
    dx = dy = 1
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        screen.fill(WHITE)
        rect = pygame.draw.rect(screen,GREEN, rect.move(0, dy))
        pygame.display.update()
        time.sleep(0.1)
    pygame.quit()

看一下效果图:
6_4.gif

发现,这个正方形还是动起来了
代码说明:

rect = pygame.draw.rect(screen,GREEN, rect.move(dx, dy))

这个代码做了两件事

  • 在rect.move(dx, dy)返回的矩形所在地方画了一个矩形
  • 将新生成的矩形重新赋值给了rect.使得rect的位置也发了改变
    这里说明一下:
  • draw方法会返回一个rect
  • move()方法也会返回一个rect
    我们再来看一下move_ip()方法
def auto_move3():
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    WHITE = 255, 255, 255
    screen.fill(WHITE)
    GREEN = 0, 255, 0
    rect = pygame.draw.rect(screen, GREEN, (0,0, 100, 100))
    dx = dy = 1
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        screen.fill(WHITE)
        rect.move_ip(dx, 0)
        pygame.draw.rect(screen,GREEN, rect)
        pygame.display.update()
        time.sleep(0.1)
    pygame.quit()

效果图如下:
6-5.gif

可以看到,正方形同样移动起来了

代码分析:

rect.move_ip(dx, dy)
pygame.draw.rect(screen,GREEN, rect)
  • 第一行: rect调用了move_ip()方法,将自己按照dx,dy的值 移动到了新的位置
  • draw()方法画出rect的矩形

可以对比发现,move()方法返回一个新的rect,如果不用变量去接收rect.move()的值,这个方法调用将毫无意义
move_ip()方法将自身移动到了新的位置.
在实际使用的时候,可以根据需要来使用.
如:需要移动后,原始位置需要保留的,用move()方法,如果原地位置不需要保留的,两者都可以,不过更倾向于move_ip()方法

后记:

移动是我们用到最多的方法.因此,需要我们熟练掌握

作业:

设计一个碰到墙壁就反弹的pygame实现

猜你喜欢

转载自blog.csdn.net/weixin_41810846/article/details/112208687
今日推荐