pygame游戏开发

Pygame游戏开发

pygame简介

模块库请参考:pygame官方文档

pygame可以用作游戏开发,但在商业游戏中真正的开发工具却不是pygame。使用pygame开发游戏周期长。

安装pygame

在pycharm中安装第三方库pygame:
在这里插入图片描述

在计算机中安装pygame:
需要用到pip:
查看pip:pip --version
在这里插入图片描述
pip也可以查看自己已经安装的扩展包: pip list
在这里插入图片描述

安装方法可以直接在命令行输入pip install -扩展包名字。

加快安装速度可以使用国内镜像源。
清华:https://pypi.tuna.tsinghua.edu.cn/simple

阿里云:http://mirrors.aliyun.com/pypi/simple/
在这里插入图片描述

游戏最小系统

所谓游戏最小系统指的是如果要写一个游戏最少要写哪些代码。

# 游戏最小系统
import pygame

# 1.初始化操作
pygame.init() # 这是对所有操作进行初始化,包括声音、图像等

# 2.创建游戏窗口
# set_mode(大小)
window = pygame.display.set_mode((800, 600))
# 设置游戏标题
pygame.display.set_caption("酷电编程")

# 3.让游戏保持一直运行的状态
# game loop(游戏循环)
while True:
    # 4.检测事件
    for event in pygame.event.get():
        # 检测关闭按钮被点击的事件
        if event.type == pygame.QUIT:
            # 退出
            exit()

显示图片

import pygame

pygame.init()
window = pygame.display.set_mode((800, 600))
pygame.display.set_caption("酷电编程")
# 设置背景颜色
window.fill((255, 255, 255))  # RGB值,(255,255,255)为白色

# 游戏开始页面静态效果
# 1、加载图片
image1 = pygame.image.load('D:\\上课内容lxl\\2024_4_20\\酷电仔.png')

# 2、渲染图片
# blit(渲染对象,坐标)
window.blit(image1, (0, 0))

# 4、操作图片
# 1)获取图片大小
width, high = image1.get_size()  # 获取图片的长、宽
print(width, high)
window.blit(image1, (800 - width, 600 - high))  # 让图片在右下角显示

# 2)旋转和缩放
# scale(缩放对象,目标大小) --> 可能会发生形变
new_image1 = pygame.transform.scale(image1, (200, 200))
window.blit(new_image1, (300, 100))

# rotozoom(缩放/旋转对象,旋转角度,缩放比例) 逆时针旋转
new_image2 = pygame.transform.rotozoom(image1, 90, 0.5)
window.blit(new_image2, (300, 400))

# 3、刷新显示页面
# pygame.display.flip() 第一次刷新
# pygame.display.update() 第二次及以后刷新。两者耗费的资源是不一样的
pygame.display.update()

while True:
    # 游戏帧刷新
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

在这里插入图片描述

显示文字

import pygame

pygame.init()
window = pygame.display.set_mode((800, 600))
pygame.display.set_caption("酷电编程")
# 设置背景颜色
window.fill((255, 255, 255))  # RGB值,(255,255,255)为白色

# 显示文字
# 1、创建字体对象(选笔)
# font = pygame.font.Font()  # Font(字体文件路径,字号)是自定义字体
# font = pygame.font.SysFont()  # SysFont(字体名,字体大小, 是否加粗=False, 是否倾斜=False)用的是系统字体
# lst = pygame.font.get_fonts()  # 获取所有可使用的字体,返回值是所有可用的字体列表
# print(lst)
font = pygame.font.SysFont('arial', 30)

# 2、通过字体创建文字对象(用笔写字)
# 字体对象.render(文字内容,True,文字颜色,背景颜色=None)
text = font.render('hello pygame', True, (0, 0, 255), (0, 255, 0))

# 3、渲染到窗口上
window.blit(text, (0, 0))

# 4、操作文字对象
# (1).获取文字内容的宽度和高度
text_w, text_h = text.get_size()
window.blit(text, (800 - text_w, 600 - text_h))

# (2)文字缩放和旋转
new_text1 = pygame.transform.scale(text, (400, 200))
window.blit(new_text1, (400, 0))
new_text2 = pygame.transform.rotozoom(text, 90, 2)
window.blit(new_text2, (100, 200))

# 刷新
pygame.display.update()

while True:
    # 游戏帧刷新
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

在这里插入图片描述

画线

import pygame

pygame.init()
window = pygame.display.set_mode((800, 600))
pygame.display.set_caption("酷电编程")
# 设置背景颜色
window.fill((255, 255, 255))  # RGB值,(255,255,255)为白色

# 显示图形
# 1、画直线(原理:两点确定一条直线)
# line(画在哪儿,线的颜色,线的起点,线的终点,线宽(默认为1))
pygame.draw.line(window, (255, 0, 0), (10, 20), (200, 20))  # 这里画在游戏窗口上(一般也是画在游戏窗口上)

# 2、画折线(原理:多个点按顺序连接起来)
# lines(画在哪儿,线的颜色,是否闭合,多个点(列表),线宽(默认为1))
points = [(10, 300), (100, 160), (180, 260), (300, 100)]
pygame.draw.lines(window, (0, 255, 0), False, points, 3)  # True:闭合;False:不闭合

