分类目录归档:Python 游戏开发

超美!教你用 Python 拍摄游戏延时摄影

为什么要拍摄游戏延时摄影?这个时代,随着游戏引擎技术的快速发展,游戏画面越来越精美,许多人迷上了游戏内的角色、场景。尤其是端游,显卡技术能够支撑精美的游戏画面,最有名的莫过于《地平线》系列游戏。

很多玩家希望拍摄这些精美游戏中的画面,尤其是希望能拍摄到游戏内不同时刻的画面,为了满足这个需求,我们就需要用上延时摄影。游戏内的时间过得比现实世界更快,一个小时内可能你就能经历白天的夜晚的变化,这也为延时摄影提供了很好的环境。

那么究竟怎么在拍摄中实现延时的效果呢?方法大致有两种,最简单的可以先录制视频,然后用后期剪辑软件或者特效软件通过丢帧的方法实现,但这样一来便造成了巨大的浪费。拍几个小时的视频,如果通过丢帧实现延时效果,最后转换为几十分钟的片段,那么被丢掉的帧就要比最后留下的多得多。如果要实现更高速的画面运动,这种浪费无疑将会被更加扩大。

本篇教程介绍第二种方法,定时截图的形式,我们将结合前面Python实用宝典使用过的三个模块——moviepy、win32gui 及 PIL 为大家讲解如何使用Python在游戏中实现延时摄影,我还将教你如何将图片拼接成视频、添加背景音乐一条龙操作。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install moviepy
pip install pypiwin32
pip install pillow

本文所有代码均开源在:https://github.com/Ckend/python-time-lapse-photo 仓库,如果你无法访问GitHub,也可以在Python实用宝典后台回复 延时摄影 下载。

2.游戏延时摄影—定时”拍摄”

为了实现定时拍摄的逻辑,我们需要用到pypiwin32模块和pillow模块,在之前的这篇文章中有介绍过:

超方便的 Python 唤醒窗口自动截图脚本

分为三个步骤:

1. 获得游戏窗口界面

2. 获得游戏界面大小

3. 截图

每隔N秒定时循环执行以上三个步骤,代码如下:

# main.py
# Python实用宝典
# 2022-03-25
import time
import win32gui
from PIL import ImageGrab


def get_window_pos(name):
    name = name
    handle = win32gui.FindWindow(0, name)
    if handle == 0:
        return None
    else:
        return win32gui.GetWindowRect(handle), handle

while True:
    try:
        (x1, y1, x2, y2), handle = get_window_pos('极限竞速:地平线 4')
        win32gui.SetForegroundWindow(handle)
        img_ready = ImageGrab.grab((x1, y1, x2, y2))
        img_ready.save(f"./result/{time.time()}.jpg")
        time.sleep(5)
    except Exception as e:
        print(e)

请注意,”极限竞速:地平线 4″ 要改成你对应拍摄的游戏名称,这样,运行程序后就会自动在result文件夹下定时生成截图:

成功截取你想要的时间段的场景图片后,就可以进行下面的拼接和补充背景音乐部分。

3.拼接延时摄影视频

为了达到延时摄影的效果,我们在这一部分中将使用moviepy模块,拼接所有图片到一个视频中。

当然还要补充背景音乐,代码其实非常简单:

# jointer.py
# Python实用宝典
# 2022-03-25
import os
import moviepy
import moviepy.video.io.ImageSequenceClip
from moviepy.editor import *

def pics2video(frames_dir, video_dst, music, fps=10):
    """
    图片合成MP4

    Args:
        frames_dir (str): 图片目录
        video_dst (str): 目标目录
        fps (int, optional): 帧数. Defaults to 25.
    """
    frames_name = sorted(os.listdir(frames_dir))
    frames_path = [frames_dir+frame_name for frame_name in frames_name]
    clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(frames_path, fps=fps)
    
    audio_clip = AudioFileClip(music).volumex(0.5)
    audio = afx.audio_loop( audio_clip, duration=clip.duration)
    final_video = clip.set_audio(audio)

    final_video.write_videofile(video_dst, codec='libx264')

music = '打上花火.mp3'
frames_dir = './result/'
video_dst = 'screenshots.mp4'
pics2video(frames_dir, video_dst, music)

1.将你的音乐放在当前目录下,修改music变量为对应的文件名。

2.调整你想要的fps参数—帧数,这个值越低,画面越顺畅。

运行此文件后就会在当前文件夹下生成 ‘screenshots.mp4’. 这个就是我们的处理结果了,双击打开试试吧。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 教你用Kivy写一个乒乓球游戏

好久没有写游戏系列教程了,今天恰好浏览到了 Kivy 这个开源、跨平台的Python 框架,它能用于开发多点触控的用户界面程序,允许快速简单的交互设计,非常方便,于是有了制作本教程的想法。本教程将教你如何使用 Kivy 编写一款乒乓球游戏。我们将从一个基本的应用程序开始,描述创建这个游戏的每个步骤。

