Day 11 武装飞船

《外星人入侵》游戏要实现的是:玩家控制一艘出现在屏幕底部中央的飞船,可以使用箭头左右移动飞船,还可以使用空格来进行射击,游戏开始时候一群外星人出现在天空,他们在屏幕中向下移动,玩家的任务是射杀这些外星人,玩家将所有外星人都消灭干净后,会出现一群新的外星人,他们移动的速度会更快,只要外星人撞到了玩家的飞船或者是到达了屏幕底部,玩家就损失一艘飞船,损失三艘以后,游戏结束。

1. 安装Pygame

直接在pycharm里file-setting-添加(我的是无效的)
在这里插入图片描述
我的环境是anaconda+pycharm,安装流程如下
step1:下载pygame http://www.pygame.org/download.shtml
step2:将下载的whl文件剪贴到anaconda\Lib\site-packages目录下,Windows+R打开cmd依次进入文件所在目录,最后输入

pip install pygame-1.9.4-cp37-cp37m-win_amd64.whl

step3:此时应该已经安装完成,可以在cmd中输入 pip list 找一下其中有没有pygame。或者在输入import pygame
在这里插入图片描述

2. 开始游戏项目

2.1 创建Pygame窗口以及响应用户输入

#alien_invasion.py
import pygame
from settings import Settings
from  ship import Ship
import sys

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(screen)
    #开始游戏的主循环
    while True:
        #监视键盘和鼠标事件
        for enevt in pygame.event.get():
            if enevt.type == pygame.QUIT:
                sys.exit()
        screen.fill(ai_settings.bg_color)
        ship.blitme()
        pygame.display.flip()

run_game()

在这里插入图片描述
在这里插入图片描述
在此处代码的实参应为元组而不是int
所以应修改为:
在这里插入图片描述

2.2 设置背景颜色

在Pygame中颜色以RGB值来指定的即红绿蓝,每个值0~255。(255,0,0)表示红色,类推即可。

bg_color = (230,230,230) 

2.3 创建设置类

把游戏添加的新功能引入一些新设置都存在一个Settings类里,便于添加和修改

#settings.py
class Settings():
    def __init__(self):
        self.screen_width = 1000
        self.screen_height = 600
        self.bg_color = (230,230,230)

2.4 添加飞船图像

在Pygame中使用.bmp位图最简单(因为是默认加载位图),加载图像以后用blit()绘制

2.5 创建飞船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()
        self.screen_rect = screen.get_rect()
    #将每艘新飞船放在屏幕底部中央
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom
    def blitme(self):
    #在指定位置绘制飞船
        self.screen.blit(self.image,self.rect)

2.6 在屏幕上绘制飞船

 pygame.display.flip()

在这里插入图片描述

2.7重构:模块game_functions

重构旨在简化既有代码的结构,使其更容易扩展

#game_functions.py
import sys
import pygame

def check_events():
    """响应按键和鼠标事件"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

def update_screen(ai_settings,screen,ship):
    """更新屏幕上的图像并切换到新的屏幕"""
      #每次循环时都重新绘制屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()

对应的alien_invasion.py改变为:

from settings import Settings
from  ship import Ship
import game_functions as gf
from  settings import Settings
import sys

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(screen)
    #开始游戏的主循环
    while True:
        gf.check_events()
        gf.update_screen(ai_settings,screen,ship)

run_game()

2.8 驾驶飞船

1)响应按键:每当用户按键时,都将在Pygame中注册一个事件,事件都是通过方法pygame.event.get()获取的,因此在函数check_events()中,我们需要指定要检查哪些类型的事件,每次按键都被注册为一个KEYDOWN事件,检测到KEYDOWN事件时我们需要检查按下的是否是特定的键。

#game_functions.py
def check_events(ship):
    """响应按键和鼠标事件"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                #向右移动飞船
                ship.rect.centerx += 1

此时check_events()包含形参ship且有检测KEYDOWN时间作出相应,判断是否右移再响应。
2)允许不断移动

#game_functions.py
def check_events(ship):
    """响应按键和鼠标事件"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                #向右移动飞船
                ship.moving_right = True
        elif event.type == pygame.KEYUP: #松开按键即不再右移
            if event.key == pygame.K_RIGHT:
                ship.moving_right = False

3)左右移动

#game_functions.py
def check_events(ship):
    """响应按键和鼠标事件"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                #向右移动飞船
                ship.moving_right = True
            elif event.key == pygame.K_LEFT:
                ship.moving_left = True

        elif event.type == pygame.KEYUP: #松开按键即不再右移
            if event.key == pygame.K_RIGHT:
                ship.moving_right = False
            elif event.key == pygame.K_LEFT: #松开按键即不再右移
                ship.moving_left = False