# 刷新显示页面
# pygame.display.flip() 第一次刷新
# pygame.display.update() 第二次及以后刷新。两者耗费的资源是不一样的
pygame.display.update()

while True:
    # 游戏帧刷新
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

在这里插入图片描述

其他图像

其他图像:圆、矩形、椭圆、弧线。

import pygame
from math import pi

pygame.init()
window = pygame.display.set_mode((800, 600))
pygame.display.set_caption("酷电编程")
# 设置背景颜色
window.fill((255, 255, 255))  # RGB值,(255,255,255)为白色

# 显示图形
# 1、画直线(原理:两点确定一条直线)
# line(画在哪儿,线的颜色,线的起点,线的终点,线宽(默认为1))
pygame.draw.line(window, (255, 0, 0), (10, 20), (200, 20))  # 这里画在游戏窗口上(一般也是画在游戏窗口上)

# 2、画折线(原理:多个点按顺序连接起来)
# lines(画在哪儿,线的颜色,是否闭合,多个点(列表),线宽(默认为1))
points = [(10, 300), (100, 160), (180, 260), (300, 100)]
pygame.draw.lines(window, (0, 255, 0), True, points, 3)  # True:闭合;False:不闭合

# 3、画圆(原理:圆心+半径)
# circle(画在哪儿,线的颜色,圆心坐标,半径,线宽(默认为0,线宽=0时为实心圆,非0时为空心圆))
pygame.draw.circle(window, (0, 0, 255), (200, 250), 100, 2)  # 这里线宽=2,画的是空心圆

# 4、画矩形(原理:根据左上角顶点坐标和长、宽即可确定一个矩形)
# rect(画在哪儿,线的颜色,矩形范围(x,y,length,width),线宽(默认为0,线宽=0时为实心矩形,非0时为空心矩形))
pygame.draw.rect(window, (120, 20, 60), (400, 100, 200, 100))  # 线宽默认为0,画的是实心矩形

# 5、画椭圆(原理:在矩形里画内切圆,因此画椭圆的参数与画矩形参数一模一样)
# ellipse(画在哪儿,线的颜色,矩形范围(x,y,length,width),线宽(默认为0,线宽=0时为实心椭圆,非0时为空心椭圆))
pygame.draw.ellipse(window, (255, 0, 0), (400, 400, 200, 100), 3)  # 这里线宽=3,画的是空心椭圆

# 6、画弧线(原理:弧线是椭圆的一段长度,因此也需要借助矩形参数)
# arc(画在哪儿,线的颜色,矩形范围(x,y,length,width),起始弧度,终止弧度,线宽(默认为1))  # 弧度:0-2π;角度:0-360
pygame.draw.arc(window, (255, 0, 0), (400, 250, 200, 100), 0, pi, 3)  # 这里的弧度与数学中的坐标是完全一样的
# 这里引入了math模块中的pi

# 刷新显示页面
# pygame.display.flip() 第一次刷新
# pygame.display.update() 第二次及以后刷新。两者耗费的资源是不一样的
pygame.display.update()

while True:
    # 游戏帧刷新
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

在这里插入图片描述

在上面画弧线时用到的弧度与数学中的坐标是一模一样的:
在这里插入图片描述

动画原理

所有动画的原理都是一样的,都是多张照片快速的播放形成动画效果。

移动、缩放和旋转动画

移动动画

import pygame

WIN_WIDTH = 800  # 窗口宽度
WIN_HEIGHT = 600  # 窗口高度

# 初始化游戏
pygame.init()

# 创建窗口
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 实际开发中窗口宽和高都是设置为全局变量,这样以后修改很方便(类似于封装的好处)
pygame.display.set_caption('动画原理')  # 设置标题
window.fill((255, 255, 255))  # 背景

# 1、显示静态球(实心圆,用画圆的方法)
# circle(画在哪儿,线的颜色,圆心坐标,半径,线宽(默认为0。线宽为0即实心圆,非0为空心圆))
y = 100
pygame.draw.circle(window, (255, 0, 0), (100, y), 50)  # 这里线宽为0画实心圆

# 刷新
pygame.display.update()

# 在循环上面写的都是静态效果,要实现动态效果必须写在循环内

# 游戏循环
while True:

    # 2、移动动画(动态球,实心)
    pygame.draw.circle(window, (255, 255, 255), (100, y), 50)  # 在画下一幅图之前需要将前面一副图覆盖掉(使用背景颜色覆盖,这里背景颜色为白色)
    y += 1  # 数字越大,动画移动的速度越快
    pygame.draw.circle(window, (255, 0, 0), (100, y), 50)
    pygame.display.update()  # 刷新

    # 检测事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            # 退出
            exit()  # 如果是多线程,这里只会退出该线程,进程并不会退出

运行上述代码发现即便在循环中写 y += 1 ,动画的移动速度还是太快,如何再减慢速度?

答:可以规定每循环 100 次(数字越大,速度越慢)移动一次。

