Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

系列文章目录

  1. 项目准备
  2. 使用pygame 创建图形窗口
  3. 理解图像并实现图像绘制
  4. 理解游戏循环 和 游戏时钟
  5. 理解精灵 和精灵组

前言

今天是空战更新备战,前天紧随其后:

[En]

Today is the update and preparation for the aircraft war, followed by the day before yesterday:

  1. 理解图像并实现图像绘制

  2. 理解游戏循环 和 游戏时钟

三、理解图像并实现图像绘制

在游戏中,可以看到的游戏元素大多是图像。

[En]

In the game, most of the game elements that can be seen are images.

图像文件 初始 是保存在磁盘上的,如果需要使用,第一步 就是需要被加载到内存

·要在屏幕上 看到某一个图像的内容,需要按照三个步骤:

  1. 使用 pygame.image.load() 加载图像的数据
  2. 使用游戏屏幕 对象,调用blit 方法将图像绘制到指定位置
  3. 调用pygame.display.update()方法更新整个屏幕的显示

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

提示:要想在屏幕上看到绘制的结果,就一定要调用pygame.display.update()方法

代码演练1——绘制背景图像

需求

  1. 加载 background.png 创建背景
  2. 将背景绘制到屏幕的(0, 0)位置
  3. 调用屏幕更新显示背景图像

操作:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

代码:

import pygame

pygame.init()

# 创建游戏的窗口
screen = pygame.display.set_mode((480, 700))

# 绘制背景图像
# 1.加载图像数据
background = pygame.image.load("./images/background.png")
# 2.blit方法 绘制图像
screen.blit(background, (0, 0))
# 3.update 方法更新屏幕显示
pygame.display.update()

while True:
    pass

pygame.quit()

输出结果:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

注意:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

这里 . 表示当前目录,意思就是当前目录下,images下,background图片,从磁盘加载到内存

代码演练2——绘制英雄图像

需求

  1. 加载 me1.png 创建英雄飞机
  2. 将英雄飞机绘制在屏幕的(200, 500)位置
  3. 调用屏幕更新显示飞机图像

透明图像

· png格式的图像是支持透明的

绘制图像时,透明区域不会显示任何内容

[En]

When you draw an image, the transparent area does not display anything

但如果下面已经有内容,它将通过透明区域显示。

[En]

But if there is already content below, it will be displayed through the transparent area.

操作:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

代码:

import pygame

pygame.init()

# 创建游戏的窗口
screen = pygame.display.set_mode((480, 700))

# 绘制背景图像
# 1.加载图像数据
background = pygame.image.load("./images/background.png")
# 2.blit方法 绘制图像
screen.blit(background, (0, 0))
# 3.update 方法更新屏幕显示
pygame.display.update()

# 绘制英雄飞机
hero = pygame.image.load("./images/me1.png")
screen.blit(hero, (200, 500))
pygame.display.update()

while True:
    pass

pygame.quit()

输出结果:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

下面是理解 update()方法的作用

可以在screen 对象完成所有 blit 方法之后统一调用一次 display.update方法,同样也可以看到最终的绘制结果

·使用 display.set_mode() 创建 screen对象 是一个内存中的屏幕数据对象

(可以理解为油画的画布)

[En]

(it can be understood as the canvas of an oil painting)

·screen.blit方法可以在画布上绘制很多图像

例如,英雄、敌机、子弹等。这些图像可能会相互重叠或重叠)

[En]

For example, heroes, enemy planes, bullets, etc. These images may overlap or overlay each other)

·screen.update()会将画布的最终结果 绘制在屏幕上,这样可以提高绘制效率,增加游戏的流畅度

四、理解 游戏循环和游戏时钟

4.1 游戏中动画实现的原理

和电影一样,游戏中的动画效果本质上是在屏幕上快速绘制图像。

[En]

Like movies, the animation effect in the game is essentially to quickly draw images on the screen.

