python快速编程入门飞机大战_Python入门项目_飞机大战

Python实现飞机大战的新手练习项目。

目前看了一个月左右的Python入门教程,推荐图灵教材《Python编程 - 从入门到实践》,看完基础的语法部分,可以开始做一些小项目的练手,进一步巩固基础知识。

飞机大战是一个有趣而又可以综合运用入门语法的项目。该项目非常能训练入门时的逻辑思维,对初级的语法有相对全面的运用。尤其是首次学习中遇到的“类”,对于自己这种编程新手来说比较抽象,该项目有很多类的使用,跟着教材进行编写,同时融入自己的创意,一个项目下来,能基本掌握类的使用。

现公布自己编写的源代码如下,与有兴趣学习的朋友共享。

启动游戏画面如下:v2-2318cddb8f0b64b4bc0f39d02fb47039.jpghttps://www.zhihu.com/video/1221594693538430976

模块一:主程序 ——综合调用各子模块

import pygame

from setting import Setting

from rocket import Rocket

import game_functions as gf

from pygame.sprite import Group

from game_stats import GameStats

from button import Button

from scoreboard import Scoreboard

def run_game():

# 初始化游戏并创建一个屏幕对象

pygame.init()

game_setting = Setting()

screen = pygame.display.set_mode((game_setting.width, game_setting.height))

pygame.display.set_caption("UFO Fight......Developed by Hansen")

play_button = Button(screen, "PLAY GAME")

# 创建一艘火箭

rocket = Rocket(screen, game_setting)

# 创建存储子弹的编组

bullets = Group()

# 创建外星人

aliens = Group()

# 创建一个用于存储统计信息的实例, 并创建记分牌

stats = GameStats(game_setting)

sb = Scoreboard(game_setting, screen, stats)

# 开始游戏主循环

while True:

gf.check_events(rocket, game_setting, screen, bullets, stats, play_button,

aliens, sb)

if stats.game_active:

rocket.update()

gf.update_bullet(rocket, bullets, aliens, stats, game_setting, sb)

gf.update_alien(aliens, rocket, stats, bullets, game_setting, screen,

sb)

# 设定创建一个alien的速率

stats.program_run += 1

if stats.program_run % game_setting.alien_generate == 0:

gf.create_alien(rocket, game_setting, screen, aliens, stats)

gf.update_screen(screen, game_setting, rocket, bullets, aliens, stats,

play_button, sb)

run_game()

模块二:创建可以自由移动的飞船类(程序中命名为Rocket)

import pygame

from pygame.sprite import Sprite

class Rocket(Sprite):

def __init__(self, screen, game_setting):

"""初始化飞船"""

super().__init__()

self.screen = screen

self.game_setting = game_setting

# 加载火箭图片并获得外接矩形

self.image = pygame.image.load('images/rocket.png')

self.rect = self.image.get_rect()

self.screen_rect = self.screen.get_rect()

# 将火箭放在屏幕底部

self.rect.centerx = self.screen_rect.centerx

self.rect.bottom = self.screen_rect.bottom

# 移动判别标志

self.moving_right = False

self.moving_left = False

self.moving_up = False

self.moving_down = False

# 在火箭的属性center中存储小数值

self.center = float(self.rect.centerx)

# 在火箭的属性bottom中存储小数值

self.bottom = float(self.rect.bottom)

def update(self):

# 控制左右移动并限制移动边界

if self.moving_right and self.rect.right < self.screen_rect.right:

self.center += self.game_setting.rocket_speed

if self.moving_left and self.rect.left > 0:

self.center -= self.game_setting.rocket_speed

# 控制上下移动并限制移动边界

if self.moving_up and self.rect.top > 0:

self.bottom -= self.game_setting.rocket_speed

if self.moving_down and self.rect.bottom < self.screen_rect.bottom:

self.bottom += self.game_setting.rocket_speed

# 根据self.center更新rect对象

self.rect.centerx = self.center

# 根据self.middle更新rect对象

self.rect.bottom = self.bottom

def blitme(self):

self.screen.blit(self.image, self.rect)

def set_center(self):

"""让飞船在屏幕上居中"""

self.center = self.screen_rect.centerx

self.bottom = self.screen_rect.bottom

模块三:创建准备从飞船发射的子弹类

import pygame

from pygame.sprite import Sprite

class Bullet(Sprite):

def __init__(self, game_setting, rocket, screen):

super().__init__()

self.screen = screen

# 在(0,0)位置创建表示子弹的矩形,并设置其位置到火箭发射处

self.rect = pygame.Rect(0, 0, game_setting.bullet_width,

game_setting.bullet_height)

self.rect.centerx = rocket.rect.centerx

