Python 小白学习之路(项目一 外星人入侵)

《python编程 从入门到实践》图林程序设计丛书 学习笔记

项目一 外星人入侵

  • pygame中的几个模块

    1> display模块

    pygame.display.set_mode(resolution=(0,0),flags=0,depth=0)

    返回的是一个surface对象,resolution控制窗口大小,flags是扩展选项,depath一般不设置

    2> pygame.display.get_caption()获得窗口的标题

    3> pygame.event.get()监视键盘和鼠标事件

    4> pygame.display.flip()让最近绘制的屏幕可见

    5> run_game()初始化游戏并进入主循环

    6> screen.fill(color) 绘制屏幕颜色,只接受一个参数:表示颜色的RGB

    7> get_rect() 获取相应的surface 的属性 rect

    ​ 要将元素居中,可设置相应对象的属性centercenterxcentery

    ​ 要将元素与屏幕边缘对齐,可设置相应对象的属性topbottomleftright

    ​ 要调整游戏元素水平或者垂直位置,可使用属性xy

    8> pygame.image.load()加载图像,传递参数为图像位置

(一)武装飞船
1,开始游戏项目
  • 创建Pygame窗口以及响应用户输入
  • 设置背景色

alien_invasion.py

import sys
import pygame

def run_game():
    pygame.init()   #初始化背景设置
    screen = pygame.display.set_mode((1200,700))                #创建显示窗口
    pygame.display.set_caption('Alien Invasion')                #获得窗口标题
    bg_color = (230,230,230)                                    #设置背景颜色
    
    #开始游戏主循环
    while True:

        #监视键盘和鼠标事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        # 如果点击窗口关闭按钮,那么检测到pygame.QUIT时间,调用sys.exit()来退出游戏

        screen.fill(bg_color)       #重绘屏幕
        pygame.display.flip()       #让最近绘制的屏幕可见

run_game()
  • 创建设置类

seetings.py

class Settings:

    def __init__(self):
        #设置屏幕属性:长,宽,颜色
        self.screen_width = 1200
        self.screen_height = 700
        self.bg_color = (230,230,230)

alien_invasion.py

import sys
import pygame

from settings import Settings		# 引用Settings类

def run_game():
    pygame.init()   
    ai_settings = Settings()		# 实例化
    screen =pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height)) #调用
    pygame.display.set_caption('Alien Invasion')                

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        screen.fill(ai_settings.bg_color)       #调用
        pygame.display.flip()      

run_game()
2,添加飞船图像
  • 创建Ship

ship.py

import pygame
class Ship():

    def __init__(self,screen):
        self.screen = screen
        self.image = pygame.image.load('images/ship.bmp')   # 加载图像
        self.rect = self.image.get_rect()                   # get_rect() 来获取图像属性
        self.screen_rect = screen.get_rect()   # get_rect() 来获取屏幕属性,存储在 self.screen_rect
        self.rect.centerx = self.screen_rect.centerx        # 设置图像元素横轴位置
        self.rect.bottom = self.screen_rect.bottom          # 设置图像元素纵轴位置

    def blitme(self):                                # 定义函数根据 self.rect 指定的位置将图像绘制到屏幕上
        self.screen.blit(self.image,self.rect)
  • 在屏幕上绘制飞船

alien_invasion.py

   --snip--
from settings import Settings
from ship import Ship									#引用Ship类中的ship函数

def run_game():
   --snip--
    pygame.display.set_caption('Alien Invasion')
    ship = Ship(screen)										#创建一艘飞船
    
   --snip--
        screen.fill(ai_settings.bg_color)
        ship.blitme()									#调用ship.blitme(),确保飞船绘制在背景前面
        pygame.display.flip() 

run_game()
3,重构模块:game_fuction
  • 函数check_events()

game_fuction.py

import sys
import pygame

def check_events():

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

alien_invasion.py

--snip--
from ship import Ship
import game_fuction as gf

