用树莓派和乐高、针筒做个潜水艇

视频地址:

https://mp.weixin.qq.com/s/wYKvfumwgpyK7EUVU2AE0w

https://weibo.com/5408421566/M1milvVlX

相关代码:

1、Dropbox

链接:https://www.dropbox.com/sh/u8a45maz3brrwrw/AADbUx9VZEw5UJPny1bJI-Lwa

2、百度网盘

链接:https://pan.baidu.com/s/1kc8RyThILrkOc4ObzOXD0Q?pwd=vrag
提取码:vrag

python-crontab 设置定时任务

通过python-crontab 设置定时任务(创建设置定时任务的.py文件,并运行即可)
安装包: pip install python-crontab

创建新的py文件, 内容如下:

from crontab import CronTab
# 创建linux系统当前用户的crontab,当然也可以创建其他用户的,但得有足够权限,如:user='root'
cron_manager = CronTab(user=True)


# 创建任务 指明运行python脚本的命令(crontab的默认执行路径为:当前用户的根路径, 因此需要指定绝对路径)
job = cron_manager.new(command='python /root/hong/crontab_test/data_test.py >> /root/hong/crontab_test/data_result.log 2>&1 &')

# 设置任务执行周期,每两分钟执行一次

job.setall('*/2 * * * *')

# 将crontab写入linux系统配置文件
my_user_cron.write()

运行py文件,完成! 此时定时任务已经创建(可在linux终端 输入 contrab -l 查看), crontab 会按照设定的时间 定时调用指定路径下的data_test.py文件。

作者:酷酷的图图
链接:https://www.jianshu.com/p/925de5998e1d

Python实现二分查找法

基本思想:对于一个有序数组,从数组中间元素开始与target元素进行比较,target较大则到中间元素的右半部分继续二分查找,target较小则到中间元素的左半部分继续二分查找,相等则查找到了target缘故。

注意:
(1)必须是有序数组
(2)target元素可能找不到

两种实现方法:注意索引边界的不同。

def binarySearch(list, target):
	left = 0
	right = len(list) - 1  
	#在list[left...right]里查找target,注意是左闭右闭
	while left <= right:
		mid = (right + left) // 2    #取中间元素索引
		if list[mid] == target:
			return mid
		elif target > list[mid]
			left = mid + 1     #到list[mid + 1 ...right]里查找
		else:  #target < list[mid]
			right = mid - 1    #到list[left ...mid - 1]里查找
	return -1    #未找到target元素
def binarySearch(list, target):
	left = 0
	right = len(list)
	#在list[left...right)里查找target,注意是左闭右开
	while left < right:
		mid = (right - left) // 2 + left    #防止上面的写法整型溢出
		if list[mid] == target:
			return mid
		elif target > list[mid]
			left = mid + 1     #到list[mid + 1 ...right)里查找
		else:  #target < list[mid]
			right = mid        #到list[left ...mid)里查找
	return -1     #未找到target元素

二分查找法的时间复杂度:O(logn)

3、循环不变量:在循环中不改变的量,即在循环开始和在循环迭代过程中永远保持不变的条件。

比如二分查找的第一个写法里循环开始和在循环迭代过程中要一直保持在list[left…right]左闭右闭的范围里查找target,这个条件就是一个循环不变量。

其他数据结构基本算法的Python实现版本可从github:全python实现的数据结构与算法中获取

树莓派摄像头Picamera2库公测中

作者:大卫·普洛曼

如果你使用过任何 Raspberry Pi 相机,你可能对Picamera很熟悉,这是一个出色的 Python 库,旨在轻松操作 Raspberry Pi 的拍摄功能。

但你可能也知道,随着我们最近转向更开放和更标准的 Linux API,Picamera库(建立在专有的 Broadcom 相机堆栈之上)将来不会再支持了。

带有Raspberry Pi HQ 摄像头的Raspberry Pi 4

