当前位置:   article > 正文

Python中的pygame游戏模块的使用(修改)_pygame库动画文字动态逐行显示

pygame库动画文字动态逐行显示

Python中的pygame游戏模块的使用(修改)

Pygame 是一组用来开发游戏软件的 Python 程序模块,Pygame 在 SDL(Simple DirectMedia Layer) 的基础上开发而成。它提供了诸多操作模块,比如图像模块(image)、声音模块(mixer)、输入/输出(鼠标、键盘、显示屏)模块,擅长开发 2D 游戏,Python 也提供了开发 3D 游戏的软件包,比如 Pyglet、Panda3D、PyOgre 等。Pygame 是一个高可移植性的模块可以支持多个操作系统。用它来开发小游戏非常适合。官网https://www.pygame.org/news

pygame模块的安装

若使用pygame模块(python的2D游戏开发库),这是第三方(扩展)模块,若未预先装,需要在CMD中,使用 pip install pygame 先装入,可能需要花点时间。

查看是否电脑上是否有pygame,在CMD中,使用pip list命令,参见下图

若没有 pygame,需要在CMD中,使用 pip install pygame 命令安装,参见下图:

【关于安装安装第三方库的更多情况,可参见:https://blog.csdn.net/cnds123/article/details/104393385

验证是否成功安装

法一、在CMD中,使用python -m pygame.examples.aliens命令验证,参见下图:

法二、进入Python的交互界面,输入以下命令验证是否成功安装,参见下图:

不报错,则说明安装成功。

pygame快速入门

Pygame的坐标原点(0,0)点位于左上角,X轴自左向右,Y轴自上向下,单位为像素,参见下图:

在游戏中,所有可见的元素都是以矩形区域来描述位置的;

pygame专门提供了一个类Rect 用于 描述矩形区域,格式:

Rect(x,y,width,height)

Pygame的Rect对象,表示的区域必须位于一个 Surface 对象之上,比如游戏的主窗口(screen)。上述方法由四个关键参数值构成,分别是 left、top、width、height

pygame. Rect(left, top, width, height)

display 用于创建、管理游戏窗口

pygame.display.set_mode()    #初始化游戏显示窗口

pygame.dispaly.update()      #刷新屏幕内容显示,稍后使用

为了做到游戏程序启动后,不会立即退出,通常会在游戏程序中使用一个游戏循环。

pygame开发游戏的大体框架结构如下:

import pygame
 
# 初始化pygame
pygame.init()
 
# 创建游戏的窗口  350 * 573(宽,高);注意:此窗口的大小是依据游戏的背景图片而设定的
screen=pygame.display.set_mode((350,600))
 
# 游戏循环
while True:
    pass
 

 

 示例代码如下:

  1. # 导入所需的模块
  2. import pygame
  3. import sys
  4. # 导入所有pygame.locals里的变量(比如下面大写的QUIT变量)
  5. from pygame.locals import *
  6. # 初始化pygame
  7. pygame.init()
  8. # 设置窗口的大小,单位为像素
  9. screen = pygame.display.set_mode((450, 300))
  10. # 设置窗口标题
  11. pygame.display.set_caption('Hello World')
  12. # 程序主循环
  13. while True:
  14. # 获取事件
  15. for event in pygame.event.get():
  16. # 判断事件是否为退出事件
  17. if event.type == QUIT:
  18. # 退出pygame
  19. pygame.quit()
  20. # 退出系统
  21. sys.exit()
  22. # 绘制屏幕内容
  23. pygame.display.update()

运行之,显示如下:

Pygame设置窗口图标和设置窗口背景图片

#设置窗口图标,下面两句
icon = pygame.image.load("./images/xyicon.png") # 加载图像数据
pygame.display.set_icon(icon)  #设置图标  

#设置窗口背景图片,下面三两句
bg = pygame.image.load("./images/background.png") # 加载图像数据
screen.blit(bg,(0,0)) #绘制图像 blit(图像,位置);
pygame.display.update() #更新屏幕显示

在前面示例代码,设置窗口标题之后,添加设置窗口图标和设置窗口背景图片:

运行之,如下图所示:

Pygame播放音频

有两个方法:

☆播放特效声音:

pygame.mixer.Sound(filename)

该方法返回一个Sound对象,调用它的.play( )方法,即可播放较短的音频文件(如游戏中的枪炮声等);

☆播放背景音乐:

pygame.mixer.music.load(filename)

该方法用来加载背景音乐,之后调用pygame.mixer.music.play( )方法就可以播放背景音乐(在同一个时刻只允许加载一个背景音乐)

# 加载并播放一个特效音频文件)

sound = pygame.mixer.Sound('./music/alter.mp3')

sound.play()

# 加载背景音乐文件