self.rect.top = rocket.rect.top

# 加载子弹颜色和速度参数

self.color = game_setting.bullet_color

self.speed = game_setting.bullet_speed

# 在子弹的Y轴方向设置浮点型存储值,可以更精准移动

self.Y = float(self.rect.top)

# 管理子弹的位置

def update(self):

self.Y -= self.speed

# 更新子弹在Y方向的位置

self.rect.top = self.Y

# 在屏幕中画出子弹

def draw_bullet(self):

pygame.draw.rect(self.screen, self.color, self.rect)

模块四:创建随机从屏幕上出现的外星飞船类

import pygame

from pygame.sprite import Sprite

class Alien(Sprite):

def __init__(self, rocket, game_setting, screen, stats):

super().__init__()

self.screen = screen

self.game_setting = game_setting

self.stats = stats

# 加载Alien图片并获得外接矩形

self.image = pygame.image.load('images/alien.png')

self.rect = self.image.get_rect()

# 加载alien移动速度

self.speed = game_setting.alien_speed

# 绘制alien, 让其在水平轴线上随机出现,与画面上边框距离为火箭的高度

self.rect.x = self.rect.width

self.rect.y = 50

self.x = float(self.rect.x)

self.y = float(self.rect.y)

def update(self):

# 更新alien在Y轴的位置

self.y += self.speed * \

pow(self.game_setting.speedup_scale, (self.stats.game_level - 1))

self.rect.y = self.y

def blitme(self):

# 在指定位置绘制alien

self.screen.blit(self.image, self.rect)

模块五:创建游戏开始和结束时出现在屏幕的启动按钮

import pygame.ftfont

class Button():

def __init__(self, screen, msg):

"""初始化按钮属性"""

self.screen = screen

self.screen_rect = screen.get_rect()

# 设置按钮的属性

self.width, self.height = 220, 50

self.button_color = (65, 65, 65)

self.text_color = (255, 255, 255)

self.font = pygame.font.SysFont(None, 48)

# 创建按钮并在屏幕居中

self.rect = pygame.Rect(0, 0, self.width, self.height)

self.rect.center = self.screen_rect.center

# 按钮标签只需创建一次

self.prep_msg(msg)

def prep_msg(self, msg):

"""将msg渲染为图像,并使其在按钮上居中"""

self.msg_image = self.font.render(msg, True, self.text_color,

self.button_color)

self.msg_image_rect = self.msg_image.get_rect()

self.msg_image_rect.center = self.rect.center

def draw_button(self):

# 绘制一个用颜色填充的按钮,再绘制文本

self.screen.fill(self.button_color, self.rect)

self.screen.blit(self.msg_image, self.msg_image_rect)

模块六:创建用于记录游戏中得分的信息库

import pygame.ftfont

class Scoreboard():

"""显示得分信息的类"""

def __init__(self, game_setting, screen, stats):

"""初始化得分涉及的属性"""

self.game_setting = game_setting

self.stats = stats

self.screen = screen

self.screen_rect = screen.get_rect()

self.max_point = 0

# 显示得分信息时使用的字体设置

self.text_color = (30, 30, 30)

self.text_color_maxpoint = (125, 215, 60)

self.font = pygame.font.SysFont(None, 36)

self.font_rocket_left = pygame.font.SysFont(None, 60)

# 渲染得分的图像

self.prep_score()

# 显示游戏等级

self.prep_game_level()

def prep_score(self):

"""将得分转化为一幅渲染的图像"""

# 显示前置"Point: "

score_prompt = "Point: " + str(self.stats.score)

self.score_prompt_image = self.font.render(score_prompt, True,

self.text_color, self.game_setting.bg_color)

self.score_prompt_rect = self.score_prompt_image.get_rect()

self.score_prompt_rect.right = self.screen_rect.right - 10

self.score_prompt_rect.top = 0

# 在屏幕上显示得分

self.screen.blit(self.score_prompt_image, self.score_prompt_rect)

def prep_game_level(self):

"""将游戏等级显示在画面中"""

# 显示前置"Level: "

level_prompt = "Level: " + str(self.stats.game_level)

self.level_prompt_image = self.font.render(level_prompt, True,

self.text_color,

self.game_setting.bg_color)

self.level_prompt_rect = self.level_prompt_image.get_rect()

self.level_prompt_rect.right = self.screen_rect.right - 10

self.level_prompt_rect.top = self.score_prompt_rect.bottom + 5

# 在屏幕上显示游戏等级

self.screen.blit(self.level_prompt_image, self.level_prompt_rect)

def prep_max_point(self):

"""在屏幕上显示最高得分"""

# 设置属性

self.max_point_str = "Highest Point: " + str(self.max_point)