num = 1
while True:
    num += 1
	if num % 100 == 0:
		y += 1
		# 画图代码...

具体实现:

import pygame

WIN_WIDTH = 800  # 窗口宽度
WIN_HEIGHT = 600  # 窗口高度

# 初始化游戏
pygame.init()

# 创建窗口
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 实际开发中窗口宽和高都是设置为全局变量,这样以后修改很方便(类似于封装的好处)
pygame.display.set_caption('动画原理')  # 设置标题
window.fill((255, 255, 255))  # 背景

# 1、显示静态球(实心圆,用画圆的方法)
# circle(画在哪儿,线的颜色,圆心坐标,半径,线宽(默认为0。线宽为0即实心圆,非0为空心圆))
y = 100
pygame.draw.circle(window, (255, 0, 0), (100, y), 50)  # 这里线宽为0画实心圆

# 刷新
pygame.display.update()

# 在循环上面写的都是静态效果,要实现动态效果必须写在循环内

num = 1
# 游戏循环
while True:
    num += 1
    # 1)移动动画(动态球,实心)
    if num % 1000 == 0:
        pygame.draw.circle(window, (255, 255, 255), (100, y), 50)  # 在画下一幅图之前需要将前面一副图覆盖掉(使用背景颜色覆盖,这里背景颜色为白色)
        y += 1  # 数字越大,动画移动的速度越快
        pygame.draw.circle(window, (255, 0, 0), (100, y), 50)
        pygame.display.update()  # 刷新

    # 检测事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            # 退出
            exit()  # 如果是多线程,这里只会退出该线程,进程并不会退出

pygame学习-移动动画章节-动画演示

缩放动画

import pygame

WIN_WIDTH = 800  # 窗口宽度
WIN_HEIGHT = 600  # 窗口高度

# 初始化游戏
pygame.init()

# 创建窗口
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 实际开发中窗口宽和高都是设置为全局变量,这样以后修改很方便(类似于封装的好处)
pygame.display.set_caption('动画原理')  # 设置标题
window.fill((255, 255, 255))  # 背景

# 1、显示静态球(实心圆,用画圆的方法)
# circle(画在哪儿,线的颜色,圆心坐标,半径,线宽(默认为0。线宽为0即实心圆,非0为空心圆))
y = 100  # 圆心初始纵坐标
r = 50  # 圆的初始半径
pygame.draw.circle(window, (255, 0, 0), (100, y), r)  # 这里线宽为0画实心圆

# 刷新
pygame.display.update()

# 在循环上面写的都是静态效果,要实现动态效果必须写在循环内

num = 1
# 游戏循环
while True:
    num += 1
    # 2)缩放动画(动态球,实心)
    if num % 1000 == 0:
        pygame.draw.circle(window, (255, 255, 255), (100, y), r)  # 在画下一幅图之前需要将前面一副图覆盖掉(使用背景颜色覆盖,这里背景颜色为白色)
        r += 1  # r += 1 --->半径增大,动画放大;r -= 1 --->半径减小,动画缩小
        pygame.draw.circle(window, (255, 0, 0), (100, y), r)
        pygame.display.update()  # 刷新

    # 检测事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            # 退出
            exit()  # 如果是多线程,这里只会退出该线程,进程并不会退出

pygame学习-缩放动画章节-动画演示

旋转动画

# 3)旋转动画
    if num % 1000 == 0:
        window.fill((255, 255, 255))
        pygame.draw.circle(window, (255, 0, 0), (100, y), r)
        pygame.draw.rect(window, (255, 255, 255), (ix, iy, iw, ih))
        d += 1
        new_image = pygame.transform.scale(image, d, 1)  # 旋转
        window.blit(new_image, (ix, iy))
        pygame.display.update()

移动和缩放同时进行

    # 2)移动和缩放同时进行动画(动态球,实心)
    if num % 1000 == 0:
        pygame.draw.circle(window, (255, 255, 255), (100, y), r)  # 在画下一幅图之前需要将前面一副图覆盖掉(使用背景颜色覆盖,这里背景颜色为白色)
        y += 2  # 移动
        r += 1  # r += 1 --->半径增大,动画放大;r -= 1 --->半径减小,动画缩小
        pygame.draw.circle(window, (255, 0, 0), (100, y), r)
        pygame.display.update()  # 刷新

动画的灵活控制

下面检测边界和修改坐标值得学习:

import pygame

WIN_WIDTH = 800  # 窗口宽度
WIN_HEIGHT = 600  # 窗口高度

# 初始化游戏
pygame.init()

# 创建窗口
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 实际开发中窗口宽和高都是设置为全局变量,这样以后修改很方便(类似于封装的好处)
pygame.display.set_caption('动画原理')  # 设置标题
window.fill((255, 255, 255))  # 背景

# 静态球(实心圆,用画圆的方法)
# circle(画在哪儿,线的颜色,圆心坐标,半径,线宽(默认为0。线宽为0即实心圆,非0为空心圆))
x, y = 200, 30  # 圆心初始坐标
r = 30  # 圆的初始半径
y_speed = 1  # 圆上下移动的速度
pygame.draw.circle(window, (255, 0, 0), (x, y), r)  # 这里线宽为0画实心圆