4)调整飞船的速度
在这里的修改要注意的是rect的centerx等属性只能存储整数值,因此需要使用函数float()将self.rect.centerx的值转换为小数,将结果存到self.center中。在Ship中需要传入实参ai_settings.

5)限制飞船的活动范围
出现的错误:
在这里插入图片描述
错误的原因:
screen 是一个没有 rect 属性的pygame.Surface
代码的书写中有错误!!要细心呐!
在这里插入图片描述
6)重构check_events()

#game_functions.py
def check_keydown_events(event,ship):
    if event.key == pygame.K_RIGHT:
    #向右移动飞船
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
def check_keyup_events(event,ship):
     #松开按键即不再右移
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif 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()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,ship)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event,ship)

def update_screen(ai_settings,screen,ship):
    """更新屏幕上的图像并切换到新的屏幕"""
      #每次循环时都重新绘制屏幕
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()

7)简单回顾
alien_invasion.py: 创建一系列整个游戏都要用到的对象,存储在ai_settings中的设置、存储在screen中主显示surface以及一个飞船实例。包括游戏的主循环,调用check_events()、ship.update()以及update_screen()的while循环
settings.py: 初始化控制游戏外观和飞船速度的属性
game_functions.py: 在这个文件里包含一系列函数,游戏的大部分工作都是由它们完成的,函数check_events()检测相关事件,比如按键和松开,并使用付出函数来处理这些事件,目前这些函数管理飞船的移动。模块还包括update_screen(),用于每次执行主循环的时候都重回屏幕
ship.py: 管理飞船位置的方法以及在屏幕上绘制飞船的方法。

2.9 射击

1)添加子弹设置
2)创建Bullet类
3)将子弹存储到编组中
4)开火
5)删除已消失的子弹
6)限制子弹数量
7)创建函数update_bullets()
8)创建函数fire_bullet()

热门文章

暂无图片
编程学习 ·

NASM系列啊

文章目录NASM是什么?NASM下载与安装 NASM是什么?The Netwide Assembler, 一款基于80x86和x86-64平台的汇编语言编译程序, 是为了实现编译器程序跨平台和模块化的特性。 NASM支持大量的文件格式,包括Linux,*BSD,a.out,ELF,COFF,Mach−O,Microsoft 16−bit OBJ,Win32…
暂无图片
编程学习 ·

2020上半年为你留下了什么?

今天是2020年6月30号,2020年上半年的最后一天.蓦然回首,发现时光过得飞快,记忆中那憋在家里,数着日子,焦虑不安的情景还历历在目.那时候最大的愿望就是像电视中那样:一觉醒来,半年过去了,大家又都按部就班没羞没躁的生活着.好多文人墨客都会鼓吹:每种经历都是人生的财富,人生没…
暂无图片
编程学习 ·

利用BootStrap创建搜索框--」详解

今天学了bootstrap由于官网上没有搜索框,我要做一个网站正好需要,我就自己做了一个搜索框,话不多说直接上代码下面是jsp代码<div class="col-sm-5" id="so"><div class="input-group"><input type="text" class="…
暂无图片
编程学习 ·

Java-eclipse 设置字体字号大小,如何设置居中

文字一般都放在 标签内: 这里以 JLable 与 按钮 为实例: JLabel label; JButton exitBtn; //表题**标签** label = new JLabel("个人停车详情",JLabel.CENTER);//设置字体居中 label.setFont(new Font("微软雅黑", Font.BOLD, 20));//设置字体字号大小 l…
暂无图片
中恒嘉业 ·

[Redux/Mobx] 在Redux中怎么发起网络请求?

[Redux/Mobx] 在Redux中怎么发起网络请求&#xff1f; 如果单纯的使用Redux&#xff0c;因为redux的actionCreator返回一个plain object&#xff0c;所以不能在actionCreator中发起网络请求&#xff1b;reducer是一个纯函数&#xff0c;不能有副作用&#xff0c;所以也不能有异…
暂无图片
中恒嘉业 ·

学习笔记六——循环神经网络

一、RNN 前馈神经网络&#xff1a;信息往一个方向流动。包括MLP和CNN 循环神经网络&#xff1a;信息循环流动&#xff0c;网络隐含层输出又作为自身输入&#xff0c;包括RNN、LSTM、GAN等。 RNN模型结构如下图所示&#xff1a; 展开之后相当于堆叠多个共享隐含层参数的前馈…
暂无图片
郑州普通话 ·

[Redux/Mobx] 在Redux中怎么发起网络请求?

[Redux/Mobx] 在Redux中怎么发起网络请求&#xff1f; 如果单纯的使用Redux&#xff0c;因为redux的actionCreator返回一个plain object&#xff0c;所以不能在actionCreator中发起网络请求&#xff1b;reducer是一个纯函数&#xff0c;不能有副作用&#xff0c;所以也不能有异…
暂无图片
郑州普通话 ·