Kivy 是用 Python 和 Cython 编写的,基于 OpenGL ES 2,支持各种输入设备并拥有丰富的部件库。使用相同的代码,你可直接实现多平台应用,包括 Windows、macOS、Linux、Android 和 iOS。所有 Kivy 部件都支持多点触控。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install kivy[base] kivy_examples

2.简单使用 Kivy

这一节将简单介绍Kivy的基本使用,首先为我们游戏创建一个目录和一个名为main.py的文件:

# main.py
from kivy.app import App
from kivy.uix.widget import Widget


class PongGame(Widget):
    pass


class PongApp(App):
    def build(self):
        return PongGame()


if __name__ == '__main__':
    PongApp().run()

在命令行中输入 python main.py 运行该应用程序。它应该只显示一个黑色的窗口。所以我们所做的只是创建一个非常简单的Kivy应用程序,它创建了一个 PongGame Widget 类的实例,并将其作为应用程序用户界面的根元素返回。

在这一点上你应该把它想象成一个 Widget 的分层树。Kivy 将这个 Widget树 放在默认的窗口中。在下一步,我们将通过定义 PongGame 小部件的外观来绘制Pong的背景和游戏分数。

3.Kivy – 添加简单图形

我们将使用一个 .kv 文件来定义 PongGame 类的外观。由于我们的应用程序类被称为 PongApp,我们可以简单地在同一目录下创建一个名为 pong.kv 的文件,当应用程序运行时将会自动加载。

因此,为了定义游戏的外观,我们创建一个名为 pong.kv 的新文件并添加以下内容:

#:kivy 1.0.9

<PongGame>:    
    canvas:
        Rectangle:
            pos: self.center_x - 5, 0
            size: 10, self.height
            
    Label:
        font_size: 70  
        center_x: root.width / 4
        top: root.top - 50
        text: "0"
        
    Label:
        font_size: 70  
        center_x: root.width * 3 / 4
        top: root.top - 50
        text: "0"

注意一个常见错误:kv文件的名称,例如 pong.kv,必须与应用程序的名称一致,例如 PongApp(App结尾之前的部分)。

如果你现在运行这个应用程序,你应该看到中间有一个竖条,还有两个零,那里将显示玩家的分数,如下所示:

可以看到,在第一行,我们有:

#:kivy 1.0.9

每个 kv 文件都需要第一行。它应该以 #:kivy 及一个空格开头,然后是它要使用的 Kivy 版本(因此 Kivy 可以确保您至少拥有所需的版本,或者稍后处理向后兼容性)。

再往下看 kv 文件里定义了三个元素,一个 canvas 和两个 label。

先说说两个label,他们代表的是左右两个数字,设定了 font_size(字体大小), center_x(中心位置), top(离顶部距离), text(文本),此外可以看到 root.width 和 root.top 的使用,这样写的好处是能跟跟随窗口宽度和高度的变化而变化。

另一个元素 canvas,它的下面定义了 Rectangle 参数,意思是我们向画布添加一个矩形。将矩形的 pos 设置为小部件水平中心左侧 5 个像素,y 设置为 0,这就定义了矩形的显示位置。

然后矩形的大小 size 设置为宽度为 10 像素,高度为小部件的高度。像这样定义图形的好处是,当值表达式中使用的任何小部件的属性发生变化时,渲染的矩形将自动更新。

4. Kivy – 增加乒乓球球体

好了,我们有一个基本的乒乓球场(虽然很简陋),但我们仍然需要球拍和一个球来打球。让我们从球开始。我们将添加一个新的 PongBall 类来创建一个小部件,它将成为我们的球并使它弹跳起来。

PongBall 类:

class PongBall(Widget):

    # velocity of the ball on x and y axis
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)

    # referencelist property so we can use ball.velocity as
    # a shorthand, just like e.g. w.pos for w.x and w.y
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    # ``move`` function will move the ball one step. This
    #  will be called in equal intervals to animate the ball
    def move(self):
        self.pos = Vector(*self.velocity) + self.pos

白球的 kv 配置如下:

<PongBall>:
    size: 50, 50
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size

为了使这一切顺利进行,你还必须为球体增加所用的Property属性类。下面是这一步更新后的python代码和kv文件。

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty
from kivy.vector import Vector