# 刷新
pygame.display.update()

# 在循环上面写的都是静态效果,要实现动态效果必须写在循环内

num = 1
# 游戏循环
while True:
    num += 1
    # 小球上下反弹的效果
    if num % 1000 == 0:
        '''
        前面在学习移动、缩放动画时用的都是:在画下一幅图之前需要将前面一副图覆盖掉
        pygame.draw.circle(window, (255, 255, 255), (x, y), r) # (使用背景颜色覆盖,这里背景颜色为白色)
        
        也可以用其他方法处理,就是直接再填充一次背景颜色:window.fill((255, 255, 255))  # 原来背景颜色为白色
        当再次填充完背景颜色后其余之前在窗口中显示的内容需要再重新画出来。【这条不要忘了】
        '''
        window.fill((255, 255, 255))  # 再填充一次背景颜色,需要注意其余之前在窗口中显示的内容需要再重新画出来

        # 修改y坐标
        y += y_speed

        # 检测边界
        # 下边界
        if y >= WIN_HEIGHT - r:
            y_speed = y_speed * -1
        # 上边界
        if y <= r:
            y_speed = y_speed * -1

        pygame.draw.circle(window, (255, 0, 0), (x, y), r)
        pygame.display.update()
    # 检测事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            # 退出
            exit()  # 如果是多线程,这里只会退出该线程,进程并不会退出

pygame学习-动画的灵活控制章节-动画演示

鼠标事件

import pygame
from random import randint

WIN_WIDTH = 800  # 窗口宽度
WIN_HEIGHT = 600  # 窗口高度

# 初始化游戏
pygame.init()

# 创建窗口
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 实际开发中窗口宽和高都是设置为全局变量,这样以后修改很方便(类似于封装的好处)
pygame.display.set_caption('动画原理')  # 设置标题
window.fill((255, 255, 255))  # 背景

# 刷新
pygame.display.update()

count = 0  # 统计事件发生的次数
# 游戏循环
while True:

    # 检测事件
    for event in pygame.event.get():
        # for循环中的代码只有事件发生后才会执行
        # 发生什么事件执行对应的代码一定要写在for循环中
        count += 1
        print(count)

        # event的type属性是用来区分不同类型的事件
        '''
        QUIT ---> 点击关闭按钮对应的事件
        
        1、鼠标事件
        MOUSEBUTTONDOWN ---> 鼠标按下
        MOUSEBUTTONUP ---> 鼠标弹起
        MOUSEMOTION ---> 鼠标移动
        
        pos ---> 鼠标位置属性(点的哪儿)
        '''
        if event.type == pygame.QUIT:
            # 退出
            exit()  # 如果是多线程,这里只会退出该线程,进程并不会退出

        # ---------鼠标事件---------
        if event.type == pygame.MOUSEBUTTONDOWN:
            print('鼠标按下', '鼠标按下的位置', event.pos)  # x,y = event.pos 。 event.pos会返回(x,y)元组类型
            mx, my = event.pos  # 取出鼠标的x,y坐标
            pygame.draw.circle(window, (255, 255, 0), (mx, my), 50)  # 画圆
            pygame.display.update()  # 刷新

        if event.type == pygame.MOUSEBUTTONUP:
            print('鼠标弹起')

        if event.type == pygame.MOUSEMOTION:
            print('鼠标移动')
            r = randint(0, 255)
            g = randint(0, 255)
            b = randint(0, 255)
            mx, my = event.pos  # 取出鼠标的x,y坐标
            pygame.draw.circle(window, (r, g, b), (mx, my), 30)  # 画圆
            pygame.display.update()  # 刷新

pygame学习-鼠标事件章节-动画演示

键盘事件

说明
如果按下键盘没反应一般就是输入法的问题,切换成英文输入法即可。

import pygame

WIN_WIDTH = 800  # 窗口宽度
WIN_HEIGHT = 600  # 窗口高度

# 初始化游戏
pygame.init()

# 创建窗口
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 实际开发中窗口宽和高都是设置为全局变量,这样以后修改很方便(类似于封装的好处)
pygame.display.set_caption('动画原理')  # 设置标题
window.fill((255, 255, 255))  # 背景

# 刷新
pygame.display.update()

# 字体
font = pygame.font.SysFont('arial', 30)
tx = 0

count = 0  # 统计事件发生的次数
# 游戏循环
while True:

    # 检测事件
    for event in pygame.event.get():
        # for循环中的代码只有事件发生后才会执行
        # 发生什么事件执行对应的代码一定要写在for循环中
        count += 1
        print(count)

        # event的type属性是用来区分不同类型的事件
        '''
        QUIT ---> 点击关闭按钮对应的事件
        
        2、键盘事件
        KEYDOWN ---> 键盘按键按下
        KEYUP ---> 键盘按键弹起
        
        key ---> 按键值属性(哪个键被按了)
        '''
        if event.type == pygame.QUIT:
            # 退出
            exit()  # 如果是多线程,这里只会退出该线程,进程并不会退出

        # ---------键盘事件---------
        if event.type == pygame.KEYDOWN:
            print('键盘按键按下', event.key, chr(event.key))  # event.key返回的是ASCII码值,需要转换成对应的字符

            # 注意这里如果按下键盘没反应一般就是输入法的问题,切换成英文输入法即可

            if chr(event.key) == 'f':
                print('闪现')

            text = font.render(chr(event.key), True, (250, 0, 0))
            # window.fill((255, 255, 255))  # 再填充一次背景将原来的内容覆盖掉
            tx += 20
            window.blit(text, (tx, 300))
            pygame.display.update()

        if event.type == pygame.KEYUP:
            print('键盘按键弹起')