pygame.mixer.music.load('./music/bgmusic.mp3')

# 播放背景音乐,第一个参数为播放的次数(-1表示无限循环),第二个参数是设置播放的起点(单位为秒)

pygame.mixer.music.play(-1, 0.0)

可以在适当的地方,作为测试在背景图片之后插入播放音频代码段,当然音频文件需要准备好。

Pygame绘制图形

Pygame绘制图形的常用的方法:

☆ pygame.draw.line(Surface, color, start_pos, end_pos, width)此方法用于绘制一条线段

☆ pygame.draw.aaline(Surface, color, start_pos, end_pos, blend)此方法用于绘制一条抗锯齿的线

☆ pygame.draw.lines(Surface, color, closed, pointlist, width)此方法用于绘制一条折线

☆ pygame.draw.rect(Surface, color, Rect)此方法用于绘制一个矩形

☆ pygame.draw.rect(Surface, color, Rect, width)此方法用于绘制一个矩形框

☆ pygame.draw.ellipse(Surface, color, Rect)此方法用于绘制一个椭圆

☆ pygame.draw.ellipse(Surface, color, Rect, width)此方法用于绘制一个椭圆框

☆ pygame.draw.polygon(Surface, color, pointlist, width)此方法用于绘制一个多边形

☆ pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width)此方法用于绘制一条弧线

☆ pygame.draw.circle(Surface, color, Rect, radius)此方法用于绘制一个圆

示例代码

  1. # 导入需要的模块
  2. import pygame, sys
  3. from pygame.locals import *
  4. from math import pi
  5. # 初始化pygame
  6. pygame.init()
  7. # 设置窗口的大小,单位为像素
  8. screen = pygame.display.set_mode((400,300))
  9. # 设置窗口标题
  10. pygame.display.set_caption('Drawing')
  11. # 定义颜色
  12. BLACK = ( 0, 0, 0)
  13. WHITE = (255, 255, 255)
  14. RED = (255, 0, 0)
  15. GREEN = ( 0, 255, 0)
  16. BLUE = ( 0, 0, 255)
  17. # 设置背景颜色
  18. screen.fill(WHITE)
  19. # 绘制一条线
  20. pygame.draw.line(screen, GREEN, [10, 10], [50,30], 5)
  21. # 绘制一条抗锯齿的线
  22. pygame.draw.aaline(screen, GREEN, [10, 50],[50, 80],True)
  23. # 绘制一条折线
  24. pygame.draw.lines(screen, BLACK, False,[[10, 80], [50, 90], [200, 80], [220, 30]], 5)
  25. # 绘制一个空心矩形
  26. pygame.draw.rect(screen, BLACK, [75, 10, 50, 20], 2)
  27. # 绘制一个矩形
  28. pygame.draw.rect(screen, BLACK, [150, 10, 50, 20])
  29. # 绘制一个空心椭圆
  30. pygame.draw.ellipse(screen, RED, [225, 10, 50, 20], 2)
  31. # 绘制一个椭圆
  32. pygame.draw.ellipse(screen, RED, [300, 10, 50, 20])
  33. # 绘制多边形
  34. pygame.draw.polygon(screen, BLACK, [[100, 100], [0, 200], [200, 200]], 5)
  35. # 绘制多条弧线
  36. pygame.draw.arc(screen, BLACK,[210, 75, 150, 125], 0, pi/2, 2)
  37. pygame.draw.arc(screen, GREEN,[210, 75, 150, 125], pi/2, pi, 2)
  38. pygame.draw.arc(screen, BLUE, [210, 75, 150, 125], pi,3*pi/2, 2)
  39. pygame.draw.arc(screen, RED, [210, 75, 150, 125], 3*pi/2, 2*pi, 2)
  40. # 绘制一个圆
  41. pygame.draw.circle(screen, BLUE, [60, 250], 40)
  42. # 程序主循环
  43. while True:
  44. # 获取事件
  45. for event in pygame.event.get():
  46. # 判断事件是否为退出事件
  47. if event.type == QUIT:
  48. # 退出pygame
  49. pygame.quit()
  50. # 退出系统
  51. sys.exit()
  52. # 绘制屏幕内容
  53. pygame.display.update()

运行之,显示如下:

Pygame绘制文字

Pygame不仅可以在屏幕上绘制形状,还可以将文本绘制到屏幕上。Pygame 提供了一些非常简单易用的函数,可以创建字体和文本。字体(font)是字体类型的一种描述,表示按照统一风格绘制的一整套的字母、数字、符号和字符,例如 宋体 和 Times New Roman 都是字体。

☆font.SysFont()函数来创建一个 Font 对象,这个函数有两个参数,第 1 个参数是字体名称,第 2 个参数是字体大小(以像素点为单位)