class PongBall(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos


class PongGame(Widget):
    pass


class PongApp(App):
    def build(self):
        return PongGame()


if __name__ == '__main__':
    PongApp().run()

kv文件如下:

#:kivy 1.0.9

<PongBall>:
    size: 50, 50 
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size          

<PongGame>:
    canvas:
        Rectangle:
            pos: self.center_x - 5, 0
            size: 10, self.height
    
    Label:
        font_size: 70  
        center_x: root.width / 4
        top: root.top - 50
        text: "0"
        
    Label:
        font_size: 70  
        center_x: root.width * 3 / 4
        top: root.top - 50
        text: "0"
    
    PongBall:
        center: self.parent.center

5. kivy – 增加乒乓球体运动

现在我们的目的是让这个球动起来,因此必须定期调用 move 函数让他动起来。使用 Kivy 提供的 Clock 函数可以轻易地做到这一点:

Clock.schedule_interval(game.update, 1.0/60.0)

这一行将导致游戏对象的更新函数每秒被调用60次。

不过我们还有一个问题。我们想确保PongBall的移动函数被定期调用,但是在我们的代码中没有任何对球对象的引用,因为我们只是通过 kv 文件在 PongGame 类的 kv 规则中添加了它。

由于我们要做的不仅仅是移动球(比如把球从墙上弹下来,然后再弹到球员的球拍上),我们可能需要为我们的PongGame类建立一个更新方法。

class PongGame(Widget):

    def update(self, dt):
        # call ball.move and other stuff
        pass

class PongApp(App):

    def build(self):
        game = PongGame()
        Clock.schedule_interval(game.update, 1.0/60.0)
        return game

然而,这仍然不能改变我们没有对kv规则所创建的 PongBall 进行操作的这一事实。为了解决这个问题,我们可以给PongGame类添加一个ObjectProperty,并将其与kv规则中创建的widget挂钩。一旦这样做了,我们就可以很容易地在更新方法中引用球的属性,甚至可以让它从边缘弹起。

class PongGame(Widget):
    ball = ObjectProperty(None)

    def update(self, dt):
        self.ball.move()

        # bounce off top and bottom
        if (self.ball.y < 0) or (self.ball.top > self.height):
            self.ball.velocity_y *= -1

        # bounce off left and right
        if (self.ball.x < 0) or (self.ball.right > self.width):
            self.ball.velocity_x *= -1

在kv文件中将其与代码中设定的 id: ball 映射起来:

<PongGame>:
    ball: pong_ball

    # ... (canvas and Labels)

    PongBall:
        id: pong_ball
        center: self.parent.center

6. Kivy – 球拍移动事件

现在,我们的球正在弹来弹去。唯一缺少的是可移动的球拍和对分数的跟踪。我们不会再去讨论创建类和kv规则的所有细节,因为这些概念已经在前面的步骤中涵盖了。相反,让我们把重点放在如何响应用户的输入而移动球拍上。你可以在Python实用宝典公众号后台回复:乒乓球 获得全部代码和kv规则。

在Kivy中,小部件可以通过实现 on_touch_down、on_touch_move和on_touch_up 方法对输入做出反应。默认情况下,Widget类实现这些方法时,只是在其子部件上调用相应的方法来传递事件,直到其中一个子部件返回True。

乒乓运动是非常简单的。球拍只需要向上和向下移动。事实上,它是如此简单,我们甚至不需要让球员小部件自己处理事件。我们只需为PongGame类实现on_touch_move函数:

def on_touch_move(self, touch):
    if touch.x < self.width/3:
        self.player1.center_y = touch.y
    if touch.x > self.width - self.width/3:
        self.player2.center_y = touch.y

我们将在NumericProperty中保留每个球员的分数。PongGame的分数标签通过改变 NumericProperty score来保持更新,这反过来又会更新PongGame的子标签文本属性。

这是如何实现的?因为Kivy属性会自动绑定到其对应的kv文件中的任何引用。当球从两侧逃出时,我们将通过PongGame类中的更新方法来更新分数并再次发球。

PongPaddle类也实现了一个 bounce_ball 方法,这样球就会根据它击中球拍的位置而产生不同方向的弹跳,非常有意思。下面是PongPaddle类的代码:

class PongPaddle(Widget):

    score = NumericProperty(0)

    def bounce_ball(self, ball):
        if self.collide_widget(ball):
            speedup  = 1.1
            offset = 0.02 * Vector(0, ball.center_y-self.center_y)
            ball.velocity =  speedup * (offset - ball.velocity)

到这一步我们基本就完成了整个游戏的制作,如何,你心动了吗?如果你想体验一下这个游戏,可以在Python实用宝典公众号后台回复:乒乓球 获得全部代码和 kv 规则。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python编写的超帅数独可视化解题器

数独相信大家都玩过,它被称为“聪明人的游戏”,在很多人眼里:

会玩数独=高智商

为什么?因为数独能够培养观察力,提高反应力: 数独的练习能够锻炼手眼脑的协调性、提高手脑并用的能力,锻炼大脑的思维灵活度,全面提高反应力。

非常适合孩子在成长过程中锻炼大脑,适合成年人在生活中激活思维。

不过当我们遇到不会解的数独怎么办?答案是,用Python算出来!

基于 Pygame-Sudoku-Solver 这个开源项目,可视化解决数独问题变得极其简单。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

1.在终端输入以下命令下载该开源库

git clone https://github.com/tymscar/Pygame-Sudoku-Solver.git

2.使用cd命令进入该文件夹,并安装依赖:

cd Pygame-Sudoku-Solver
pip install -r requirements.txt

接下来,可以试试运行该项目了:

python solver.py

此时会出现一个空白3*3的九宫格

2.怎么解题

这个开源项目的解题方法如下:

1.输入题目数字 — 你只需要点击空白区域,此时会回显绿色方块,输入数字,如果数字合法则会填入框内,如果不合法则会闪现红色。

2.当你将数独题目里的所有数字填写完毕,单击空格键即可开始运算:

而且,细心的作者还帮大家准备了夜晚模式,单击“d”键可切换到夜晚模式:

3.原理

所有的解题源代码都放在了solver.py文件中,大家可以在里面看到整个解题过程。

作者没有写任何注释,但是代码逻辑思路是清晰的,比如核心判断逻辑,Cell类里的 isValid, 用于判断某个值 (what变量) 放进某个 Cell 里是否合法:

此处,lineV.cells 表示数组中每一列组成的cell;lineH.cells即每一行组成的cell;box.cells即每个子九宫格。他们都有一个共同的特点:其中不能出现重复的值。

因此你会看到如果某个值存在于这些cells当中,isValid直接返回False,表明其不应该出现在这个位置。

如果你的网络较差,git clone拿不到代码,可以在公众号后台回复:数独 下载源代码。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

代号Mallow, 一款普通人用Python耗费两年制作的精美游戏!

blob:https://pythondict.com/f3977feb-9962-4cd2-8fb4-0e29c5dfdf92

代号Mallow,是国外一位叫u/Ancalabro的用户耗费了两年自学成才制成的一款多人本地/在线2D游戏。

这款游戏基于Pygame制作,针对绳索物理、粒子引擎等一系列难题做了针对性的解决方案。从画面效果来看,作者确实做的非常用心。

1.游戏介绍

该游戏拥有以下特点

1.最多同时可在线4名玩家一同游玩(需要转发UDP端口)

2.在线游戏和离线游戏都支持

3.支持玩家对战

4.十二个独特的场景

5.一击必杀的武器机制和“无臂”近战战斗

6.重力反转机制

7.支持三种系统(Mac\Linux\Windows)

不过,尽管这款游戏支持多人游戏,但是需要你对UDP端口进行转发,这会有一定的安全隐患,所以建议大家单人把玩就好了。

键盘控制方法如下:

Z – 菜单选择 / 跳
X – 菜单返回 / 滚动
C – 使用物品
Y – 菜单命令
ENTER – 暂停 / 取消暂停
ESC – 退出程序
箭头 – 移动
减号 – 切换全屏 / 窗口化

2.源代码

如果你很好奇作者是如何用pygame完成这么多功能的,你可以在
https://ancalabro.itch.io/codename-mallow

下载这款游戏的源代码和游戏程序体验一把,相信不会让你失望的。如下图所示,进入网站后拉到留言区上方便会看到下载地址。从上到下分别是windows、Linux、Mac对应的游戏程序,最下方是游戏源代码。

3.好评如潮

Python社区经常会出现许多精心制作的游戏分享,但是像作者这样花了两年时间沉浸在自己的开发世界里制作一款游戏的人并不多见。

社区里大家对这款游戏都赞赏有加,相信这对于作者而言是一个正反馈,让他对制作游戏更有激情。

也希望大家能跟这位作者一样,认真地坚持做一件事情,逐步地将成果分享于众,获得正反馈。

如果能获得超预期的正反馈,就能极大地唤起我们的热情,像催化剂一样,使得我们的“反应”加快。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 一个漂亮的音乐节奏可视化方案

相信很多人都有这样的疑问:如何用Python音乐的节奏可视化出来?我曾有过一篇文章:Python 提取音乐频谱并可视化,也不过是浅尝辄止,没有完成精美的可视化,只是将频谱用折线图进行了可视化

国外有个网友(u/avirzayev)分享了他的可视化方案。上方的视频就是用他的方案可视化Tattoo.mp3得到的结果,大家可以欣赏一下。

这份代码确实有效地跟上了音乐的节奏,如果能加强可视化效果,丰富颜色,是一份非常好的可视化代码。

下面给大家介绍一下怎么使用这份代码:

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),准备开始输入命令安装依赖。