pygame学习-键盘事件章节-动画演示

按钮点击效果

按钮被点击就是要判断鼠标点击事件发生时鼠标点击的坐标是否在按钮的范围内,点击效果实现就是将按钮再重新画一遍。

import pygame

WIN_WIDTH = 800  # 窗口宽度
WIN_HEIGHT = 600  # 窗口高度

# 初始化游戏
pygame.init()

# 创建窗口
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 实际开发中窗口宽和高都是设置为全局变量,这样以后修改很方便(类似于封装的好处)
pygame.display.set_caption('动画原理')  # 设置标题
window.fill((255, 255, 255))  # 背景

# 按钮上的文字
font = pygame.font.SysFont('隶书', 30)

# 按钮:需要先画矩形,再在上面写字
# 1、“确定”按钮
bx1, by1, bw, bh = 30, 100, 100, 50  # x,y,width,height
pygame.draw.rect(window, (255, 0, 0), (bx1, by1, bw, bh))
text1 = font.render('确定', True, (255, 255, 255))
tw1, th1 = text1.get_size()  # 获取文字对象的长、宽
tx1 = bx1 + bw / 2 - tw1 / 2  # 文字对象x坐标
ty1 = by1 + bh / 2 - th1 / 2  # 文字对象y坐标
window.blit(text1, (tx1, ty1))

# 2、“取消”按钮
bx2, by2 = 30, 200
pygame.draw.rect(window, (0, 255, 0), (bx2, by2, bw, bh))
text2 = font.render('取消', True, (255, 255, 255))
tw2, th2 = text2.get_size()  # 获取文字对象的长、宽
tx2 = bx2 + bw / 2 - tw2 / 2  # 文字对象x坐标
ty2 = by2 + bh / 2 - th2 / 2  # 文字对象y坐标
window.blit(text2, (tx2, ty2))

# 刷新
pygame.display.update()

# 游戏循环
while True:

    # 检测事件
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            # 退出
            exit()  # 如果是多线程,这里只会退出该线程,进程并不会退出

        # 鼠标点击按钮要做的事
        if event.type == pygame.MOUSEBUTTONDOWN:
            mx, my = event.pos  # 获取鼠标点击的坐标
            # 是否点击了“确定”按钮
            if bx1 <= mx <= bx1 + bw and by1 <= my <= by1 + bh:  # 运算符优先级:算术运算符>比较运算符>逻辑运算符。因此这里并不需要加小括号
                # 按钮点击的反应:按钮被点击后背景颜色改变,松开后背景颜色恢复
                pygame.draw.rect(window, (200, 200, 200), (bx1, by1, bw, bh))  # 这里按钮被点击时变为灰色
                window.blit(text1, (tx1, ty1))  # 文字也要重新渲染
                pygame.display.update()  # 刷新

                print('确定按钮被点击')

            # 是否点击了“取消”按钮
            if bx2 <= mx <= bx2 + bw and by2 <= my <= by2 + bh:  # 运算符优先级:算术运算符>比较运算符>逻辑运算符。因此这里并不需要加小括号
                # 按钮点击的反应:按钮被点击后背景颜色改变,松开后背景颜色恢复
                pygame.draw.rect(window, (200, 200, 200), (bx2, by2, bw, bh))  # 这里按钮被点击时变为灰色
                window.blit(text2, (tx2, ty2))  # 文字也要重新渲染
                pygame.display.update()  # 刷新
                print('取消按钮被点击')
                # exit()

        # 鼠标松开按钮要做的事
        if event.type == pygame.MOUSEBUTTONUP:
            # 鼠标松开后背景颜色恢复
            # 这里并没有获取鼠标松开的坐标,意思是不管在哪松开都要执行

            # “确定”按钮被松开
            pygame.draw.rect(window, (255, 0, 0), (bx1, by1, bw, bh))  # 鼠标松开时恢复为红色
            window.blit(text1, (tx1, ty1))  # 文字也要重新渲染
            pygame.display.update()  # 刷新

            # “取消”按钮被松开
            pygame.draw.rect(window, (0, 255, 0), (bx2, by2, bw, bh))  # 鼠标松开时恢复为绿色
            window.blit(text2, (tx2, ty2))  # 文字也要重新渲染
            pygame.display.update()  # 刷新

其中确定文字对象坐标的方法:
在这里插入图片描述

pygame学习-按钮点击效果章节-动画演示

封装好的按钮