--snip--
    while True:
        # for event in pygame.event.get():			#gf.check_events()重构主程序for循环
        #     if event.type == pygame.QUIT:
        #         sys.exit()
        gf.check_events()
        
--snip--
run_game()
  • 函数update_screen()

game_fuction.py

--snip--
def check_events(ship):
--snip--
def update_screen(ai_settings, screen, ship):

    screen.fill(ai_settings.bg_color)  # 重绘屏幕
    ship.blitme()
    pygame.display.flip()       #让最近绘制的屏幕可见
4,驾驶飞船
  • 相应按键

  • 允许不断移动

  • 调整飞船速度

  • 限制飞船活动范围

ship.py

--snip--
def update(self):
    #更新飞船的center值而不是rect
    if self.moving_right and self.rect.right < self.screen_rect.right:  #限制飞船活动范围 1
        self.center += self.ai_settings.ship_speed_factor
        
    if self.moving_left and  self.rect.left > 0:                         #限制飞船活动范围 2
        self.center -= self.ai_settings.ship_speed_factor
--snip--
  • 重构 check_event()

game_fuction.py

import sys
import pygame


def check_keydown_event(event, ship):       #keydown事件
    # 左右移动
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True


def check_keyup_event(event, ship):			#keyup事件
        if event.key == pygame.K_RIGHT:
            ship.moving_right = False
        if event.key == pygame.K_LEFT:
            ship.moving_left = False


def check_events(ship):

    # 监视键盘和鼠标事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    # 如果点击窗口关闭按钮,那么检测到pygame.QUIT时间,调用sys.exit()来退出游戏
        if event.type == pygame.KEYDOWN:
            check_keydown_event(event, ship)
        elif event.type == pygame.KEYUP:
            check_keyup_event(event, ship)


def update_screen(ai_settings, screen, ship):

    screen.fill(ai_settings.bg_color)  # 重绘屏幕
    ship.blitme()
    pygame.display.flip()       #让最近绘制的屏幕可见
5,射击
  • 添加子弹设置

bullet.py

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):

    def __init__(self,ai_settings,screen,ship):
        super(Bullet,self).__init__()           #调用super继承Sprite类
        self.screen = screen
        self.rect = pygame.Rect(0,0,ai_settings.bullet_width,ai_settings.bullet_height)
        self.rect.centerx = ship.rect.centerx
        self.rect.top = ship.rect.top
        self.y = float(self.rect.y)
        self.color = ai_settings.bullet_color
        self.speed_factor = ai_settings.bullet_speed_factor

        def update(self):
            self.y -= self.speed_factor
            self.rect.y = self.y
       
        def draw_buttle(self):
            pygame.draw.rect(self.screen,self.color,self.rect)
  • 将子弹存储在编组中

aline_invasion.py

--snip--
import pygame
from pygame.sprite import Group
--snip--
def run_game():
   --snip--
    bullets = Group()

    --snip--
    while True:
        gf.check_events(ai_settings,screen,ship,bullets)
        ship.update()
        bullets.update()
        gf.update_screen(ai_settings,screen,ship,bullets)
run_game()
  • 开火
  • 删除已消失的子弹
  • 限制子弹的数量
  • 创建函数 update_bullets() & fire_bullet()
第一部分完整代码

alien_invasion.py

import sys
import pygame
from pygame.sprite import Group
from settings import Settings
from ship import Ship
import game_fuction as gf

def run_game():
    pygame.init()   #初始化背景设置
    ai_settings = Settings()
    screen =pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption('Alien Invasion')                #获得窗口标题
    ship = Ship(ai_settings,screen)                 #创建飞船
    bullets = Group()

    #开始游戏主循环
    while True:

        gf.check_events(ai_settings,screen,ship,bullets)
        ship.update()
        gf.update_bullets(bullets)
        gf.update_screen(ai_settings,screen,ship,bullets)


run_game()

settings.py

class Settings:

    def __init__(self):
        self.screen_width = 1000
        self.screen_height = 500
        self.bg_color = (230,230,230)

        self.ship_speed_factor = 1.5   #设置飞船的速度 1

        self.bullet_speed_factor = 1
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 60,60,60
        self.bullets_allowed = 3    #限制子弹数量

