pygame游戏开发

news2024/11/20 9:34:44

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学习-贪吃蛇章节-动画演示

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C# OCCT Winform 界面搭建

目录 1.创建一个WInform项目 2.代码总览 代码解析 3.添加模型到场景 4.鼠标交互 1.创建一个WInform项目 2.代码总览 using Macad.Occt.Helper; using Macad.Occt; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Remoting.Co…

机器学习课程复习——支持向量机

支持向量机是一种二类分类模型。基本模型:定义在特征空间上的间隔最大的线性分类器模型升级:线性分类器+核技巧=非线性分类器学习策略:间隔最大化(可形式化为求解凸二次规划的问题;可等价于正则化的合页损失函数的最小化问题)学习算法:求解图二次规划的最优化算法支持向…

什么是Linux挂载

首先先说一下在Linux中一切皆文件&#xff08;硬件设备也是文件&#xff09;&#xff0c;所有文件都是存放在以根目录为树形目录结构中&#xff1b;下面来说说一下什么是挂载 挂载&#xff1a;指的就是将设备文件中的顶级目录连接到 Linux 根目录下的某一目录&#xff08;最好是…

架构师篇-1、总体架构设计

业务架构哲学本质 定位&#xff1a;赋予业务架构设计能力&#xff0c;具备业务架构设计思维模型&#xff0c;掌握业务架构哲学本质&#xff0c;形成以不变应万变的业务架构设计能力。 架构师所需要的能力&#xff1a; 带领业务成功通过框架思维赋能业务架构师知识体系构建掌…

如何卸载windows系统自带游戏

为了清晰地指导如何卸载Windows系统自带游戏&#xff0c;我们可以参考以下步骤进行&#xff1a; 方法一&#xff1a;通过控制面板卸载 打开控制面板进入程序和功能在控制面板中&#xff0c;找到并点击“程序和功能”。在程序列表中&#xff0c;找到你想要卸载的自带游戏。 方…

反激开关电源压敏电阻选型及计算

作用:在浪涌时间里面吸收一个很高的浪涌电压 压敏电阻对电压敏感&#xff0c;有变阻电压阈值 在电压阈值以下&#xff0c;表现出阻抗很大&#xff0c;超过电压阈值&#xff0c;表现出阻抗很小 压敏的选型及计算 压敏电阻的作用是抑制来自电源在异常时的尖峰电压和瞬态过电压&a…

C++编程入门,五个学习阶段让你变成高手

C是一门非常复杂而强大的编程语言&#xff0c;涵盖了广泛的知识领域&#xff0c;从语法基础到高级特性&#xff0c;再到网络通信和数据库操作&#xff0c;都需要逐步掌握。如果你是一个编程新手&#xff0c;尤其是对C感兴趣的新手&#xff0c;可能会发现这门语言的学习曲线有些…

【Linux】进程间通信3——system V共享内存

1.system V进程间通信 管道通信本质是基于文件的&#xff0c;也就是说操作系统并没有为此做过多的设计工作&#xff0c;而system V IPC是操作系统特地设计的一种通信方式。但是不管怎么样&#xff0c;它们的本质都是一样的&#xff0c;都是在想尽办法让不同的进程看到同一份由操…

HTML静态网页成品作业(HTML+CSS)——新媒体专业介绍介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

韩国裸机云站群服务器托管租用方案

随着网络技术的飞速发展&#xff0c;站群服务器在网站运营中扮演着越来越重要的角色。韩国裸机云站群服务器&#xff0c;以其独特的优势&#xff0c;如地理位置优越、价格相对较低、技术实力雄厚等&#xff0c;吸引了众多企业的关注。本文将为您详细介绍韩国裸机云站群服务器的…

机器学习课程复习——朴素贝叶斯

1. 定义 是一种基于贝叶斯定理与特征条件独立假设的生成式分类方法。 2. 公式 原版公式 简化版公式 由于上述公式无法计算&#xff0c;引入条件独立假设 条件独立版公式 3. 贝叶斯分类器 由上述公式可得贝叶斯分类器 化简为 4. 参数估计 4.1. 极大似然估计 4.2. 学习与分…

Psim仿真教程-电路仿真软件功能介绍/电源工程师初级到高级进阶之路

点击下面文字下载需要的版本: Psim2022中文版下载链接: Psim2022中文版软件下载地址 Psim9.1经典版本下载链接: Psim 9.1软件下载地址 有了Psim仿真软件后,无论是电气系统设计还是软件控制设计,都让自己有了质的提升,因此对控制领域感兴趣的朋友们,一定要跟着作者去…

ruoyi框架第二天,自定义接口,在若依框架显示数据

书接上文&#xff0c;搭建好若依&#xff0c;并且创建自己想要的模块。 让ruoyi框架显示自己想要的模块。 今天&#xff0c;我们就要自定义接口&#xff0c;模仿ruoyi框架收发数据模式&#xff0c;来创建自己的模块。 我们创建好自己想要的接口&#xff0c;我这个是无参的查…

【面试干货】Java方法重载规则

【面试干货】Java方法重载规则 1、方法重载的规则和注意事项1.1 方法名必须一致1.2 参数列表必须不同1.3 代码示例1.4 与方法的返回值无关1.5 存在于父类和子类或同类中1.6 可以抛出不同的异常1.7 可以有不同的修饰符 2、注意事项3、总结 &#x1f496;The Begin&#x1f496;点…

据APO Research(阿谱尔)统计,2023年全球乳酸企业产能约119.3万吨

乳酸又称 2-羟基丙酸&#xff0c;一种天然有机酸&#xff0c;分子式是 C3H6O3。是自然界中最为广泛存在的羟基酸&#xff0c;于 1780 年被瑞典科学家 Scheele 首次发现。乳酸是自然界最小的手性分子&#xff0c;以两种立体异构体的形式存在于自然界中&#xff0c;即左旋型 L-乳…

白酒:酒文化传承中的挑战与机遇

随着时代的变迁&#xff0c;酒文化传承面临着许多挑战与机遇。我们来看看酒文化传承面临的挑战。随着现代生活方式的改变&#xff0c;人们对于传统酒文化的认知逐渐淡化。与此同时&#xff0c;年轻一代对于酒文化的兴趣不如老一辈浓厚&#xff0c;这使得酒文化的传承面临断层的…

001、DM8安装

参照&#xff1a;https://eco.dameng.com/document/dm/zh-cn/pm/install-uninstall.html 1. 准备工作 操作系统查看 [rootora19c ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)新建用户 [rootora19c ~]# groupadd dinstall -g 2001 [rootora19c ~]# …

聚观早报 | 小米15配置规格曝光;比亚迪车险开售

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 6月19日消息 小米15配置规格曝光 比亚迪车险开售 真我GT6细节曝光 极星汽车加速全球扩张 Model 3高性能版开启交…

部署LVS-NAT群集

目录 LVS-NAT模式部署 ​1.准备工具 2.所有虚拟机初始化 3.配置NFS共享存储&#xff08;20.0.0.40&#xff09; 3.1安装软件包 3.2创建共享目录和测试文件 4.web服务器部署&#xff08;20.0.0.20 20.0.0.30配置相同&#xff09; 4.1yum安装nginx服务 4.2测试nfs共享服…

SpringCloud Alibaba Sentinel基础入门与安装

GitHub地址&#xff1a;https://github.com/alibaba/Sentinel 中文文档&#xff1a;https://sentinelguard.io/zh-cn/docs/introduction.html 下载地址&#xff1a;https://github.com/alibaba/Sentinel/releases Spring Cloud Alibaba 官方说明文档&#xff1a;Spring Clou…