学写一个飞机大战游戏,功能有些简单。参考:http://res.crossincode.com/wechat/pygame.html
注释写的有点多,方便自己看,随时修改。。。。
#!/usr/bin/env python3
# encoding: utf-8
import pygame
from sys import exit
import random
import math
# 打飞机小游戏
# 定义bullet(子弹)
class Bullet:
'''
bullet(子弹)类包含x,y属性, 左侧子弹初始化,右侧子弹初始化,子弹移动方法
'''
def __init__(self):
self.x = 0
self.y = -1
self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\pygame-plane\bullet.png').convert_alpha() # 加载子弹图片
self.active = False
def move(self): # 子弹移动
if self.active:
self.y -= 2
if self.y<0:
self.active = False
def restart_center(self): # 中间子弹
self.x = x
self.y = y
self.active = True
def restart_left(self): # 左侧机翼子弹
self.x = x + 25
self.y = y
self.active = True
def restart_right(self): # 右侧机翼侧子弹
self.x = x - 25
self.y = y
self.active = True
# 定义Enemy(敌机)
class Enemy:
'''
设置敌机的初始化位置,移动方法。
'''
def restart(self):
self.x = random.randint(31,419) # 根据窗口大小,敌机尺寸 随机设置敌机出现的横坐标位置(不要超出窗口)
self.y = random.randint(-200,-120) # 随机设置敌机出现的纵坐标位置
self.speed = random.random()+0.4 # 设置子弹移动速度
def __init__(self):
#初始化(未经初始化,属性不能直接使用)
self.restart()
self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\pygame-plane\enemy.png').convert_alpha() # 加载敌机图片
def move(self):
if self.y > 600:
self.restart()
else:
self.y += self.speed
# 定义Plane(飞机)
class Plane:
def restart(self):
self.x = 450
self.y = 300
def __init__(self):
self.restart()
self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\pygame-plane\plane.png').convert_alpha()
def move(self):
self.x = x - self.image.get_width()/2
self.y = y - self.image.get_height()/2
screen.blit(self.image,(self.x,self.y)) # 将飞机图片绘制到窗口,(x,y)位置表示图片左上角
# 子弹与敌机碰撞检测
'''
忽略bullet本身面积,当做一个坐标(x,y)与敌机碰撞检测。
'''
def checkhit(bullet,enemy):
if ( bullet.x > enemy.x and bullet.x < enemy.x + enemy.image.get_width()) and (
bullet.y > enemy.y and bullet.y < enemy.y + enemy.image.get_height()):
enemy.restart()
bullet.active = False
return True
return False
# 飞机(plane)与敌机碰撞检测
'''
两个矩形相交的条件:两个矩形的重心距离在X和Y轴上都小于两个矩形长或宽的一半之和,分两次判断一下就行了。
如果一旦有重合就算是碰撞,会让游戏看上去有些奇怪:有时候你觉得并没有撞上,而实际已经有了重合,游戏就失败了。为了避免这一现象,在检测的长度上打点折扣(0.7)
'''
def checkCrash(plane,enemy):
if ( math.sqrt((x - (enemy.x + enemy.image.get_width()/2))**2) < 0.7*(plane.image.get_width()/2 + enemy.image.get_width()/2) ) and (
math.sqrt((y - (enemy.y + enemy.image.get_height()/2))**2) < 0.7*(plane.image.get_height()/2 + enemy.image.get_height()/2) ):
return True
return False
pygame.init() # 初始化
screen = pygame.display.set_mode((450,700),0,0) # 绘制窗口(像素大小与背景图片一样)。_mod(resolution=(0,0), flags=0, depth=0)
pygame.display.set_caption('小游戏') # 设置窗口标题
img_background = pygame.image.load(r'C:\Users\Administrator\Desktop\pygame-plane\back.jpg').convert() # 加载背景图片
plane = Plane() # 设置飞机
bullets_left = [] # 左侧机翼子弹,添加5颗子弹
bullets_right = [] # 右侧机翼子弹,添加5颗子弹
bullets_center = []# 中间子弹列表,添加5颗子弹
for i in range(5):
bullets_left.append(Bullet())
bullets_right.append(Bullet())
bullets_center.append(Bullet())
count = len(bullets_left)
index = 0
interval = 0 # 表示循环次数(重新接受新的坐标值,发射下一颗子弹)
enemies = [] # 创建Enemy(敌机)列表,添加2个敌机
for i in range(4):
enemies.append(Enemy())
score = 0 # 设置分数
gameover = False # 设置游戏结束的条件(飞机与敌机碰撞后,plane/enemy/bullets循环停止)
#循环主体
while True:
for event in pygame.event.get(): # 事件列表
if event.type == pygame.QUIT: # 判断是否触发了关闭事件(pygame.QUIT,是一个整数)
print('关闭了屏幕')
pygame.quit() # 关闭窗口(pygame库停止工作)
exit()
if gameover and event.type == pygame.MOUSEBUTTONUP: # 点击鼠标,游戏重启
plane.restart()
for e in enemies:
e.restart()
for b in bullets_left:
b.active = False
for b in bullets_right:
b.active = False
for b in bullets_center:
b.active = False
score = 0
gameover = False
screen.blit(img_background,(0,0)) # 将背景图片绘制到窗口,(x,y)位置表示窗口左上角
x,y = pygame.mouse.get_pos() # 获取鼠标坐标位置(x,y均为整数)
if not gameover:
interval -= 1
if interval < 0:
if score < 10:
bullets_center[index].restart_center()
elif 10 <= score <= 11:
bullets_left[index].restart_left()
bullets_right[index].restart_right()
else:
gameover = True
my_font = pygame.font.Font(r'C:\Windows\Fonts\STZHONGS.TTF',20)
text_score = my_font.render(u'您的得分: %d' % score, True, (144, 238, 144),(0,0,0))
screen.blit(text_score,(0,0))
text_end = my_font.render(u'通关成功,游戏结束!', True, (0, 0, 0))
screen.blit(text_end,(100,400))
pygame.display.update() # 刷新绘制窗口
break
interval = 100
index = (index +1) % count
for b in bullets_center: # 判断飞机中间子弹是否初始化并发射,检查子弹与敌机是否碰撞
if b.active:
for e in enemies:
if checkhit(b,e): # 中间子弹与敌机碰撞检查
score += 1
b.move()
screen.blit(b.image,(b.x,b.y))
for b in bullets_left: # 判断飞机左侧子弹是否初始化并发射,检查子弹与敌机是否碰撞
if b.active:
for e in enemies:
if checkhit(b,e): # 左侧子弹与敌机碰撞检查
score += 1
b.move()
screen.blit(b.image,(b.x,b.y))
for i in bullets_right: # 判断飞机右侧子弹是否初始化并发射,检查子弹与敌机是否碰撞
if i.active:
for e in enemies:
if checkhit(i,e): # 右侧子弹与敌机碰撞检查
score += 1
i.move()
screen.blit(i.image,(i.x,i.y))
for e in enemies:
if checkCrash(plane,e): # 飞机与敌机碰撞检测(游戏结束)
gameover = True
e.move() # 调用敌机向下移动
screen.blit(e.image,(e.x,e.y)) # 将敌机绘制在窗口
plane.move()
else:
my_font = pygame.font.Font(r'C:\Windows\Fonts\STZHONGS.TTF',20) # 创建font对象,(‘C:\Windows\Fonts\STZHONGS.TTF’)是字体样式,也可以用None表示使用默认字体,20是字号
my_font.set_italic(True) # 斜体
text_score = my_font.render(u'您的得分: %d ' % score, True, (144, 238, 144),(0,0,0)) # 文字只支持单行,多行的话,建立多个对象。注:my_font.render()的参数分别是:字体,布尔值[字体平滑/锯齿],字体颜色,字体背景颜色[可选]
screen.blit(text_score,(0,0))
text_end = my_font.render(u'——点击鼠标重新游戏——', True, (0, 0, 0))
screen.blit(text_end,(100,400))
pygame.display.update() # 刷新绘制窗口