当然,我更推荐大家用vscode编辑器,把本文代码Copy下来,在编辑器下方的终端运行命令安装依赖模块,多舒服的一件事啊:Python 编程的最好搭档—VSCode 详细指南。

在终端输入以下命令安装我们所需要的依赖模块:

pip install matplotlib
pip install librosa
pip install numpy
pip install pygame

看到 Successfully installed xxx 则说明安装成功。

当然,还有作者的源代码,请在 Python实用宝典 公众号后台回复:【音乐可视化】获取

2.代码调整

代码架构分为两个部分,一个是用于计算频谱的 AudioAnalyzer.py,一个用于渲染生成动态视频的 mAIn.py.

这个“动态视频”是基于pygame实现的,部分代码如下:

作者的代码风格随意,不过仔细阅读还是能读懂大概的。

首先,通过pygame加载(load)音乐文件并播放(play).

然后,通过while循环和ticks对画面中的图像进行实时渲染。

渲染的代码比较长,就是一些计算柱体长度的过程,这里就不赘述了,有兴趣的同学可以开源代码。

如果你想要将你的音乐用这份代码进行可视化,仅需要修改mAIn.py的第5行代码:

这个filename可以是当前运行Python的路径下的音乐文件名称,也可以是音乐文件的绝对路径。