ship.py

import pygame

class Ship():

    def __init__(self,ai_settings,screen):
        self.screen = screen
        self.ai_settings = ai_settings        #设置飞船的速度 2

        self.image = pygame.image.load('images/ship.bmp')   # 加载图像
        self.rect = self.image.get_rect()                   # get_rect() 来获取图像属性
        self.screen_rect = screen.get_rect()   # get_rect() 来获取屏幕属性,存储在 self.screen_rect

        self.rect.centerx = self.screen_rect.centerx        # 设置图像元素横轴位置
        self.rect.bottom = self.screen_rect.bottom          # 设置图像元素纵轴位置

        self.center = float(self.rect.centerx)     #设置飞船的速度 3 (在飞船的属性center中存储小数值)
        self.moving_right = False
        self.moving_left = False

    def update(self):
        #更新飞船的center值而不是rect
        if self.moving_right and self.rect.right < self.screen_rect.right: #限制飞船活动范围 1
            self.center += self.ai_settings.ship_speed_factor
            #self.rect.centerx += 1
        if self.moving_left and  self.rect.left > 0:                        #限制飞船活动范围 2
            self.center -= self.ai_settings.ship_speed_factor
            #self.rect.centerx -= 1

        #根据self.center更新rect对象
        self.rect.centerx = self.center


    def blitme(self):                           # 定义函数根据 self.rect 指定的位置将图像绘制到屏幕上
        self.screen.blit(self.image,self.rect)

game_fuction.py

import sys
import pygame
from bullet import Bullet

def check_keydown_event(event,ai_settings,screen,ship,bullets):           #keydown 事件
    # 左右移动
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    elif event.key == pygame.K_SPACE:
        fire_bullet(ai_settings,screen,ship,bullets)


def fire_bullet(ai_settings,screen,ship,bullets):

    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings,screen,ship)
        bullets.add(new_bullet)


def check_keyup_event(event, ai_settings,screen,ship,bullets):             #keyup事件
        if event.key == pygame.K_RIGHT:
            ship.moving_right = False
        if event.key == pygame.K_LEFT:
            ship.moving_left = False


def check_events(ai_settings,screen,ship,bullets):

    # 监视键盘和鼠标事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    # 如果点击窗口关闭按钮,那么检测到pygame.QUIT时间,调用sys.exit()来退出游戏
        if event.type == pygame.KEYDOWN:
            check_keydown_event(event, ai_settings, screen, ship, bullets)

        elif event.type == pygame.KEYUP:
            check_keyup_event(event, ai_settings, screen, ship, bullets)


def update_screen(ai_settings, screen, ship,bullets):

    screen.fill(ai_settings.bg_color)  # 重绘屏幕
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    pygame.display.flip()       #让最近绘制的屏幕可见


def update_bullets(bullets):
    bullets.update()

    #删除已消失子弹
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)

bullet.py

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):

    def __init__(self,ai_settings,screen,ship):
        super(Bullet,self).__init__()           #调用super继承Sprite类
        self.screen = screen

        self.rect = pygame.Rect(0,0,ai_settings.bullet_width,ai_settings.bullet_height)
        self.rect.centerx = ship.rect.centerx
        self.rect.top = ship.rect.top
        self.y = float(self.rect.y)

        self.color = ai_settings.bullet_color
        self.speed_factor = ai_settings.bullet_speed_factor


    def update(self):
        #向上移动子弹
        self.y -= self.speed_factor  #更新表示子弹位置的小数值
        self.rect.y = self.y         ##更新表示子弹rect的位置


    def draw_bullet(self):
        #在屏幕上绘制子弹
        pygame.draw.rect(self.screen,self.color,self.rect)
(二)外星人
1,创建第一个外星人
2,创建一群外星人
3,让外星人群移动
4,射杀外星人
5,结束游戏
(三)记分
1,添加play按钮
2,提高等级
3,记分
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值