首先要pycharm中安裝pygame,
源代碼
mport sys # 導入系統模塊
import random # 導入隨機數
import pygame # 導入pygame模塊
import pygame.locals # 導入pygame本地策略
APP_ICON = “res/app.ico” # 設計圖片常量
IMG_BACKGROUND = “res/img_bg_level_1.jpg” # 設計圖片常量
設置敵機圖片庫常量元組
IMG_ENEMYS = (“res/img-plane_1.png”,“res/img-plane_2.png”,“res/img-plane_3.png”,“res/img-plane_4.png”,“res/img-plane_5.png”,“res/img-plane_6.png”,“res/img-plane_7.png”)
IMG_PLAYER = “res/hero2.png” # 設置玩家飛機圖片
IMG_BULLET = “res/bullet_13.png” # 設置子彈圖片
創建所有顯示的圖形父類Model
class Model:
window = None # 主窗體對象,用於模型訪問使用
構造方法
def init(self, img_path, x, y):
self.img = pygame.image.load(img_path) # 背景圖片
self.x = x # 窗體中放置的x坐標
self.y = y # 窗體中放置的y坐標
將模型加入窗體的方法抽取到父類
def display(self):
self.window.blit(self.img, (self.x, self.y)) # 填充圖片到窗體中
@staticmethod # 碰撞操作與模型對象無關,屬於模型相關操作,定義為靜態方法
def is_hit(rect1,rect2): # 定義雙方是否碰撞的靜態方法
return pygame.Rect.colliderect(rect1, rect2) # 返回兩個矩形是否相交,即是否碰撞
背景類
class Background(Model):
定義背景移動的方法
def move(self):
加入判斷
if self.y <= Game.WINDOW_HEIGHT: # 更新高度的引用 # 如果沒有超出屏幕就正常移動
self.y += 1 # 縱坐標自增1
else: # 如果超出屏幕,恢復圖片位置為原始位置
self.y = 0 # 縱坐標 = 0
覆蓋父類display方法,做輔助背景貼圖
def display(self):
self.window.blit(self.img, (self.x, self.y)) # 原始背景貼圖,推薦使用super().display()
self.window.blit(self.img, (self.x, self.y - Game.WINDOW_HEIGHT)) # 更新高度的引用 # 輔助背景即將原始背景圖片展示第二遍,坐標位置與第一遍展示上下拼接吻合
玩家類
class PlayerPlane(Model):
覆蓋init方法
def init(self,img_path, x, y):
super().init(img_path, x, y) # 調用父類構造方法
self.bullets = [] # 定義子彈列表為空,默認沒有子彈
覆蓋display方法
def display(self,enemys): # 在顯示飛機和子彈的同時,傳入敵機列表,判斷子彈是否與敵機相撞,添加enemys形參
super().display() # 調用父類方法
remove_bullets = [] # 定義被刪除的子彈列表
for bullet in self.bullets: # 循環子彈
優化子彈存儲隊列,超出屏幕移出子彈
if bullet.y < -29 : # 如果子彈位置超出屏幕
remove_bullets.append(bullet) # 將要刪除的子彈加入列表
else: # 如果子彈位置未超出屏幕范圍
rect_bullet = pygame.locals.Rect(bullet.x, bullet.y, 20, 29) # 創建子彈矩形對象,傳入x,y,width,height
for enemy in enemys: # 對未超出屏幕顯示范圍的子彈與所有敵機進行碰撞檢測
rect_enemy = pygame.locals.Rect(enemy.x,enemy.y,100,68) # 創建敵機矩形對象,傳入x,y,width,height
調用碰撞檢測方法,傳入當前子彈對象,傳入敵機對象,判斷是否碰撞
if Model.is_hit(rect_bullet,rect_enemy) : # 如果碰撞
enemy.is_hited = True # 擊中敵機即設置當前敵機為被擊中狀態
enemy.bomb.is_show = True # 設置爆破效果狀態開啟
enemy.bomb.x = enemy.x # 設置爆破效果開啟位置x坐標
enemy.bomb.y = enemy.y # 設置爆破效果開啟位置y坐標
remove_bullets.append(bullet) # 將產生碰撞的子彈加入刪除列表
sound = pygame.mixer.Sound(“res/bomb.wav”) # 添加混音音效文件
sound.play() # 播放爆破效果音
break # 當前子彈擊中了一架敵機,終止對剩余敵機的碰撞檢測,終止敵機循環
for bullet in remove_bullets: # 循環刪除子彈列表
self.bullets.remove(bullet) # 從原始子彈列表中刪除要刪除的子彈
敵機類
class EnemyPlane(Model):
覆蓋init方法
def init(self):
img = IMG_ENEMYS[random.randint(0,len(IMG_ENEMYS)-1)] # 設置圖片路徑隨機從元組中獲取
x = random.randint(0, Game.WINDOW_WIDTH - 100) # 設置x坐標隨機生成 橫向位置 0 到 屏幕寬度 - 飛機寬度(100)
y = random.randint(-Game.WINDOW_HEIGHT, -68) # 設置y坐標隨機生成 縱向位置 -屏幕高度 到 -飛機高度
super().init(img,x,y) # 調用父類構造方法
self.is_hited = False # 添加敵機被擊中的狀態
self.bomb = Bomb() # 為敵機添加綁定的爆破效果對象
定義敵機移動的方法
def move(self):
控制敵機到達底部后,返回頂部
if self.y < Game.WINDOW_HEIGHT and not self.is_hited : # 添加敵機被擊中的狀態判定 # 敵機未超出屏幕
self.y += 4 # 控制敵機移動速度
else: # 敵機超出屏幕
self.img = pygame.image.load(IMG_ENEMYS[random.randint(0, len(IMG_ENEMYS) - 1)]) # 修改敵機到達底部后返回的圖片隨機生成,同初始化策略
self.x = random.randint(0, Game.WINDOW_WIDTH - 100) # 修改敵機到達底部后返回頂部的策略,x隨機生成,同初始化策略
self.y = random.randint(-Game.WINDOW_HEIGHT, -68) # 修改敵機到達底部后返回頂部的策略,y隨機生成,同初始化策略
self.is_hited = False # 重置敵機是否被擊中狀態為未被擊中,False
子彈類
class Bullet(Model):
定義子彈移動的方法
def move(self):
self.y -= 12 # 控制子彈移動速度
爆炸效果類
class Bomb(Model): # 創建爆炸效果類
def init(self): # 定義單獨的初始化方法
self.x = None # 定義爆炸顯示的橫坐標x
self.y = None # 定義爆炸顯示的縱坐標y
self.imgs = [ pygame.image.load(“res/bomb-”+str(i)+".png") for i in range(1,7)] # 加載爆炸效果使用的所有圖片列表
self.is_show = False # 定義是否開啟爆破效果屬性
self.times = 0 # 定義爆破圖片展示控制變量
設置測試類入口操作
if name == “main”:
Game().run()import sys # 導入系統模塊
import random # 導入隨機數
import pygame # 導入pygame模塊
import pygame.locals # 導入pygame本地策略
APP_ICON = “res/app.ico” # 設計圖片常量
IMG_BACKGROUND = “res/img_bg_level_1.jpg” # 設計圖片常量
設置敵機圖片庫常量元組
IMG_ENEMYS = (“res/img-plane_1.png”,“res/img-plane_2.png”,“res/img-plane_3.png”,“res/img-plane_4.png”,“res/img-plane_5.png”,“res/img-plane_6.png”,“res/img-plane_7.png”)
IMG_PLAYER = “res/hero2.png” # 設置玩家飛機圖片
IMG_BULLET = “res/bullet_13.png” # 設置子彈圖片
創建所有顯示的圖形父類Model
class Model:
window = None # 主窗體對象,用於模型訪問使用
構造方法
def init(self, img_path, x, y):
self.img = pygame.image.load(img_path) # 背景圖片
self.x = x # 窗體中放置的x坐標
self.y = y # 窗體中放置的y坐標
將模型加入窗體的方法抽取到父類
def display(self):
self.window.blit(self.img, (self.x, self.y)) # 填充圖片到窗體中
@staticmethod # 碰撞操作與模型對象無關,屬於模型相關操作,定義為靜態方法
def is_hit(rect1,rect2): # 定義雙方是否碰撞的靜態方法
return pygame.Rect.colliderect(rect1, rect2) # 返回兩個矩形是否相交,即是否碰撞
背景類
class Background(Model):
定義背景移動的方法
def move(self):
加入判斷
if self.y <= Game.WINDOW_HEIGHT: # 更新高度的引用 # 如果沒有超出屏幕就正常移動
self.y += 1 # 縱坐標自增1
else: # 如果超出屏幕,恢復圖片位置為原始位置
self.y = 0 # 縱坐標 = 0
覆蓋父類display方法,做輔助背景貼圖
def display(self):
self.window.blit(self.img, (self.x, self.y)) # 原始背景貼圖,推薦使用super().display()
self.window.blit(self.img, (self.x, self.y - Game.WINDOW_HEIGHT)) # 更新高度的引用 # 輔助背景即將原始背景圖片展示第二遍,坐標位置與第一遍展示上下拼接吻合
class Game:
WINDOW_WIDTH = 512 # 定義窗體寬度常量
WINDOW_HEIGHT = 768 # 定義窗體高度常量
設置測試類入口操作
if name == “main”:
Game().run()
最后運行,圖片如下