·一般在电脑上每秒绘制60次,就能够达到非常连续高品质的动画效果

(每秒绘制的结果被称为 帧 Frame,意思就是每次调用update 方法的结果,叫做 帧,

要到达一个高品质的效果,每秒钟要调用60次 update 方法)

4.2 游戏循环

游戏的两个组成部分

游戏循环开始 就意味着 游戏正式的开始

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

游戏循环的作用

  1. 保证游戏不会直接退出

  2. 变化图像位置——动画效果

·每隔1/60 秒 移动一下所有图像的位置

·调用 pygame.display.update() 更新屏幕显示

  1. 检测用户交互——按键、鼠标等

4.3 游戏时钟

·pygame 专门提供一个类pygame.time.Clock 可以非常方便的设置屏幕绘制速度——刷新帧率

·要使用时钟对象 需要两步:

  1. 在游戏初始化创建一个时钟对象
  2. 在游戏循环中让时钟对象调用tick(帧率)方法

·tick方法会根据上次被调用的时间,自动设置游戏循环中的延时

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

现在有很多循环,但我们不需要循环这么多次。

[En]

There are a lot of loops now, but we don’t need to loop so many times.

以下是使用时钟设置游戏周期的频率

[En]

The following is the use of the clock to set the game cycle frequency

操作:

把频率设置成每分钟 60次

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

执行的频率就比较合适了

代码:

import pygame

pygame.init()

# 创建游戏的窗口
screen = pygame.display.set_mode((480, 700))

# 绘制背景图像
# 1.加载图像数据
background = pygame.image.load("./images/background.png")
# 2.blit方法 绘制图像
screen.blit(background, (0, 0))

# 绘制英雄飞机
hero = pygame.image.load("./images/me1.png")
screen.blit(hero, (200, 500))

# 可以在所有的绘制工作完成之后,同意调用update方法
pygame.display.update()

# 创建时钟对象
clock = pygame.time.Clock()

# 游戏循环 -> 意味着游戏正式开始
i = 0

while True:

    clock.tick(60)

    print(i)

    i += 1
    pass

pygame.quit()

4.4 英雄的简单动画实现

需求

  1. 在游戏初始化 定义一个pygame.Rect 的变量记录英雄的初始位置
  2. 在游戏循环中,每次让英雄的y-1 ( 向上移动 )
  3. 当y

提示: 每一次调用update方法之前,需要把所有的游戏图像重新绘制一遍

并且应该首先重新绘制背景图像。

[En]

And the background image should be redrawn first.

操作:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

它是在本节中添加的代码绘制的箭头。

[En]

It is the code added in this section that draws the arrow.

代码:

import pygame

pygame.init()

# 创建游戏的窗口
screen = pygame.display.set_mode((480, 700))

# 绘制背景图像
# 1.加载图像数据
background = pygame.image.load("./images/background.png")
# 2.blit方法 绘制图像
screen.blit(background, (0, 0))

# 绘制英雄飞机
hero = pygame.image.load("./images/me1.png")
screen.blit(hero, (200, 500))

# 可以在所有的绘制工作完成之后,同意调用update方法
pygame.display.update()

# 创建时钟对象
clock = pygame.time.Clock()

# 1.定义一个Rect 记录飞机的初始位置
hero_rect = pygame.Rect(150, 300, 102, 126)

# 游戏循环 -> 意味着游戏正式开始
i = 0

while True:
    # 可以指定循环体内部的代码执行的频率
    clock.tick(60)

    # 2.修改飞机的位置
    hero_rect.y -= 1

    # 判断飞机的位置,y

输出结果:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

飞机会向上方缓缓移动

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

当飞机出现并从上方飞出时,它将自动出现在屏幕底部。

[En]

When the plane appears and flies out from above, it will automatically appear at the bottom of the screen.

4.5 在游戏循环中 监听事件

事件 event

也就是说,用户在游戏开始后对游戏做了什么。