如果你想优化生成的动态图像的颜色,可以修改rnd_color函数,该函数控制图形颜色的变化:

如果你想修改生成的动态图像的形状,比如说去掉中间那个圆,仅需要这么改:

pygame.draw.circle(screen, circle_color, (circleX, circleY), int(radius))

将radius直接设为0,或者直接将这行代码注释掉即可:

pygame.draw.circle(screen, circle_color, (circleX, circleY), 0)

效果:

如果你熟悉pygame的相关函数,可以对这份可视化的代码做更多的DIY,比如说将其展平到平面上,用一条条柱体来展示,像网易云音乐一样:

尽管不可能做得像真正的产品那样好看,不过大家可以先试试,这份代码我就留着下次再展示吧。

如果有遇到不懂的,请在公众号后台回复:加群,加入互助群。记得备注相应的验证信息我才会通过哦。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 开发任天堂Switch程序??奉上教程!

用Python开发Switch程序,在你的Switch上运行Python代码,你需要用到一个名为PyNX的开源工具,操作流程如下:

1.用读卡器将SD卡插入开发设备(电脑or笔记本)中

2.将PyNX的Zip版本的内容复制到SD卡的/switch目录下

3.编辑main.py文件, 将你的代码逻辑写入该文件中

4.将SD卡插入Switch

5.在Homebrew菜单中运行PyNX

听起来挺简单,不过其中第5步的Homebrew菜单你需要通过特殊的方法来绕过Switch的限制,这里不过多描述,可以看这篇文章:
https://switch.homebrew.guide/

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda

当然,我更推荐大家用VSCode编辑器,写代码可惬意了:Python 编程的最好搭档—VSCode 详细指南。

按照流程,接下来你需要下载源代码的Zip版本:

https://github.com/nx-python/PyNX/archive/master.zip

无法下载请在Python实用宝典后台回复: Switch 获取​网盘链接。​

解压后将其复制到SD卡的/switch目录下。

2.编写简单的备份工具

接下来就可以编写该源代码中的main.py文件了,这个就是我们DIY程序的主要代码。

首先,需要导入一些库以开始在我们的自制应用程序上工作,主要用到了作者的nx包。此外,我们还想向用户显示选择菜单,因此我们也应该导入AnsiMenu:

import nx
from nx.utils import AnsiMenu

接下来,创建常量来存储《塞尔达传说:狂野的呼吸》和《超级马里奥·奥德赛》的名称ID:

# title IDs are hexadecimal numbers
BOTW_TITLE_ID = 0x01007EF00011E000
SMO_TITLE_ID = 0x0100000000010000

创建两个列表,将其用于菜单栏。用户可以选择的标题名称在中title_nametitle_ids用于以相同顺序存储游戏ID:

title_names = ["The Legend of Zelda - Breath of the Wild", "Super Mario Odyssey"]
title_ids = [BOTW_TITLE_ID, SMO_TITLE_ID]

设置完列表后就可以使用AnsiMenu实用程序类创建菜单。此菜单将允许用户选择将保存数据备份的游戏名称:

select_title_menu = AnsiMenu(title_names)

每个Python程序的主要执行流程最好进行如下包装:

if __name__ == '__main__':

现在可以使用其query方法呈现查询菜单:

selected_index = select_title_menu.query()

query方法返回用户选择的索引(index),该索引现在存储在selected_index变量中。由于我们先前创建的两个列表的顺序相等,因此我们可以使用索引从title_ids列表中获取游戏ID :

selected_title_id = title_ids[selected_index]

selected_title_id现在包含所选的游戏ID。现在,我们可以使用此游戏ID创建一个功能Title对象:

selected_title = nx.titles[selected_title_id]

现在,我们需要备份所选择的游戏数据。为此,我们需要挂载游戏的savedata。这需要通过selected_title对象的savedata来完成:

with selected_title.savedata as savedata:
    savedata.backup()

这将创建数据备份/backups/savedata/{title_id}/。当然你还可以提供自己的备份路径,如下所示:

with selected_title.savedata as savedata:
    savedata.backup('/savedata_backups/{}/'.format(title_names[selected_index]))

完整代码如下:

import nx
from nx.utils import AnsiMenu


