# _*_ coding: utf-8 _*_ import pygame from pygame.locals import * from sys import exit import random #设置游戏屏幕大小 SCREEN_WIDTH=480 SCREEN_HEIGHT=800 import codecs #子弹类 class Bullet(pygame.sprite.Sprite): def __init__(self,bullet_img,init_pos): pygame.sprite.Sprite.__init__(self) self.image = bullet_img self.rect = self.image.get_rect() self.rect.midbottom=init_pos self.speed = 10 def move(self): self.rect.top = self.speed #玩家飞机类 class player(pygame.sprite.Sprite): def __init__(self,plane_img,player_rect,init_pos): pygame.sprite.Sprite.__init__(self) self.image = [] #用来存储玩家飞机图片的列表 for i in range(len(player_rect)): self.image.append(plane_img.subsurface(player_rect[i]).convert_alpha()) self.rect =player_rect[0] #初始化图片处在矩形 self.rect.topleft = init_pos #初始化矩形的左上角图标 self.speed = 8 #初始化玩家飞机速度,这里是一个确定的值 self.bullets = pygame.sprite.Sprite.Gruop() #玩家飞机所发射的子弹的集合 self.img_index = 0 #玩家飞机图片索引 self.is_hit =False #玩家是否被击中 # 玩家飞机类 class Player(pygame.sprite.Sprite): def __init__(self, plane_img, player_rect, init_pos): pygame.sprite.Sprite.__init__(self) self.image = [] # 用来存储玩家飞机图片的列表 for i in range(len(player_rect)): self.image.append(plane_img.subsurface(player_rect[i]).convert_alpha()) self.rect = player_rect[0] # 初始化图片所在的矩形 self.rect.topleft = init_pos # 初始化矩形的左上角坐标 self.speed = 8 # 初始化玩家飞机速度,这里是一个确定的值 self.bullets = pygame.sprite.Group() # 玩家飞机所发射的子弹的集合 self.img_index = 0 # 玩家飞机图片索引 self.is_hit = False # 玩家是否被击中 #发射子弹 def shoot(self,bullet_img): bullet=Bullet(bullet_img,self.rect.midtop) self.bullets.add(bullet) #向上移动,需要判定边界 def moveUp(self): if self.rect.top<=0: self.rect.top=0 else: self.rect.top-=self.speed #向下移动,需要判定边界 def moveDown(self): if self.rect.top >= SCREEN_HEIGHT - self.rect.height: self.rect.top = SCREEN_HEIGHT - self.rect.height else: self.rect.top+=self.speed #向左移动,需要判定边界 def moveLeft(self): if self.rect.left<=0: self.rect.left=0 else: self.rect.left-=self.speed #向右移动,需要判定边界 def moveRight(self): if self.rect.left>=SCREEN_WIDTH-self.rect.width: self.rect.left=SCREEN_WIDTH-self.rect.width else: self.rect.left+=self.speed #敌机类 class Enemy(pygame.sprite.Sprite): def __init__(self,enemy_img,enemy_down_imgs,init_pos): pygame.sprite.Sprite.__init__(self) self.image=enemy_img self.rect=self.image.get_rect() self.rect.topleft =init_pos self.down_imgs=enemy_down_imgs self.speed=2 self.down_index=0 #敌机移动,边界判定及删除在游戏主循环里处理 def move(self): self.rect.top+=self.speed #写文本 def write_txt(content,strim,path): # noinspection PyUnresolvedReferences f = codecs.open(path,strim,'utf8') f.write(str(content)) f.close() #读文本 def read_txt(path): with open(path,'r',encoding='utf8')as f: lines = f.readlines() return lines #初始化pygame pygame.init() #设置游戏界面大小,背景及标题 #游戏像素大小 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) #游戏界面标题 pygame.display.set_caption('飞机大战') # 图标 ic_launcher = pygame.image.load('resources/image/ic_launcher.png').convert_alpha() pygame.display.set_icon(ic_launcher) # 背景图 background = pygame.image.load('resources/image/background.png').convert() # Game Over 的背景图 game_over = pygame.image.load('resources/image/gameover.png') # 飞机及子弹图片集合 plane_img = pygame.image.load('resources/image/shoot.png') def startGame(): #设置玩家飞机不同状态图片列表,多张图片展示为动画效果 player_rect = [] #玩家飞机图片 player_rect.append(pygame.Rect(0,99,102,136)) player_rect.append(pygame.Rect(165, 360, 102, 126)) #玩家飞机爆炸图片 player_rect.append(pygame.Rect(165, 360, 102, 126)) player_rect.append(pygame.Rect(330, 624, 102, 126)) player_rect.append(pygame.Rect(330, 498, 102, 126)) player_rect.append(pygame.Rect(432, 624, 102, 126)) player_pos = [200,600] player =Player(plane_img,player_rect,player_pos) #子弹图片 bullet_rect = pygame.Rect(69,77,10,21) bullet_img = plane_img.subsurface(bullet_rect) #敌机不同状体列表,多张图片显示为动画效果 enemy1_rect = pygame.Rect(534, 612, 57, 43) enemy1_img =plane_img.subsurface(enemy1_rect) enemy1_down_imgs = [] enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(267, 347, 57, 43))) enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(873, 697, 57, 43))) enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(267, 296, 57, 43))) enemy1_down_imgs.append(plane_img.subsurface(pygame.Rect(930, 697, 57, 43))) #存储敌机 enemies1 = pygame.sprite.Group() #存储北极击毁飞机,用来渲染效果 enemies_down = pygame.sprite.Group() #初始化射击及敌机移动速度 shoot_frequency = 0 enemy_frequency = 0 #玩家飞机被击中的效果 player_down_index = 16 #初始化分数 score = 0 #游戏循环频率设置 clock = pygame.time.Clock() #判断游戏循环退出的参数 running=True #游戏主循环 while running: #绘制背景 screen.fill(0) screen.blit(background,(0,0)) #控制游戏最大频率 clock.tick(60) #生成子弹,需要控制发射频率 #首先判断玩家飞机有没有被击中 if not player.is_hit: if shoot_frequency%15==0: player.shoot(bullet_img) shoot_frequency+=1 if shoot_frequency>=15: shoot_frequency=0 for bullet in player.bullets: #以固定速度移动子弹 bullet.move() #移出屏幕后删除子弹 if bullet.rect.bottom<0: player.bullets.remove(bullet) #显示子弹 player.bullets.draw(screen) #生成敌机,需要控制生成频率 if enemy_frequency%50==0: enemy1_pos=[random.randint(0,SCREEN_WIDTH-enemy1_rect.width),0] enemy1 = Enemy(enemy1_img,enemy1_down_imgs,enemy1_pos) enemies1.add(enemy1) enemy_frequency +=1 if enemy_frequency>=100: enemy_frequency =0 for enemy in enemies1: #移动敌机 enemy.move() #敌机与玩家飞机碰撞效果处理 if pygame.sprite.collide_circle(enemy,player): enemies_down.add(enemy) enemies1.remove(enemy) player.is_hit= True break #移动出屏幕后删除飞机 if enemy.rect.top < 0: enemies1.remove(enemy) #敌机被子弹击中效果处理 #将被击中的敌机对象添加击毁敌机group中,用来渲染击毁动画 enemies1_down =pygame.sprite.groupcollide(enemies1,player.bullets,1,1) for enemy_down in enemies1_down: enemies_down.add(enemy_down) #绘制玩家飞机 if not player.is_hit: screen.blit(player.image[player.img_index],player.rect) #更换图片索引使飞机有动画效果 player.img_index=shoot_frequency //8 else: #玩家飞机被击中后的效果处理 player.img_index=player_down_index //8 screen.blit(player.image[player.img_index],player.rect) if player_down_index > 47: #击中效果处理完成后游戏结束 running =False #敌机被子弹击中效果显示 for enmey_down in enemies1_down: if enemy_down.down_index==0: pass if enemy_down.down_index>7: enemies1_down.remove(enemy_down) score+=100 continue screen.blit(enemy_down.down_imgs[enemy_down.down_index //2],enemy_down.rect) enemy_down.down_index+=1 #显示敌机 enemies1.draw(screen) #绘制当前得分 score_font =pygame.font.Font(None,36) score_text = score_font.render(str(score),True,(128,128,128)) text_rect =score_text.get_rect() text_rect.topleft = [10,10] screen.blit(score_text,text_rect) #更新屏幕 pygame.display.update() #处理游戏退出 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() #获取键盘事件(上下左右键) key_pressed = pygame.key.get_pressed() #处理键盘事件 if key_pressed[K_w] or key_pressed[K_UP]: player.moveUp() if key_pressed[K_a] or key_pressed[K_LEFT]: player.moveLeft() if key_pressed[K_s] or key_pressed[K_DOWN]: player.moveDown() if key_pressed[K_d] or key_pressed[K_RIGHT]: player.moveRight() #绘制游戏背景 screen.blit(game_over,(0,0)) #game over最后得分 font = pygame.font.Font(None,48) text = font.render('Score'+ str(score),True,(255,0,0)) text_rect = text.get_rect() text_rect.centery = screen.get_rect().centerx text_rect.centery = screen.get_rect().centerx + 24 screen.blit(text,text_rect) #使用系统字体 xtfont = pygame.font.SysFont('semHei',30) #重新开始按钮 textstart = xtfont.render('重新开始',True,(255,0,0)) text_rect = textstart.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centerx = screen.get_rect().conterx +180 screen.blit(textstart,text_rect) # 判断得分更新排行榜 # 临时的变量在到排行榜的时候使用 j = 0 # 获取文件中内容转换成列表使用mr分割开内容 arrayscore = read_txt(r'score.txt')[0].split('mr') # 循环分数列表在列表里排序 for i in range(0, len(arrayscore)): # 判断当前获得的分数是否大于排行榜上的分数 if score > int(arrayscore[i]): # 大于排行榜上的内容 把分数和当前分数进行替换 j = arrayscore[i] arrayscore[i] = str(score) score = 0 # 替换下来的分数下移动一位 if int(j) > int(arrayscore[i]): k = arrayscore[i] arrayscore[i] = str(j) j = k #循环分数列表 写入文档 for i in range(0, len(arrayscore)): # 判断列表中第一个分数 if i == 0: # 覆盖写入内容追加mr方便分割内容 write_txt(arrayscore[i] + 'mr', 'w', r'score.txt') else: # 判断是否为最后一个分数 if (i == 9): # 最近添加内容最后一个分数不添加mr write_txt(arrayscore[i], 'a', r'score.txt') else: # 不是最后一个分数,添加的时候添加mr write_txt(arrayscore[i] + 'mr', 'a', r'score.txt') # 排行榜 def gameRanking(): screen2 = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # 绘制背景 screen2.fill(0) screen2.blit(background, (0, 0)) # 使用系统字体 xtfont = pygame.font.SysFont('SimHei', 30) # 重新开始按钮 textstart = xtfont.render('排行榜 ', True, (255, 0, 0)) text_rect = textstart.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centery = 50 screen.blit(textstart, text_rect) # 使用系统字体 xtfont = pygame.font.SysFont('SimHei', 30) # 重新开始按钮 textstart = xtfont.render('重新开始 ', True, (255, 0, 0)) text_rect = textstart.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centery = screen.get_rect().centery + 120 screen2.blit(textstart, text_rect) #获取排行文档内容 arrayscore = read_txt(r'score.text')[0].split('mr') #循环排行榜文件显示排列 for i in range(0,len(arrayscore)): #game over 结束后显示的得分 font =pygame.font.Font(None,48) #排名1到10 k = i+1 text =font.render(str(k)+ "" +arrayscore[i],True,(255,0,0)) text_rect = text.get_rect() text_rect.centerx = screen2.get_rect().centerx text_rect.centery = 80 +30*k #绘制分数内容 screen2.blit(text,text_rect) #开始游戏 startGame() #判断点击位置及游戏处理游戏退出 while True: for event in pygame.event.get(): #关闭游戏界面退出 if event.type ==pygame.QUIT: pygame.quit() exit() #单机鼠标 elif event.type == pygame.MOUSEBUTTONDOWN: #判断鼠标单击位置是否在开始按钮范围内 if screen.get_rect().centerx - 70 <= event.pos[0] \ and event.pos[0] <= screen.get_rect().centerx + 50 \ and screen.get_rect().centery + 100 <= event.pos[1] \ and screen.get_rect().centery + 140 >=event.pos[1]: #重新开始游戏 startGame() #判断鼠标点击排行榜按钮 if screen.get_rect().centerx - 70 <= event.pos[0] \ and event.pos[0] <= screen.get_rect().centerx + 50 \ and screen.get_rect().centery + 140 <= event.pos[1] \ and screen.get_rect().centery + 160 >= event.pos[1]: #显示排行榜 gameRanking() #更新界面 pygame.display.update()