在上面“按钮点击效果”中发现要实现一个按钮点击效果的代码很多,如果按钮很多,写起来会很繁琐。这时可以用面向对象编程思想,将按钮封装起来,使用时直接调用。

坦克控制

坦克控制主要在于键盘按住不放,坦克移动;键盘松开,坦克停止。

学会了键盘按住不放,移动;键盘松开,停止。鼠标按住不放,鼠标松开实现的方法是一样的。关键在于用到了一个bool值

说明
如果按下键盘没反应一般就是输入法的问题,切换成英文输入法即可。

import pygame

WIN_WIDTH = 800  # 窗口宽度
WIN_HEIGHT = 600  # 窗口高度

# 初始化游戏
pygame.init()

# 创建窗口
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 实际开发中窗口宽和高都是设置为全局变量,这样以后修改很方便(类似于封装的好处)
pygame.display.set_caption('动画原理')  # 设置标题
window.fill((255, 255, 255))  # 背景

# 放坦克
tank_up = pygame.image.load('坦克up.png')  # 向上的坦克
tank_down = pygame.image.load('坦克down.png')  # 向下的坦克
tank_left = pygame.image.load('坦克left.png')  # 向左的坦克
tank_right = pygame.image.load('坦克right.png')  # 向右的坦克

tank_up_width, tank_up_height = tank_up.get_size()
tank_x, tank_y = WIN_WIDTH / 2 - tank_up_width / 2, WIN_HEIGHT - tank_up_height  # 坦克的坐标。涉及坦克的移动(动画的移动),坐标不能写死

tank = tank_up  # 默认画的是向上的坦克

window.blit(tank, (tank_x, tank_y))

# 刷新
pygame.display.update()

is_move = False  # 是否移动。默认不动
x_speed = 0  # x坐标移动速度
y_speed = 0  # y坐标移动速度
# 游戏循环
while True:

    # 要实现“键盘按住不放,移动;键盘松开,停止”的效果需要将移动的效果写在for循环外面
    if is_move == True:
        window.fill((255, 255, 255))  # 以背景色覆盖掉原来的
        tank_x += x_speed
        tank_y += y_speed
        window.blit(tank, (tank_x, tank_y))
        pygame.display.update()

    # 检测事件
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            # 退出
            exit()  # 如果是多线程,这里只会退出该线程,进程并不会退出

        # 坦克移动
        if event.type == pygame.KEYDOWN:
            char = chr(event.key)
            # 往上移动
            if char == 'w':
                is_move = True  # 移动
                x_speed = 0
                y_speed = -1
                tank = tank_up
            elif char == 's':
                is_move = True  # 向下移动
                x_speed = 0
                y_speed = 1
                tank = tank_down
            elif char == 'a':
                is_move = True  # 向左移动
                x_speed = -1
                y_speed = 0
                tank = tank_left
            elif char == 'd':
                is_move = True  # 向右移动
                x_speed = 1
                y_speed = 0
                tank = tank_right
            else:
                is_move = False  # 停止

        if event.type == pygame.KEYUP:
            is_move = False  # 停止

在这里插入图片描述

pygame学习-坦克控制章节-动画演示

补充

前面提到使用如下代码减慢动画速度:

num = 1
while True:
    num += 1
	if num % 100 == 0:
		y += 1
		# 画图代码...

但事实上有更好的方法。pygame中有time类,可以设置游戏帧数,以此来减慢动画速度。

clock = pygame.time.Clock()  # (放到while循环外)

clock.tick(60)   # 设置帧频。(放到while循环内)

贪吃蛇(简易版)

实现了简易版的贪吃蛇,没有实现更详细的控制(比如此时蛇正向上走,如果向让蛇向下走,不能直接按 ‘s’ 键,而应该先向右或向左,然后向下)。

代码目录:
在这里插入图片描述

import pygame
import random
from pygame import Rect

WIN_WIDTH = 800  # 窗口宽度
WIN_HEIGHT = 600  # 窗口高度

# 初始化游戏
pygame.init()

# 创建窗口
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))  # 实际开发中窗口宽和高都是设置为全局变量,这样以后修改很方便(类似于封装的好处)
pygame.display.set_caption('贪吃蛇')  # 设置标题
window.fill((255, 255, 255))  # 背景

# 覆盖背景
snakebg = pygame.image.load("snakebg.png")
applebg = pygame.image.load("applebg.png")

# 食物(apple)
apple = pygame.image.load("apple.png")
apple_width, apple_height = apple.get_size()
apple_x, apple_y = WIN_WIDTH // 4, WIN_HEIGHT // 4
window.blit(apple, (apple_x, apple_y))

# 蛇
snake_up = pygame.image.load("snakeup.png")  # 向上
snake_down = pygame.image.load("snakedown.png")  # 向下
snake_left = pygame.image.load("snakeleft.png")  # 向左
snake_right = pygame.image.load("snakeright.png")  # 向右

snake_width, snake_height = snake_up.get_size()
snake_x, snake_y = WIN_WIDTH / 2 - snake_width / 2, WIN_HEIGHT - snake_height

snake = snake_up  # 默认向上
window.blit(snake, (snake_x, snake_y))