☆font.render()函数的参数:第 1 个参数是要绘制的文本的字符串;第 2 个参数指定是否想要抗锯齿的一个 Boolean 值,如果是 True,文本看上去更加平滑一些;第 3 个参数是用来渲染文本的颜色,这个例子中使用的是白色。

☆blit() 函数,将像素从一个 Surface 复制到另一个 Surface 之上。常用两个参数:第一个参数是某矩形图像(Surface实例),第二个参数用于指定绘制的位置。

示例代码

  1. import pygame
  2. import sys
  3. from pygame.locals import *
  4. pygame.init()
  5. wS=pygame.display.set_mode((400,300)) #创建画布名称wS
  6. WHITE=(255,255,255)
  7. myString="Hello World!"
  8. font = pygame.font.SysFont("Times New Roman", 48) #来创建 Font对象
  9. text = font.render(myString, True, WHITE)
  10. wS.blit(text, (100,150)) #将text复制到指定位置(100,150)
  11. # 程序主循环
  12. while True:
  13. # 获取事件
  14. for event in pygame.event.get():
  15. # 判断事件是否为退出事件
  16. if event.type == QUIT:
  17. # 退出pygame
  18. pygame.quit()
  19. # 退出系统
  20. sys.exit()
  21. # 绘制屏幕内容
  22. pygame.display.update()

 运行之,显示如下:

Pygame实现动画

Pygame实现动画

由于人类眼睛的特殊生理结构,当所看画面的帧率高于24的时候,就会认为是连贯的。

帧率(Frame rate)是用于测量显示帧数的量度,所谓的测量单位为每秒显示帧数(Frames per Second,简称:FPS)。

在原有坐标系的基础上添加偏移量,再重新绘制,依次一张一张的循环绘制下去,就会得到我们想要的物体移动的效果。

Pygame实现动画主要用到的方法:

☆ pygame.image.load(filename) 加载一张图片

☆pygame.Surface.blit(source, dest, area=None, special_flags = 0) 将图片绘制到屏幕相应坐标上(后面两个参数默认,可以不传)

☆pygame.time.Clock() 获得pygame的时钟

☆pygame.time.Clock.tick(FPS) 设置pygame时钟的间隔时间

示例代码如下:

  1. # 导入需要的模块
  2. import pygame, sys
  3. from pygame.locals import *
  4. # 初始化pygame
  5. pygame.init()
  6. # 设置帧率(屏幕每秒刷新的次数)
  7. FPS = 30
  8. # 获得pygame的时钟
  9. fpsClock = pygame.time.Clock()
  10. # 设置窗口大小
  11. screen = pygame.display.set_mode((500, 400), 0, 32)
  12. # 设置标题
  13. pygame.display.set_caption('Animation')
  14. # 定义颜色
  15. WHITE = (255, 255, 255)
  16. # 加载一张图片
  17. img = pygame.image.load('./images/bird.png')
  18. # 初始化图片的位置
  19. imgx = 10
  20. imgy = 10
  21. # 初始化图片的移动方向
  22. direction = 'right'
  23. # 程序主循环
  24. while True:
  25. # 每次都要重新绘制背景白色
  26. screen.fill(WHITE)
  27. # 判断移动的方向,并对相应的坐标做加减
  28. if direction == 'right':
  29. imgx += 5
  30. if imgx == 380:
  31. direction = 'down'
  32. elif direction == 'down':
  33. imgy += 5
  34. if imgy == 300:
  35. direction = 'left'
  36. elif direction == 'left':
  37. imgx -= 5
  38. if imgx == 10:
  39. direction = 'up'
  40. elif direction == 'up':
  41. imgy -= 5
  42. if imgy == 10:
  43. direction = 'right'
  44. # 该方法将用于图片绘制到相应的坐标中
  45. screen.blit(img, (imgx, imgy))
  46. for event in pygame.event.get():
  47. if event.type == QUIT:
  48. pygame.quit()
  49. sys.exit()
  50. # 刷新屏幕
  51. pygame.display.update()
  52. # 设置pygame时钟的间隔时间
  53. fpsClock.tick(FPS)

Pygame事件简介

pygame事件可以处理游戏中的各种事情,事件是一个概念,比如点击鼠标左键,按下一个键盘的按键,关闭窗口等等都是一个事件,pygame提供了一个函数来获取游戏的事件,并把他们存放在一个队列中,程序通过读取整个事件队列,来获取当前发生的时间,并作出响应。

Pygame常用的事件如下表:

事件

产生途径

参数

QUIT

用户按下关闭按钮

none

ACTIVEEVENT

Pygame被激活或者隐藏

gain, state

KEYDOWN

键盘被按下

unicode, key, mod

KEYUP

键盘被放开

key, mod