最初的Picamera库是第三方软件,由 Dave Jones 开发。事实证明该库在我们的用户中非常受欢迎,因此我们承诺提供替代品。命名为Picamera2的新库正在由 Raspberry Pi 在剑桥内部开发,最终将成为官方支持的软件包。

所以今天我们要宣布Picamera2的第一个预览版

在 Bullseye 桌面上运行的Picamera2示例

预览版是什么意思?

我们所说的预览版是指正在进行的工作。它已经有很多你可以尝试的功能,但仍然缺少一些重要的东西,在我们更广泛地发布该库之前,功能和API 的许多方面也会发生变化。

当前版本中支持的功能包括:

  • 你可以配置和启动摄像头,并接收多个图像流。
  • Picamera2支持预览窗口,无论是独立的还是嵌入在Qt应用程序中。
  • 可以查询和设置相机参数。
  • 你可以将全分辨率图像捕获为JPEGPNG
  • 或者,你可以将它们捕获为numpy数组,以提供给图像分析程序。

但有一个明显缺失的功能,就是我们仍在使用 Raspberry Pi 的硬件h.264编码器进行视频录制。如果你想使用Picamera2从 Python 录制视频,那现在还无法做到,可能还需要“几周”的时间。

如果你有兴趣查看新的Picamera2库(预览版),我们也很想听到相关反馈。比如不该忽略的功能,或者可以优化的地方。

我能用它做什么?

最好的解释可能只是显示一些代码片段!第一个示例启动一个预览窗口,然后进行全分辨率的JPEG捕获:

from qt_gl_preview import *
from picamera2 import *
import time

picam2 = Picamera2()
preview = QtGlPreview(picam2)

preview_config = picam2.preview_configuration()
capture_config = picam2.still_configuration()
picam2.configure(preview_config)

picam2.start()
time.sleep(2)

picam2.switch_mode_and_capture_file(capture_config, "capture.jpg")

在下一个示例中,我们捕获预览图像并将它们传递给OpenCV,以查看它是否可以使用Haar 级联检测图像中的任何人脸。

一位树莓派博主的脸部识别测试

它会在找到的任何人脸周围绘制检测框,并再次在预览窗口中显示图像:

#!/usr/bin/python3

import cv2

from null_preview import *
from picamera2 import *

# Grab images as numpy arrays and leave everything else to OpenCV.

face_detector = cv2.CascadeClassifier("/usr/local/lib/python3.9/dist-packages/cv2/data/haarcascade_frontalface_default.xml")
cv2.startWindowThread()

picam2 = Picamera2()
preview = NullPreview(picam2)
picam2.configure(picam2.preview_configuration(main={"size": (640, 480)}))
picam2.start()

while True:
    im = picam2.capture_array()

    grey = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(grey, 1.1, 5)

    for (x, y, w, h) in faces:
        cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0))

    cv2.imshow("Camera", im)

除了这两个之外,我们还创建了 20 多个小示例脚本作为非正式教程,并帮助人们探索此预览版本中可用的功能。在适当的时候,一旦事情变化的速度稳定下来,我们将努力扩展这些信息并添加一些更正式的文档和教程。

我该如何尝试?

你可以在 Github 上找到Picamera2 的预览版,并且存储库README.md提供了完整的安装说明。

但是,预览版不适合胆小的人。由于Picamera2是建立在libcamera自己的 Python 绑定之上的,这些绑定目前处于原始阶段,因此目前的安装涉及libcamera库的一个特殊版本,需要手动编译它。

目前还无法通过包管理器或其他机制安装Picamera2的预览版。你必须从源代码构建它。如果你对此感到不自在,最好等待稳定版本。

但是,如果你有机会查看示例代码并尝试使用该库,我们将非常感谢任何有用的建议。我将密切关注相机论坛上的讨论,以便尝试回答你遇到的任何问题。

Python的各种排序

一、插入排序(Insertion-Sort)

  插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

  把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。

