上篇寫的動畫示例其實算不上一個遊戲,頂多算是利用pygame進行的圖形操做,今天着手實現一個小遊戲:傳說哥大戰劇毒術士。名字很玄乎,其實就是最簡單的一個射擊遊戲。好了廢話很少說,先上截圖吧:html
1、初始化程序和定義變量python
import pygame import math import random # 1 - Initialize the game pygame.init() # prepare the variables width, height = 640, 480 screen=pygame.display.set_mode((width, height)) playerpos=[100,100] speed_x=5 speed_y=5 speed_bullet=10 speed_shit=3 shot=0 alive=True bullet=[] shit=[] green=[0,255,0] # 2 - Load images player = pygame.image.load("1.bmp") badguy = pygame.image.load("2.bmp") backgroud= pygame.image.load("3.bmp") bullet_bmp=pygame.image.load("4.bmp") shit_bmp=pygame.image.load("5.bmp") player.set_colorkey([0,0,0]) badguy.set_colorkey([0,0,0]) shit_bmp.set_colorkey([255,255,255])
第一部分聲明的變量中主要是傳說哥的移動速度,子彈的數據,劇毒術士噴出的便便速度等。第二部分預載入圖片資源:角色,背景圖等。注意設置set_colorkey進行透明色處理(書上有介紹)。編程
2、響應事件處理相關app
1 # 4 - clear the screen before drawing it again 2 screen.fill(0) 3 # 5 - draw the backgroud 4 for x in range(width/backgroud.get_width()+1): 5 for y in range(height/backgroud.get_height()+1): 6 screen.blit(backgroud,(x*90,y*65)) 7 # 6 - loop through the events 8 for event in pygame.event.get(): 9 # check if the event is the X button 10 if event.type==pygame.QUIT: 11 # if it is quit the game 12 pygame.quit() 13 exit(0) 14 if event.type==pygame.KEYDOWN: 15 if event.key == pygame.K_w: 16 playerpos[1]-=speed_y 17 elif event.key == pygame.K_s: 18 playerpos[1]+=speed_y 19 elif event.key == pygame.K_a: 20 playerpos[0]-=speed_x 21 elif event.key == pygame.K_d: 22 playerpos[0]+=speed_x 23 position = pygame.mouse.get_pos() 24 angle = math.atan2(position[1]-(playerpos[1]+32),position[0]-(playerpos[0]+32)) 25 playerrot = pygame.transform.rotate(player, 360-angle*57.29) 26 playerpos1 = (playerpos[0]-playerrot.get_rect().width/2, playerpos[1]-playerrot.get_rect().height/2) 27 if event.type==pygame.MOUSEBUTTONDOWN: 28 position=pygame.mouse.get_pos() 29 bullet.append([math.atan2(position[1]-(playerpos1[1]+32), 30 position[0]-(playerpos1[0]+32)),playerpos1[0]+32,playerpos1[1]+32])
這一部分首先將加載進的背景圖片利用blit函數貼到窗口裏。隨後進入事件循環:這裏主要是兩種事件:WSAD控制人物運動,鼠標點擊射出子彈,因爲是用鼠標控制射擊方向,所以須要獲取圖片的新位置,簡單的數學知識,偏轉角計算以下圖,這塊的處理具體參照一篇不錯的文章http://bbs.chinaunix.net/thread-4094150-1-2.html,這個小東東借鑑了裏面不少知識。dom
3、處理對戰邏輯ide
1 # 7 - process fight 2 screen.blit(playerrot, playerpos1) 3 for oneshot in bullet: 4 index=0 5 velx=math.cos(oneshot[0])*speed_bullet 6 vely=math.sin(oneshot[0])*speed_bullet 7 oneshot[1]+=velx 8 oneshot[2]+=vely 9 if oneshot[1]<-64 or oneshot[1]>640 or oneshot[2]<-64 or oneshot[2]>480: 10 bullet.pop(index) 11 index+=1 12 for eachone in bullet: 13 pos_x=int(eachone[1]) 14 pos_y=int(eachone[2]) 15 pos=[pos_x,pos_y] 16 bullet_bmp_new=pygame.transform.rotate(bullet_bmp,360-eachone[0]*57.29) 17 screen.blit(bullet_bmp_new,pos) 18 pygame.display.flip() 19 for oneshot in bullet: 20 if oneshot[1]<badguy_pos[0]+57 and oneshot[1]>badguy_pos[0] and\ 21 oneshot[2]<badguy_pos[1]+70 and oneshot[2]>badguy_pos[1]: 22 shot+=1 23 alive=False 24 break 25 if shot<5 and alive==False: 26 badguy_x=random.randrange(0,640-57) 27 badguy_y=random.randrange(0,480-70) 28 badguy_pos=[badguy_x,badguy_y] 29 alive=True 30 if alive ==True: 31 screen.blit(badguy, badguy_pos) 32 else: 33 pygame.quit() 34 exit(0) 35 if len(shit)<2: 36 shit.append([math.atan2(playerpos1[1]-(badguy_pos[1]+32), 37 playerpos1[0]-(badguy_pos[0]+32)),badguy_pos[0]+32,badguy_pos[1]+32]) 38 for oneshit in shit: 39 index=0 40 velx=math.cos(oneshit[0])*speed_shit 41 vely=math.sin(oneshit[0])*speed_shit 42 oneshit[1]+=velx 43 oneshit[2]+=vely 44 if oneshit[1]<-64 or oneshit[1]>640 or oneshit[2]<-64 or oneshit[2]>480: 45 shit.pop(index) 46 index+=1 47 for eachshit in shit: 48 pos_x=int(eachshit[1]) 49 pos_y=int(eachshit[2]) 50 pos=[pos_x,pos_y] 51 shit_bmp_new=pygame.transform.rotate(shit_bmp,360-eachshit[0]*57.29) 52 screen.blit(shit_bmp_new,pos) 53 pygame.display.flip() 54 for oneshit in shit: 55 if oneshit[1]<playerpos1[0]+66 and oneshit[1]>playerpos1[0] and\ 56 oneshit[2]<playerpos1[1]+66 and oneshit[2]>playerpos1[1]: 57 pygame.quit() 58 exit(0) 59 pygame.display.flip()
每次點擊一次鼠標,子彈發射,保存到列表中,可是當子彈離開屏幕須要刪除掉改子彈,同時記得由第二部分保存的偏轉角計算子彈的偏轉。劇毒噴出的大便處理相似,也要由傳說哥的位置計算出偏轉角利用設定的速度甩向咱們的主人公火槍哥。函數
這裏的輸贏斷定爲火槍打死5個劇毒即獲取勝利,扔出的便便有一次砸到咱們的主人公,遊戲失敗即結束,無論勝利仍是失敗,遊戲均退出處理。oop
以上即是整個遊戲的大致邏輯,能夠看出利用python 100行左右的代碼便可以實現一個最簡單的人機對戰,不過代碼寫的比較亂得說,也沒有用函數編程和麪向對象的東西。另外提一下寫遊戲這塊效率性能確實不敢恭維(明顯的遲鈍)。。無論怎麼樣,利用pygame實現小遊戲仍是比較方便的。性能
這個小遊戲寫的確實雖然簡單和幼稚,不過花了半天時間就能從零搞起來,確實有所收穫。有時間的話能夠進一步增長敵方的難度和可玩性,先這樣吧。動畫
附下代碼吧:
1 import pygame 2 import math 3 import random 4 5 # 1 - Initialize the game 6 pygame.init() 7 # prepare the variables 8 width, height = 640, 480 9 screen=pygame.display.set_mode((width, height)) 10 playerpos=[100,100] 11 speed_x=5 12 speed_y=5 13 speed_bullet=10 14 speed_shit=3 15 shot=0 16 alive=True 17 bullet=[] 18 shit=[] 19 badguy_x=random.randrange(0,640) 20 badguy_y=random.randrange(0,480) 21 badguy_pos=[badguy_x,badguy_y] 22 green=[0,255,0] 23 # 2 - Load images 24 player = pygame.image.load("1.bmp") 25 badguy = pygame.image.load("2.bmp") 26 backgroud= pygame.image.load("3.bmp") 27 bullet_bmp=pygame.image.load("4.bmp") 28 shit_bmp=pygame.image.load("5.bmp") 29 player.set_colorkey([0,0,0]) 30 badguy.set_colorkey([0,0,0]) 31 shit_bmp.set_colorkey([255,255,255]) 32 # 3 - main loop 33 while 1: 34 # 4 - clear the screen before drawing it again 35 screen.fill(0) 36 # 5 - draw the backgroud 37 for x in range(width/backgroud.get_width()+1): 38 for y in range(height/backgroud.get_height()+1): 39 screen.blit(backgroud,(x*90,y*65)) 40 41 42 # 6 - loop through the events 43 for event in pygame.event.get(): 44 # check if the event is the X button 45 if event.type==pygame.QUIT: 46 # if it is quit the game 47 pygame.quit() 48 exit(0) 49 if event.type==pygame.KEYDOWN: 50 if event.key == pygame.K_w: 51 playerpos[1]-=speed_y 52 elif event.key == pygame.K_s: 53 playerpos[1]+=speed_y 54 elif event.key == pygame.K_a: 55 playerpos[0]-=speed_x 56 elif event.key == pygame.K_d: 57 playerpos[0]+=speed_x 58 position = pygame.mouse.get_pos() 59 angle = math.atan2(position[1]-(playerpos[1]+32),position[0]-(playerpos[0]+32)) 60 playerrot = pygame.transform.rotate(player, 360-angle*57.29) 61 playerpos1 = (playerpos[0]-playerrot.get_rect().width/2, playerpos[1]-playerrot.get_rect().height/2) 62 if event.type==pygame.MOUSEBUTTONDOWN: 63 position=pygame.mouse.get_pos() 64 bullet.append([math.atan2(position[1]-(playerpos1[1]+32), 65 position[0]-(playerpos1[0]+32)),playerpos1[0]+32,playerpos1[1]+32]) 66 # 7 - process fight 67 screen.blit(playerrot, playerpos1) 68 for oneshot in bullet: 69 index=0 70 velx=math.cos(oneshot[0])*speed_bullet 71 vely=math.sin(oneshot[0])*speed_bullet 72 oneshot[1]+=velx 73 oneshot[2]+=vely 74 if oneshot[1]<-64 or oneshot[1]>640 or oneshot[2]<-64 or oneshot[2]>480: 75 bullet.pop(index) 76 index+=1 77 for eachone in bullet: 78 pos_x=int(eachone[1]) 79 pos_y=int(eachone[2]) 80 pos=[pos_x,pos_y] 81 bullet_bmp_new=pygame.transform.rotate(bullet_bmp,360-eachone[0]*57.29) 82 screen.blit(bullet_bmp_new,pos) 83 pygame.display.flip() 84 for oneshot in bullet: 85 if oneshot[1]<badguy_pos[0]+57 and oneshot[1]>badguy_pos[0] and\ 86 oneshot[2]<badguy_pos[1]+70 and oneshot[2]>badguy_pos[1]: 87 shot+=1 88 alive=False 89 break 90 if shot<5 and alive==False: 91 badguy_x=random.randrange(0,640-57) 92 badguy_y=random.randrange(0,480-70) 93 badguy_pos=[badguy_x,badguy_y] 94 alive=True 95 if alive ==True: 96 screen.blit(badguy, badguy_pos) 97 else: 98 pygame.quit() 99 exit(0) 100 if len(shit)<2: 101 shit.append([math.atan2(playerpos1[1]-(badguy_pos[1]+32), 102 playerpos1[0]-(badguy_pos[0]+32)),badguy_pos[0]+32,badguy_pos[1]+32]) 103 for oneshit in shit: 104 index=0 105 velx=math.cos(oneshit[0])*speed_shit 106 vely=math.sin(oneshit[0])*speed_shit 107 oneshit[1]+=velx 108 oneshit[2]+=vely 109 if oneshit[1]<-64 or oneshit[1]>640 or oneshit[2]<-64 or oneshit[2]>480: 110 shit.pop(index) 111 index+=1 112 for eachshit in shit: 113 pos_x=int(eachshit[1]) 114 pos_y=int(eachshit[2]) 115 pos=[pos_x,pos_y] 116 shit_bmp_new=pygame.transform.rotate(shit_bmp,360-eachshit[0]*57.29) 117 screen.blit(shit_bmp_new,pos) 118 pygame.display.flip() 119 for oneshit in shit: 120 if oneshit[1]<playerpos1[0]+66 and oneshit[1]>playerpos1[0] and\ 121 oneshit[2]<playerpos1[1]+66 and oneshit[2]>playerpos1[1]: 122 pygame.quit() 123 exit(0) 124 pygame.display.flip()