MOUSEMOTION

鼠标移动

pos, rel, buttons

MOUSEBUTTONDOWN

鼠标按下

pos, button

MOUSEBUTTONUP

鼠标放开

pos, button

VIDEORESIZE

Pygame窗口缩放

size, w, h

示例代码:

  1. # 导入需要的模块
  2. import pygame, sys
  3. from pygame.locals import *
  4. # 定义颜色
  5. WHITE = (255, 255, 255)
  6. # 初始化pygame
  7. pygame.init()
  8. # 设置窗口的大小,单位为像素
  9. screen = pygame.display.set_mode((500,400), 0, 32)
  10. # 设置窗口的标题
  11. pygame.display.set_caption('Event')
  12. # 设置背景
  13. screen.fill(WHITE)
  14. # 程序主循环
  15. while True:
  16. # 获取事件
  17. for event in pygame.event.get():
  18. # 判断事件是否为退出事件
  19. if event.type == QUIT:
  20. # 退出pygame
  21. pygame.quit()
  22. # 退出系统
  23. sys.exit()
  24. # 获得鼠标按下的位置
  25. if event.type ==MOUSEBUTTONDOWN:
  26. print("鼠标按下:",event.pos)
  27. # 获得鼠标抬起的位置
  28. if event.type ==MOUSEBUTTONUP:
  29. print("鼠标抬起:",event.pos)
  30. # 获得键盘方向键按下的事件
  31. if event.type == KEYDOWN:
  32. if(event.key==K_UP or event.key==K_w):
  33. print("上")
  34. if(event.key==K_DOWN or event.key==K_s):
  35. print("下")
  36. if(event.key==K_LEFT or event.key==K_a):
  37. print("左")
  38. if(event.key==K_RIGHT or event.key==K_d):
  39. print("右")
  40. # 按下键盘的Esc键退出
  41. if(event.key==K_ESCAPE):
  42. # 退出pygame
  43. pygame.quit()
  44. # 退出系统
  45. sys.exit()
  46. # 绘制屏幕内容
  47. pygame.display.update()

效果图如下:

综合例子

下面给出综合例子

1、画一个小房子,房前有树,树顶上有太阳

先给出效果图:

源码如下:

  1. import pygame
  2. import sys
  3. # 初始化pygame
  4. pygame.init()
  5. # 设置窗口尺寸
  6. width, height = 861, 594
  7. screen = pygame.display.set_mode((width, height))
  8. pygame.display.set_caption('画图')
  9. # 定义颜色
  10. WHITE = (255, 255, 255)
  11. ORANGE = (255, 165, 0)
  12. BROWN = (165, 42, 42)
  13. GREEN = (0, 128, 0)
  14. RED = (255, 0, 0)
  15. GRAY = (128, 128, 128)
  16. # 绘制背景
  17. screen.fill(WHITE)
  18. # 画房子
  19. pygame.draw.polygon(screen, GRAY, [(150, 300), (350, 300), (250, 200)]) # 房子的屋顶
  20. pygame.draw.polygon(screen, ORANGE, [(150, 400), (350, 400), (350, 300), (150, 300)]) # 房子的底部
  21. # 画房子的门和窗户
  22. pygame.draw.rect(screen, WHITE, (180, 350, 30, 30)) # 窗户1
  23. pygame.draw.rect(screen, WHITE, (230, 350, 40, 50)) # 门
  24. pygame.draw.rect(screen, WHITE, (290, 350, 30, 30)) # 窗户2
  25. # 画树1
  26. pygame.draw.rect(screen, BROWN, (400, 300, 20, 100)) # 树干
  27. pygame.draw.circle(screen, GREEN, (410, 250), 50) # 树冠
  28. # 画树2
  29. pygame.draw.rect(screen, BROWN, (560, 300, 40, 150)) # 绘制树干
  30. # 绘制树冠
  31. pygame.draw.circle(screen, GREEN, (550, 250), 50)
  32. pygame.draw.circle(screen, GREEN, (620, 250), 50)
  33. pygame.draw.circle(screen, GREEN, (590, 220), 50)
  34. pygame.draw.circle(screen, GREEN, (560, 280), 50)
  35. pygame.draw.circle(screen, GREEN, (610, 280), 50)
  36. # 画太阳
  37. pygame.draw.circle(screen, RED, (650, 50), 25) # 太阳
  38. # 刷新屏幕
  39. pygame.display.flip()
  40. # 保持窗口打开
  41. while True:
  42. for event in pygame.event.get():
  43. if event.type == pygame.QUIT:
  44. pygame.quit()
  45. sys.exit()
2、用方向键控制小猫移动示例

需要两个素材文件:小猫图片 cat.png 和背景图片bg1.jpg,为简便将它们 和源码程序文件,放在同一文件夹中。