1、原理

  • 从第二个元素开始和前面的元素进行比较,如果前面的元素比当前元素大,则将前面元素 后移,当前元素依次往前,直到找到比它小或等于它的元素插入在其后面
  • 然后选择第三个元素,重复上述操作,进行插入
  • 依次选择到最后一个元素,插入后即完成所有排序

2、举例

举个例子,假设我现在有一个数列[11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]需要使用插入排序,我们来看看使用插入排序的详细步骤:

  • 首先第二个元素99和前面的元素11比较,99>11,第一轮完了,列表是 1 [11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22] 
  • 然后,33作为比较元素,和前面的元素99比较,11<33<99交换位置,33插入到11和99之间,列表为 1 [11, 33, 99, 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22] 
  • 接着,33<69<99交换位置,列表变为    1 [11, 33, 69, 99, 77, 88, 55, 11, 33, 36,39, 66, 44, 22] 
  • 以此类推,69<77<99,77插入到69和99之间,列表变为   1 [11, 33, 69, 77, 99, 88, 55, 11, 33, 36,39, 66, 44, 22] 
  • 77<88<99, 88插入到77和99之间,列表变为    1 [11, 33, 69, 77, 88, 99, 55, 11, 33, 36,39, 66, 44, 22]  
  • 33<55<69<77<88<99,55插入到33和69之间,列表变为   1 [11, 33, 69, 77, 88, 99, 55, 11, 33, 36,39, 66, 44, 22]  
  • 。。。。。。。
  • 最终得到列表  1 [11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99] 

注:从第二个元素开始,以此和前面的元素比较,找出相应位置插入。

3、特点

插入排序的适用场景:一个新元素需要插入到一组已经是有序的数组中,或者是一组基本有序的数组排序

  • 比较性:排序时元素之间需要比较,所以为比较排序
  • 稳定性:从代码我们可以看出只有比较元素大于当前元素,比较元素才会往后移动,所以相同元素是不会改变相对顺序
  • 时间复杂度:插入排序同样需要两次循坏一个一个比较,故时间复杂度也为O(n^2)
  • 空间复杂度:只需要常数个辅助单元,所以空间复杂度也为O(1)
  • 记忆方法:想象成在书架中插书:先找到相应位置,将后面的书往后推,再将书插入
def insertion_sort(arr):
    """插入排序"""
    # 第一层for表示循环插入的遍数
    for i in range(1, len(arr)):
        # 设置当前需要插入的元素
        current = arr[i]
        # 与当前元素比较的比较元素
        pre_index = i - 1
        while pre_index >= 0 and arr[pre_index] > current:
        # 当比较元素大于当前元素则把比较元素后移
            arr[pre_index + 1] = arr[pre_index]
        # 往前选择下一个比较元素
            pre_index -= 1
        # 当比较元素小于当前元素,则将当前元素插入在 其后面
            arr[pre_index + 1] = current
    return arr

arr = [4,5,6,1,3,2]
print (insertion_sort(arr))

正确的输出内容:

[1, 2, 3, 4, 5, 6]

二、选择排序(Selection sort)

  选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,所以称为:选择排序。

1、原理

(1)设第一个元素为比较元素,依次和后面的元素比较,比较完所有元素找到最小的元素,将它和第一个元素互换。
(2)重复上述操作,我们找出第二小的元素和第二个位置的元素互换,以此类推找出剩余最小元素将它换到前面,即完成排序。

2、举例

举个例子,假设我现在有一个数列需要使用冒泡来排序 [11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22],

我们来看看使用冒泡的详细步骤:

1、首先11作为比较元素和列表后面的所有元素比较,找到最小的11,并放在第一位,第一轮完了,列表是  [11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]

2、然后,99作为比较元素,和后面的元素[33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]作比较,找到最小的11,和第二位元素99交换位置,即第二轮比较完后,列表为   [11, 11, 33 , 69, 77, 88, 55, 99, 33, 36,39, 66, 44, 22]      

