前一段在数据分析中突然感觉到了一阵阵的空虚寂寞冷,所以我决定小小放松一下,于是萌生出了写一个小游戏的想法。所以在pygame中摸索了2天,终于完成了无聊的飞机大战代码。之前从来没写过游戏,所以感觉还蛮好玩儿的。在此分享出来,有兴趣的可以拿去玩玩儿咯!!
游戏完成的主要功能:
①用户飞机由用户控制;敌机自动移动。
②用户飞机由用户按空格键开火;敌机自动开火。
③击毁敌机会使敌机子弹速度逐渐增加,以达到逐渐增加游戏困难的目的。
④加入飞机坠毁的五毛特效。
⑤加入bonus功能,吃到bonus可以增加用户子弹速度,并减缓敌机子弹速度。
具体代码如下:
#coding=utf-8
import pygame
import time
from pygame.locals import *
import random
keydown_list = [0]
class Bullet(object):
def __init__(self, screen, x, y, image):
self.x = x
self.y = y
self.image = pygame.image.load(image)
self.screen = screen
def blit(self): #放置玩家飞机的子弹图片
self.screen.blit(self.image, (self.x, self.y))
class userBullet(Bullet):
def __init__(self, screen, x, y):
Bullet.__init__(self, screen, x + 40, y - 20, "./feiji/bullet.png")
def blit(self): #放置玩家飞机的子弹图片
Bullet.blit(self)
def move(self, move_variable):
self.y -= move_variable
def judge(self): #判断子弹是否越界
if self.y < -50:
return False
else:
return True
class enemyBullet(Bullet):
def __init__(self, screen, x, y):
Bullet.__init__(self, screen, x + 30, y + 45, "./feiji/bullet1.png")
def blit(self): #放置玩家飞机的子弹图片
Bullet.blit(self)
def move(self, bullet_move_variable): #敌机子弹移动
self.y += bullet_move_variable
def judge(self): #判断子弹是否越界
if self.y > 800:
return False
else:
return True
class Bonus(object):
def __init__(self, screen, x, y, image):
self.x = x
self.y = y
self.image = pygame.image.load(image)
self.screen = screen
def blit(self):
self.screen.blit(self.image,(self.x, self.y))
def move(self):
self.x += random.randint(-5,4)
self.y += 5
def missed(self):
if (self.y > 700):
return 1
class Plane(object):
def __init__(self, screen, x, y, image):
self.x = x
self.y = y
self.image = pygame.image.load(image) #导入玩家飞机图片
self.screen = screen
self.bullet_list = []
self.destroy_director = 0
def blit(self, bullet_move_variable): #放置玩家飞机方法 Notice:飞机发射的炸弹,所以fire()以后在飞机的blit中调用并且移动
self.screen.blit(self.image, (self.x, self.y))
for bullet in self.bullet_list:
bullet.blit()
bullet.move(bullet_move_variable)
if not bullet.judge():
self.bullet_list.remove(bullet)
class user_Plane(Plane):
def __init__(self, screen):
Plane.__init__(self, screen, 190, 550, "./feiji/hero1.png")
def blit(self, bullet_move_variable): #放置玩家飞机方法 Notice:飞机发射的炸弹,所以fire()以后在飞机的blit中调用并且移动
Plane.blit(self, bullet_move_variable)
def fire(self): #玩家开火
self.bullet_list.append(userBullet(self.screen, self.x, self.y))
def destroyed(self, enemy_Plane):
if self.destroy_director == 0:
for bullet in enemy_Plane.bullet_list:
if (bullet.x > self.x and bullet.x < (self.x + 100)) and (bullet.y > self.y and bullet.y < (self.y + 120)):
enemy_Plane.bullet_list.remove(bullet)
self.image = pygame.image.load("./feiji/hero_blowup_n1.png")
self.destroy_director = 1
else:
self.destroy_director += 1
if self.destroy_director == 4:
self.image = pygame.image.load("./feiji/hero_blowup_n2.png")
elif self.destroy_director == 8:
self.image = pygame.image.load("./feiji/hero_blowup_n3.png")
elif self.destroy_director == 12:
self.image = pygame.image.load("./feiji/hero_blowup_n4.png")
elif self.destroy_director == 16:
exit()
def getBonus(self, bonus):
if (bonus.x > self.x and bonus.x < (self.x + 100)) and (bonus.y > self.y and bonus.y < (self.y + 120)):
del bonus
return 1
def __del__(self):
print "Game Over"
class enemy_Plane(Plane):
def __init__(self, screen):
randx = random.randint(0,410)
randy = random.randint(0,200)
Plane.__init__(self, screen, randx, randy, "./feiji/enemy0.png")
self.times = 0 #敌机自动左右移的标志变量
def blit(self, bullet_move_variable): #放置玩家飞机方法 Notice:飞机发射的炸弹,所以fire()以后在飞机的blit中调用并且移动
Plane.blit(self, bullet_move_variable)
def fire(self): #让敌机自动开火
random_num = random.randint(0,100)
random_list = [15,30,45,60,75,90]
if random_num in random_list:
self.bullet_list.append(enemyBullet(self.screen, self.x, self.y))
def move(self): #让敌机自动移动
if self.times % 2 == 0:
self.x += 5
else:
self.x -= 5
if self.x >= 430 or self.x <= 0:
self.times += 1
def destroyed(self, user_Plane):
if self.destroy_director == 0:
for bullet in user_Plane.bullet_list:
if (bullet.x > self.x and bullet.x < (self.x + 45)) and (bullet.y > self.y and bullet.y < (self.y + 33)):
user_Plane.bullet_list.remove(bullet)
self.image = pygame.image.load("./feiji/enemy0_down1.png")
self.destroy_director = 1
else:
self.destroy_director += 1
if self.destroy_director == 4:
self.image = pygame.image.load("./feiji/enemy0_down2.png")
elif self.destroy_director == 8:
self.image = pygame.image.load("./feiji/enemy0_down3.png")
elif self.destroy_director == 12:
self.image = pygame.image.load("./feiji/enemy0_down4.png")
elif self.destroy_director >= 16:
self.image = pygame.image.load("./feiji/point.png")
return 1
def monitor_keyboard_userplane(userplane): #监测键盘以及鼠标点击
global keydown_list
for event in pygame.event.get():
if event.type == QUIT:
exit()
elif event.type == KEYDOWN:
if event.key == K_LEFT and userplane.x >= 0: #检测按键并规定不能出界
if keydown_list[0] == 0:
keydown_list[0] = K_LEFT
else:
keydown_list.append(K_LEFT)
elif event.key == K_RIGHT and (userplane.x + 100) <= 480:
if keydown_list[0] == 0:
keydown_list[0] = K_RIGHT
else:
keydown_list.append(K_RIGHT)
elif event.key == K_DOWN and (userplane.y + 120) <= 700:
if keydown_list[0] == 0:
keydown_list[0] = K_DOWN
else:
keydown_list.append(K_DOWN)
elif event.key == K_UP and userplane.y >= 0:
if keydown_list[0] == 0:
keydown_list[0] = K_UP
else:
keydown_list.append(K_UP)
elif event.key == K_SPACE: #检测空格键,开火
userplane.fire()
elif event.key == K_ESCAPE: #检测退出键
exit()
elif event.type == KEYUP:
if (event.key == K_LEFT or event.key == K_RIGHT or event.key == K_UP or event.key == K_DOWN) and len(keydown_list) > 1:
keydown_list.remove(event.key)
elif (event.key == K_LEFT or event.key == K_RIGHT or event.key == K_UP or event.key == K_DOWN) and len(keydown_list) == 1:
keydown_list[0] = 0
def realMove(userplane):
if keydown_list[-1] == K_LEFT and userplane.x >= 0:
userplane.x -= 6
elif keydown_list[-1] == K_RIGHT and (userplane.x + 100) <= 480:
userplane.x += 6
elif keydown_list[-1] == K_DOWN and (userplane.y + 120) <= 700:
userplane.y += 6
elif keydown_list[-1] == K_UP and userplane.y >= 0:
userplane.y -= 6
def main():
screen = pygame.display.set_mode((480, 700), 0, 32) #创建一个480*700尺寸的窗口
background = pygame.image.load("./feiji/background.png") #导入背景图片
enemyplane_list = []
userplane_list = []
bonus_list = []
user_plane = user_Plane(screen) #创建玩家飞机
userplane_list.append(user_plane) #存储玩家飞机的列表
enemy_plane = enemy_Plane(screen) #创建敌机
enemyplane_list.append(enemy_plane) #存储敌机的列表
bullet_move_variable_user = 12 #敌人和玩家的子弹速度
bullet_move_variable_enemy = 12
score = 0
while True:
screen.blit(background, (0, 0)) #将背景图片贴到窗口上,对齐点是(0,0)点处对齐贴
if len(enemyplane_list) == 0: #若敌机被毁,再创建敌机
score += 1
print "大笨Q,你现在得分是%d分,加油啊" % score
bullet_move_variable_enemy += 1
enemy_plane = enemy_Plane(screen)
enemyplane_list.append(enemy_plane)
user_plane.blit(bullet_move_variable_user) #显示玩家飞机并且显示移动的子弹
user_plane.destroyed(enemy_plane)
if enemy_plane.destroyed(user_plane) != 1: #若敌机被毁,则停止敌机的行动
enemy_plane.move() #敌机自动移动调用
enemy_plane.fire() #敌机发射子弹
enemy_plane.blit(bullet_move_variable_enemy) #显示敌机
if enemy_plane.destroyed(user_plane) == 1: #删除敌机对象时候的条件,否则敌机子弹会立刻消失
if len(enemy_plane.bullet_list) == 0:
del enemy_plane
del enemyplane_list[0]
elif enemy_plane.bullet_list[-1].y > 690:
del enemy_plane
del enemyplane_list[0]
if random.randint(1,300) == 1 and len(bonus_list) == 0: #产生Bonus情况
randx = random.randint(50, 430)
bonus = Bonus(screen, randx, -50, "./feiji/bomb-1.png")
bonus_list.append(bonus)
if len(bonus_list) != 0: #通过bonus改变玩家或者敌机的子弹速度
bonus.move()
bonus.blit()
if user_plane.getBonus(bonus) == 1:
bullet_move_variable_user += 1
bullet_move_variable_enemy -= 1
del bonus_list[0]
elif bonus.missed() == 1:
bullet_move_variable_user -= 1
bullet_move_variable_enemy += 1
del bonus_list[0]
pygame.display.update() #贴完以后不会显示,必须调用update函数更新后才会显示新图
monitor_keyboard_userplane(user_plane) #监测键盘
realMove(user_plane)
time.sleep(0.01)
main()
总体总结:
①我采用的是面向对象的设计方法,创建了多个类,其中还有几个基类让其他类继承以达到减少代码量的目的。
②游戏整体算法采用的都是pygame中的基本操作,因为只是无聊消遣,所以我并没有太深的去探究pygame。
③在处理用户连续的不抬起按键时遇到了一些小问题,采用KEYUP与KEYDOWN结合可以解决这个小问题。
④在敌机摧毁时,如何消除敌机与敌机已经发出的子弹是个小难点。我采用的方法是当敌机被摧毁后,该敌机最后一颗子弹消失 后,再创建出一架新的敌机。
⑤bonus包的下落轨迹我采用随机函数产生随机数来决定,并不是让它直线下落以稍稍增加捡包的难度。
飞机大战基本就是这些内容啦。第一次写游戏,还是值得纪念一下的!!!