2020年9月12日星期六

82 《零基礎入門學習Python》筆記 第082講:Pygame:提高遊戲的顏值2

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


有些同學在上節課學完transform 模塊之後,便躍躍欲試,其中有一個chop() 方法沒有講,chop 翻譯過來就是砍、剪、裁的意思,有的人就以為這個方法可以實現裁剪工具,但是呢,結果卻事與願違,這是為啥呢?我們這裡嘗試將小蛇從中間裁剪掉50*50像素,看看是什麼樣子。
代碼如下:
  1. import pygame
  2. import sys
  3. from pygame.locals import *
  4. pygame.init()
  5. size = width, height = 300, 300
  6. bg = (255, 255, 255)
  7. clock = pygame.time.Clock()
  8. screen = pygame.display.set_mode(size)
  9. pygame.display.set_caption("Python Demo")
  10. oturtle = pygame.image.load("Python.png")
  11. #裁剪
  12. turtle = pygame.transform.chop(oturtle, (100, 105, 50, 50)) #小蛇尺寸为200*210,中间位置就是100*105
  13. #不裁剪
  14. #turtle = oturtle
  15. position = turtle.get_rect()
  16. position.center = width // 2, height // 2
  17. while True:
  18. for event in pygame.event.get():
  19. if event.type == QUIT:
  20. sys.exit()
  21. screen.fill(bg)
  22. screen.blit(turtle, position)
  23. pygame.draw.rect(screen, (0, 0, 0), position, 1)
  24. pygame.display.flip()
  25. clock.tick(30)
我們首先看看不裁剪是怎樣的:
如果使用chop() 裁剪之後會這樣呢,我們看看:
chop() 之後,面目全非,慘不忍睹。
不知道大家有沒有發現,這個chop() 方法是如何實現的?
其實chop() 方法是把中間50*50 部分不見了,但在中間的位置不是留空(留白),其實將四周所有的元素給擠進去了。也不是我們希望實現的效果。
這一節課我們就來學習如何實現才裁剪工具。
我們先來看一下demo。
  1. import pygame
  2. import sys
  3. from pygame.locals import *
  4. pygame.init()
  5. size = width, height = 400, 400
  6. bg = (255, 255, 255)
  7. clock = pygame.time.Clock()
  8. screen = pygame.display.set_mode(size)
  9. pygame.display.set_caption("Python Demo")
  10. turtle = pygame.image.load("Python.png")
  11. # 0 -> 未选择,1 -> 选择中,2 -> 完成选择
  12. select = 0
  13. select_rect = pygame.Rect(0, 0, 0, 0)
  14. # 0 -> 未拖拽,1 -> 拖拽中,2 -> 完成拖拽
  15. drag = 0
  16. position = turtle.get_rect()
  17. position.center = width // 2, height // 2
  18. while True:
  19. for event in pygame.event.get():
  20. if event.type == QUIT:
  21. sys.exit()
  22. elif event.type == MOUSEBUTTONDOWN:
  23. if event.button == 1:
  24. # 第一次点击,选择范围
  25. if select == 0 and drag == 0:
  26. pos_start = event.pos
  27. select = 1
  28. # 第二次点击,推拽图像
  29. elif select == 2 and drag == 0:
  30. capture = screen.subsurface(select_rect).copy()
  31. cap_rect = capture.get_rect()
  32. drag = 1
  33. # 第三次点击,初始化
  34. elif select == 2 and drag == 2:
  35. select = 0
  36. drag = 0
  37. elif event.type == MOUSEBUTTONUP:
  38. if event.button == 1:
  39. # 第一次释放,结束选择
  40. if select == 1 and drag == 0:
  41. pos_stop = event.pos
  42. select = 2
  43. # 第二次释放,结束拖拽
  44. if select == 2 and drag == 1:
  45. drag = 2
  46. screen.fill(bg)
  47. screen.blit(turtle, position)
  48. # 实时绘制选择框
  49. if select:
  50. mouse_pos = pygame.mouse.get_pos()
  51. if select == 1:
  52. pos_stop = mouse_pos
  53. select_rect.left, select_rect.top = pos_start
  54. select_rect.width, select_rect.height = pos_stop[0] - pos_start[0], pos_stop[1] - pos_start[1]
  55. pygame.draw.rect(screen, (0, 0, 0), select_rect,1)
  56. # 拖拽裁剪的图像
  57. if drag:
  58. if drag == 1:
  59. cap_rect.center = mouse_pos
  60. screen.blit(capture, cap_rect)
  61. pygame.display.flip()
  62. clock.tick(30)
鼠標第一次拖拽時,選中一個矩形的框,第二次拖拽的時候,會把選中的區域裁剪出來,這就是我們希望的裁剪工具,再點鼠標,就恢復原樣。然後就可以進行新一輪的裁剪。
現在對於大家來說,有一點小難度,主要的難度就是在於鼠標每次按下到釋放,就是拖拽的過程,不同次數的按下有不同的意義,大家不妨思考一下,看能不能獨立寫出實現的代碼。
我們來分析一下:
鼠標第一次拖拽左鍵的時候,要裁剪一個範圍;第二次拖拽左鍵的時候,是表示移動裁剪的圖像;第三次點擊的時候就是取消選擇。
所以鼠標要按3中情況來響應它的事件。
首先,第一次拖拽鼠標時的這個黑邊矩形怎麼繪製呢?
我們是調用draw 模塊的rect() 方法,我們接下來會講如何繪製矩形,這個和之前講過的Tkinter繪製圖形是差不多的。
rect ( Surface, color, Rect, width = 0)
第一個參數為Surface,確定是要繪製在哪個Surface 對像上。
第二個參數color 指定邊框的顏色;
第三個參數Rect 指定矩形的範圍;
第四個參數width 指定邊框的大小,默認值為0,表示填充矩形,如果設為1,就表示邊框為1像素的大小。
那既然無法用tranform 模塊的chop() 方法來裁剪,那麼裁剪操作我們該如何處理呢?
我們可以使用subsurface() 方法,就相當於創建surface 的一個子圖像,然後將它copy 出來,即:
capture = screen.subsurface(select_rect).copy()

0 留言:

發佈留言