self.max_point_str_image = self.font.render(self.max_point_str, True,

self.text_color_maxpoint, self.game_setting.bg_color)

# 将得分放在屏幕右上角

self.max_point_str_rect = self.max_point_str_image.get_rect()

self.max_point_str_rect.x = self.screen_rect.centerx - 100

self.max_point_str_rect.y = 0

# 绘制最高得分

self.screen.blit(self.max_point_str_image, self.max_point_str_rect)

模块七:创建用于程序中各项参数的设定

class Setting():

"""存储游戏所有的设置类"""

def __init__(self):

# 游戏屏幕设置

self.width = 700

self.height = 620

self.bg_color = (255, 255, 255)

# 火箭移动速度设置

self.rocket_speed = 0.8

# 剩余火箭数量

self.rocket_limit = 3

# 子弹参数设置

self.bullet_width = 3

self.bullet_height = 12

self.bullet_speed = 0.8

self.bullet_color = (60, 60, 60)

self.qty_allowed = 4

# Alien的设置

# alien 向下移动速度

self.alien_speed = 0.04

# 生成alien的速度

self.alien_generate = 600

# 以什么样的速度加快alien的节奏

self.speedup_scale = 1.1

# 击中每个alien的得分

self.alien_points = 50

模块八:存储游戏过程中各变量的状态

class GameStats():

"""跟踪游戏的统计信息"""

def __init__(self, game_setting):

"""初始化统计信息"""

self.game_setting = game_setting

self.reset_stats()

self.program_run = 0

self.aliens_kill = 0

def reset_stats(self):

"""初始化游戏运行期间可能变化的统计信息"""

self.rocket_left = self.game_setting.rocket_limit

self.score = 0

self.game_level = 1

self.aliens_kill = 0

# 刚启动时游戏处于活动状态

self.game_active = False

self.program_run = 0

模块九:存储游戏主程序中调用的各函数及其子函数

import sys

import pygame

from bullet import Bullet

from alien import Alien

import random

from time import sleep

import math

import json

def check_events(rocket, game_setting, screen, bullets, stats, play_button,

aliens, sb):

# 监视键盘和鼠标事件

for event in pygame.event.get():

if event.type == pygame.QUIT:

# 关闭游戏窗口时,记录最高得分

max_point_write(sb)

sys.exit()

elif event.type == pygame.KEYDOWN:

check_keydown_events(rocket, event, game_setting, screen, bullets,

stats, sb)

elif event.type == pygame.KEYUP:

check_keyup_events(rocket, event)

elif event.type == pygame.MOUSEBUTTONDOWN:

mouse_x, mouse_y = pygame.mouse.get_pos()

check_play_button(stats, play_button, aliens, bullets, rocket,

game_setting, screen, mouse_x, mouse_y)

# 单击开始游戏时,加载最高得分

max_point_load(sb)

def check_play_button(stats, play_button, aliens, bullets, rocket, game_setting,

screen, mouse_x, mouse_y):

button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)

# 当游戏处于静态时,才可以check button状态

if not stats.game_active and button_clicked:

# 隐藏光标

pygame.mouse.set_visible(False)

if play_button.rect.collidepoint(mouse_x, mouse_y):

# 重置游戏统计信息

stats.reset_stats()

stats.game_active = True

# 清空alien列表和bullet列表

aliens.empty()

bullets.empty()

# 创建新的aliens,并让rocket居中

create_alien(rocket, game_setting, screen, aliens, stats)

rocket.set_center()

def check_keydown_events(rocket, event, game_setting, screen, bullets, stats, sb):

if event.key == pygame.K_RIGHT:

rocket.moving_right = True

elif event.key == pygame.K_LEFT:

rocket.moving_left = True

elif event.key == pygame.K_UP:

rocket.moving_up = True

elif event.key == pygame.K_DOWN:

rocket.moving_down = True

elif event.key == pygame.K_SPACE:

if len(bullets) < game_setting.qty_allowed + stats.game_level:

new_bullet = Bullet(game_setting, rocket, screen)

bullets.add(new_bullet)

elif event.key == pygame.K_q:

# 按'q'键退出时,记录最高得分

max_point_write(sb)

sys.exit()

def check_keyup_events(rocket, event):

if event.key == pygame.K_RIGHT:

rocket.moving_right = False

elif event.key == pygame.K_LEFT:

rocket.moving_left = False

elif event.key == pygame.K_UP:

rocket.moving_up = False

elif event.key == pygame.K_DOWN:

rocket.moving_down = False

def update_screen(screen, game_setting, rocket, bullets, aliens, stats,

play_button, sb):

# 每次循环时重绘屏幕