# 刷新
pygame.display.update()

clock = pygame.time.Clock()

x_speed = 0  # x坐标移动速度
y_speed = -1  # y坐标移动速度

# 游戏循环
while True:
    # 创建矩形对象用于碰撞检测
    snake_rect = Rect(snake_x, snake_y, snake_width, snake_height)  # 蛇的矩形对象
    apple_rect = Rect(apple_x, apple_y, apple.get_width(), apple.get_height())  # 苹果的矩形对象

    # 碰撞检测
    if snake_rect.colliderect(apple_rect):  # 碰撞函数
        window.blit(applebg, (apple_x, apple_y))
        apple_x, apple_y = random.randint(0, WIN_WIDTH - apple_width), random.randint(0, WIN_HEIGHT - apple_height)
        window.blit(snake, (snake_x, snake_y))
        window.blit(apple, (apple_x, apple_y))
        print("吃掉苹果")

    pygame.draw.circle(window, (255, 255, 255), (snake_x + snake_width / 2, snake_y + snake_height / 2), 52)
    # window.blit(snakebg, (snake_x, snake_y))

    snake_x += x_speed
    snake_y += y_speed
    if snake_x <= 0 or snake_x >= WIN_WIDTH - snake_width:
        print('碰到墙壁,游戏结束')
        exit()
    if snake_y <= 0 or snake_y >= WIN_HEIGHT - snake_height:
        print('碰到墙壁,游戏结束')
        exit()
    window.blit(snake, (snake_x, snake_y))
    pygame.display.update()

    # 设置帧频
    clock.tick(60)

    # 检测事件
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            # 退出
            exit()  # 如果是多线程,这里只会退出该线程,进程并不会退出

        if event.type == pygame.KEYDOWN:
            char = chr(event.key)
            if chr(event.key) == 'w':  # 向上
                x_speed = 0
                y_speed = -1
                snake = snake_up
            elif chr(event.key) == 's':  # 向下
                x_speed = 0
                y_speed = 1
                snake = snake_down
            elif chr(event.key) == 'a':  # 向左
                x_speed = -1
                y_speed = 0
                snake = snake_left
            elif chr(event.key) == 'd':  # 向右
                x_speed = 1
                y_speed = 0
                snake = snake_right
            else:
                pass

pygame学习-贪吃蛇章节-动画演示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/721534.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI虚拟数字人上线需要办理哪些资质?

近年来&#xff0c;随着AI 技术快速发展&#xff0c;虚拟数字人行业也进入了新的发展阶段。AI 技术可覆盖虚拟数字人的建模、视频生成、驱动等全流程&#xff0c;一方面使虚拟数字人的制作成本降低、制作周期缩短&#xff0c;另一方面&#xff0c;多模态 AI 技术使得虚拟数字人…

【RK3588/算能/Nvidia智能盒子】AI“值守”,规范新能源汽车充电站停车、烟火及充电乱象

近年来&#xff0c;中国新能源汽车高速发展&#xff0c;产量连续8年位居全球第一。根据中国充电联盟数据&#xff0c;截至2023年6月&#xff0c;新能源汽车保有量1620万辆&#xff0c;全国充电基础设施累计数量为665.2万台&#xff0c;车桩比约2.5:1。 虽然新能源汽车与充电桩供…

短视频矩阵系统:高效运营,解决多账号管理难题

前言 在当下短视频风靡的时代&#xff0c;如何高效管理和运营多个短视频账号&#xff0c;成为了众多运营者面临的挑战。而今&#xff0c;一款全新的短视频矩阵系统应运而生&#xff0c;它不仅融合了AI文案生成与剪辑模式等先进功能&#xff0c;更支持多平台授权&#xff0c;助…

小阿轩yx-Nginx 优化与防盗链

小阿轩yx-Nginx 优化与防盗链 Nginx 服务优化 在企业应用环境中&#xff0c;服务器的安全性和响应速度需要根据实际情况进行相应参数配置&#xff0c;以达到最优的用户体验。 Nginx默认的安装参数 只能提供最基本的服务 需要调整 网页缓存时间连接超时网页压缩等相应参数…

【记录44】【案例】echarts地图

效果&#xff1a;直接上效果图 环境&#xff1a;vue、echarts4.1.0 源码 // 创建容器 <template><div id"center"></div> </template>//设置容器大小&#xff0c;#center { width: 100%; height: 60vh; }这里需注意&#xff1a;笔者在echar…

如何轻松进行照片压缩?5个软件帮助你快速进行照片压缩

如何轻松进行照片压缩&#xff1f;5个软件帮助你快速进行照片压缩 照片压缩是一种常见的图像处理操作&#xff0c;旨在减小图像文件的大小而尽量保持图像质量。有许多软件和工具可供选择&#xff0c;每个工具都有其独特的压缩算法和功能。以下是一些关于照片压缩的详细信息&am…

微信小程序毕业设计-小区疫情防控系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

Python 数据可视化 散点图