源码如下:

  1. import sys
  2. import pygame
  3. from pygame.locals import *
  4. def control_ball(event):
  5. speed = [x,y] =[0,0]# 设置相对位移
  6. speed_offset = 1 #小球的速度
  7. # 如果事件的类型是 键盘输入,就根据方向键来求出速度的方向(默认是从左往右为1,从上往下为1)
  8. if event.type == KEYDOWN:
  9. if event.key == pygame.K_LEFT:
  10. speed[0] -= speed_offset
  11. event.key
  12. if event.key == pygame.K_RIGHT:
  13. speed[0] = speed_offset
  14. event.key
  15. if event.key == pygame.K_UP:
  16. speed[1] -= speed_offset
  17. event.key
  18. if event.key == pygame.K_DOWN:
  19. speed[1] = speed_offset
  20. event.key
  21. #如果没有方向键的输入,则速度为0,小球不动
  22. if event.type in (pygame.K_UP, pygame.K_LEFT, pygame.K_RIGHT, pygame.K_DOWN):
  23. speed = [0,0]
  24. return speed
  25. #定义函数
  26. def play_ball():
  27. pygame.init()#初始化
  28. window_size = Rect(0,0,600,440)#设置窗口的大小
  29. screen = pygame.display.set_mode(window_size.size)#设置窗口模式
  30. pygame.display.set_caption('hello cat')#设置窗口标题
  31. ball_image = pygame.image.load('cat.png')#载入小球图片
  32. back_image = pygame.image.load('bg1.jpg')#载入背景图片
  33. ball_rect = ball_image.get_rect()# 获取小球图片所在的区域
  34. while True:
  35. #退出事件的处理
  36. for event in pygame.event.get():
  37. if event.type == QUIT:
  38. pygame.quit()
  39. sys.exit()
  40. control_speed = control_ball(event)#获取到小球的方向
  41. ball_rect = ball_rect.move(control_speed).clamp(window_size)#小球按照方向移动,并且不会移出窗口。
  42. screen.blit(back_image,(0,0))#设置窗口背景,位于(0,0)处,窗口左上角。
  43. screen.blit(ball_image, ball_rect)#把小球绘制到背景surface上。
  44. pygame.display.flip()#更新窗口内容
  45. #调用函数
  46. play_ball()

3、拼图游戏

两种实现:点击交换式和拖动交换式

★拼图游戏之点击交换式

加载一张图片分块打乱,用户用鼠标单击两块图片则两块图片交换位置,拼图完成后提示成功。确保图像文件存在并与代码中指定的路径相匹配——我这里图片名是player.png,和源码文件放在同一文件夹中。

