2020年9月12日星期六

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

我們接下來談談圖像的變化。
想要給我們的程序加特技,那麼你的圖像還必須支持一定的變換,例如我們演示過的左右翻轉,還有按角度轉動、放大、縮小。
Pygame 有一個模塊是可以支持的,就是transform 模塊,下面列舉了該模塊幾個常用的方法:
我們來給大家講幾個,其實tranform 的這些方法事實上玩的都是像素的小把戲,事實上就是將像素進行相應的轉換,位置更改,大多數變換之後難免會有一些精度的遺失,只有flip () 方法不會,因此,我們不建議對變換後的Surface 對象進行再變換,因為這樣幾輪之後,圖像就會慘不忍睹了。
前面的代碼,我們使用flip() 方法使得小蛇撞牆之後翻轉,下面我們修改代碼,使得小蛇可以實現縮放,分別響應我們鍵盤上的等於號("=",放大),減號(“- ”,縮小),空格就恢復到原來大小。
  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. ratio = 1.0
  17. # 加载图片
  18. oturtle = pygame.image.load("python.png") #保存原始图像
  19. turtle = oturtle
  20. # 获得图像的位置矩形
  21. position = position_0 = oturtle.get_rect() #position_0记录起始位置
  22. l_head = turtle
  23. r_head = pygame.transform.flip(turtle, True, False)
  24. while True:
  25. for event in pygame.event.get():
  26. if event.type == pygame.QUIT:
  27. sys.exit()
  28. if event.type == pygame.KEYDOWN:
  29. if event.key == pygame.K_LEFT: #按下方向键左键
  30. turtle = l_head #调头
  31. speed = [-1, 0]
  32. if event.key == pygame.K_RIGHT:
  33. turtle = r_head #调头
  34. speed = [1, 0]
  35. if event.key == pygame.K_UP:
  36. speed = [0, -1]
  37. if event.key == pygame.K_DOWN:
  38. speed = [0, 1]
  39. #全屏(F11)
  40. if event.key == pygame.K_F11:
  41. fullscreen = not fullscreen
  42. if fullscreen:
  43. screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE)
  44. width , height = 1920, 1080
  45. else:
  46. screen = pygame.display.set_mode((600, 400))
  47. width, height = 600, 400
  48. if position.right > width or position.bottom > height:#如果在边界外时恢复原始尺寸,就复位
  49. position = turtle.get_rect()
  50. #放大、缩小 小蛇(=、-),空格键恢复原始尺寸
  51. if event.key == pygame.K_EQUALS or event.key == pygame.K_MINUS or event.key == pygame.K_SPACE:
  52. #最大只能放大一倍,缩小50%
  53. if event.key == pygame.K_EQUALS and ratio < 2:
  54. ratio += 0.1
  55. if event.key == pygame.K_MINUS and ratio > 0.5:
  56. ratio -= 0.1
  57. if event.key == pygame.K_SPACE:
  58. ratio = 1.0
  59. turtle = pygame.transform.smoothscale(oturtle, (int(position_0.width*ratio), int(position_0.height*ratio)))
  60. #用户调整窗口尺寸
  61. if event.type == pygame.VIDEORESIZE:
  62. size = event.size
  63. width, height = size
  64. screen = pygame.display.set_mode(size, pygame.RESIZABLE)
  65. if position.right > width or position.bottom > height:#如果缩小尺寸使得小蛇蛇出界了,就复位
  66. position = turtle.get_rect()#获取当前大小的位置矩形
  67. # 移动图像
  68. position = position.move(speed)
  69. if position.left < 0 or position.right > width:
  70. # 翻转图像
  71. turtle = pygame.transform.flip(turtle, True, False)
  72. # 反方向移动
  73. speed[0] = -speed[0]
  74. if position.top < 0 or position.bottom > height:
  75. speed[1] = -speed[1]
  76. # 填充背景
  77. screen.fill(bg)
  78. # 更新图像
  79. screen.blit(turtle, position)
  80. # 更新界面
  81. pygame.display.flip()
  82. # 延迟10毫秒
  83. #pygame.time.delay(10)
  84. #设置帧率
  85. clock.tick(200)