# title IDs are hexadecimal numbers
BOTW_TITLE_ID = 0x01007EF00011E000
SMO_TITLE_ID = 0x0100000000010000
title_names = ["The Legend of Zelda - Breath of the Wild", "Super Mario Odyssey"]
title_ids = [BOTW_TITLE_ID, SMO_TITLE_ID]

select_title_menu = AnsiMenu(title_names)

if __name__ == '__main__':
    selected_title = select_title_menu.query()

    selected_title = title_ids[selected_title]
    selected_title = nx.titles[selected_title]

    with selected_title.savedata as savedata:
        savedata.backup('/savedata_backups/{}/'.format(title_names[selected_index]))

恭喜,你已使用Python创建了第一个Switch自制程序!

文章增删改自作者的tutorial, 感谢他:
https://nx-python.readthedocs.io/en/latest/getting_started/tutorial.html

我们的文章到此就结束啦,如果你喜欢我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

快来试试Python写的游戏《我的世界》

《我的世界 Minecraft》大家应该都听说过,但你有没有想过自己用Python写一个这样的游戏呢?太难、太复杂了?也许吧,但是不试一试你怎么知道能不能成呢?

国外有位叫fogleman的开发者就用Python做了这样的一件事——自制《我的世界 Minecraft》,谁能想到,仅仅900行的代码,玩起来竟然还像模像样的:

接下来,我们就带你运行这个项目,并对这个开源的小游戏做一下简单的更改,让它变成“你的”世界。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),准备开始输入命令安装依赖。

当然,我更推荐大家用VSCode编辑器,把本文代码Copy下来,在编辑器下方的终端运行命令安装依赖模块,多舒服的一件事啊:Python 编程的最好搭档—VSCode 详细指南。

在终端输入以下命令安装我们所需要的依赖模块:

pip install pyglet

看到 Successfully installed xxx 则说明安装成功。然后需要下载这个游戏的源代码,你可以通过输入命令下载:

git clone https://github.com/fogleman/Minecraft.git

也可以在Python实用宝典公众号后台回复:MC 下载。

2.运行及操作

运行这个项目非常简单,你只需要进入源代码文件夹输入以下命令:

python main.py

即可成功运行该游戏项目,然后体验一下这个游戏:

移动

  • W: 前进
  • S: 后退
  • A: 往左
  • D: 往右
  • 鼠标移动: 视角
  • 空格: 跳跃
  • Tab: 切换到飞行模式

建筑

  • 选择建造类型:
    • 1: 砖块
    • 2: 草丛
    • 3: 沙丘
  • 鼠标左键:去除建筑
  • 鼠标右键:增加建筑

退出

  • ESC: 关闭窗口

来看看我的实画:

这个“实”字着实难画,宝典两个字被我略去了,因为我选的地儿右边空位不够。

3.代码解读与自定义

接下来让我们看看这份游戏的代码,整个游戏代码只有902行,真优秀:

在上图红框的位置可以设定默认的窗口大小。作者还给了一些参数以供自定义速度、重力、跳跃高度等:

# 每秒帧数
TICKS_PER_SEC = 60

# 砖块大小
SECTOR_SIZE = 16

# 行走速度与飞行速度
WALKING_SPEED = 5
FLYING_SPEED = 15

# 重力与跳跃高度
GRAVITY = 20.0
MAX_JUMP_HEIGHT = 1.0

我们能不能自定义砖块类型呢?注意,源代码文件夹下有一个texture图片:

而在源代码中,涉及到用户增加区块的代码只有3行,如SAND:

SAND = tex_coords((1, 1), (1, 1), (1, 1))
# ... ...
t = random.choice([GRASS, SAND, BRICK])
# ... ...
self.inventory = [BRICK, GRASS, SAND]
# 1.brick, 2.grass, 3.sand

也就是说,我们增加自己的区块是完全可能的,那么这个tex_coords((1, 1), (1, 1), (1, 1))是什么意思呢?

def tex_coord(x, y, n=4):
    """ Return the bounding vertices of the texture square.

    """
    m = 1.0 / n
    dx = x * m
    dy = y * m
    return dx, dy, dx + m, dy, dx + m, dy + m, dx, dy + m


def tex_coords(top, bottom, side):
    """ Return a list of the texture squares for the top, bottom and side.

    """
    top = tex_coord(*top)
    bottom = tex_coord(*bottom)
    side = tex_coord(*side)
    result = []
    result.extend(top)
    result.extend(bottom)
    result.extend(side * 4)
    return result


TEXTURE_PATH = 'texture.png'

GRASS = tex_coords((1, 0), (0, 1), (0, 0))
SAND = tex_coords((1, 1), (1, 1), (1, 1))
BRICK = tex_coords((2, 0), (2, 0), (2, 0))
STONE = tex_coords((2, 1), (2, 1), (2, 1))

看完tex_coords函数的参数你大概就知道了,这里第一个参数,代表砖块的顶部图像,第二个参数代表底部图像,第三个参数代表四个边的图像。而传入的参数中,(1, 0) 则表示为texture.png 的第(1,0)个图:

比如沙子,顶边、底边、四边都为一样的(1,1)这个图像,因此是:

SAND = tex_coords((1, 1), (1, 1), (1, 1))

相信明白了这个原理后,你自己加一个自定义图形的砖块也不难了吧?大家可以动手试一试。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 小游戏—加农炮送特朗普上太阳

美股熔断历史上只发生过4次,上上次熔断和上一次熔断,还要追溯到2020年3月9日和2020年3月13日,那两天我的记忆很深刻,那感觉,仿佛就在几天前。

话又说回来了,特朗普可是说过狠话的:

这是在2015年竞选期间他发过的一条推特:“如果有一天道琼斯指数单日狂跌超过1000点,那当时的总统就应该被装进加农炮里,以极快的速度被射向太阳。不能找任何借口!”

嘻嘻,见过骗吃骗喝的,还第一次见骗太空游的。而且还骗了3次,这招高明。 不过,各大媒体很快辟谣,推特实际上是网友的p图,特朗普本人可没有立过这样的flag。

不过这真的是一个有趣的话题,今天我们就来用Python模拟一下,制作一个太空小游戏。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),准备开始输入命令安装依赖。

当然,我更推荐大家用VSCode编辑器,把本文代码Copy下来,在编辑器下方的终端装依赖模块,多舒服的一件事啊:Python 编程的最好搭档—VSCode 详细指南

输入以下命令安装我们所需要的依赖模块:

pip install freegames
pip install turtle

看到 Successfully installed xxx 则说明安装成功。你可以在Python实用宝典公众号后台回复:加农炮的特朗普 获得本文完整数据和代码。

2.编写代码

原理很简单,就是用到了张特朗普的漫画图和freegames模块,以及turtle画图模块。turtle画图模块我们以前也写过不少文章,大家不了解可以看看:

1.Python turtle 画雪花
2.Python turtle 深入理解递归

2.1 模块加载与设定图像

首先,引入turtle模块,和freegames模块,我们这一次实验需要用到freegames模块里的向量vector(用于表示坐标)。

import turtle
from random import randrange
from freegames import vector

# 设定screen
screen = turtle.Screen()
screen.setup(420, 420, 370, 0)

# 加载trump图,并设为默认turtle
trump = '3.gif'
screen.addshape(trump)
turtle.shape(trump) 

2.2 准备画图

在开始画图之前,由于需要用特朗普头像作为移动点,我们需要隐藏原有的turtle对象,并设置不显示tracer,即特朗普移动的时候不画线。

最后设定当用户点击画布的时候,执行tap函数

turtle.hideturtle()
turtle.up()
turtle.tracer(False)
turtle.onscreenclick(tap) 

tap函数如下,即设定球体的位置和初始速度。

def tap(x, y):
    """
    回应屏幕点击
    :param x: x轴位置
    :param y: y轴位置
    """
    if not inside(ball):
        ball.x = -199
        ball.y = -199
        speed.x = (x + 200) / 25
        speed.y = (y + 200) / 25 

2.3 开始画图

这一部分的核心是move函数,不过在说道move函数前,我们要重点讲一下如何将原有端点换成特朗普的头像,那就是draw函数的功能:

def draw():
    """
    绘画出太阳和trump
    """
    turtle.hideturtle()
    turtle.clear()

    for target in targets:
        turtle.goto(target.x, target.y)
        turtle.dot(20, 'red')

    if inside(ball):
        turtle.showturtle()
        turtle.goto(ball.x, ball.y)

    turtle.update() 

还记得我们在一开始就将特朗普的头像设定为turtle的shape了吗?然后在move函数运行之前,又将turtle的点隐藏了起来,其实这个时候隐藏的就是特朗普的头像。而在开始移动的时候,我们仅需要将turtle重新show回来即可。因此核心语句便是:

turtle.showturtle()
turtle.goto(ball.x, ball.y)

这两句控制了头像的移动。

接下来看看move函数主体:

def move():
    """
    移动太阳和trump
    :return:
    """

    # 生成"太阳"球体
    if randrange(40) == 0:
        y = randrange(-150, 150)
        target = vector(200, y)
        targets.append(target)

    # 移动太阳
    for target in targets:
        target.x -= 0.5

    # 如果Trump在屏幕内,减速并移动
    if inside(ball):
        speed.y -= 0.35
        ball.move(speed)

    # 重新渲染"太阳"位置
    dupe = targets.copy()
    targets.clear()

    # 和Trump距离太近,则消去球体
    for target in dupe:
        if abs(target - ball) > 13:
            targets.append(target)

    # 渲染画布
    draw()

    # 没有目标了则终止游戏
    for target in targets:
        if not inside(target):
            return

    # 每隔50毫秒递归调用本函数
    turtle.ontimer(move, 50) 

其实注释写的挺清楚的,但是这里我们还是详细解释一下:

