无聊消遣——基于pygame库的飞机大战

前一段在数据分析中突然感觉到了一阵阵的空虚寂寞冷,所以我决定小小放松一下,于是萌生出了写一个小游戏的想法。所以在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包的下落轨迹我采用随机函数产生随机数来决定,并不是让它直线下落以稍稍增加捡包的难度。


飞机大战基本就是这些内容啦。第一次写游戏,还是值得纪念一下的!!!


你可能感兴趣的:(无聊消遣——基于pygame库的飞机大战)