3、第三轮比较完,22最小,和第三个元素33交换位置,列表变为  [11, 11, 22, 69, 77, 88, 55, 99, 33, 36,39, 66, 44, 33]

4、最终得到列表  [11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]

注:是一轮比较完后,找出最小的,再交换这个元素和对应轮数位置处的元素位置,每轮只交换一次。二冒泡排序是,没比较一次,就交换一次位置,每轮要交换很多次。回到顶部(go to top)

 3、代码

   实现思路: 使用双重for循环,内层变量为i, 外层为j,在内层循环中不断的比较相邻的两个值(j, j+1)的大小,如果j+1的值大于j的值,交换两者位置,每循环一次,外层的i增加1,等到i等于(len(arr) – 1)的时候,结束循环。

def selection_sort(arr):
    """选择排序"""
    # 第一层for表示循环选择的遍数
    for i in range(len(arr) - 1):
        # 将起始元素设为最小元素
        min_index = i
        # 第二层for表示最小元素和后面的元素逐个比较
        for j in range(i + 1, len(arr)):
            if arr[j] < arr[min_index]:
                # 如果当前元素比最小元素小,则把当前元素角标记为最小元素角标
                min_index = j
        # 查找一遍后将最小元素与起始元素互换
        arr[min_index], arr[i] = arr[i], arr[min_index]
    return arr

A = [64, 25, 12, 22, 11] 
print (selection_sort(A))

正确的输出内容:

[11, 12, 22, 25, 64]

想在树莓派上跑Julia?没问题。

Julia是一款开源通用编程语言,专为科学计算而设计。它结合了 Python 和 Ruby 等高级语言的易用性,以及 C 的速度。Julia 是大学开发研究的理想选择,从本科到博士都可以考虑它。

其实在2017年,该语言的创造者之一Viral Shah就跟 Raspberry Pi 基金会取得了联系,并将 Julia 移植到了 ARM 平台,特别是针对 Raspberry Pi。从那时起,他们出色的完成了对 ARM 平台以及树莓派的支持。

而树莓派基金会也将Julia正式的纳入了Raspberry Pi OS的软件库,大家可以直接用APT安装了。

现在Julia 团队不仅将语言本身移植到 Pi,而且还增加了对GPIOSense HATMinecraft的支持。

Julia 开发人员之一 Simon 首先将 Julia 徽标加载到Jupyter 笔记本中的矩阵,然后将其显示在 Sense HAT LED 矩阵上。然后他做了一些矩阵变换,Sense HAT 显示了这些操作的效果。

可以使用以下命令在 Raspberry Pi 上安装 Julia:

sudo apt update
sudo apt install julia

为 Julia 安装 Jupyter notebook:

sudo apt install julia libzmq3-dev python3-zmq
sudo pip3 install jupyter
julia -e 'Pkg.add("IJulia");'

也可以从 Julia 控制台轻松安装额外的软件包:

Pkg.add("SenseHat")

Julia 团队还创建了一个资源网站,用于在 Pi 上开始使用 Julia:juliaberry.github.io

好了,Julia开发者们。在树莓派上用起来吧。

Jetson Nano开发AI应用的认证课程

NVIDIA的深度学习学院(DLI)为边缘计算开发人员,教育者,学生和终身学习者提供了实用的,动手的AI培训和认证。 

Jetson AI部分,NVIDIA提供了两种认证:

一、任何人都可以完成的”Jetson AI专家认证,即Jetson AI Specialist
二、是针对教育工作者的的Jetson AI大使认证,即Jetson AI Ambassador

课程介绍

如今,世界各地使用 NVIDIA Jetson Nano 开发者套件的创客、自学开发者和嵌入式技术爱好者均已掌握 AI 的强大力量。借助这款简单易用而又功能强大的计算机,您将可在图像分类、物体检测、分割和语音处理等应用中并行运行多个神经网络。在本课程中,您将在自己的 Jetson Nano 上使用 Jupyter iPython notebook 构建基于计算机视觉模型的深度学习分类项目。