[En]

That is, what the user does to the game after the game starts.

例如,单击关闭按钮、单击鼠标、按键盘等。

[En]

For example, click the close button, click the mouse, press the keyboard, etc.

监听

在游戏周期中,判断用户的具体动作

[En]

In the game cycle, judge the specific actions of the user

只有捕捉到用户的具体行为,我们才能有针对性地做出回应。

[En]

Only by capturing the specific actions of the user can we respond pertinently.

代码实现:

·pygame 中通过pygame.event.get()可以获得用户当前所做动作的事件列表

用户可以同时做很多事情

[En]

Users can do a lot of things at the same time

·提示:这段代码非常固定,几乎所有的pygame游戏都大同小异

下面是练习:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

从上面这里开始补充代码

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

(注意:增加if 判断是为了控制台不会输出空白列表)

代码:

import pygame

pygame.init()

# 创建游戏的窗口
screen = pygame.display.set_mode((480, 700))

# 绘制背景图像
# 1.加载图像数据
background = pygame.image.load("./images/background.png")
# 2.blit方法 绘制图像
screen.blit(background, (0, 0))

# 绘制英雄飞机
hero = pygame.image.load("./images/me1.png")
screen.blit(hero, (200, 500))

# 可以在所有的绘制工作完成之后,同意调用update方法
pygame.display.update()

# 创建时钟对象
clock = pygame.time.Clock()

# 1.定义一个Rect 记录飞机的初始位置
hero_rect = pygame.Rect(150, 300, 102, 126)

# 游戏循环 -> 意味着游戏正式开始
i = 0

while True:
    # 可以指定循环体内部的代码执行的频率
    clock.tick(60)

    # 捕获事件
    event_list = pygame.event.get()
    # 增加 if判断,避免控制台输出很多空列表
    if len(event_list) > 0:
        print(event_list)

    # 2.修改飞机的位置
    hero_rect.y -= 1

    # 判断飞机的位置,y

输出结果:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

下面提示的mousemotion 就是代表移动了鼠标,keydown,表示按下键盘,keyup表示手指从键盘抬起等等

下面是监听改进版

目标:

监听用户点击关闭按钮

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

在这里,选择上一个练习中的代码,将其删除,然后重新输入该代码。

[En]

Here, select the code from the previous exercise, delete it, and re-enter the code.

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

在此部分的框中添加的代码

[En]

The code added in the box for this section

(注意:这里增加 for 循环,是为了遍历一下事件列表中发生的每一个事件,来判断发生的事件 是否 是退出事件,如果是,就退出游戏)

代码:

import pygame

pygame.init()

# 创建游戏的窗口
screen = pygame.display.set_mode((480, 700))

# 绘制背景图像
# 1.加载图像数据
background = pygame.image.load("./images/background.png")
# 2.blit方法 绘制图像
screen.blit(background, (0, 0))

# 绘制英雄飞机
hero = pygame.image.load("./images/me1.png")
screen.blit(hero, (200, 500))

# 可以在所有的绘制工作完成之后,同意调用update方法
pygame.display.update()

# 创建时钟对象
clock = pygame.time.Clock()

# 1.定义一个Rect 记录飞机的初始位置
hero_rect = pygame.Rect(150, 300, 102, 126)

# 游戏循环 -> 意味着游戏正式开始
i = 0

while True:
    # 可以指定循环体内部的代码执行的频率
    clock.tick(60)

    # 监听事件
    for event in pygame.event.get():

        # 判断事件类型是否是退出事件
        if event.type == pygame.QUIT:
            print("退出游戏")

            # quit 卸载所有的模块
            pygame.quit()

            # exit() 直接终止当前正在执行的程序
            exit()
    # 2.修改飞机的位置
    hero_rect.y -= 1

    # 判断飞机的位置,y

输出结果:

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

之前点击 退出,窗口是没有反应的,现在点击退出,会直接退出来,同时控制台还会做以下输出

Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)