1.首先需要生成“太阳”球体,这里用到了vector,是一个用于生成坐标的函数,y是随机产生的,所以球体初始位置都在最右边(200, y)。
2.平移所有的太阳,包括新增的。
3.如果屏幕内存在Trump头像,令其移动。
4.重新渲染太阳位置,用新坐标代替,若和Trump距离过近,则消去该球体。
5.渲染所有的球体和Trump的新位置
6.如果没有球体了,则终止游戏,否则每50毫秒重新调用本函数。

基于这个逻辑大家也可以写一个属于自己的游戏哦。

3.玩笑终归玩笑

当然,这只是个游戏,Trump其实没说过加农炮送上太阳的那句话,不过近期美股的形式确实令人担忧。即使在美联储将利息降为0、大放水7000亿美元的情况下,依然无法挽回局势,不容乐观。

金融市场雪崩在劫难逃,站在金融周期的角度看,十年一次的洗盘即将到来,普通人如何保护好自己?那当然就是学习更多的本领啦!欢迎关注下方的Python实用宝典,优质的Python教程将源源不断奉出。

我们的文章到此就结束啦,如果你喜欢我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 精美俄罗斯方块开源项目

最近想找一些Python相关的游戏开发例子,正好在itch.io上闲逛看到这个俄罗斯方块项目,瞬间被惊艳到了。作者是 Mikhail ,项目地址是:
tetris_for_two: https://gitlab.com/2pi360/tetris_for_two

1.游戏介绍

下面就给大家介绍一下这个用Python写的俄罗斯方块具体功能。它一共有七个游戏模式:

1. 单人模式
2. 普通双人模式
3. 镜像双人模式(即掉落方块都一样)
4. 双人加速模式(每消去一行都会给对方加速)
5. 双人交换控制模式(一次控制自己的方块,一次控制对方的)
6. 双人平衡模式(会改变对方的容量)
7. 双人单容器模式

没错,是不是被这丰富的游戏模式震惊到了?而且这款游戏的界面设计也是相当简洁舒服(而且玩这样的Python开源游戏,你永远不会被广告气到):

不仅如此,除了wasd和上下左右键,它还支持用游戏手柄(仅一个)进行游戏,并且能切换两个玩家的按键设置:

双人模式类似如下, 非常适合小情侣之间消耗时光哦(如果你们都喜欢玩俄罗斯方块的话)

尤其是双人协作模式,两个人一起解决问题也是增进感情的好方法:

还有其他几种游戏模式,大家可以上 itch 上下载游戏体验,或者在公众号后台回复 俄罗斯方块 下载完整源代码和游戏包(各个系统都有)。

2.源码剖析

当然,我们首要目的还是学习这款游戏的源代码,下面就给大家介绍一些这款游戏的部分核心代码。下载该开源项目后,你会发现它的py文件分布如下:

│ base.py
│ game_modes.py
│ main.py
│ run_to_release.py
│ tetris.py
│ … ….
├─assets
│ … …

└─screens
… …

其中,main.py是程序的入口点,首先看看模块引入,sys的引入是当然的,游戏结束的时候需要调用

sys.exit()

使得Python程序正常退出。pygame是这个游戏的引擎,是一个比较老的基于Python的2D游戏引擎,但也因为存在时间长,所以已经是一个很成熟且易上手的2D游戏开发库 。

作者自己写了两个模块,一个是base,里面有画布配置、按键配置、玩家配置等等一系列游戏的基础设置。而 game_modes 则是七种游戏模式的逻辑所在模块,里头还引用了tetris.py,这个模块定义了整个俄罗斯方块旋转的方法及其数据结构。

不过由于时间关系,我们重点看看base里的主循环main_loop:

pygame.time.Clock() 用于配置游戏的帧数,Clock.tick(frameate) 代表每秒framerate帧运行,也就是说,每秒不会执行超过 framerate 次循环 。这个参数的值,我们可以在主函数里看到是600. 也就是这个循环每秒不会超过600次。

pygame.event.get() 是pygame游戏引擎的事件处理器,它用于处理所有的事件,好像打开大门让所有的人进入,然后我们可以根据事件不同的属性做相应的操作,如 event.type == pgl.KEYDOWN 表示键盘被按下时,执行条件中的语句:

pressed_keys.add(event.key) 

于是便将其加入到pressed_keys集合中,yield返回生成器,也就是说只要程序不被终止,这个函数就会不断地返回四个值: events, time_passed, pressed_keys 或 {(0, 0)}。events就是用户触发的事件,time_passed就是这些事件的时长,pressed_keys即用户按下的键。

这样就完成了一次用户事件的传递,然后再又后端对用户的事件进行处理,展示在游戏当中。当然,更复杂的还在后面,这里只是一个简单的事件处理,当然也是最重要的事件处理部分,如果大家有兴趣的话,可以 在公众号后台回复 俄罗斯方块 下载完整源代码进行学习。

我们的文章到此就结束啦,如果你喜欢我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典