源码如下: 

  1. import random
  2. from sys import exit # 使用sys模块的exit函数来退出游戏
  3. import pygame
  4. from pygame.locals import * # 导入一些常用的函数和常量
  5. from tkinter import messagebox #导入messagebox模块
  6. SCREEN_WIDTH = 600
  7. SCREEN_HEIGHT = 600
  8. ROW = 0
  9. COL = 0
  10. CELL_WIDTH = 0 #SCREEN_WIDTH / COL
  11. CELL_HEIGHT = 0 #SCREEN_HEIGHT / ROW
  12. firstClickCell = None
  13. # 标记是否游戏成功
  14. successFlag = False
  15. gamePictures='player.png' ##游戏图片##
  16. pygame.init() # 初始化pygame
  17. screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # 创建了一个窗口 大小是(宽,高)
  18. pygame.display.set_caption('单击交换式拼图') # 设置窗口标题
  19. scaled_image =pygame.transform.scale(pygame.image.load(gamePictures), (SCREEN_WIDTH//6, SCREEN_HEIGHT//6)) #加载原始图片缩小
  20. GREEN = (0, 255, 0)
  21. BLUE = (0, 0, 255)
  22. RED = (255, 0, 0)
  23. WHITE = (255, 255, 255)
  24. myfont = pygame.font.SysFont('KaiTi', 60) #None系统默认字体,楷体:KaiTi
  25. textImage1 = myfont.render("难度级别 1", True , GREEN)
  26. textImage2 = myfont.render("难度级别 2", True , BLUE)
  27. textImage3 = myfont.render("难度级别 3", True , RED)
  28. myfont = pygame.font.SysFont('SimHei', 20) #黑体:SimHei
  29. textImage4 = myfont.render("选取上面难度等级进入游戏;用户用鼠标单击", True , WHITE)
  30. textImage5 = myfont.render("两个已打乱顺序的小图块则这两块交换位置。", True , WHITE)
  31. screen.fill((0,0,0))
  32. screen.blit(scaled_image, (0, 0))
  33. screen.blit(textImage1, (150, 100))
  34. screen.blit(textImage2, (150, 250))
  35. screen.blit(textImage3, (150, 400))
  36. screen.blit(textImage4, (100, 500))
  37. screen.blit(textImage5, (100, 530))
  38. pygame.display.update()
  39. class PartPicture:
  40. # 初始化一个图片分块,保存图像和图像的位置, id代表原图第几块的位置
  41. def __init__(self, img, x, y, id):
  42. self.img = img
  43. self.x = x
  44. self.y = y
  45. self.id = id
  46. # 判断是否在图片内
  47. def isOver(self):
  48. w, h = self.img.get_size()
  49. point_x, point_y = pygame.mouse.get_pos() # 返回鼠标当前坐标
  50. in_x = self.x < point_x < self.x + w
  51. in_y = self.y < point_y < self.y + h
  52. return in_x and in_y
  53. # 检测移动
  54. def isPressed(self, pictureList):
  55. # print('is_pressed')
  56. if self.isOver():
  57. b1, b2, b3 = pygame.mouse.get_pressed()
  58. if b1 == 1:
  59. global firstClickCell
  60. global successFlag
  61. if firstClickCell is None:
  62. firstClickCell = self
  63. print('id为{}的块被点击'.format(firstClickCell.getId()))
  64. else:
  65. print('交换{}与{}的坐标'.format(firstClickCell.getId(), self.getId()))
  66. self.pictureSwitch(firstClickCell, self)
  67. if self.isFinish(pictureList):
  68. successFlag = True
  69. print('成功!')
  70. else:
  71. successFlag = False
  72. firstClickCell = None
  73. return True
  74. return False
  75. # 判断拼图完成
  76. def isFinish(self, pictureList):
  77. for cell in pictureList:
  78. nowp_x, nowp_y = cell.getXY()
  79. p_x = cell.getId() % COL * CELL_WIDTH
  80. p_y = (cell.getId() // COL) * CELL_HEIGHT
  81. print("id{} nowx{}与nowy{}的坐标 本来的坐标x{}y{}".format(cell.getId(), nowp_x, nowp_y, p_x, p_y))
  82. if nowp_x != p_x or nowp_y != p_y:
  83. return False
  84. return True
  85. def pictureSwitch(self, cell1, cell2):
  86. tempX = cell1.getX()
  87. tempY = cell1.getY()
  88. cell1.setXY(cell2.getX(), cell2.getY())
  89. cell2.setXY(tempX, tempY)
  90. def render(self, screen):
  91. screen.blit(self.img, (self.x, self.y))
  92. # get和set方法
  93. def getX(self):
  94. return self.x;
  95. def getY(self):
  96. return self.y
  97. # 获取图片坐标
  98. def getXY(self):
  99. return self.x, self.y
  100. # 修改图片坐标
  101. def setXY(self,x, y):
  102. self.x = x
  103. self.y = y
  104. # 获取id
  105. def getId(self):
  106. return self.id
  107. # 图片分块
  108. def devide(imgSrc):
  109. # 切割原来的图片
  110. pictures = []
  111. ScPictures = []
  112. id = 0 # 给每个分块的图片设置下标
  113. for i in range(ROW):
  114. for j in range(COL):
  115. # 提取部分图片
  116. partOfPicutre = imgSrc.subsurface(j * CELL_WIDTH, i * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT)
  117. # 保存第一组图片
  118. tempPicture = PartPicture(partOfPicutre, j * CELL_WIDTH, i * CELL_HEIGHT, id)
  119. pictures.append(tempPicture)
  120. # 保存第二组图片
  121. tempPicture = PartPicture(partOfPicutre, j * CELL_WIDTH, i * CELL_HEIGHT, id)
  122. ScPictures.append(tempPicture)
  123. id += 1
  124. random.shuffle(pictures)
  125. # 开始利用第二组图片来打乱原来的图片
  126. for i in range(len(pictures)):
  127. pictures[i].setXY(ScPictures[i].getX(), ScPictures[i].getY())
  128. return pictures # 把打乱的图片返回
  129. setInit = False
  130. while True:
  131. if setInit:
  132. break
  133. for event in pygame.event.get():
  134. if event.type == QUIT:
  135. exit() # 接收到退出事件后退出程序
  136. elif event.type == MOUSEBUTTONDOWN:
  137. b1, b2, b3 = pygame.mouse.get_pressed()
  138. if b1 == 1:
  139. point_x, point_y = pygame.mouse.get_pos() # 返回鼠标当前坐标
  140. if 100 < point_y < 200:
  141. ROW = 3
  142. COL = 3
  143. setInit = True
  144. elif 250 < point_y < 350:
  145. ROW = 4
  146. COL = 4
  147. setInit = True
  148. elif 350 < point_y < 450:
  149. ROW = 5
  150. COL = 5
  151. setInit = True
  152. CELL_WIDTH = SCREEN_WIDTH / COL
  153. CELL_HEIGHT = SCREEN_HEIGHT / ROW
  154. # 原图 提高 blit 的速度 convert_alpha相对于convert,保留了图像的Alpha 通道信息,可以认为是保留了透明的部分,实现了透明转换
  155. imgSrc = pygame.image.load(gamePictures).convert() ##加载游戏图片
  156. PictureList = devide(imgSrc) #图片分块
  157. while True: # 游戏主循环
  158. for event in pygame.event.get():
  159. if event.type == QUIT:
  160. exit() # 接收到退出事件后退出程序
  161. elif event.type == MOUSEBUTTONDOWN:
  162. for cell in PictureList:
  163. # 检测按键按下,并且交换图片位置
  164. if cell.isPressed(PictureList):
  165. break
  166. for partPicture in PictureList:
  167. partPicture.render(screen)
  168. if not successFlag:
  169. # # Sta 绘制分割线
  170. for i in range(1, COL):
  171. pygame.draw.lines(screen, GREEN, 0, [(i * SCREEN_WIDTH // COL, 0), (i * SCREEN_WIDTH // COL, SCREEN_HEIGHT)], 1)
  172. for i in range(1, ROW):
  173. pygame.draw.lines(screen, GREEN, 0, [(0, i * SCREEN_HEIGHT // ROW), (SCREEN_WIDTH, i * SCREEN_HEIGHT // ROW)], 1)
  174. # End 绘制分割线
  175. pygame.display.update() # 刷新一下画面
  176. if successFlag:
  177. messagebox.showinfo("祝贺你!", "成功完成!")
  178. break

效果示意图如下:

★拼图游戏之拖动交换式

下面给出拼图游戏的另一种实现

功能:窗体上有两个按钮,单击"open"按钮加载的游戏图片,单击"start"按钮将加载的游戏图片分割成9小块打乱排列。游戏规则:将一个小块拖动到另一小块时,两小块图片将交换位置,当恢复原样时,提示"success!"。

源码如下:

  1. import pygame
  2. import random
  3. import sys
  4. import tkinter as tk
  5. from tkinter import filedialog
  6. # 初始化Tkinter
  7. root = tk.Tk()
  8. root.withdraw()
  9. # 初始化游戏
  10. pygame.init()
  11. # 设置游戏窗口尺寸
  12. WIDTH = 600
  13. HEIGHT = 600
  14. window = pygame.display.set_mode((WIDTH, HEIGHT))
  15. pygame.display.set_caption("拼图游戏:拖动交换小块图")
  16. # 设置颜色
  17. WHITE = (255, 255, 255)
  18. BLUE = (0, 0, 255)
  19. # 设置字体
  20. font = pygame.font.Font(None, 36)
  21. # 设置拼图块的尺寸和间隙
  22. BLOCK_SIZE = 200
  23. BLOCK_MARGIN = 5
  24. # 设置拼图块的初始位置
  25. block_positions = [(j * (BLOCK_SIZE + BLOCK_MARGIN), i * (BLOCK_SIZE + BLOCK_MARGIN))
  26. for i in range(3) for j in range(3)]
  27. # 拼图块的当前位置
  28. current_positions = block_positions.copy()
  29. # 游戏状态
  30. game_started = False
  31. puzzle_completed = False
  32. # 选中的拼图块
  33. selected_block = None
  34. selected_block_index = None
  35. # 加载游戏图片
  36. original_image = None
  37. block_images = []
  38. def load_image():
  39. global original_image, block_images
  40. # 选择并加载计算机中的图片
  41. file_path = filedialog.askopenfilename()
  42. if file_path:
  43. try:
  44. original_image = pygame.image.load(file_path)
  45. original_image = pygame.transform.scale(original_image, (BLOCK_SIZE * 3, BLOCK_SIZE * 3))
  46. # 分割原始图片为拼图块
  47. block_images = []
  48. for i in range(3):
  49. for j in range(3):
  50. block_images.append(original_image.subsurface(pygame.Rect(j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)))
  51. # 重置游戏状态
  52. global game_started, puzzle_completed
  53. game_started = False
  54. puzzle_completed = False
  55. except pygame.error:
  56. print("加载图片失败!")
  57. sys.exit(1)
  58. # 检查拼图是否完成
  59. def check_puzzle_completed():
  60. global puzzle_completed
  61. puzzle_completed = all(current_positions[i] == block_positions[i] for i in range(len(current_positions)))
  62. # "start"按钮的点击事件处理
  63. def start_game():
  64. global game_started, puzzle_completed, current_positions
  65. if original_image is not None:
  66. current_positions = block_positions.copy()
  67. random.shuffle(current_positions)
  68. game_started = True
  69. puzzle_completed = False
  70. # 交换拼图块位置
  71. def swap_pieces(pos1, pos2):
  72. current_positions[pos1], current_positions[pos2] = current_positions[pos2], current_positions[pos1]
  73. # 获取拼图块索引
  74. def get_block_index(position):
  75. for i, pos in enumerate(current_positions):
  76. if pos == position:
  77. return i
  78. return None
  79. # 游戏主循环
  80. running = True
  81. clock = pygame.time.Clock()
  82. while running:
  83. for event in pygame.event.get():
  84. if event.type == pygame.QUIT:
  85. running = False
  86. elif event.type == pygame.MOUSEBUTTONDOWN:
  87. if 50 <= event.pos[0] <= 180 and 50 <= event.pos[1] <= 80:
  88. load_image() # 当鼠标在"open"按钮区域内按下时,调用load_image()函数加载图片
  89. elif game_started and not puzzle_completed:
  90. for i, position in enumerate(current_positions):
  91. block_rect = pygame.Rect((position[0], position[1]), (BLOCK_SIZE, BLOCK_SIZE))
  92. if block_rect.collidepoint(event.pos):
  93. selected_block = position # 记录选中的拼图块的位置
  94. selected_block_index = i # 记录选中的拼图块的索引
  95. break
  96. elif 200 <= event.pos[0] <= 330 and 50 <= event.pos[1] <= 80:
  97. start_game() # 当鼠标在"start"按钮区域内按下时,调用start_game()函数开始游戏
  98. elif event.type == pygame.MOUSEBUTTONUP:
  99. if game_started and not puzzle_completed and selected_block is not None:
  100. for i, position in enumerate(current_positions):
  101. block_rect = pygame.Rect((position[0], position[1]), (BLOCK_SIZE, BLOCK_SIZE))
  102. if block_rect.collidepoint(event.pos) and selected_block != position:
  103. swap_pieces(selected_block_index, i) # 交换选中的拼图块与鼠标释放位置上的拼图块的位置
  104. break
  105. selected_block = None
  106. selected_block_index = None
  107. elif event.type == pygame.KEYDOWN:
  108. if event.key == pygame.K_r:
  109. if original_image is not None:
  110. random.shuffle(current_positions) # 按下"r"键后,随机洗牌拼图块的位置
  111. game_started = True
  112. puzzle_completed = False
  113. elif event.key == pygame.K_q:
  114. running = False # 按下"q"键后,退出游戏循环
  115. window.fill(WHITE) # 填充窗口背景颜色为白色
  116. if original_image is not None:
  117. for i in range(len(current_positions)):
  118. position = current_positions[i]
  119. pygame.draw.rect(window, BLUE, (position[0], position[1], BLOCK_SIZE, BLOCK_SIZE)) # 绘制拼图块的矩形边框
  120. window.blit(block_images[i], position) # 在拼图块的位置上绘制对应的图像
  121. pygame.draw.rect(window, BLUE, (50, 50, 130, 30)) # 绘制"open"按钮的矩形边框
  122. open_text = font.render("open", True, WHITE) # 创建渲染的"open"文本图像
  123. window.blit(open_text, (90, 55)) # 在窗口上绘制"open"文本图像
  124. pygame.draw.rect(window, BLUE, (200, 50, 130, 30)) # 绘制"start"按钮的矩形边框
  125. start_text = font.render("start", True, WHITE) # 创建渲染的"start"文本图像
  126. window.blit(start_text, (235, 55)) # 在窗口上绘制"start"文本图像
  127. check_puzzle_completed() # 检查拼图是否完成
  128. if puzzle_completed:
  129. success_text = font.render("success!", True, WHITE) # 创建渲染的"success!"文本图像
  130. success_text_rect = success_text.get_rect(center=(WIDTH // 2, HEIGHT // 2)) # 计算"success!"文本图像的中心位置
  131. window.blit(success_text, success_text_rect) # 在窗口上绘制"success!"文本图像
  132. pygame.display.flip() # 更新窗口显示
  133. clock.tick(60) # 控制游戏循环的帧率为60帧每秒
  134. pygame.quit()

在此就不给出效果示意图了,你可以试试。

4、更多的例子

python和pygame实现烟花特效 https://blog.csdn.net/cnds123/article/details/134974517

python和pygame实现捉小兔游戏 https://blog.csdn.net/cnds123/article/details/134996061

附录

Pygame官方文档https://www.pygame.org/docs/ 

pygame中文教程 https://www.w3schools.cn/pygame/

RGB 颜色表   https://www.codeeeee.com/color/rgb.html
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/471958
推荐阅读
相关标签
  

闽ICP备14008679号