您将学习如何:

  • 安装 Jetson Nano 和相机
  • 为分类模型采集图像数据
  • 为回归模型注释图像数据
  • 基于您的数据训练神经网络,以创建模型
  • 使用您创建的模型在 Jetson Nano 上运行推理

完成课程学习后,您将能使用 Jetson Nano 创建深度学习分类和回归模型。

培训证书

成功完成本课程和测试后,您将获得 NVIDIA DLI 证书,以证明您在这一主题领域的技能,助力您的职业发展。

课程模式

个人在线自主学习,课程包含视频和代码示及练习例等

课程详情

预备知识:了解 Python 的基础知识(会有帮助,但非必需)

工具、库和框架:PyTorch、Jetson Nano

课程时长:6 学时(课件有效期 6 个月)

课程语言:中文

课程价格:免费

您需要准备好的硬件

  • NVIDIA Jetson Nano 开发者套件
  • 高性能 microSD 卡:最小 32GB(我们已测试并推荐此产品
  • 5V 4A 电源和 2.1 毫米直流桶式连接器(我们已测试并推荐此产品
  • 2 针跳线:必须添加到 Jetson Nano 开发者套件主板,以使桶式插座电源供电(此处为产品示例
  • Logitech C270 USB 网络摄像头(我们已测试并推荐 此产品) 。
  • USB 线缆:Micro-B 至 Type-A,支持数据传输(我们已测试并推荐此产品
  • 一台能以闪存形式向 microSD 卡写入数据的联网计算机

树莓派GPIO控制 —— C语言篇

一. 常用开源工程简介

树莓派内核中已经编译自带了gpio的驱动,我们常通过一些第三方写好的库函数来完成具体的操作,比较常见的操作库函数有:

  1. Python GPIO
    【开发语言】——python
    【简单介绍】——树莓派官方资料中推荐且容易上手。python GPIO是一个小型的python库,可以帮助用户完成raspberry相关IO口操作,但是python GPIO库还没有支持SPI. I2C或者1-wire等总线接口。
    【官方网站】—— https://code.google.com/p/raspberry-gpio-python/
  2. wiringPi
    【开发语言】——C语言
    【简单介绍】——wiringPi适合那些具有C语言基础,在接触树莓派之前已经接触过单片机或者嵌入式开发的人群。wiringPi的API函数和arduino非常相似,这也使得它广受欢迎。作者给出了大量的说明和示例代码,这些示例代码也包括UART设备,I2C设备和SPI设备等。
    【官方网站】—— http://wiringpi.com/
  3. BCM2835 C Library
    【开发语言】——C语言
    【简单介绍】BCM2835 C Library可以理解为使用C语言实现的相关底层驱动,BCM2835 C Library的驱动库包括GPIO. SPI和UART等,可以通过学习BCM2835 C Library熟悉BCM2835相关的寄存器操作。如果有机会开发树莓派上的linux驱动,或自主开发python或PHP扩展驱动,可以从BCM2835 C Library找到不少的“灵感”。
    【官方网站】—— http://www.airspayce.com/mikem/bcm2835/

    . 树莓派GPIO编号方式
  1. 功能物理引脚:
    从左到右,从上到下:左边基数,右边偶数:1-40
  2. BCM:
    编号侧重CPU寄存器,根据BCM2835的GPIO寄存器编号。
  3. wiringpi:
    编号侧重实现逻辑,把扩展GPIO端口从0开始编号,这种编号方便编程。正如图3 WiringPi一栏。

    三. WiringPi GPIO
  1. 说明:
    WiringPi是应用于树莓派平台的GPIO控制库函数,WiringPi遵守GUN Lv3。wiringPi使用C或者C++开发并且可以被其他语言包转,例如python. ruby或者PHP等。
    wiringPi包括一套gpio控制命令,使用gpio命令可以控制树莓派GPIO管脚。用户可以利用gpio命令通过shell脚本控制或查询GPIO管脚。
  2. wiringPi安装
     1)使用GIT工具
    git clone git://git.drogon.net/wiringPi
    cd wiringPi
    ./build
    build脚本会帮助你编译和安装wiringPi

     2)直接下载
    在https://git.drogon.net/?p=wiringPi;a=summary下载最新版本编译使用
    tar xfz wiringPi-xx.tar.gz
    cd wiringPi-xx
    ./build

     3)raspbian使用apt-get安装
    sudo apt-get install wiringpi
  3. 测试:
    wiringPi包括一套gpio命令,使用gpio命令可以控制树莓派上的各种接口,通过以下指令可以测试wiringPi是否安装成功。
    $gpio -v
    $gpio readall #即可出现下面的gpio图
  1. 样例代码:
#include <wiringPi.h>
int main(void)
{
 wiringPiSetup() ;
 pinMode (0, OUTPUT) ;
 for(;;)
 {
  digitalWrite(0, HIGH) ; delay (500) ;
  digitalWrite(0, LOW) ; delay (500) ;
 }
}
  1. 编译运行:
    在树莓派上:
    gcc -Wall -o test test.c -lwiringPi
    sudo ./test

在虚拟机中:
am-linux-gcc -Wall -o test test.c -lwiringPi
sudo ./test

注:
1)IO的编号方式略有不同,采用wiring编码方式。
2)-lwiringPi表示动态加载wiringPi共享库。