总结

关于空战的准备工作:

[En]

About the preparations for the aircraft war:

  1. 理解图像并实现图像绘制

  2. 理解游戏循环 和 游戏时钟

这两个内容都已经学过了,然后更新精灵和精灵。

[En]

These two contents have been learned, and then update the elves and elves.

在图像方面,其实和绘画一样,理解它们并不难。

[En]

In terms of images, in fact, it is not difficult to understand them in the same way as painting.

游戏周期和游戏时钟的码感还是比较固定的,通俗易懂。

[En]

The code feeling of the game cycle and the game clock is still relatively fixed and easy to understand.

Original: https://blog.csdn.net/arizia/article/details/127373674
Author: arizia
Title: Python学习日记-第二十二天- 飞机大战项目准备(图像和游戏循环)



相关阅读

Title: ubuntu18.04下,利用shell脚本启动conda虚拟环境,并实现python程序自启动

一、利用shell脚本启动conda虚拟环境
1.创建一个run.sh文件,将.bashrc文件中的conda 相关内容复制到sh文件中,具体内容如下:
(.bashrc文件在root下的home/自己的用户下)
从# >>> conda init >>>开始到# >>> conda init >>>结束


__conda_setup="$(CONDA_REPORT_ERRORS=false '/home/yang/Anaconda/enter/bin/conda' shell.bash hook 2> /dev/null)"
if [ $? -eq 0 ]; then
    \eval "$__conda_setup"
else
    if [ -f "/home/yang/Anaconda/enter/etc/profile.d/conda.sh" ]; then
        . "/home/yang/Anaconda/enter/etc/profile.d/conda.sh"
        CONDA_CHANGEPS1=false conda activate base
    else
        \export PATH="/home/yang/Anaconda/enter/bin:$PATH"
    fi
fi
unset __conda_setup


__conda_setup="$(CONDA_REPORT_ERRORS=false '/home/yang/Anaconda/enter/bin/conda' shell.bash hook 2> /dev/null)"
if [ $? -eq 0 ]; then
    \eval "$__conda_setup"
else
    if [ -f "/home/yang/Anaconda/enter/etc/profile.d/conda.sh" ]; then
        . "/home/yang/Anaconda/enter/etc/profile.d/conda.sh"
        CONDA_CHANGEPS1=false conda activate base
    else
        \export PATH="/home/yang/Anaconda/enter/bin:$PATH"
    fi
fi
unset __conda_setup

conda activate deeplearn

cd /home/yang/DL_YOLO/pythonProject
python testmain.py
exit 0

二、设置开机自启动
1.假如需要开机自启动的程序是一个简单的保存程序 testmain.py


path = '/home/yang/DL_YOLO/pythonProject/data/a.txt'

f = open(path, "w+")

f.write('保存内容')

f.close()

2.检查系统目录/lib/systemd/system/rc-local.service,如果没有自己新建,在文中增加[Install]项的。

新建文件

sudo vi /etc/systemd/system/rc-local.service

[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

[Install]
WantedBy=multi-user.target
Alias=rc-local.service

同样检查/etc/systemd/system/rc-local.service下面的内容,如上修改。
3. 创建rc.local文件

sudo vi /etc/rc.local

echo "看到这行字,说明添加自启动脚本成功。">/usr/local/test.log

bash /home/yang/run.sh
exit 0
sudo chmod +x /etc/rc.local
sudo systemctl enable rc-local
sudo systemctl start rc-local.service
sudo systemctl status rc-local.service

7.查看效果
可以看到/usr/local/test.log文件被创建了,同时查看/home/yang/DL_YOLO/pythonProject/data/a.txt是否文件保存。

Original: https://blog.csdn.net/yang_jl2019/article/details/122145981
Author: yang_jl2019
Title: ubuntu18.04下,利用shell脚本启动conda虚拟环境,并实现python程序自启动

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/344850/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载