Pygame库200行代码实现简易飞机大战的小游戏
Pygame庫實(shí)現(xiàn)200行代碼簡易飛機(jī)大戰(zhàn)的小游戲
- 安裝使用庫
- pygame簡介
- pgame中主要模塊介紹
- pygame的安裝
- 驗(yàn)證安裝
- 程序原理
- 程序升級
- 設(shè)置飛機(jī)大戰(zhàn)的精靈類和常量
- 背景類和敵機(jī)類
- 主機(jī)類和子彈類
- 主游戲類
- 事件監(jiān)聽方法
- 碰撞檢測
- 精靈組更新顯示
- 程序總結(jié)
寫在開頭,因?yàn)檫@個(gè)小游戲的實(shí)驗(yàn)主要是幫助我熟悉pygame庫的使用,所以游戲的一些地方可能存在不完善處,還望包涵。
安裝使用庫
pygame簡介
pygame是跨平臺python模塊,專為電子游戲設(shè)計(jì),包括圖像、聲音。建立在SDL基礎(chǔ)上,允許實(shí)時(shí)電子游戲研發(fā)而無需被低級語言束縛, 開發(fā)者可以把精力放在游戲的架構(gòu)上。
pgame中主要模塊介紹
(1) pygame
pygame模塊會自動導(dǎo)入其它的pygame相關(guān)模塊。
pygame模塊包括surface函數(shù), 可以返回一個(gè)新的surface 對象。 init()函數(shù)是pygame游戲的核心,必須在進(jìn)入游戲的主循環(huán)之前調(diào)用。init()會自動初始化其它所有模塊。
(2) pygame.locals
包括在你自己的模塊作用域內(nèi)使用的名字(變量)。包括事件類型、鍵和視頻模式等的名字。
(3) pygame.display
包括處理pygame顯示方式的函數(shù)。包括普通窗口和全屏模式。 pygame.display中一些常用的方法如下:
flip:更新顯示。
update:更新一部分時(shí)候使用update。
set_mode:設(shè)定顯示的類型和尺寸。
set_caption:設(shè)定pygame程序的標(biāo)題。
get_surface:調(diào)用flip和blit前返回一個(gè)可用于畫圖的surface對象。
(4) pygame.font
包括font函數(shù),用于表現(xiàn)不同的字體。
(5) pygame.sprite
游戲精靈,Group用做sprite對象的容器。調(diào)用group對象的update對象,會自動調(diào)用所有sprite對象的update方法。
(6) pygame.mouse
隱藏鼠標(biāo)光標(biāo),獲取鼠標(biāo)位置。
(7) pygame.event
追蹤鼠標(biāo)單擊、按鍵按下和釋放等事件。
(8) pygame.image
用于處理保存在GIF、PNG或者JPEG文件內(nèi)的圖像。
注:程序中除了local模塊和font模塊沒有使用,其他模塊均有涉及。
pygame的安裝
你可以選擇使用pycharm中工具欄下方的python packages搜索pygame進(jìn)行安裝,當(dāng)然也可以使用cmd命令符中常用的pip install pygame 的方法。
安裝超時(shí)網(wǎng)速慢,直接超時(shí),可以指定國內(nèi)源鏡像。
- pip install -i 國內(nèi)鏡像地址 包名
例如: pip install -i https://mirrors.aliyun.com/pypi/simple/ numpy
國內(nèi)常用源鏡像地址:
- 清華:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:http://mirrors.aliyun.com/pypi/simple/ 中國科技大學(xué)
https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣:http://pypi.douban.com/simple/
驗(yàn)證安裝
驗(yàn)證pygame是否安裝成功,在cmd命令符中使用 pip list 語句,如果安裝成功,我們可以在下方結(jié)果中找到。
程序原理
首先創(chuàng)建游戲的主窗體,主窗體的大小就是你背景圖片的大小。
import pygame #游戲初始化 pygame.init() #創(chuàng)建游戲主窗口 screen = pygame.display.set_mode((480,700)) #繪制背景圖香 #1 加載圖像數(shù)據(jù) background = pygame.image.load('./image/background.png') #2 blit繪制圖像 #從左上角繪制 screen.blit(background,(0,0)) pygame.display.update() #卸載所有的模塊 pygame.quit()繪制圖像時(shí)的方向,后面我們主機(jī)、敵機(jī)、背景、子彈的方向都需要注意這一點(diǎn)。
背景圖像繪制完之后就是我們主機(jī)、敵機(jī)的繪制,我們可以在所有的繪制工作完成后再統(tǒng)一調(diào)用update方法
其實(shí)飛機(jī)大戰(zhàn)的原理和動畫片的原理一致,我們需要對一個(gè)個(gè)按下的指令進(jìn)行反應(yīng),從而形成一個(gè)連貫的畫面,這里我們就需要使用到pygame庫中的time模塊
#創(chuàng)造時(shí)鐘對象 屏幕繪制速率 clock = pygame.time.Clock() #游戲循環(huán) while True:#指定循環(huán)體內(nèi)部代碼的執(zhí)行頻率 每秒重復(fù)60次clock.tick(60)#將移動前飛機(jī)進(jìn)行遮擋 達(dá)到動畫效果screen.blit(background, (0, 0))screen.blit(hero,hero_rect)如果你想停止程序,發(fā)現(xiàn)點(diǎn)擊窗體右上角的關(guān)閉并無反應(yīng),因?yàn)槟氵€未在循環(huán)體內(nèi)進(jìn)行事件監(jiān)聽,然后對時(shí)間進(jìn)行判斷
event_list = pygame.event.get() for event in event_list:#判斷是否為退出事件if event.type == pygame.QUIT:print("退出游戲...")#卸載所有模塊pygame.quit()exit()關(guān)于敵機(jī)的生成我們需要使用到sprite精靈和精靈組模塊,創(chuàng)建兩個(gè)一樣的敵機(jī),但是敵機(jī)的飛行速度不一樣,然后將敵機(jī)精靈添加至敵機(jī)精靈組中,然后在循環(huán)體中我們不斷將敵機(jī)精靈組進(jìn)行繪制即可
enemy = GameSprite("./image/enemy0.png") enemy1 = GameSprite("./image/enemy0.png",2) enemy_group = pygame.sprite.Group(enemy,enemy1)#精靈組調(diào)用方法 enemy_group.update() enemy_group.draw(screen)對上述部分代碼進(jìn)行整理簡化,最后我們可以得到這樣的效果圖,主機(jī)和敵機(jī)都可以移動
import pygame from plane_sprites import *#游戲初始化 pygame.init() #創(chuàng)建游戲主窗口 screen = pygame.display.set_mode((480,700))#繪制背景圖香 #1 加載圖像數(shù)據(jù) background = pygame.image.load('./image/background.png') #2 blit繪制圖像 #從左上角繪制 screen.blit(background,(0,0)) #3 update更新屏幕顯示 # pygame.display.update()#繪制飛機(jī)圖片 hero = pygame.image.load('./image/hero2.png') screen.blit(hero,(150,300))#可以在所有繪制工作完成后,統(tǒng)一調(diào)用update方法 pygame.display.update()#創(chuàng)造時(shí)鐘對象 屏幕繪制速率 clock = pygame.time.Clock()#定義飛機(jī)初始位置 hero_rect = pygame.Rect(150,300,100,122)#敵機(jī)精靈創(chuàng)建 enemy = GameSprite("./image/enemy0.png") enemy1 = GameSprite("./image/enemy0.png",2) enemy_group = pygame.sprite.Group(enemy,enemy1)#游戲循環(huán) while True:#指定循環(huán)體內(nèi)部代碼的執(zhí)行頻率 每秒重復(fù)60次clock.tick(60)#監(jiān)聽時(shí)間event_list = pygame.event.get()# if len(event_list)>0:# print(event_list)for event in event_list:#判斷是否為退出事件if event.type == pygame.QUIT:print("退出游戲...")#卸載所有模塊pygame.quit()exit()hero_rect.y -= 1if hero_rect.y <=0:hero_rect.y = 700#將移動前飛機(jī)進(jìn)行遮擋 達(dá)到動畫效果screen.blit(background, (0, 0))screen.blit(hero,hero_rect)#精靈組調(diào)用方法enemy_group.update()enemy_group.draw(screen)pygame.display.update()pass pygame.quit()程序升級
設(shè)置飛機(jī)大戰(zhàn)的精靈類和常量
這里的update方法主要是在為了后面背景類、敵機(jī)類和子彈類中達(dá)到可以垂直飛行的效果
#屏幕大小 SCREEN_RECT = pygame.Rect(0,0,480,700) #刷新幀率 SCREEN_PER_SEC = 60 #創(chuàng)建敵機(jī)的定時(shí)器常量 CREATE_ENEMY_EVENT = pygame.USEREVENT #英雄發(fā)射子彈事件 HERO_FIRE_EVENT = pygame.USEREVENT + 1class GameSprite(pygame.sprite.Sprite):def __init__(self,image_name,speed=1):#調(diào)用父類初始化方法super().__init__()#定義對象屬性self.image = pygame.image.load(image_name)self.rect = self.image.get_rect()self.speed = speed#更新顯示def update(self):self.rect.y += self.speed背景類和敵機(jī)類
因?yàn)橄胍尘皶S著移動,所以在背景類中的init設(shè)置了is_alt參數(shù),用來添加背景到原圖像的上方,這樣就可以達(dá)到背景滾動的效果。
在敵機(jī)類中對敵機(jī)的位置進(jìn)行判斷,如果敵機(jī)超過我們預(yù)設(shè)屏幕y的方位就會使用kill()方法從精靈組中刪除,敵機(jī)生成的位置和速度采用了random隨機(jī)數(shù)的randint()方法
主機(jī)類和子彈類
SCREEN_RECT.centerx是用來保證一開始主機(jī)初始在屏幕中央部分,關(guān)于主機(jī)的y因?yàn)樵谝婚_始畫了一張繪制示意圖所以這里應(yīng)該為屏幕的SCREEN_RECT.bottom減去部分距離。
子彈類中和敵機(jī)類同理需要判斷是否飛出屏幕范圍,如果超過使用kill()方法從精靈組中刪除,子彈的初始位置應(yīng)該是主機(jī)的上方,既子彈的x等于主機(jī)的x
主游戲類
在主類中進(jìn)行精靈組的創(chuàng)建,背景精靈組的創(chuàng)建是為了達(dá)到背景滾動的效果
#精靈組的創(chuàng)建 def __create_sprites(self):#創(chuàng)建背景精靈和精靈1組bg1 = Background()bg2 = Background(True)self.back_group = pygame.sprite.Group(bg1,bg2)#創(chuàng)建敵機(jī)精靈和精靈組self.enemy_group = pygame.sprite.Group(#創(chuàng)建英雄精靈和精靈組self.hero = Hero()self.hero_group = pygame.sprite.Group(self.hero)游戲的初始化
def __init__(self):print("游戲初始化")#創(chuàng)建游戲窗口self.screen = pygame.display.set_mode(SCREEN_RECT.size)#創(chuàng)建游戲時(shí)鐘self.clock = pygame.time.Clock()self.__create_sprites()#敵機(jī)生成和主機(jī)開火的定時(shí)器pygame.time.set_timer(CREATE_ENEMY_EVENT,1000)#單位是mspygame.time.set_timer(HERO_FIRE_EVENT,500)事件監(jiān)聽方法
關(guān)于事件的監(jiān)聽過程中,需要對敵機(jī)生成和子彈飛行、主機(jī)移動指令做出對應(yīng)反應(yīng)
def __event_handler(self):for event in pygame.event.get():if event.type == pygame.QUIT:PlaneGame.__game_over()elif event.type == CREATE_ENEMY_EVENT:print("敵機(jī)生成...")#創(chuàng)建敵機(jī)精靈enemy = Enemy()#敵機(jī)精靈加入精靈組self.enemy_group.add(enemy)elif event.type == HERO_FIRE_EVENT:print("發(fā)射子彈...")self.hero.fire()#飛機(jī)移動keyss_pressed = pygame.key.get_pressed()if keyss_pressed[pygame.K_RIGHT]:print("向右移動")self.hero.speed = 2elif keyss_pressed[pygame.K_LEFT]:print("向左移動")self.hero.speed = -2else:self.hero.speed = 0碰撞檢測
對于子彈碰撞敵機(jī)和敵機(jī)碰撞主機(jī)的情況進(jìn)行判定
#碰撞檢測 def __check_collide(self):#子彈摧毀敵機(jī)pygame.sprite.groupcollide(self.hero.bullet_group,self.enemy_group,True,True)#敵機(jī)撞毀英雄enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)if len(enemies) > 0:self.hero.kill()PlaneGame.__game_over()精靈組更新顯示
#精靈更新顯示 def __update_sprites(self):#背景精靈組self.back_group.update()self.back_group.draw(self.screen)#敵機(jī)精靈組self.enemy_group.update()self.enemy_group.draw(self.screen)#主機(jī)精靈組self.hero_group.update()self.hero_group.draw(self.screen)#子彈精靈組self.hero.bullet_group.update()self.hero.bullet_group.draw(self.screen)游戲的開始與結(jié)束
def start_game(self):print("游戲開始...")while True:#1 設(shè)置刷新幀率self.clock.tick(SCREEN_PER_SEC)#2 時(shí)間監(jiān)聽self.__event_handler()#3 碰撞檢測self.__check_collide()#4 更新敵機(jī)self.__update_sprites()#5 更新顯示pygame.display.update() @staticmethod def __game_over():print("游戲結(jié)束")pygame.quit()exit()程序總結(jié)
程序中print語句是為了我在運(yùn)行中進(jìn)行功能的檢測,可以直接注釋掉,對于整個(gè)程序的運(yùn)行并無影響。游戲只是簡單的規(guī)則,主機(jī)可以左右移動,敵機(jī)會隨機(jī)從上方垂直下來,敵機(jī)撞到主機(jī)之后就會游戲結(jié)束直接關(guān)閉游戲窗體,比如擊毀敵機(jī)也沒有得分這一設(shè)置,這些都是可以再對規(guī)則進(jìn)行優(yōu)化的部分,因?yàn)橹皇菫榱藥椭沂煜ygame庫的功能,所以代碼并未寫的更加詳細(xì),感興趣的話你可以對代碼部分進(jìn)行更改達(dá)到你想要的效果,程序升級部分并未進(jìn)行太多的文字解釋部分,在代碼中我保留了我的注釋部分方便你對代碼進(jìn)行解讀。總結(jié)不易麻煩給個(gè)點(diǎn)贊收藏!
程序中用到的素材以及未使用到的音樂都在鏈接中。
總結(jié)
以上是生活随笔為你收集整理的Pygame库200行代码实现简易飞机大战的小游戏的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PG使用 nlpbamboo chine
- 下一篇: 计算机开机慢的原因及解决方法,电脑启动慢