从Scratch到Python:会动的猫

大部分人提起儿童编程,就会想到Scratch,然而当儿童升入中学,学习什么语言比较合适呢?我认为,Python是未来的方向,为此我将会把一些经典的Scratch案例用Python重新实现,抛砖引玉,希望能给大家带来一定的启发。我坚信,未来中学的编程教育,Python一定会有自己的一席之地。
作者:少儿创客帮
转载请注明作者、出处

概述

相比于简化了编程的Scratch,python要涉及到更多细节要处理,是Scratch没有讲清楚的那一部分,对于Python程序,教师在实际教学中可以自己封装好一些涉及到细节函数让学生调用,然后等学生掌握整体之后讲解细节的实现,我认为这是一种合适的教学策略。
在用Python实现Scratch项目的过程中,为了避免大量繁琐的细节工作,我采用pygame这个库来简化实现,在《父与子的编程之旅:与小卡特一起学编程》一书中也采用pygame来实现一些比较有意思的东西。

Pygame

Pygame

要让图形(和声音)在你计算机上显示,是比较复杂的一项工作,涉及到不同的操作系统和显卡,还需要大量的底层代码(然而初中生很难理解这些底层代码),所我们需要用pygame模块来提供帮助,让问题变得更简单。
要让游戏在不同的计算机和操作系统上工作,所需要的图形和其他内容都可以用pygame来创建,而不必了解每个系统的繁琐细节。Pygame是免费的。
——《父与子的编程之旅:与小卡特一起学编程》

Pygame参考教程,Pygame系列教程建议阅读全文之后学习

让小猫动起来

下面我们来做一个让小猫动起来的例子

Scratch实现

为了便于大家用手机阅读,Scratch程序实现的时候我采用与Scratch类似的编程猫,这样大家可以单击链接直接在手机上观看效果;但是截图仍然用Scratch本身的截图。

Scratch程序实现

程序代码,这个Scratch里面可以说最简单的一个例子,我们用了4个代码块实现了让小猫动起来,并且在碰到墙壁的时候反弹。下面我们就用python实现。
编程猫实现的小猫动起来效果

Python实现

在用Python的模块Pygame实现小猫动起来之前,我们来分析这个程序,单击绿旗,重复执行移动10步并且在碰到墙壁的时候反弹。我们需要解决的问题是:

  • 如何用Pygame创建舞台
  • 如何在Pygame的舞台上添加小猫角色
  • 如何用Pygame让小猫动起来
  • 如何实现碰到墙壁就反弹,Scratch屏蔽了这部分细节,而我们要自己实现

用Pygame创建舞台

#安装Pygame,如果安装了Python并且勾选安装pip可以如下安装Pygame
sudo pip install pygame

用Pygame创建舞台实际上就是要创建一个窗口,就像我们平时打开应用程序都有窗口一样,这个可以参考之前提供的教程,也可以如下:
如果要利用Pygame创建窗口,首先要导入pygame模块

import pygame

然后初始化模块

pygame.init()

如果把pygame看做是一个创建游戏的工厂,那么pygame.init()就好比告诉操作系统,我准备好生产游戏了,要开张了。
接下来就是要创建窗口了,如同工厂有不同的部门工种一样,Pygame也有很多不同的模块负责不同的功能

#导入pygame模块
import pygame
#初始化pygame
pygame.init()
#创建舞台,利用Pygame中的display模块,来创建窗口
screen = pygame.display.set_mode((640,480),0,32)
#设置窗口标题
pygame.display.set_caption("从Scratch到Python")

这个时候大家运行就能得到一个窗口但是窗口一闪而过,那么我们就需要检测是否关闭了窗口,我比较懒,所以放一张《父与子的编程之旅》书里的内容来解释:

使Pygame的窗口正式工作

Pygame的作用是建立游戏,游戏本身不做任何事情,只是与玩家交互。
我们知道在Scratch中重复执行的事情比如移动10步是放到一个无限循环之中的,那么Pygame重也有一个这样的无限循环,叫做事件循环(event loop),不断检测用户在作什么,比如按键、移动鼠标或者关闭窗口,Pygame程序需要有个时间循环一直运行。我们的第一个Pygame中,没有启动时间循环,所以程序没有正常运行。
可以用while循环让程序一直运行,然后当单机关闭按钮的时候让程序退出:

#导入pygame模块
import pygame
#初始化pygame
pygame.init()
#创建舞台,利用Pygame中的display模块,来创建窗口
screen = pygame.display.set_mode((640,480),0,32)
# 填充舞台背景色为白色,利用rgb颜色
screen.fill([255,255,255])
#设置窗口标题
pygame.display.set_caption("从Scratch到Python")
while 1:
    for event in pygame.event.get():
    #这段程序大家可能比较费解,实际上是检测quit事件,实际讲课中让学生直接模仿即可,时间足够也可以讲明白
        if event.type == pygame.QUIT:
            pygame.quit()
Sublime Text下的程序截图
程序运行截图

那么现在舞台(窗口)中啥都没有,我们来加载图片。

添加角色

为了添加角色,我们需要一张小猫的图片,同时要求是png图片有alpha通道的。
Pygame可以很容的绘制点、线、面,但是如何利用从网上、拍照,图像软件创作的图片呢?
最简单的办法就是利用image模块的load函数加载图片。

