2020年9月12日星期六

81 A 《零基礎入門學習Python》筆記 第081講:Pygame:提高遊戲的顏值1 上

《零基礎入門學習Python》第081講:Pygame:提高遊戲的顏值1


毋庸置疑,在這個出門看臉的時代,高顏值的界面會給你的遊戲帶來更多的眼球。這兩節課我們就來談談如何提高Pygame遊戲的顏值。
我們一直通過display模塊的set_mode() 方法來指定界面的大小,這個方法會返回一個Surface 對象,我們就使用這個Surface 對像作為界面。今天我們就來仔細講解set_mode() 方法。
set_mode(resolution = (0, 0), flags = 0, depth = 0) -> Surface
這個方法有三個參數,
第一個參數resolution 用於指定界面的大小。如果什麼都不給的話,就是使用默認的(0, 0),Pygame 會根據當前的屏幕分辨率來創建一個窗口。大家要注意,這一功能只有在SDL版本高於或等於1.2.10時才會實現。如果是低於這個版本號,就會拋出異常。所以一般情況下,第一個參數還是給定較好。
第二個參數flags是指定擴展選項,同時指定多組選項可以使用管道操作符"|",這兒是flags參數提供的幾個可選項:
選項
含義
pygame.FULLSCREEN創建一個全屏顯示
pygame.DOUBLEBUF1.雙緩沖模式 
2.推薦和HWSURFACE或OPENGL一起使用
pygame.HWSURFACE硬件加速,只有在FULLSCREEN 下可以使用
pygame.OPENGL創建一個OPENGL 渲染的顯示
pygame.RESIZABLE創建一個可調整尺寸的窗口
pygame.NOFRAME創建一個沒有邊框和控制按鈕的窗口
第三個參數depth 用於指定顏色的位數,一般不推薦自己設置,Pygame 會根據當前的操作系統去取一個最合適的值。
大家可能會注意一個情況,我們玩的大多數遊戲都是全屏模式,不是全屏還不給玩,你知道是為什麼嗎?
因為全屏的好處有太多了,你可以顯示更多的內容,可以開啟硬件加速,最重要的是你一個程序霸占了所有的屏幕,其他軟件就不能玩了。
全屏模式在Pygame中非常簡單,只需要將第二個參數設置為 FULLSCREEN 即可,同時,我們還可以加上硬件加速。
我們需要關聯一個快捷鍵,讓我們的全屏得到控制。
代碼如下:
  1. import pygame
  2. import sys
  3. # 初始化Pygame
  4. pygame.init()
  5. size = width, height = 600, 400
  6. speed = [-2, 1]
  7. bg = (255, 255, 255) # RGB
  8. fullscreen = False #设置一个决定全屏的变量
  9. #实例化Pygame 的time 模块的 Clock 对象
  10. clock = pygame.time.Clock()
  11. # 创建指定大小的窗口 Surface
  12. screen = pygame.display.set_mode(size)
  13. # 设置窗口标题
  14. pygame.display.set_caption("初次见面,请大家多多关照!")
  15. # 加载图片
  16. turtle = pygame.image.load("python.png")
  17. # 获得图像的位置矩形
  18. position = turtle.get_rect()
  19. l_head = turtle
  20. r_head = pygame.transform.flip(turtle, True, False)
  21. while True:
  22. for event in pygame.event.get():
  23. if event.type == pygame.QUIT:
  24. sys.exit()
  25. if event.type == pygame.KEYDOWN:
  26. if event.key == pygame.K_LEFT: #按下方向键左键
  27. turtle = l_head #调头
  28. speed = [-1, 0]
  29. if event.key == pygame.K_RIGHT:
  30. turtle = r_head #调头
  31. speed = [1, 0]
  32. if event.key == pygame.K_UP:
  33. speed = [0, -1]
  34. if event.key == pygame.K_DOWN:
  35. speed = [0, 1]
  36. #全屏(F11)
  37. if event.key == pygame.K_F11:
  38. fullscreen = not fullscreen
  39. if fullscreen:
  40. screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE)
  41. else:
  42. screen = pygame.display.set_mode(size)
  43. # 移动图像
  44. position = position.move(speed)
  45. if position.left < 0 or position.right > width:
  46. # 翻转图像
  47. turtle = pygame.transform.flip(turtle, True, False)
  48. # 反方向移动
  49. speed[0] = -speed[0]
  50. if position.top < 0 or position.bottom > height:
  51. speed[1] = -speed[1]
  52. # 填充背景
  53. screen.fill(bg)
  54. # 更新图像
  55. screen.blit(turtle, position)
  56. # 更新界面
  57. pygame.display.flip()
  58. # 延迟10毫秒
  59. #pygame.time.delay(10)
  60. #设置帧率
  61. clock.tick(200)