[Redux/Mobx] Redux和vuex有什么区别?

[Redux/Mobx] Redux和vuex有什么区别&#xff1f; 1&#xff1a;vuex的异步数据不需要使用到中件间&#xff0c;redux需要 2&#xff1a;vuex可以直接commit&#xff0c;action不是必须的&#xff0c;redux是必须的 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知…
暂无图片
代理记账 ·

[Redux/Mobx] 在Redux中怎么发起网络请求?

[Redux/Mobx] 在Redux中怎么发起网络请求&#xff1f; 如果单纯的使用Redux&#xff0c;因为redux的actionCreator返回一个plain object&#xff0c;所以不能在actionCreator中发起网络请求&#xff1b;reducer是一个纯函数&#xff0c;不能有副作用&#xff0c;所以也不能有异…
暂无图片
代理记账 ·

[Redux/Mobx] Redux和vuex有什么区别?

[Redux/Mobx] Redux和vuex有什么区别&#xff1f; 1&#xff1a;vuex的异步数据不需要使用到中件间&#xff0c;redux需要 2&#xff1a;vuex可以直接commit&#xff0c;action不是必须的&#xff0c;redux是必须的 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知…
暂无图片
cgfy ·

学习笔记六——循环神经网络

一、RNN 前馈神经网络&#xff1a;信息往一个方向流动。包括MLP和CNN 循环神经网络&#xff1a;信息循环流动&#xff0c;网络隐含层输出又作为自身输入&#xff0c;包括RNN、LSTM、GAN等。 RNN模型结构如下图所示&#xff1a; 展开之后相当于堆叠多个共享隐含层参数的前馈…
暂无图片
coreui ·

[Redux/Mobx] Redux和vuex有什么区别?

[Redux/Mobx] Redux和vuex有什么区别&#xff1f; 1&#xff1a;vuex的异步数据不需要使用到中件间&#xff0c;redux需要 2&#xff1a;vuex可以直接commit&#xff0c;action不是必须的&#xff0c;redux是必须的 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知…
暂无图片
未来博客 ·

[Redux/Mobx] Redux和vuex有什么区别?

[Redux/Mobx] Redux和vuex有什么区别&#xff1f; 1&#xff1a;vuex的异步数据不需要使用到中件间&#xff0c;redux需要 2&#xff1a;vuex可以直接commit&#xff0c;action不是必须的&#xff0c;redux是必须的 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知…
暂无图片
建站日记 ·

[Redux/Mobx] Redux和vuex有什么区别?

[Redux/Mobx] Redux和vuex有什么区别&#xff1f; 1&#xff1a;vuex的异步数据不需要使用到中件间&#xff0c;redux需要 2&#xff1a;vuex可以直接commit&#xff0c;action不是必须的&#xff0c;redux是必须的 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知…
暂无图片
mfbz ·

[Redux/Mobx] 在Redux中怎么发起网络请求?

[Redux/Mobx] 在Redux中怎么发起网络请求&#xff1f; 如果单纯的使用Redux&#xff0c;因为redux的actionCreator返回一个plain object&#xff0c;所以不能在actionCreator中发起网络请求&#xff1b;reducer是一个纯函数&#xff0c;不能有副作用&#xff0c;所以也不能有异…
暂无图片
mfbz ·

学习笔记六——循环神经网络

一、RNN 前馈神经网络&#xff1a;信息往一个方向流动。包括MLP和CNN 循环神经网络&#xff1a;信息循环流动&#xff0c;网络隐含层输出又作为自身输入&#xff0c;包括RNN、LSTM、GAN等。 RNN模型结构如下图所示&#xff1a; 展开之后相当于堆叠多个共享隐含层参数的前馈…
暂无图片
珊珊日记 ·

学习笔记六——循环神经网络

一、RNN 前馈神经网络&#xff1a;信息往一个方向流动。包括MLP和CNN 循环神经网络&#xff1a;信息循环流动&#xff0c;网络隐含层输出又作为自身输入&#xff0c;包括RNN、LSTM、GAN等。 RNN模型结构如下图所示&#xff1a; 展开之后相当于堆叠多个共享隐含层参数的前馈…
暂无图片
珊珊日记 ·

AOV网是否存在回路-拓扑排序-C++

拓扑排序是对测试AOV网是否存在回路的方法&#xff01; 拓扑排序的过程中&#xff0c;由于需要查找所有以某顶点为尾的弧&#xff0c;即找到该顶点的所有出边&#xff0c;故图要采用邻接表的存储方式。但拓扑排序较邻接表的存储方式有一点不同&#xff0c;由于要查找入度为0的点…