# 我的cat.png和cat.py文件在同一个文件夹下面
# 所以可以直接这样加载图片的
# laod函数加载图片
cat = pygame.image.load("cat.png")
# blit函数的作用是把加载的图片放到舞台的(50,50)坐标的位置
screen.blit(cat,(50,50))
#然后更新舞台显示
pygame.display.flip()
Flip函数的作用

python可以在交互式命令行下用help函数查看函数的功能,比如flip函数的作用就是把显示Surface更新到屏幕,可以简单的理解成一次性的更新窗口内容的显示

加载小猫角色
加载小猫角色

我们可以看到小猫被成功的加载到了舞台

让小猫动起来

我们已经把小猫角色加载到了舞台(窗口),那么我们就让小猫动起来,没错我们要做一些计算机动画,计算机动画就是把图像(像素组)从一个位置不断的移动到另外一个位置。
在利用计算机图形做动画的时候,移动一个东西需要两个步骤:

  • 在新的位置上画出图形
  • 把原来的图形擦掉

实际上《父与子的编程之旅:跟小卡特学Python》一书中给出的解决办法并不是通俗易懂,我们在这里直接把让小猫移动的代码写到while循环,用到的相关知识也少,这样与Scratch也更加类似,即在每个循环里更新cat角色的位置,然后更新画面,当然《卡特》这本书里更好的讲解了计算机动画的原理,不过我懒啊,所以就偷懒了:

import pygame
#初始化pygame
pygame.init()
#创建舞台,利用Pygame中的display模块,来创建窗口
screen = pygame.display.set_mode((640,480),0,32)
# 填充舞台背景色为白色,利用rgb颜色
screen.fill([255,255,255])
#设置窗口标题
pygame.display.set_caption("从Scratch到Python")
cat = pygame.image.load("cat.png")
cat_x, cat_y = 0, 0
while 1:
    for event in pygame.event.get():
    #这段程序大家可能比较费解,实际上是检测quit事件,
    #实际讲课中让学生直接模仿即可,时间足够也可以讲明白
        if event.type == pygame.QUIT:
            pygame.quit()
    screen.blit(cat,(cat_x,cat_y))
    cat_x += 1
    pygame.display.update()

诡异的效果

之所以会形成上面诡异的效果,是因为前面提到用计算机做动画的时候,需要在新的位置上绘制出图形,然后把原来的擦掉,我没有擦掉,所以就会出现这种残影的效果,那么怎么办嗯?只需要改一个地方

cat = pygame.image.load("cat.png")

改成

cat = pygame.image.load("cat.png").convert()

就正常了

convert把图像转变成一个面
正常移动的猫

小结:上面实现了会移动的猫

小猫碰到墙壁就反弹

碰到墙壁就反弹其实很简单,如果小猫的x坐标大于屏幕640,就让他向左移动,如果小于0就向右移动

判断小猫的坐标是否大于640
import pygame
#初始化pygame
pygame.init()
#创建舞台,利用Pygame中的display模块,来创建窗口
screen = pygame.display.set_mode((640,480),0,32)
# 填充舞台背景色为白色,利用rgb颜色
screen.fill([255,255,255])
#设置窗口标题
pygame.display.set_caption("从Scratch到Python")
cat = pygame.image.load("cat.png").convert()
cat_x, cat_y = 0, 0 # 猫的坐标
h_direction = 1; # 水平方向
while 1:
    for event in pygame.event.get():
    #这段程序大家可能比较费解,实际上是检测quit事件,
    #实际讲课中让学生直接模仿即可,时间足够也可以讲明白
        if event.type == pygame.QUIT:
            pygame.quit()
    screen.blit(cat,(cat_x,cat_y))
    cat_x += 0.5 * h_direction
   # 如果猫的坐标超出了640,就让小猫反向
   # 如果猫的坐标小于了0,也让小猫反向,这样就实现了碰到墙壁反弹的效果
    if cat_x > 640:
        h_direction = -h_direction
    elif cat_x < 0:
        h_direction = -h_direction
    pygame.display.update()

小猫动起来

以上就是用Python实现会动的猫的过程,这个只是个简单的例子,后面还会有系列文章来讲解,通过学习pygame实现会动的小猫,学生能够了解计算机动画的原理,从而自己绘制动画。利用convert函数,可以简化计算机动画的实现,如果有心的读者运行代码后会发现一个小的bug,这里先卖个关子,这个跟pygame的原理有关。接下来我会依次用pygame来实现Scratch的各个代码块,便于读者自行编写动画。
通过这篇文章探索用python实现Scratch一些程序的可能,同时程序涉及了更多的细节,但是这些世界其实又很容易理解,进一步加深学生对于计算机动画的理解,了解计算机背后的原理,激发学生的兴趣。
后面将陆续退出:

  • pygame中的绘图
  • pygame中的大小控制
  • 按键控制舞台角色移动
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,513评论 25 707
  • 炎热的夏天似乎烤死了好多臭虫,搞得殡仪车总在村里进出。 大学放暑假,我选择先回家呆几天,然后再和她一起去找事做,总...
    无忧无虑的大鲸鱼阅读 848评论 0 1
  • 曾经,我理想中的大学生活是很美好的,有再别康桥的浪漫,也有钱钟书和杨绛先生的传奇,有花、有月、有书,还有男朋友。 ...
    喵欣人的生活观阅读 425评论 2 10