(其實,上面的程序在全屏時還存在一個小BUG,不知道大家發現了沒有,小蛇蛇在原始尺寸的位置就調頭了,大家可以動手修改一下,很簡單的。)(修改的代碼如下:)
  1. import pygame
  2. import sys
  3. # 初始化Pygame
  4. pygame.init()
  5. size = width, height = 600, 400
  6. speed = [-2, 1]
  7. bg = (255, 255, 255) # RGB
  8. fullscreen = False #设置一个决定全屏的变量
  9. #实例化Pygame 的time 模块的 Clock 对象
  10. clock = pygame.time.Clock()
  11. # 创建指定大小的窗口 Surface
  12. screen = pygame.display.set_mode(size)
  13. # 设置窗口标题
  14. pygame.display.set_caption("初次见面,请大家多多关照!")
  15. # 加载图片
  16. turtle = pygame.image.load("python.png")
  17. # 获得图像的位置矩形
  18. position = turtle.get_rect()
  19. l_head = turtle
  20. r_head = pygame.transform.flip(turtle, True, False)
  21. while True:
  22. for event in pygame.event.get():
  23. if event.type == pygame.QUIT:
  24. sys.exit()
  25. if event.type == pygame.KEYDOWN:
  26. if event.key == pygame.K_LEFT: #按下方向键左键
  27. turtle = l_head #调头
  28. speed = [-1, 0]
  29. if event.key == pygame.K_RIGHT:
  30. turtle = r_head #调头
  31. speed = [1, 0]
  32. if event.key == pygame.K_UP:
  33. speed = [0, -1]
  34. if event.key == pygame.K_DOWN:
  35. speed = [0, 1]
  36. #全屏(F11)
  37. if event.key == pygame.K_F11:
  38. fullscreen = not fullscreen
  39. if fullscreen:
  40. screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE)
  41. width , height = 1920, 1080
  42. else:
  43. screen = pygame.display.set_mode(size)
  44. width, height = size
  45. # 移动图像
  46. position = position.move(speed)
  47. if position.left < 0 or position.right > width:
  48. # 翻转图像
  49. turtle = pygame.transform.flip(turtle, True, False)
  50. # 反方向移动
  51. speed[0] = -speed[0]
  52. if position.top < 0 or position.bottom > height:
  53. speed[1] = -speed[1]
  54. # 填充背景
  55. screen.fill(bg)
  56. # 更新图像
  57. screen.blit(turtle, position)
  58. # 更新界面
  59. pygame.display.flip()
  60. # 延迟10毫秒
  61. #pygame.time.delay(10)
  62. #设置帧率
  63. clock.tick(200)
接下來我們又發現了一個BUG,就是如果在全屏模式下,小蛇蛇跑出了原始尺寸的邊界的時候恢復原始尺寸,小蛇蛇就不見了,在這種情況下,我們應該復位:
  1. import pygame
  2. import sys
  3. # 初始化Pygame
  4. pygame.init()
  5. size = width, height = 600, 400
  6. speed = [-2, 1]
  7. bg = (255, 255, 255) # RGB
  8. fullscreen = False #设置一个决定全屏的变量
  9. #实例化Pygame 的time 模块的 Clock 对象
  10. clock = pygame.time.Clock()
  11. # 创建指定大小的窗口 Surface
  12. screen = pygame.display.set_mode(size)
  13. # 设置窗口标题
  14. pygame.display.set_caption("初次见面,请大家多多关照!")
  15. # 加载图片
  16. turtle = pygame.image.load("python.png")
  17. # 获得图像的位置矩形
  18. position = position_0= turtle.get_rect() #position_0保存原始位置
  19. l_head = turtle
  20. r_head = pygame.transform.flip(turtle, True, False)
  21. while True:
  22. for event in pygame.event.get():
  23. if event.type == pygame.QUIT:
  24. sys.exit()
  25. if event.type == pygame.KEYDOWN:
  26. if event.key == pygame.K_LEFT: #按下方向键左键
  27. turtle = l_head #调头
  28. speed = [-1, 0]
  29. if event.key == pygame.K_RIGHT:
  30. turtle = r_head #调头
  31. speed = [1, 0]
  32. if event.key == pygame.K_UP:
  33. speed = [0, -1]
  34. if event.key == pygame.K_DOWN:
  35. speed = [0, 1]
  36. #全屏(F11)
  37. if event.key == pygame.K_F11:
  38. fullscreen = not fullscreen
  39. if fullscreen:
  40. screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE)
  41. width , height = 1920, 1080
  42. else:
  43. screen = pygame.display.set_mode(size)
  44. width, height = size
  45. if position.right > width or position.bottom > height:#如果在边界外时恢复原始尺寸,就复位
  46. position = position_0
  47. # 移动图像
  48. position = position.move(speed)
  49. if position.left < 0 or position.right > width:
  50. # 翻转图像
  51. turtle = pygame.transform.flip(turtle, True, False)
  52. # 反方向移动
  53. speed[0] = -speed[0]
  54. if position.top < 0 or position.bottom > height:
  55. speed[1] = -speed[1]
  56. # 填充背景
  57. screen.fill(bg)
  58. # 更新图像
  59. screen.blit(turtle, position)
  60. # 更新界面
  61. pygame.display.flip()
  62. # 延迟10毫秒
  63. #pygame.time.delay(10)
  64. #设置帧率
  65. clock.tick(200)