四. BCM2835 C Library
下载:
$ wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.35.tar.gz
解压缩:
$tar xvzf bcm2835-1.35.tar.gz
进入压缩之后的目录:
$cd bcm2835-1.35
配置编译:
./configuremake
执行检查:
$sudo make check
安装bcm2835库:
$sudo make install

样例代码

#include < bcm2835.h>
//P1插座第11脚
#define PIN RPI_GPIO_P1_11
int main(int argc, char **argv)
{
  if (!bcm2835_init())
   return 1;

 // 输出方式
 bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);

 while (1)
 {
   bcm2835_gpio_write(PIN, HIGH);
  bcm2835_delay(100);

  bcm2835_gpio_write(PIN, LOW);
  bcm2835_delay(100);
 }
 bcm2835_close();
 return 0;
}

编译运行
gcc -o blink blink.c -lbcm2835
./blink

注:
1)IO的编号方式略有不同,采用BCM编码方式
2)-lbcm2835表示动态加载bcm2835共享库

参考链接:

http://elinux.org/RPi_Low-level_peripherals
http://blog.csdn.net/xukai871105/article/details/23115627

Windows装不上Wordcloud?看这里

如果你是一个写Python,且又喜欢做词云的朋友。

你应该遇到过Windows上跑不动你词云程序的情况,比如你可能在装Wordcloud时候会遇到如下情况:

虽然网上也有一些教程,但好像都不是很清晰。

有的教程,干脆让我们先去下载一个微软的Visual Studio……

其实,就差一个C++生成工具。

而这个工具包含在了Build tools这么个套件里面。

下载地址:

https://visualstudio.microsoft.com/zh-hans/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16

打开以后不要慌,选中这个勾就行。

如果你的硬盘不富裕,就别全选了,继续往后边看。

我一般是选这几个。

然后,该程序会提醒你。要下载4.4GB左右的组件包。

管你要不要,反正它要下载。

好的一点是,它可以边下边安装,总算能节约一点时间。

下载完成后要重启生效。

然后,你的wordcloud就可以装上了。

下面写段代码测试一下:

from wordcloud import WordCloud

f = open('text.txt','r',encoding='utf8').read()
wordcloud = WordCloud(background_color="white",width=800, height=600, margin=2).generate(f)

# width,height,margin可以设置图片属性
wordcloud = WordCloud(font_path = r'simsun.ttf').generate(f)
# 你可以通过font_path参数来设置字体集
#background_color参数为设置背景颜色,默认颜色为黑色