screen.fill(game_setting.bg_color)

rocket.blitme()

for bullet in bullets.sprites():

bullet.draw_bullet()

aliens.draw(screen)

# 显示得分

sb.prep_score()

# 显示最高得分

check_largest_point(stats, sb)

# 显示游戏等级

sb.prep_game_level()

# 绘制剩余rocket

prep_rocket(stats, sb, game_setting, screen)

# 如果游戏处于非活动状态,就绘制按钮

if not stats.game_active:

play_button.draw_button()

# 提升游戏难度等级

level_up(stats, aliens, bullets, rocket, game_setting, screen)

# 绘制屏幕并显示

pygame.display.flip()

def update_bullet(rocket, bullets, aliens, stats, game_setting, sb):

# 更新每一颗子弹的位置

bullets.update()

# 删除消失的子弹

for bullet in bullets.copy():

if bullet.rect.bottom < rocket.rect.height:

bullets.remove(bullet)

# 检测子弹是否击中alien,若击中,则删除相应的子弹和alien

collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)

# 若子弹击中alien,则计入加分

if collisions:

stats.score += game_setting.alien_points

sb.prep_score()

stats.aliens_kill += 1

def update_alien(aliens, rocket, stats, bullets, game_setting, screen, sb):

# 更新alien在Y轴方向的位置

aliens.update()

if pygame.sprite.spritecollideany(rocket, aliens):

rocket_hit(stats, aliens, bullets, rocket, game_setting, screen)

check_alien_bottom(stats, aliens, bullets, rocket, game_setting, screen)

def create_alien(rocket, game_setting, screen, aliens, stats):

alien = Alien(rocket, game_setting, screen, stats)

available_space_x = game_setting.width - 2 * alien.rect.width

number_alien_x = math.floor(available_space_x / (alien.rect.width * 1.5))

# 创建在X轴方向上随机出现的alien

alien = Alien(rocket, game_setting, screen, stats)

index = random.randint(0, number_alien_x)

alien.x = alien.rect.width + (alien.rect.width * 1.5) * index

alien.rect.x = alien.x

aliens.add(alien)

def prep_rocket(stats, sb, game_setting, screen):

rocket_pits = 'A'

for rocket in range(stats.rocket_left):

for rocket_pit in rocket_pits:

rocket_pit_image = sb.font_rocket_left.render(rocket_pit, True,

sb.text_color,

game_setting.bg_color)

rocket_pit_image_rect = rocket_pit_image.get_rect()

rocket_pit_image_rect.x = (rocket_pit_image_rect.width + 5) * rocket

rocket_pit_image_rect.y = 0

screen.blit(rocket_pit_image, rocket_pit_image_rect)

def rocket_hit(stats, aliens, bullets, rocket, game_setting, screen):

if stats.rocket_left > 0:

# alien和rocket撞击后,rocket的数量减1

stats.rocket_left -= 1

# 清空外星人和子弹列表

aliens.empty()

bullets.empty()

# 暂停1秒

sleep(1)

# 重新创建alien

create_alien(rocket, game_setting, screen, aliens, stats)

# 重新创建飞船

rocket.set_center()

# 单个等级击杀的alien清零

stats.aliens_kill = 0

else:

stats.game_active = False

pygame.mouse.set_visible(True)

def check_alien_bottom(stats, aliens, bullets, rocket, game_setting, screen):

"""侦测是否有alien达到屏幕底端"""

screen_rect = screen.get_rect()

for alien in aliens.sprites():

if alien.rect.bottom >= screen_rect.bottom:

# 若达到屏幕底端,则当作与rocket撞击

rocket_hit(stats, aliens, bullets, rocket, game_setting, screen)

break

def level_up(stats, aliens, bullets, rocket, game_setting, screen):

if stats.aliens_kill >= 30:

# 等级数字提升

stats.game_level += 1

# 清空外星人和子弹列表

aliens.empty()

bullets.empty()

# 重新创建alien

create_alien(rocket, game_setting, screen, aliens, stats)

# 重新创建飞船

rocket.set_center()

# 暂停1秒

sleep(1)

# 单个等级击杀的alien清零

stats.aliens_kill = 0

def check_largest_point(stats, sb):

"""检查是否诞生了最高分"""

if sb.max_point < stats.score:

sb.max_point = stats.score

sb.prep_max_point()

def max_point_write(sb):

"""记录最高得分到文件中"""

filename = 'max_point.json'

with open(filename, 'w') as f_object:

json.dump(sb.max_point, f_object)

def max_point_load(sb):

"""从文件中加载最高得分"""

filename = 'max_point.json'

with open(filename) as f_object:

sb.max_point = json.load(f_object)

程序完成。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值