pygame游戏开发框架(9)之完整游戏代码分享
程序员文章站
2022-11-27 22:58:21
@英雄类
import pygame
from pygame.sprite import Sprite
# 继承于精灵类
class Hero(Sprite):...
@英雄类
import pygame from pygame.sprite import Sprite # 继承于精灵类 class Hero(Sprite): # 创建英雄对象 # 传入窗口宽高参数 def __init__(self,winWidth,winHeight): # 调用精灵父类方法 super().__init__() # 记录窗口宽高 self.winWidth = winWidth self.winHeight = winHeight # 加载英雄喷火飞行图片的两帧 # 这里由于英雄图片有透明区域,因此必须使用convert_alpha()来转化为表面对象 self.mSurface1 = pygame.image.load("./images/me1.png").convert_alpha() self.mSurface2 = pygame.image.load("./images/me2.png").convert_alpha() # 以第一幅图片为基准获取矩形对象 self.rect = self.mSurface1.get_rect() # 定义飞行速度 self.speed = 10 # 计算英雄出现的位置,此处使其出现的位置位于窗口偏底部的正* # 通过矩形的left和top确定矩形区域的位置 self.rect.left = self.winWidth // 2 - self.rect.width // 2 self.rect.top = self.winHeight - 50 - self.rect.height # 从mSurface1生成非透明区域遮罩,用于做碰撞检测 self.mask = pygame.mask.from_surface(self.mSurface1) # 向左飞行 def moveLeft(self): # 只要矩形区域的左边缘没有越界,就持续更新精灵矩形的位置 if self.rect.left > 0: self.rect.left -= self.speed # 向右飞行:只要右侧没有越界就持续更新矩形位置 def moveRight(self): if self.rect.right < self.winWidth: self.rect.left += self.speed # 向上飞行:只要矩形顶部没有越界就持续更新矩形的位置 def moveUp(self): if self.rect.top > 0: self.rect.top -= self.speed # 向下飞行:只要矩形底部没有越界就持续更新矩形的位置 def moveDown(self): if self.rect.bottom < self.winHeight: self.rect.bottom += self.speed # 按指定向量移动矩形位置 def move(self,dx,dy): self.rect.left += dx self.rect.top += dy
@敌机类
import random import pygame from pygame.sprite import Sprite # 敌机类 class SmallEnemy(Sprite): # 构造方法:确定颜值、确定初始位置、引擎功率 def __init__(self, winWidth, winHeight): Sprite.__init__(self) self.winWidth = winWidth self.winHeight = winHeight # 外形 self.mSurface = pygame.image.load("./images/enemy1.png").convert_alpha() # 爆炸 self.dSurface1 = pygame.image.load("./images/enemy1_down1.png").convert_alpha() self.dSurface2 = pygame.image.load("./images/enemy1_down2.png").convert_alpha() self.dSurface3 = pygame.image.load("./images/enemy1_down3.png").convert_alpha() self.dSurface4 = pygame.image.load("./images/enemy1_down4.png").convert_alpha() self.dList = [self.dSurface1, self.dSurface2, self.dSurface3, self.dSurface4] self.dIndex = 0 # 确定敌机位置 self.rect = self.mSurface.get_rect() self.reset() # 敌机飞行速度 self.speed = 5 # 添加碰撞检测遮罩 self.mask = pygame.mask.from_surface(self.mSurface) # 重置敌机位置和生命 def reset(self): self.rect.left = random.randint(0, self.winWidth - self.rect.width) self.rect.top = 0 - random.randint(0, 1000) self.isAlive = True self.dIndex = 0 # 机械地向下飞行 def move(self): if self.rect.top < self.winHeight: self.rect.bottom += self.speed else: self.isAlive = False self.reset() # fCount=当前第几帧 def destroy(self, fCount, winSurface,dSound): winSurface.blit(self.dList[self.dIndex],self.rect) if fCount % 3 == 0: # 切下一副面孔 self.dIndex += 1 if self.dIndex == 4: dSound.play() self.reset()
@子弹类
import pygame from pygame.sprite import Sprite class Bullet(Sprite): # 构造方法:颜值、位置、速度 # position = 机头位置 def __init__(self): super().__init__() # 颜值 self.mSurface = pygame.image.load("./images/bullet1.png").convert_alpha() self.rect = self.mSurface.get_rect() # 将子弹的顶部*对齐机头位置 # self.reset(position) self.isAlive = False # 子弹速度 self.speed = 15 # 添加碰撞检测遮罩 self.mask = pygame.mask.from_surface(self.mSurface) # 重置子弹位置和生命 def reset(self, position): self.rect.left = position[0] - self.rect.width // 2 self.rect.bottom = position[1] self.isAlive = True # 飞行方法 def move(self): if self.rect.bottom > 0: self.rect.top -= self.speed else: self.isAlive = False
@按钮类
import pygame from pygame.sprite import Sprite class PauseButton(Sprite): def __init__(self,winWidth,winHeight,paused): super().__init__() self.winWidth = winWidth self.winHeight = winHeight self.paused = paused # 颜值 self.sPauseNor = pygame.image.load("./images/pause_nor.png").convert_alpha() self.sPausePressed = pygame.image.load("./images/pause_pressed.png").convert_alpha() self.sResumeNor = pygame.image.load("./images/resume_nor.png").convert_alpha() self.sResumePressed = pygame.image.load("./images/resume_pressed.png").convert_alpha() self.currentSurface = self.sPauseNor self.rect = self.sPauseNor.get_rect() # 位置 self.rect.right = self.winWidth - 10 self.rect.top = 10 def onBtnClick(self, paused): self.paused = paused if self.paused: self.currentSurface = self.sResumeNor # print("sResumeNor") else: self.currentSurface = self.sPauseNor # print("sPauseNor") def onBtnHover(self): # print("onBtnHover") if self.paused: self.currentSurface = self.sResumePressed # print("sResumePressed") else: self.currentSurface = self.sPausePressed # print("sPausePressed") def onBtnOut(self): # print("onBtnOut") if self.paused: self.currentSurface = self.sResumeNor # print("sResumeNor") else: self.currentSurface = self.sPauseNor # print("sPauseNor")
@主业务逻辑
import pygame import sys from demos.W3.myplane.Bullet import Bullet from demos.W3.myplane.Button import PauseButton from demos.W3.myplane.Enemy import SmallEnemy from demos.W3.myplane.Hero import Hero # 全局初始化 pygame.init() pygame.mixer.init() # 设置窗口大小和标题 resolution = width, height = 480, 700 windowSurface = pygame.display.set_mode(resolution) # 设置分辨率并得到全局的绘图表面 pygame.display.set_caption("飞机大战") # 加载背景图 bgSurface = pygame.image.load("./images/background.png").convert() # 加载背景音乐 pygame.mixer.music.load("./sound/game_music.ogg") pygame.mixer.music.play(-1) pygame.mixer.music.set_volume(0.4) # 加载音效 bombSound = pygame.mixer.Sound("./sound/use_bomb.wav") bulletSound = pygame.mixer.Sound("./sound/bullet.wav") # 加载字体 textFont = pygame.font.Font("./font/font.ttf", 30) # 创建时钟对象 clock = pygame.time.Clock() # 系统常量 ENEMY_NUM = 10 BULLET_NUM = 10 # 业务变量 score = 0 # 统计得分 paused = False if __name__ == '__main__': # 创建英雄实例 hero = Hero(width, height) # 创建敌机Group seGroup = pygame.sprite.Group() for i in range(ENEMY_NUM): se = SmallEnemy(width, height) seGroup.add(se) # 创建子弹 bList = [] bIndex = 0 for i in range(BULLET_NUM): b = Bullet() bList.append(b) # 创建暂停按钮 pauseBtn = PauseButton(width,height,paused) count = 0 # 开启消息循环 while True: # 处理用户输入 for event in pygame.event.get(): # 处理退出事件 if event.type == pygame.QUIT: pygame.quit() sys.exit() # 感应和处理鼠标事件 if event.type == pygame.MOUSEBUTTONDOWN: # print("MOUSEBUTTONDOWN @ ", event.pos) if hero.rect.collidepoint(event.pos): print("别摸我") if event.type == pygame.MOUSEBUTTONUP: print("MOUSEBUTTONUP @ ", event.pos) if pauseBtn.rect.collidepoint(event.pos): paused = not paused pauseBtn.onBtnClick(paused) if event.type == pygame.MOUSEMOTION: # print("MOUSEMOTION @ ", event.pos) if pauseBtn.rect.collidepoint(event.pos): pauseBtn.onBtnHover() else: pauseBtn.onBtnOut() # 处理键盘事件 if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE and not paused: print("开炮!") # 把窗口内的敌人全杀死 for se in seGroup: if se.rect.bottom > 0: se.isAlive = False score += 100 # 绘制背景 windowSurface.blit(bgSurface, (0, 0)) if paused == False: pygame.mixer.music.unpause() count += 1 # 检测当前按下的按钮有哪些 bools = pygame.key.get_pressed() # print(bools) if bools[pygame.K_w]: hero.moveUp() if bools[pygame.K_s]: hero.moveDown() if bools[pygame.K_a]: hero.moveLeft() if bools[pygame.K_d]: hero.moveRight() # 每10帧在机头射出一颗子弹 if count % 10 == 0: b = bList[bIndex] # 取出一颗子弹 b.reset(hero.rect.midtop) # 立即装载到【当前】机头位置 # windowSurface.blit(b.mSurface, b.rect) # 画子弹 bulletSound.play() # 呼啸声 bIndex = (bIndex + 1) % BULLET_NUM # 序号递增 # 精灵碰撞检测 for b in bList: if b.isAlive: hitEnemyList = pygame.sprite.spritecollide(b, seGroup, False, pygame.sprite.collide_mask) if len(hitEnemyList) > 0: b.isAlive = False for se in hitEnemyList: se.isAlive = False score += 100 # 打死一个敌人加100分 else: pygame.mixer.music.pause() # 绘制英雄 if count % 3 == 0: windowSurface.blit(hero.mSurface1, hero.rect) else: windowSurface.blit(hero.mSurface2, hero.rect) # 绘制敌机 for se in seGroup: if se.isAlive: windowSurface.blit(se.mSurface, se.rect) # 每一帧都让敌机飞行5公里 if not paused: se.move() else: se.destroy(count, windowSurface, bombSound) # 每帧都让子弹飞 for b in bList: if b.isAlive: windowSurface.blit(b.mSurface, b.rect) # 画子弹 if not paused: b.move() # 绘制文字 textSurface = textFont.render("Score:%d" % (score), True, (255, 255, 255)) windowSurface.blit(textSurface, (10, 10)) # 绘制按钮 windowSurface.blit(pauseBtn.currentSurface, pauseBtn.rect) # 刷新界面 pygame.display.flip() # 时钟停留一帧的时长 clock.tick(60)
下一篇: 学Seo搞网赚 选好产品和关键词才是关键