import matplotlib.pyplot as plt
plt.imshow(wordcloud)
plt.axis("off")
plt.show()

wordcloud.to_file('test.png')

能生成词云了,只是不够好看,得再调整一下。

更多精彩内容,欢迎关注“IoT前哨站”的微博和公众号。我是王文文。

用Python实现经典游戏《小蜜蜂》

估计很多老玩家在小时候都玩过Galaxian(小蜜蜂)吧。这款射击游戏的鼻祖叫《太空侵略者》,上手简单,但可玩性很强。

高手用C语言精准复现的1978年《太空侵略者》版本

《太空侵略者》大火之后,新推出的Galaxian(小蜜蜂)于1979年成为其最大竞争对手。由Namco发行的Galaxian为外星敌人提供了新的色彩和不可预测的动作,后者不但会发射炮弹,还会自杀式俯冲攻击。

《Galaxian》在街机游戏中大受欢迎,以至于Namco在两年后又发布了续作《Galaga》——这款游戏使攻击模式更加复杂。

很难说《Galaxian》究竟有多少移植和克隆的版本,因为几乎每个家用游戏机上都有类似版本。

小霸王平台的《Galaxian》

玩家在《Galaxian》中的角色与《太空侵略者》类似,驾驶一艘飞船与一支外星舰队战斗。

与《太空侵略者》不同的是,在《Galaxian》中,外星人总会打破队形向玩家的飞船发起俯冲轰炸。

玩家需要摧毁所有敌人,然后进入下一关。随着玩家的推进,一波又一波的敌人将让过关变得更加困难。

我们这里将着眼于外星人的俯冲机制,用Pygame Zero开发《Galaxian》游戏的核心功能。

用Pygame Zero开发的版本

首先,《Galaxian》拥有一个纵向显示画面,所以我们将游戏区域的宽度和高度分别设置为600和800。

接下来,我们可以用位图创建一个滚动的星空背景。​将位图逐渐往屏幕下方移动,用第二颗恒星来填充第一颗恒星向下滚动时留下的空间,我们还可以在后面添加另一个静态背景图像,这将提供一些视野深度。

然后,我们将玩家的飞船设置为Actor。并在update()函数中捕获左右箭头键,以便在屏幕上左右移动飞船。我们也可以用空格键发射子弹,子弹会沿屏幕向上移动,直到击中外星人或离开屏幕顶部。

和原版《Galaxian》一样,你一次只能发射一颗炮弹,所以我们只需要一个Actor。

外星人排成一行,一起在屏幕上左右移动。在这个例子中,我们只画一种类型的外星人,共画两行。你可以添加额外的类型和任意多行。当我们创建alien Actors时,我们还可以添加一个状态标志,我们需要确定当它们打破队形时,它们在行的哪一边,两边朝相反的方向飞行。在这种情况下,每行左边有4个外星人,右边有4个。

一旦它们在列表中建立起来,我们就可以在每次更新时遍历列表,并向前或向后移动它们。

当我们在移动外星人时,我们也可以查看它们是否与炮弹或玩家飞船相撞。

如果与炮弹碰撞,那么外星人将使用状态标志连续播放爆炸的那几帧,当状态达到5时,它们将不再被绘制到界面上。

如果碰撞发生在玩家的飞船身上,那么玩家会死亡,游戏也就结束了。

我们也可以检查一个随机数,看看外星人是否开始轰炸。如果是,我们将状态设置为1,这将开始调用flyAlien()函数。这个函数会检查外星人的位置,并根据侧边的不同改变外星人的角度,然后根据角度更改x和y坐标。为了方便大家看明白,我们这里处理的比较简单,你也可以使用一些乘数变量将其折叠到x坐标和角度上,将其收窄。

相关代码:

https://github.com/IoToutpost/Python_game

要运行调试请先安装Pygame Zero。

现在大家应该初步掌握了Galaxian游戏的基础知识。你可以试着完善它了。