這裡還是有問題的,第一個Bug就是當我們按下方向鍵的時候,它就會恢復原形,這是因為我們按下方向鍵時,調用的r_head 和l_head 是原形小蛇賦值的,所以,我們還需要將縮放後的小蛇賦值給r_head 和l_head ,在這之前,我們需要判斷一下小蛇的運動方向,確定把當前的小蛇賦值給r_head 還是l_head 。修改如下:
  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. ratio = 1.0
  17. # 加载图片
  18. oturtle = pygame.image.load("python.png") #保存原始图像
  19. turtle = oturtle
  20. # 获得图像的位置矩形
  21. position = position_0 = oturtle.get_rect() #position_0记录起始位置
  22. l_head = turtle
  23. r_head = pygame.transform.flip(turtle, True, False)
  24. while True:
  25. for event in pygame.event.get():
  26. if event.type == pygame.QUIT:
  27. sys.exit()
  28. if event.type == pygame.KEYDOWN:
  29. if event.key == pygame.K_LEFT: #按下方向键左键
  30. turtle = l_head #调头
  31. speed = [-1, 0]
  32. if event.key == pygame.K_RIGHT:
  33. turtle = r_head #调头
  34. speed = [1, 0]
  35. if event.key == pygame.K_UP:
  36. speed = [0, -1]
  37. if event.key == pygame.K_DOWN:
  38. speed = [0, 1]
  39. #全屏(F11)
  40. if event.key == pygame.K_F11:
  41. fullscreen = not fullscreen
  42. if fullscreen:
  43. screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE)
  44. width , height = 1920, 1080
  45. else:
  46. screen = pygame.display.set_mode((600, 400))
  47. width, height = 600, 400
  48. if position.right > width or position.bottom > height:#如果在边界外时恢复原始尺寸,就复位
  49. position = turtle.get_rect()
  50. #放大、缩小 小蛇(=、-),空格键恢复原始尺寸
  51. if event.key == pygame.K_EQUALS or event.key == pygame.K_MINUS or event.key == pygame.K_SPACE:
  52. #最大只能放大一倍,缩小50%
  53. if event.key == pygame.K_EQUALS and ratio < 2:
  54. ratio += 0.1
  55. if event.key == pygame.K_MINUS and ratio > 0.5:
  56. ratio -= 0.1
  57. if event.key == pygame.K_SPACE:
  58. ratio = 1.0
  59. turtle = pygame.transform.smoothscale(oturtle, (int(position_0.width*ratio), int(position_0.height*ratio)))
  60. #把当前 的 小蛇 赋值给  r_head 或者 l_head
  61. if speed[0] < 0:#如果向左走
  62. l_head = turtle
  63. r_head = pygame.transform.flip(turtle, True, False)
  64. else:
  65. r_head = turtle
  66. l_head = pygame.transform.flip(turtle, True, False)
  67. #用户调整窗口尺寸
  68. if event.type == pygame.VIDEORESIZE:
  69. size = event.size
  70. width, height = size
  71. screen = pygame.display.set_mode(size, pygame.RESIZABLE)
  72. if position.right > width or position.bottom > height:#如果缩小尺寸使得小蛇蛇出界了,就复位
  73. position = turtle.get_rect()#获取当前大小的位置矩形
  74. # 移动图像
  75. position = position.move(speed)
  76. if position.left < 0 or position.right > width:
  77. # 翻转图像
  78. turtle = pygame.transform.flip(turtle, True, False)
  79. # 反方向移动
  80. speed[0] = -speed[0]
  81. if position.top < 0 or position.bottom > height:
  82. speed[1] = -speed[1]
  83. # 填充背景
  84. screen.fill(bg)
  85. # 更新图像
  86. screen.blit(turtle, position)
  87. # 更新界面
  88. pygame.display.flip()
  89. # 延迟10毫秒
  90. #pygame.time.delay(10)
  91. #设置帧率
  92. 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, pygame.RESIZABLE)
  13. # 设置窗口标题
  14. pygame.display.set_caption("初次见面,请大家多多关照!")
  15. #设置放大缩小的比例
  16. ratio = 1.0
  17. # 加载图片
  18. oturtle = pygame.image.load("python.png") #保存原始图像
  19. turtle = oturtle
  20. # 获得图像的位置矩形
  21. position = position_0 = oturtle.get_rect() #position_0记录起始位置
  22. l_head = turtle
  23. r_head = pygame.transform.flip(turtle, True, False)
  24. while True:
  25. for event in pygame.event.get():
  26. if event.type == pygame.QUIT:
  27. sys.exit()
  28. if event.type == pygame.KEYDOWN:
  29. if event.key == pygame.K_LEFT: #按下方向键左键
  30. turtle = l_head #调头
  31. speed = [-1, 0]
  32. if event.key == pygame.K_RIGHT:
  33. turtle = r_head #调头
  34. speed = [1, 0]
  35. if event.key == pygame.K_UP:
  36. speed = [0, -1]
  37. if event.key == pygame.K_DOWN:
  38. speed = [0, 1]
  39. #全屏(F11)
  40. if event.key == pygame.K_F11:
  41. fullscreen = not fullscreen
  42. if fullscreen:
  43. screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE)
  44. width , height = 1920, 1080
  45. else:
  46. screen = pygame.display.set_mode((600, 400))
  47. width, height = 600, 400
  48. if position.right > width or position.bottom > height:#如果在边界外时恢复原始尺寸,就复位
  49. position = turtle.get_rect()#获取当前大小的位置矩形并回到原点
  50. #放大、缩小 小蛇(=、-),空格键恢复原始尺寸
  51. if event.key == pygame.K_EQUALS or event.key == pygame.K_MINUS or event.key == pygame.K_SPACE:
  52. #最大只能放大一倍,缩小50%
  53. if event.key == pygame.K_EQUALS and ratio < 2:
  54. ratio += 0.1
  55. if event.key == pygame.K_MINUS and ratio > 0.5:
  56. ratio -= 0.1
  57. if event.key == pygame.K_SPACE:
  58. ratio = 1.0
  59. turtle = pygame.transform.smoothscale(oturtle, (int(position_0.width*ratio), int(position_0.height*ratio)))
  60. # 相应的修改 小蛇的位置矩阵的宽度和高度
  61. position.height = int(position_0.height*ratio)
  62. position.width = int(position_0.width*ratio)
  63. #把当前 的 小蛇 赋值给  r_head 或者 l_head
  64. if speed[0] < 0:#如果向左走
  65. l_head = turtle
  66. r_head = pygame.transform.flip(turtle, True, False)
  67. else:#如果向右走
  68. r_head = turtle
  69. l_head = pygame.transform.flip(turtle, True, False)
  70. #用户调整窗口尺寸
  71. if event.type == pygame.VIDEORESIZE:
  72. size = event.size
  73. width, height = size
  74. screen = pygame.display.set_mode(size, pygame.RESIZABLE)
  75. if position.right > width or position.bottom > height:#如果缩小尺寸使得小蛇蛇出界了,就复位
  76. position = turtle.get_rect()#获取当前大小的位置矩形并回到原点
  77. # 移动图像
  78. position = position.move(speed)
  79. if position.left < 0 or position.right > width:
  80. # 翻转图像
  81. turtle = pygame.transform.flip(turtle, True, False)
  82. # 反方向移动
  83. speed[0] = -speed[0]
  84. if position.top < 0 or position.bottom > height:
  85. speed[1] = -speed[1]
  86. # 填充背景
  87. screen.fill(bg)
  88. # 更新图像
  89. screen.blit(turtle, position)
  90. # 更新界面
  91. pygame.display.flip()
  92. # 延迟10毫秒
  93. #pygame.time.delay(10)
  94. #设置帧率
  95. clock.tick(200)