當我們運行程序時按下F11,就會全屏顯示,這裡的全屏尺寸(1920,1080)是我知道自己電腦的尺寸設置的。但是你的遊戲是開發給大家用的,這樣子你就不知道用戶的顯示器的尺寸了,那怎麼辦呢?
事實上有一種方法可以獲得,Pygame 我們可以使用display 模塊裡的list_modes() 方法。
我們打開IDLE 嘗試一下:
  1. >>> import pygame
  2. pygame 1.9.4
  3. Hello from the pygame community. https://www.pygame.org/contribute.html
  4. >>> pygame.init()
  5. (6, 0)
  6. >>> pygame.display.list_modes()
  7. [(1920, 1080), (1680, 1050), (1440, 900), (1280, 1024), (1280, 960), (1280, 720), (1024, 768), (800, 600)]
它會打印當前顯示器支持的所有分辨率尺寸。list_modes() 是返回一個列表,從大到小依次列舉當前顯示器支持的分辨率,所以全屏的話,就是將這個列表獲取之後,取第一個元素作為set_mode() 的尺寸即可。
我們接下來談談使得窗口可變。默認情況下窗口是不可以通過拖拽來改變窗口大小的。
你想一下,遊戲裡面的任務都是提前設定好尺寸的,被你一拖拽,馬上面目全非了。
儘管如此,Pygame 還是提供了支持改變窗口尺寸的選項。就是設置 RESIZABLE 選項來實現。
如果用戶調整窗口尺寸時,會引發一個事件,叫做VIDEORESIZE。
如果只是在set_mode() 中添加參數pygame.RESIZABLE ,如下:
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
顯然是沒有任何作用的,我們需要關注 VIDEORESIZE 事件,並執行相應操作,如下:
  1. import pygame
  2. import sys
  3. # 初始化Pygame
  4. pygame.init()
  5. size = width, height = 600, 400
  6. speed = [-2, 1]
  7. bg = (255, 255, 255) # RGB
  8. fullscreen = False #设置一个决定全屏的变量
  9. #实例化Pygame 的time 模块的 Clock 对象
  10. clock = pygame.time.Clock()
  11. # 创建指定大小的窗口 Surface
  12. screen = pygame.display.set_mode(size, pygame.RESIZABLE)
  13. # 设置窗口标题
  14. pygame.display.set_caption("初次见面,请大家多多关照!")
  15. # 加载图片
  16. turtle = pygame.image.load("python.png")
  17. # 获得图像的位置矩形
  18. position = position_0 = turtle.get_rect() #position_0记录起始位置
  19. l_head = turtle
  20. r_head = pygame.transform.flip(turtle, True, False)
  21. while True:
  22. for event in pygame.event.get():
  23. if event.type == pygame.QUIT:
  24. sys.exit()
  25. if event.type == pygame.KEYDOWN:
  26. if event.key == pygame.K_LEFT: #按下方向键左键
  27. turtle = l_head #调头
  28. speed = [-1, 0]
  29. if event.key == pygame.K_RIGHT:
  30. turtle = r_head #调头
  31. speed = [1, 0]
  32. if event.key == pygame.K_UP:
  33. speed = [0, -1]
  34. if event.key == pygame.K_DOWN:
  35. speed = [0, 1]
  36. #全屏(F11)
  37. if event.key == pygame.K_F11:
  38. fullscreen = not fullscreen
  39. if fullscreen:
  40. screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE)
  41. width , height = 1920, 1080
  42. else:
  43. screen = pygame.display.set_mode((600, 400))
  44. width, height = 600, 400
  45. if position.right > width or position.bottom > height:#如果在边界外时恢复原始尺寸,就复位
  46. position = position_0
  47. #用户调整窗口尺寸
  48. if event.type == pygame.VIDEORESIZE:
  49. size = event.size
  50. width, height = size
  51. screen = pygame.display.set_mode(size, pygame.RESIZABLE)
  52. if position.right > width or position.bottom > height:#如果缩小尺寸使得小蛇蛇出界了,就复位
  53. position = position_0
  54. # 移动图像
  55. position = position.move(speed)
  56. if position.left < 0 or position.right > width:
  57. # 翻转图像
  58. turtle = pygame.transform.flip(turtle, True, False)
  59. # 反方向移动
  60. speed[0] = -speed[0]
  61. if position.top < 0 or position.bottom > height:
  62. speed[1] = -speed[1]
  63. # 填充背景
  64. screen.fill(bg)
  65. # 更新图像
  66. screen.blit(turtle, position)
  67. # 更新界面
  68. pygame.display.flip()
  69. # 延迟10毫秒
  70. #pygame.time.delay(10)
  71. #设置帧率
  72. clock.tick(200)

0 留言:

發佈留言