Python 数据可视化 散点图 import matplotlib.pyplot as plt import numpy as npdef plot_scatter(ref_info_dict, test_info_dict):# 绘制散点图&#xff0c;ref横&#xff0c;test纵plt.figure(figsize(80, 48))n 0# scatter_header_list [peak_insert_size, median_insert…

多模态大模型通用模式

MM-LLMs&#xff08;多模态大模型&#xff09;是目前比较新的和实用价值越发显著的方向。其指的是基于LLM的模型&#xff0c;具有接收、推理和输出多模态信息的能力。这里主要指图文的多模态。 代表模型&#xff1a;GPT-4o、Gemini-1.5-Pro、GPT-4v、Qwen-VL、CogVLM2、GLM4V、…

JCR一区 | Matlab实现GAF-PCNN、GASF-CNN、GADF-CNN的多特征输入数据分类预测/故障诊断

JJCR一区 | Matlab实现GAF-PCNN、GASF-CNN、GADF-CNN的多特征输入数据分类预测/故障诊断 目录 JJCR一区 | Matlab实现GAF-PCNN、GASF-CNN、GADF-CNN的多特征输入数据分类预测/故障诊断分类效果格拉姆矩阵图GAF-PCNNGASF-CNNGADF-CNN 基本介绍程序设计参考资料 分类效果 格拉姆…

java架构设计-COLA

参考&#xff1a;https://github.com/alibaba/COLA 架构 要素&#xff1a;组成架构的重要元素 结构&#xff1a;要素直接的关系 意义&#xff1a;定义良好的结构&#xff0c;治理应用复杂度&#xff0c;降低系统熵值&#xff0c;改善混乱状态 创建COLA应用&#xff1a; mvn …

Centos8.5安装mysql8.0

1.检查是否有安装mysql数据库&#xff08;如果有mysql或者mariadb数据库&#xff0c;则卸载&#xff09; [rootmyhost ~]# rpm -qa |grep mysql [rootmyhost ~]# rpm -qa | grep mariadb [rootmyhost ~]# ll /etc/my.cnf ls: 无法访问/etc/my.cnf: No such file or directory…

猫头虎分享已解决Bug || 前端领域技术问题解析

原创作者&#xff1a; 猫头虎 作者微信号&#xff1a; Libin9iOak 作者公众号&#xff1a; 猫头虎技术团队 更新日期&#xff1a; 2024年6月6日 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &…

python中scrapy

安装环境 pip install scrapy 发现Twisted版本不匹配 卸载pip uninstall Twisted 安装 pip install Twisted22.10.0 新建scrapy项目 scrapy startproject 项目名 注意&#xff1a;项目名称不允许使用数字开头&#xff0c;也不能包含中文 eg: scrapy startproject scrapy_baidu_…

Redis数据结构学习

Redis 关于redis相关的技术文章我一直没什么思路 直到最近的端午节,我偶然和一个程序员朋友聊到了关于redis数据结构相关的知识点, 所以我决定写一篇文章记录一下 首先我们需要知道redis支持哪些数据类型 Strings (字符串)Lists(列表)Hashes(哈希)Sets(集合)Sorted Sets(有序…

Transformer模型:未来的改进方向与潜在影响

Transformer模型&#xff1a;未来的改进方向与潜在影响 自从2017年Google的研究者们首次提出Transformer模型以来&#xff0c;它已经彻底改变了自然语言处理&#xff08;NLP&#xff09;领域的面貌。Transformer的核心优势在于其“自注意力&#xff08;Self-Attention&#xf…

【C语言习题】31.冒泡排序

文章目录 作业标题作业内容2.解题思路3.具体代码 作业标题 冒泡排序 作业内容 实现一个对整形数组的冒泡排序 2.解题思路 先了解一下冒泡排序&#xff1a; 两两相邻的元素进行比较&#xff0c;如果前面元素大于后面元素就交换两个元素的位置&#xff0c;最终的结果是最大的…

RERCS系统开发实战案例-Part08 FPM 应用程序的表单组件(From UIBB)与列表组件(List UIBB)组合的创建

1、新建From UIBB的FPM Application的快速启动面板 备注&#xff1a;该步骤可第一步操作&#xff0c;也可最后一步操作&#xff0c;本人习惯第一步操作。 1&#xff09;使用事务码 LPD_CUST&#xff0c;选择对应的角色与实例进入快速启动板定制页面&#xff1b; 2&#xff09…

pg表空间和mysql表空间的区别

一、表空间的定义 1、在pg中表空间实际上是为表指定一个存储的目录。并且在创建数据库时可以为数据库指定默认的表空间。创建表和索引时可以指定表空间&#xff0c;这样表和索引就可以存储到表空间对应的目录下了。 在pg中一个库中可以有多个表空间&#xff0c;一个表空间可以…

U盘量产经历二——phisonPS2251-70(PS2270)

写在前面&#xff1a; 量产相关的BBS看了挺多&#xff0c;phison群联的芯片PS2251-70(PS2270)的量产工具比较少&#xff0c;而且很难下载。这里我访问了国外的网站下载来了&#xff0c;也贴出来给童鞋们取用。 以下是记录的量产过程&#xff1a; https://www.usbdev.ru 工具…