接下來講一個新知識,我們希望通過rotate() 來旋轉圖像,讓小蛇蛇貼邊爬行,頭要一直向前。
  1. import pygame
  2. import sys
  3. # 初始化Pygame
  4. pygame.init()
  5. size = width, height = 600, 400
  6. bg = (255, 255, 255) # RGB
  7. fullscreen = False
  8. # 创建指定大小的窗口 Surface
  9. screen = pygame.display.set_mode(size)
  10. # 设置窗口标题
  11. pygame.display.set_caption("初次见面,请大家多多关照!")
  12. # 加载图片
  13. turtle = pygame.image.load("python.png")
  14. # 获得图像的位置矩形
  15. position = turtle.get_rect()
  16. speed = [5, 0]
  17. turtle_right = pygame.transform.rotate(turtle, 90)
  18. turtle_top = pygame.transform.rotate(turtle, 180)
  19. turtle_left = pygame.transform.rotate(turtle, 270)
  20. turtle_bottom = turtle
  21. turtle = turtle_top #初始从上边开始
  22. l_head = turtle
  23. r_head = pygame.transform.flip(turtle, True, False)
  24. while True:
  25. for event in pygame.event.get():
  26. if event.type == pygame.QUIT:
  27. sys.exit()
  28. if event.type == pygame.KEYDOWN:
  29. # 全屏(F11)
  30. if event.key == pygame.K_F11:
  31. fullscreen = not fullscreen
  32. if fullscreen:
  33. screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE)
  34. width , height = 1920, 1080
  35. else:
  36. screen = pygame.display.set_mode((600, 400))
  37. width, height = 600, 400
  38. # 移动图像
  39. position = position.move(speed)
  40. if position.right > width:
  41. turtle = turtle_right
  42. position = turtle_rect = turtle.get_rect()
  43. position.left = width - turtle_rect.width
  44. speed = [0, 5]
  45. if position.bottom > height:
  46. turtle = turtle_bottom
  47. position = turtle_rect = turtle.get_rect()
  48. position.left = width - turtle_rect.width
  49. position.top = height - turtle_rect.height
  50. speed = [-5, 0]
  51. if position.left < 0:
  52. turtle = turtle_left
  53. position = turtle_rect = turtle.get_rect()
  54. position.top = height - turtle_rect.height
  55. speed = [0, -5]
  56. if position.top < 0:
  57. turtle = turtle_top
  58. position = turtle_rect = turtle.get_rect()
  59. speed = [5, 0]
  60. # 填充背景
  61. screen.fill(bg)
  62. # 更新图像
  63. screen.blit(turtle, position)
  64. # 更新界面
  65. pygame.display.flip()
  66. # 延迟10毫秒
  67. pygame.time.delay(10)
這節課內容比較多,大家好好消化。主要是鍛煉大家消除Bug的能力。加油^_^

0 留言:

發佈留言