浮云小站

欢迎来到浮云小站。

这里有关于App Inventor 2 的常见问题、扩展插件、教程案例等。。。

有什么疑问,欢迎在下面留言。

常见问题

如何正确打开屏幕

打开新屏幕前,需要关闭当前屏幕。否则多次打开新屏幕,可能会造成系统内存耗尽,app崩溃。

三种打开屏幕的方法:

2018-11-15_132302

如何获取本机IP地址

20190508203807

如何判断当前有无网络

mark

如何实现滑动屏幕效果

新版的wxbit服务器增强了布局的点击和拖动效果,可以在不使用外部插件的情况下,实现滑动屏幕效果。

  1. 在屏幕内拖入一个垂直布局,宽高都设为充满。

  2. 每次按下布局时,记录下点击的x位置和y位置

  3. 每次松开布局时,对比松开点的位置与原来按下的位置变化,就可以判断滑动方向了

    mark

如何发送邮件

1.使用活动启动器发送(不会直接发送,需要手机配置邮箱。打开手机邮箱服务,手动点发送)

mark

2.使用小白接口发送 (详见这里


联系方式

QQ

270988017(请注明AppInventor)

电子邮箱

270988017 at qq dot com


源码市场

应用列表(持续更新中):

点我查看应用截图

购买链接:

http://pr.kuaifaka.com/item/kevinkun

APK下载预览

https://share.weiyun.com/5tChM8i

购买须知:

  • 源码仅作为学习交流之用,不得用于其他目的。
  • 本站源码采用http://app.wxbit.com服务器开发,不保证其他服务器或离线版本的兼容性
  • 购买前请先下载APK安装,查看是否符合你的要求。数码产品性质特殊,售出概不退货。
  • 购买源码即被认为同意本须知。

购买流程:

  • 选好想要的源码,点击上面的购买链接
  • 在付款页面完成付款,请务必留下你的联系方式
  • 付款后不要关闭浏览器,系统自动给一个下载链接,下载源码
  • 如果已经关闭了浏览器,请点击这里自助找回下载链接:

使用方法:

  • 源码的扩展名为.aia,不要使用压缩软件对他解压缩。

  • 将源码文件名称改为全部英文字母,文件名不要用中文(扩展名.aia不要改动)

  • 打开http://app.wxbit.com并登录(没有账号的请先注册)

  • 依次点击左上角菜单“项目”-->"导入项目(.aia)"

  • 点"选择文件",选中你的源码文件,点"确定",就可以导入源码并查看了

  • 点右上角的“逻辑设计”,可以查看代码。

  • 若代码是折叠的,可代码上点鼠标右键,展开代码块。

  • 若代码有重叠,可在空白位置点鼠标右键,选整理块。

  • 若代码很少或者不全,可能是源码有多个屏幕。点左上角的Screen1,选择其他屏幕查看。


应用列表

忍者突袭

认识国旗

恐龙快跑

玉兔吃月饼

四则运算

汤姆猫

天气预报

大鱼吃小鱼

拼图(按钮版)

弹珠祖玛

聊天机器人

幸运转盘

指南针与水平仪

秒表

录音机

计算器

割圆术求圆周率

剪子包袱锤

捕鱼达人

读心术

单位换算

捉虫子

像素小鸟

公路赛车

汉诺塔

井字棋(双人对战)

打飞机(初级)

快算24

迎战陨石雨

数钱数到手抽筋

颜色找不同

青蛙过河

把灯关掉

四巧板

火柴人跑酷

见缝插针

对角线消方块

一笔画

抓住红色方块

水果连连看

超级染色

跳一跳

记忆小球改进版

重力迷宫

别踩白块

拼图1

记事本

贪吃蛇

撑杆过河

台球

一根筋

合到10

2048

俄罗斯方块

数字生存

数独

飞行棋

围住神经猫

泡泡龙

我的油漆桶

微信打飞机

连连看(改进版)

七彩连珠

推箱子

扫雷

太空大战

饼干消消乐

华容道

伤脑筋12块

水果忍者

别猜白块(按钮版)

16宫格拼图

五子棋

贪吃蛇(图像精灵版)

纪念日


Airtable extension

Description

Why another extension about Airtable? Because this one is different. This one can select/ insert/ update/ delete according to your filter/condition.

V2 Update history 2020/12/24

  1. fix bug of "can not update value with space", now in the formula, use " and " to quote the value with space.
  2. add perperty of FetchIdAndTime. if set to true, in the SelectFinished event you will get 'id' and 'createdTime' for each record.

2020-12-24_200204

  1. add method 'UpdateById' and 'DeleteById' for update or delete one record, which is faster than by filter.

    2020-12-24_200214

V1:

Add a picture of all the blocks

Initialize the extension

2020-12-13_104001 Same like other Airtable component, get your API Key, BaseId, TableName from the airtable website.

Select records

2020-12-13_104207

fields: String. or called "column names", Format like "name,age,phone". Leave it blank for all fields

filter: String. condition the records have to fit. Format like "age>30" or "OR(age>20, age<50)". For more info, please refer to here

pageSize: Number. how much records returned one time.. Max value 100.

offset: String. If the records fit the filter more than pageSize, you will get an offset at SelectFinished event, use it here for more records.

sort: String. the records will be ordered on this field. Format like "age desc" or "age asc"

count: Number. how much records selected.

records: String. Json format. it's a json array of dictionaries.

Insert records

2020-12-13_104231

records: String. Json format. it's a json array of dictionaries. Format like [{"name":"Jasmine Lake","age":43,"phone":"513937"}, {"name":"Ava Sharp","age":21,"phone":"293309"}]

IMPORTANT: If you want to feed this param with List component, remember to check "Show List As Json" at Screen1 Properties panel.

count: Number. how much records inserted. if count=0, means no records inserted.

Update records

2020-12-13_104254 filter: pls refer to Select part NOTE: ONLY up to 10 records will be updated. if more than 10 records fit the filter, there will be Error Cccured.

formula:String. How to change the data. Format like: "age += 1". there are spaces before and after the “+=”。 Now the accepted operators are +=,-=, *=, /=, = for number field, and to for string field.

count: Number. how much records updated. if count=0, means no records updated.

Delete records

2020-12-13_104311 filter: pls refer to Select part NOTE: ONLY up to 10 records will be deleted. if more than 10 records fit the filter, there will be Error Cccured.

count: Number. how much records deleted. if count=0, means no records deleted

Error Occurred

2020-12-13_104319 message: String. Error reason.

Download link here

aix: v1 v2

<结束>


AgoraRTC实时音视频扩展

本扩展基于AgoraRTC(实时音视频)技术开发。提供在同一频道内的多人语音和/或视频通讯功能。若想实现两个人的私聊,请自行在应用层控制进入频道的权限。

AgoraRTC提供每个账号每月10000分钟的免费额度,具体怎么计算时间,请参照这里

index.html

准备工作:

  1. 注册agora账号,网址:https://www.agora.io/cn/
  2. 进入控制面板
  3. 创建新项目,建议鉴权机制选择AppId(开发更简单,但安全性稍弱)
  4. 记下appId (这个很重要,注意保密)

代码块介绍

组件初始化

初始化之前需要设置appId。(如果准备工作中选择了鉴权方式为appId, 这里就不用设置token)

Snipaste_2020-06-16_12-07-34

Snipaste_2020-06-16_12-12-22

Snipaste_2020-06-16_12-12-31

加入频道

所有音视频通讯都在频道内进行。只有相同的appId和相同的频道名channel,才能互相通讯。

本扩展默认只开启语音通讯。

若需要开启视频,需要在加入频道前设置enableVideo(开启视频)为逻辑真,并且设置localLayout(本地视频显示布局)为某个垂直布局(或水平布局)。加入频道成功后,该布局原来内容会被清空,仅只能显示本次视频。

Snipaste_2020-06-24_09-43-54

加入频道是个异步操作,加入成功后在本地会收到OnJoinChannel事件。并返回一个uid(系统分配的用户编号)。

因为默认开启音频,收到本事件,表明你就可以开始音频通讯了。

Snipaste_2020-06-16_12-20-45

每次有其他用户加入频道,本地会收到OnRemoteUserJoin事件,并返回一个用户uid和userName(用户名)

Snipaste_2020-06-16_12-23-04

如果其他用户开启了视频,本地还会收到OnGetRemoteVideo事件,并返回一个用户uid

Snipaste_2020-06-16_12-25-01

在OnGetRemoteVideo事件中,使用setupRemoteVideo方法设置远程用户的视频显示在哪个布局里面。注意:一个布局只能显示一个用户的视频,多个用户需要设置多个布局。

Snipaste_2020-06-16_12-27-43

离开频道

离开频道,就会结束实时通讯,关闭所有视频。

Snipaste_2020-06-16_12-30-03

离开频道是个异步操作,成功后本地会收到OnLeaveChannel事件。

Snipaste_2020-06-16_12-32-01

频道内其他用户会收到OnRemoteUserLeave事件,并关闭相关的视频。

Snipaste_2020-06-16_12-35-05

发生错误

如发生错误,会返回一个错误代码,具体错误原因,可以在这里查找

Snipaste_2020-06-16_12-37-06

切换摄像头

切换本地视频前后摄像头

Snipaste_2020-06-16_12-39-39

开启关闭扬声器

开启或关闭扬声器

Snipaste_2020-06-16_12-39-46

其他

若想赞助其他功能,请直接联系我。


KevinkunAgoraRTC


组件描述:

Extension for real time communication via voice and/or video, based on AgoraRTC technology.

Agora have 10,000 free minutes per month.

Property

AppId

you need to sign up at here, and open Console, create one new project (for authentication mechanism, pls choose "App Id"), get the appId

2020-10-12_154027

Token

This property will be no use if you choose "App Id" for authentication when you create the project.

2020-10-12_154031

EnableVideo

default value is false, which means only voice talk enabled. Set it to true if video talk wanted.

2020-10-12_154022

LibUrl

the location where the agorartc sdk stored. Use this only when you want to host your own sdk. Contact me for more information.

2020-10-12_154035

Init

initialize the sdk.

if the app is running for first time, it will download the sdk from libUrl automaticly.

2020-10-12_153936

JoinChannel

try to join channel. If success, this will fire the OnJoinChannel event, and other user in the channel will get OnRemoteUserJoin event.

2020-10-12_153942

LeaveChannel

try to leave channel. if success, this will fire the OnLeaveChannel event, and other user in the channel will get OnRemoteUserLeave event.

2020-10-12_153948

SetupLocalVideo

set one layout (arrangemetn) to be the container of the local video.

Its' s to be called before JoinChannel

2020-10-12_153955

SetupRemoteVideo

set one layout (arrangemetn) to be the container of the remote video.

Its' s to be called inside the OnGetRemoteVideo event

2020-10-12_154000

EnableSpeakerphone

2020-10-12_154005

SwitchCamera

2020-10-12_154009

事件

OnRemoteUserJoin:

when other user joined the channel.

2020-10-12_154043

OnRemoteUserLeave

when other user left channel

2020-10-12_154047

OnJoinCnannel

2020-10-12_154052

OnLeaveChannel

2020-10-12_154057

OnGetRemoteVideo

Call SetupRemoteVideo method here

2020-10-12_154101

OnError

2020-10-12_154110


Chart图表扩展

下载链接

更新历史

  • 2020/05/15 修改label/legend/dataset参数为列表类型
  • 2020/04/19 发布

已知问题

初始化方法后必须稍等一段时间,比如1000毫秒后,执行ShowChart方法才有效,否则不能显示图表。

参数说明

  • type: 类别,支持以下之一:bar, horizontalBar, stackedBar, pie, doughnut, polarArea, line, radar
  • title:图表标题
  • label:相当于x轴上的标签,列表类型
  • legend:图例,列表类型
  • dataset:数据集合,二维列表(列表的列表)

使用方法

  1. 目前支持8种图表:折线图,条状图,水平条状图,堆叠条状图,雷达图,饼图,甜甜圈图,极坐标图
  2. 其中前5种支持多套数据,后3种支持一套数据。
  3. 参看以下图片,可以看出代码和图表的对应关系。

blocks-20200515_181759

Screenshot_20200419_194205


百度翻译扩展


下载

cn.kevinkun.KevinkunBaiduFanyi.aix

方法

  • 方法描述:
  • 翻译内容:待翻译的文字,语言种类自动识别。
  • 翻译语言:需要翻译到的语言,可以是zh,en,jp,fra,it等等,具体参看这里
  • 成功回调:回调函数需要1个参数 translation文本
  • 失败回调:回调函数需要1个参数reason文本型

2020-10-12_155423

属性

  • 属性描述:设置appid

    2020-10-12_155228

  • 属性描述:设置appkey

    2020-10-12_155233


EXCEL扩展

直接读取素材或者sdcard上的excel文件,无需转为csv文件。

仅支持xls格式,暂不支持xlsx格式

下载链接

方法

导入扩展后,将鼠标放到紫色块上停留,就会出现详情介绍。

读取工作表

mark

读取行

mark

读取列

mark

读取单元格

mark

其他功能

如果想赞助其他功能,请直接联系我。


比目微数据库扩展

内置的网络微数据库,服务器是国外公用服务器,速度慢,不安全。

比目微数据库可以代替内置的网络微数据库,但是更高效,更安全。

更新记录

  • v3 改为回调函数版本
  • v2 修复了返回值全部为文本的bug, 更名为BmobDB。自带默认appid,apikey和tablename,可以不用设置就直接使用(仅做测试之用,默认key随时可能失效)。
  • v1 新发布

下载链接

准备工作

  1. 注册比目账号 http://www.bmob.cn;
  2. 进入“我的控制台”,创建应用,进入应用,添加表,记住表名;
  3. 进入设置,记住 Application Id, Rest Api Key;

使用方法

V3:

保存数据

2020-10-12_160108

获取数据

如果数据不存在,会引发失败回调

2020-10-12_160101

V2:

跟内置的网络微数据库功能基本相同:

mark

注意:有点不同的是,保存数字、逻辑值、列表时,都会保存为文本格式。获取数据时,返回值也是个文本。

所以如果想保存列表的话,在组件设计界面,Screen1组件属性最下面,有个是否将列表转为JSON,这个必须选中。然后获取返回值后,可以使用Http客户端.解码json文本,变成列表格式。

2019-05-22_104913


手机联系人

下载链接

更新历史

  • 2019/05/23 发布

方法

根据姓名返回手机号

20190523192931

根据手机号返回姓名

20190523192954

exactMatch 是否精确查找

返回值是个列表的列表


KevinkunTools扩展

下载链接

cn.kevinkun.KevinkunTools

方法

获取手机的UniqueID

2021-01-10_201721

返回前n个自然数组成的列表

2021-01-10_201728

中文字符和unicode互相转换

20181113150303


LeanCloud扩展

更少的代码,做更多的事。。。

简介

包含6个部分,分别是

组件名中文具体描述
LeanStorage数据存储添加、查询、更新、删除 (本组件已经单独免费发布
LeanUser用户管理用户注册、登录、修改密码、重置密码等
LeanLeaderBoard排行榜功能添加成绩、获取成绩、获取前10,获取我前后成绩等
LeanFile上传文件上传文件
LeanCaptcha图形验证码获取和验证图形验证码
LeanMessage实时聊天发送文消息、接受消息,获取历史消息。不只是聊天

购买链接

准备工作

  1. 注册LeanCloud账号,网址是 https://www.leancloud.cn
  2. 可能需要实名认证;
  3. 进入控制台,新建应用(相当于关系型数据库中的数据库)。;
  4. 进入应用,点设置,点应用Keys,将右侧的Appid,AppKey,Rest Api服务器地址记下,初始化时用到;

代码示例

LeanUser 用户管理

blocks-20200512_143148

LeanLeaderBoard 排行榜

需要配合LeanUser先注册用户,需要事先创建排行榜:

进入LeanCloud控制台,进入应用,点左边游戏,点排行榜下的数据,新建排行榜。按你的要求输入相关参数,完成创建。

排行榜参数:

1.名称,不解释

2.排序,你的排行榜按升序ascending还是 降序descending排列

3.更新策略,better(提交多次成绩只记录最好的),last(多次记录只记录最后提交的),sum(所有提交的记录相加。)

4.自动重置频率,每个相应的时间,排行榜就重置。可以设为从不重置。

blocks-20200512_143014

LeanFile 文件上传

仅支持Leancloud华北节点,限制10m以下文件。

blocks-20200512_143108

LeanMessage 实时通讯

这个初始化,不能直接在屏幕初始化中进行,需要延时一段时间比如500毫秒。

需要配合LeanUser先注册用户。

blocks-20200512_143047

LeanCaptcha 验证码

blocks-20200512_142957


LeanStorage扩展

LeanStorage扩展可以作为app inventor应用的后端数据支撑。进行数据的增加、修改、删除、查询等功能。

更新记录

2020.3.22 支持回调函数,已部署在Wxbit服务器 的存储模块,不用下载,直接使用。

下载链接

点我下载aix(旧版本,使用返回数据事件接受返回数据)

不会使用扩展?点我

准备工作

  1. 注册LeanCloud账号,网址是 https://www.leancloud.cn;
  2. 可能需要实名认证;
  3. 进入控制台,新建应用(相当于关系型数据库中的数据库)。我这里是新建了个应用 Jiaocheng;
  4. 进入应用,点设置,点应用Keys,将右侧的Appid,AppKey,Rest Api服务器地址记下;
  5. 创建一个新的Class(相当于关系型数据库中的表)。我这里新建一个Class,叫Scores。

相关功能

扩展初始化

使用上面准备工作中的数据初始化扩展。

mark

插入数据

mark

  • 数据json:要写入的数据

假设我们要在Scores中保存班级里面学生的考试成绩。要添加学生的一条考试记录(包括学生姓名、语文成绩、数学成绩),数据Json可以这样写

{"xingming":"张三","yuwen":89,"shuxue":96}

如果同时添加多名学生成绩,可以这样写

 [
 	{"xingming":"张三","yuwen":56,"shuxue":89},
 	{"xingming":"李四","yuwen":69,"shuxue":83},
 	{"xingming":"王五","yuwen":98,"shuxue":87}
 ]

注意要加方括号(一条记录可以不用)。

  • 成功回调:若成功,返回插入成功的记录数

  • 失败回调:若失败,返回失败原因

查询数据

mark

  • 字段名字:需要返回的记录中包含的字段。比如你想返回姓名和数学,就写xingming,shuxue,中间用半角逗号分隔。如果是想取回全部字段,可以设为空字串。如果全部返回,返回记录中除去我们手动添加的xingming、shuxue、yuwen等字段外,还有三个系统自己添加的:objectId(每条记录的id号)、createdAt(记录添加时间)、updatedAt(记录修改事件)。

  • 条件json:记录符合的条件。为json格式。比如查询姓名是老王的纪录,可以写为{“xingming“:”老王“}。也可以使用字典组件构建,请参照leancloud文档查看写法。推荐用下面的构造条件json来构造。如果想取回全部记录,可以设为空字串。

  • 排序字段: 返回的记录按照哪个字段排序。比如我们要按照数学成绩降序排列,可以这样写:-shuxue。负号表示降序,正号或者没有符号表示升序。多个字段用半角逗号分隔。

  • 起始记录:从第几条开始返回。默认1

  • 最大记录数:一次最多返回记录的条数。默认100

  • 成功回调:若成功,返回查询成功的记录数数据json

  • 失败回调:若失败,返回失败原因

更新数据

mark

  • 条件json:见上面查询数据部分

  • 更新json:要修改的数据,json格式。例如

    • {"xinging":"zhang san"} 表示将符合条件的记录xingming字段改为zhangsan,
    • 或者{"shuxue":{"__op":"Increment","amount":5}} 表示将shuxe字段的值自增加5。
    • 具体请查看leancloud文档学习更多写法。推荐使用下面的构造更新json来构建。
  • 成功回调:若成功,返回更新成功的记录数

  • 失败回调:若失败,返回失败原因

删除数据

mark

  • 条件json:见上面查询数据部分

  • 成功回调:若成功,返回删除成功的记录数

  • 失败回调:若失败,返回失败原因

构造条件json

mark

这个辅助块可以构造查询(或者更新或者删除)命令的条件json。可以更快速、更简洁的写出查询条件,减少出错率。

比如我们要查询“数学成绩大于等于60 或者 语文成绩小于等于80”的学生记录,手动写json这样写:

{"$and":[{"shuxue":{"$gte":60}},{"yuwen":{"$lte":80}}]}

如果用字典组件来写,是这样:

mark

如果使用这个生成器,可以这样写:

mark

是不是非常的精炼,更加的符合自然语言。

  • 条件表达式:半角空格(至少一个空格)隔开的字符串表达式,必须为三段。第一段为字段名,两侧不要有引号,第三段为要比较的值(文本或者列表需要用半角双引号括起来。其中有"双引号要写为\"。\要转义为\\),第二段为比较符号,数字时支持=,<,<=,>,>=,!=,文本时支持like(模糊),is(精确),时间用before或者after,查询数组用in,nin,all。多个条件用and或者 or连接,并前后留有一个或以上空格。(暂不支持用括号改变比较顺序)中间的比较符号目前支持以下几种:
符号意义举例备注
=等于shuxue = 80比较数字
> 或 gt 或 $gt大于shuxue > 80比较数字
>= 或 gte 或 $gte大于等于shuxue >= 80比较数字
< 或 lt 或 $lt小于shuxue < 80比较数字
<= 或 lte 或 $lte小于等于shuxue <= 80比较数字
!= 或 ne 或 $ne不等于shuxue != 80比较数字
like包含(模糊查找)xingming like "张"比较文本
is等于(精确查找)xingming is "张三"比较文本
before...时间之前createdAt before 2020-02-20T00:00:00.000Z比较时间
after...时间之后createdAt after 2020-02-20T00:00:00.000Z比较时间
in 或 $in包含任意一个数组值id in "[2,3,4]"数组查询
nin 或 $nin不包含任意一个数组值xingming nin "[\”老张\”,\”老李\”,\”老王\”]"数组查询
all 或 $all包括所有的数组值hobby all "[\"skating\",\"reading\”]"数组查询
size 或 $size列表长度hobby size 3数组查询

构造更新json

mark

这个辅助块可以构造更新命令的更新json,更快速、简洁的写出数据更新json,减少出错率。

比如,我们要将姓名为‘张三’的学生的yuwen成绩和shuxue成绩分别加10分。我们可以这样手动写json格式的更新json:

{"shuxue":{"__op":"Increment","amount":10},"yuwen":{"__op":"Increment","amount":10}}

如果用字典构造,可以这样写:

mark

用本构造器来写,可以非常简单的用两个块来这样写:

mark

更新表达式: 半角空格(一个或以上)隔开的字符串表达式,需要为3段。第一段为字段名,第三段为要改变的值(文本或者列表需要用半角双引号括起来。其中有"双引号要写为\"。\要转义为\\)。第二段是修改符号。如:'=,+,-'操作数字。'to'操作字符串。'add,addunique,remove'操作数组。如果修改多个字段,多个表达式之间用一个或以上半角空格分开。

中间部分的op操作符号支持以下:

符号意义举例备注
+ 或者 +=原字段值累加shuxue + 10数字字段
- 或者 -=原字段值累减shuxue - 10数字字段
=原字段直接赋值shuxue = 10数字字段
is 或者 to原字段直接赋值xingming to 张三文本字段
add数组添加项hobby add "[\"sleeping\"]"数组字段
addunique数组添加不重复项hobby addunique "[\"sleeping\"]"数组字段
remove数组闪出项hobby remove "[\"sleeping\"]"数组字段

数据格式转换

mark

csvTable格式如:

xingming,yuwen,shuxue\n
张三,78,79\n
李四,60,90

jsonArray格式如:

[
	{
		"xingming":"张三",
		"yuwen":78,
		"shuxue":79
	},
	{
		"xingming":"李四",
		"yuwen":60,
		"shuxue":90
	}
]

这两个块可以配合Insert和AfterSelect,方便输入或显示数据,减少出错。


小白接口扩展

小白接口,免费,免开发,直接可用的云端数据接口

更新:

小白官网网址已经改为http://www.yesapi.cn

下载链接

准备工作

  1. 注册小白账号 http://www.okayapi.com
  2. 进入"我的套餐",记下接口域名、app_key、app_secret。
  3. 进入“我的数据库”,创建一个新模型(自定义数据库),记下数据库名和各字段名。

属性

2018-11-07_092119

设置接口域名

2018-11-07_092106

设置appKey

2018-11-07_092111

设置appSecret

2018-11-07_092125

设置是否显示隐藏错误信息。默认是否(不隐藏)。

方法

以下方法的接口参数格式,可以参照这里的接口文档 http://api.okayapi.com/docs.php自定义数据模型部分

2018-11-07_092315

查询数据库

table:数据库名

fields:字段名,多个字段用半角逗号隔开。空字串表示全部字段

where:查询条件,形式如 ["nianling",">","35"] ,空字串表示全部记录

第一个位置表示字段名称(字段必须先存在),

第二个位置表示判断>符号(可以是:>、>=、<、<=、=、<>、LIKE、NLIKE、IN、NIN、BETWEEN、NBETWEEN),

第三个位置表示判断值。

如果是多个条件,用半角逗号隔开,例如: ["id",">",9],["id","<=",10] 。

几个例子:

查询id=7,id=70,id=700这三个ID,可以写["id","IN",[7,70,700]]。

查询某个月1号到30号添加的数据,可以写["add_time","BETWEEN",['2019-06-01 00:00:00', '2019-06-30 23:59:59']]

logic: 如果where为多个条件时,logic可以设为and或者or

order:排序字段,形式如 gongzi DESC ,空字串表示按记录添加时间排序

limit: 返回记录的数量。最大2500,空字串表示默认500.

2018-11-07_092158

插入记录

table:数据库名

datas:插入的数据,需要json格式。形式如[{"username":"lee","score":80}]。如果是多条记录,用半角逗号隔开。注意必须有方括号

2018-11-07_092217

更新记录(文本方式)

data:要修改的数据,需要json格式。形式如{"username":"lee","score":80}。官方文档中不能有方括号,这里可有可无。

其他插口说明见以上方法

2018-11-07_092225

更新记录(批量四则运算)

field:要更新的字段

op:取值范围add/sub/mul/div,即加/减/乘/除

number: 待运算的数字,例如加多少,减多少,乘多少,除多少。必须为合法的数字,可以是小数

field=gongzi&op=add&number=500 就是gongzi=gongzi+500

2018-11-07_092236

删除记录

插口说明见以上方法

20181118194335027

将csv格式转化为json格式

比如shuxue,yuwen,yingyu\n78,89,78\n90,95,94 转化为 [{"shuxue":" 78","yuwen":"89","yingyu":"78"},{"shuxue":" 90","yuwen":"95","yingyu":"94"}]

事件

20181118194222724

查询结束事件

recordCount:符合条件的记录条数

recordList:查询结果,列表格式,第一行为字段名,第二行开始是数据

2018-11-07_092431

数据变化事件

添加、修改、删除后引发此事件。

affectedRowNum: 收到影响的记录条数

action:引发此事件的方法:insert/update/delete


规则表达式插件

下载地址

cn.kevinkun.KevinkunRegEx.aix

方法

regex1

GetMatches方法可以返回符合条件的字符串列表

SplitWith方法可以使用规则表达式对字符串进行分割,并返回列表

regex2

ReplaceFirst方法和ReplaceAll方法可以返回替换第一个或所有符合条件的子字符串后的新字符串

regex4

IndexOf方法可以返回符合条件的第一个字串的位置

regex3

IsMatch方法可以判断字符串是否符合规则表达式,返回真或假

IsNumber方法可以判断字符串是否为数字格式

IsEmail方法可以判断字符串是否为邮箱格式

IsStrongPassword方法可以判断字符串是否为强密码(至少8位,只好有1位大写和1位小写和1为数字)

IsEmail和IsStrongPassword可以用在用户注册、登录等情况


SocketIO客户端扩展

SocketIO客户端可以用来开发实时网络聊天,实时网络游戏等…

SocketIO extension can be used for real time chat, real time game, ...

下载链接

发送邮件到wangsk789@qq.com

Send a message to email: wangsk789@qq.com for the aix

方法与事件

设置服务器网址 URL

服务器需要自己搭建,方法见下面

You need to setup your own server, pleae check below to find how to.

There is a default URL you can use.

mark

设置存储空间 Namespace

用于区分同一服务器上的不同应用。给你的应用取一个独特的空间名。

There can be more than 1 app runing on the same server, there should use different namespace.

Always give your app a unique namespace.

mark

连接服务器 Connect

用户名必须是独一的

Try to connect with the server. the username should be unique underwater the same namespace.

After connected, you will get a connected event.

mark

断开连接 Disconnect

因网络原因断开连接,也会引发 已断开连接 事件 (和离开房间事件,如果在房间内)

Disconnect with the server manually.

Fired when the internet lost connection, or you leave the room manually (if you are in a room).

mark

自动匹配房间/取消匹配房间 AutoMatch/CancelMatch Event

AutoMatch会进入排队队列,排队人数达到要求,会自动加入一个房间(房间名随机)

AutoMatch will let you be in line waiting. When the amount reach the compacity, they will join a random room automaticly.

And get a Matched event, and the userlist in the room

mark

主动加入房间 JoinRoom

房间内所有人(包括自己)都会收到此消息

Try to Join a room with room name. If succeed, you will get a JoinedRoon Event.

When other user joined the room (if you are in this room), you will also get this JoinedRoom event.

mark

主动离开房间 LeaveRoom

用户会收到Leftroom事件,其他人收到OtherLeftRoom事件

Try to leave the room

If succeed, you will get a LeftRoom Event. And other user (still in the room) will get OtherLeftRoom event.

mark

发送消息 Send Message

房间内所有人会收到消息

Send a message to the users in the room

If succeed, all users in the room (including the sender) will get a GotMessage event.

mark

设置房间容量 SetRoomCapacity

同时也是排队人数。默认房间最大人数2人

Set up how many users can be in the room (also the match up line up).

This should be called after connected to server.

Default capacity is 2.

mark

发生错误事件 Got Error

mark

如何自己部署服务器 How to setup server.

服务器源码已经上传到gitee。 点这里 获取源码,你可以将它部署到支持nodejs的服务器上。

the code is on Gitee : HERE , you can download and then deploy to your own server.

最后的话 Other

Socket.io的功能远不止如此,如果你有其他的需求,请直接联系我。

If you want more function, please feel free to contact me.


Enhancement 系统界面增强扩展

Enhangcement可以设置组件的背景色、背景图像、边框、圆角矩形、外边距、内边距、高程、使用自定义字体等

更新历史

v4 增加背景色渐变

v2 增加文本行间距、字间距,增加进入全屏模式

v1 第一次发布

下载链接

v4.aix

v2.aix

v1.aix

示例截图

实时调整布局外观(感谢ldtxinkai提供截图)

mark

属性块

设置背景颜色及圆角

背景颜色fillColor、边框宽度borderWidth、边框颜色borderColor、圆角半径roundRadius。

"圆角半径可以是一个数字(同时设置四个角),或者是四个数字用逗号隔开(顺时针分别设置左上、右上、右下、左下)。

mark

设置背景图片及圆角

背景图片imagePath、边框宽度borderWidth、边框颜色borderColor、圆角半径roundRadius。

imagePath:以//开始表明是素材,以/sdcard/开始表明是在外部存储卡。

"圆角半径可以是一个数字(同时设置四个角),或者是四个数字用逗号隔开(顺时针分别设置左上、右上、右下、左下)。

mark

设置外边距

设置组件的外边距margin。外边距可以是一个数字(同时设置四个方向),或者是四个数字用逗号隔开(分别设置左、上、右、下)。

mark

设置内边距

设置组件的内边距padding。内边距可以是一个数字(同时设置四个方向),或者是四个数字用逗号隔开(分别设置左、上、右、下)。

mark

设置高程

设置组件的高程elevation。会在组件周围显示阴影效果(必须提前设置背景)

mark

设置自定义字体

设置组件字体。fontName字体名以//开始表明字体在素材库,以/sdcard/开始表明在外部存储卡。

mark

其他

组件component那里不仅可以接布局,还可以接标签、按钮等。更多可能等你去发现~~~

有疑问或者bug请在下方留言。


网上收集的扩展

Account Manager Extension账号管理链接
ActionBar Extension导航栏链接
Advanced Android Toast消息提示框链接
AdvancedBarcodeScanner Version2二维码条形码扫描链接
Alarm Extension闹钟链接
AndroID Extension获取手机信息链接
Android Theme Extension主题 设置应用主题链接
Animacion Extension动画 按钮、文本框、复选框、图像、布局等动画效果链接
Animated Gif Clickable. Transparent bggif动画链接
Animation Color background extension背景颜色动画链接
Another AES encryption extension加密与解密链接
AppyEcho mic to speaker with pitch control声音有关 设置音高、音量等链接
Arduino USB Serial ExtensionArduino Arduino相关链接
AsyncImageLoader异步图片加载器链接
Audio Player Extension音频播放器链接
Augmented Reality Plugin on Scene3DScene3D插件链接
AutoCompleteBox文本输入框提示链接
BaiduFanyi百度翻译Api链接
Barometer Sensor Extension气压传感器链接
Battery Manager Extension电池管理链接
Bitwise Extension位运算链接
BluetoothLEBLE链接
Button Addon extension按钮增强 设置按钮图标和文字提示链接
Call Android API from string调动andriod API链接
Cameraviewer摄像机视图链接
CameraViewer Extension摄像头视图链接
Canvas scale gesture extension画布缩放比例链接
CardView Extension卡片视图链接
Cell finder手机位置链接
ChartMaker图表生成器 饼图、柱状图、线性图等链接
Circular Progress Extension (Preview)环状进度指示器链接
Clipboard Extension剪切板链接
ColinTreeFirstRun判断首次运行链接
ColinTreeGoHome返回手机桌面链接
ColinTreeIMEI获取手机识别号链接
ColinTreeListView自定义列表显示链接
ColinTreeNinePatch9-patch位图显示器链接
ColinTreeNotifier系统对话框链接
ColinTreeSlideShow图片轮播链接
ColinTreeSysLang获取系统语言链接
Color Extension颜色值转换 ai颜色值与HEX, RGB互转链接
ColorPicker颜色选择器 选择颜色 调色板链接
Colours Extension颜色链接
Control Dimmer Extension仪表盘 汽车仪表盘样式的数字指示链接
Create Pdf from Table Extension生成pdf链接
Create QR code without network二维码、条形码 创建二维码、条形码链接
Create TextBox by code. Set and Get text动态创建文本框链接
Create WebViewer by code动态创建网页浏览器链接
CreateView动态创建多种组件链接
cropping the image图片裁切链接
CssAnimation Extension图片动画链接
CSV to Json encode ExtensionJSON工具集链接
Date Tools (was Working Days)日期工具链接
Date Utils Extension日期工具链接
Delete characters from a text文本删除字符链接
DialogAnyThing对话框 将布局作为对话框弹出链接
Dialogs Extension对话框链接
Display Table in Webviewer Extension表格 将csv格式文本用表格形式显示链接
Distance tools extension两点距离链接
DotsView Extension点状进度指示条链接
Dual SIM IMEI Viewer Extension双卡手机链接
Dynamic Component Extension动态组件链接
DynamicCompanion Extension v2动态组件 设置组件属性链接
Entity Keyboard Extension按键事件 调用某个按键的按下、抬起等事件链接
Evaluator JS extension运行javascript链接
EventCaller (in test) by ColinTree事件调用链接
Explorer Files文件浏览链接
Extended Web Viewer Extension网页浏览器功能扩展链接
Extension AirtableClassicairtable数据库 保存 查询数据链接
Extension change the design of the button按钮设计 按钮样式设置链接
Extension ComponentToImage组件转图片链接
EXtension ExplosionAnimation for components组件爆炸特效链接
Extension FlipShare可作为弹出菜单链接
Extension HalfMenu底部浮动按钮链接
Extension InfinityProgressBars (Version 2)进度指示条 有多种样式链接
Extension JSignature签名 将签名转为base30字串链接
Extension Mqtt for websocket Arduino y Esp8266Mqtt通讯链接
Extension PulseAnimator脉动动画链接
StepProgress Horizontal StepView步骤进度指示条链接
ExtraComponents Extension动态组件链接
File Extension文件管理链接
FileAlt文件管理器链接
FileInfo文件管理器链接
Flashlight Extension手电筒链接
Floating Action Bar Extension悬浮按钮链接
FontArt Extension艺术字体链接
Gesture Handler Extension手势处理链接
Get all TinyDB Extension微数据库链接
Get Frequency tone Microphone声音频率链接
Get IP Address获取IP地址链接
Get Level sound Microphone声音有关链接
Get Location Details位置 根据经纬度求位置链接
GetAllIpwifi ip地址链接
Glide Extension (SPONSORED!)图片加载链接
Gradient in a Layout. Colors by list背景色渐变链接
HackProtect Extension是否root等链接
Headset Plug Status Extension耳机链接
HorizontalArrangementAddons extension垂直布局增强链接
Hotspot Extension手机热点链接
Image Editor Extension图像编辑链接
Image Extension图片处理 剪切、修改大小、旋转、切成碎片等链接
Image interceptor viewer图片裁切 可视化的裁切图片链接
Image Metadata Extension文件元数据链接
Image Print Extension图片打印链接
ImageProcessor图像处理 合并两张图片链接
Install app安装应用链接
Introducing DeviceInfo设备信息链接
Joystick Extension游戏手柄链接
JsonUtilsJSON工具链接
Kawa Parser Extensionkawa字串解析链接
LableImageClick标签、图片点击事件链接
LED View ExtensionLED灯视图链接
Light Sensor Extension亮度传感器链接
Limited String List Extension有限字符串列表链接
List Utils Extension列表工具链接
Look神经网络识别物体链接
Magnetic Sensor Extension磁力传感器链接
Material Card卡片视图链接
Math Extension数学 可以计算一个数学表达式链接
Memory Info Extension内存信息链接
Memory Size Extension内存大小 手机内存相关数据链接
Metatag per file mp3音频元数据 获取音频文件元数据链接
Microsoft Emotion Recognizer微软表情识别链接
Microsoft Image Recognizer微软图像识别链接
Mp3Duration extension for get length of mp3 and video音频视频时间长度链接
Multitouch多点触摸链接
Multitouch in Canvas画布多点触摸链接
New improved Notification Extension改进版桌面通知链接
New Notification to status bar extension桌面通知链接
Notification, run application. Background. Foreground. Run桌面通知链接
Notify_v3 Extension桌面通知链接
OCR Extension (Version 5)文字识别链接
Package Manager Extension包管理器链接
PasswordBoxSwitch密码框文字可见度链接
PDF Viewpdf查看链接
PedrozaThumbnail Extension缩略图链接
QR Code Extension二维码链接
QuizMaker Extension测试出题链接
Radio Buttons Extension单选按钮链接
Rating Bar Dialog评分条链接
Rating Bar Extension评分条链接
ReadMoreLabel Extension显示更多文字 可以在显示部分文字和全部文字间切换链接
RippleEffect Extension波纹效果链接
Root Checker ExtensionROOT检查链接
ScaleDetector画布缩放比例探测链接
Scene3DScene3D链接
ScrollArrangementHandlers滚动布局管理器链接
ScrollBar Extension滚动条样式链接
Security Extension安全加密与解密 ASS, BASE64, MD5, RSA, SHA256, SHA1链接
Settings Extension设置链接
Sharing Extension分享链接
Sidebar Navigation侧边导航栏链接
Simple Notification Extension桌面通知链接
Simple Pdf Tools extensionpdf工具 提取文字、图片等链接
Simple Web Server Extension by Juan Antonio简易文件服务器链接
SimpleBase64图片和BASE64互转链接
SliderThumbColor Extension滑动条样式链接
SliderTools Extension v2滑动条工具链接
Small Camera相机扩展 拍照前可以设置图像保存位置链接
Snackbar extension消息提示框链接
Sound Wave View Extension波动曲线视图链接
SoundAnalysis声音分析链接
SourceCodeWeb获取网页源码链接
spacing between lines in a label文本行间距链接
Special Tools Extension特殊工具链接
SQLitesqlite链接
SQLite extension (SPONSORED!)sqlite链接
sunset/rise times日升日落时间链接
SwipeRefresh下拉刷新链接
Switch Extension开关按钮链接
TableView Extension v3表格视图 将数据显示为表格 支持点击事件链接
Tabs Extension页面切换指示器链接
Tabs swipe Look whatsapp滑动切换页面链接
Take Screenshot Extension屏幕截图链接
Telephony Manager Extension手机信息链接
Terminal / Shell Extension by Juan Antonio终端命令链接
TexboxSyn文本框增强链接
Text Utils Extension文本工具链接
Textbox Extension文本框增强链接
TextBox/PasswordTextBoxHelper文本框增强 文本框内容回撤 重做 文本变化事件等链接
Texting Extension短信链接
TickView Extension Preview精致带感的打钩小动画链接
TimerX循环链接
TinyDBX Extension微数据库链接
ToneGenerator声音有关链接
ToneGenerator声音有关链接
Tools Extension工具集链接
TouchEvent触碰事件链接
UDP client extensionUDP客户端链接
UDP Extensionudp通讯链接
VectorArithmetic向量运算链接
Vibrate extension震动链接
VU Beta. Free beta Extension声音 振幅链接
WaveAudioTools extension音频 声音有关链接
WavRecorder extension录音链接
WavSoundRecorderExtension录音链接
Web Viewer Dialog网页浏览器对话框链接
WebSocket Client ExtensionWebSocket客户端链接
WebViewer Interact Extension网络浏览器增强 可以与网页浏览器交互链接
WEBVIEWTOOLS Extension网页浏览器功能扩展链接
Welcome Screen Extension欢迎屏幕链接
WheelView Extension拨盘视图链接
WiFi Manager Extensionwifi相关链接
Zip/Unzip Extension压缩与解压缩链接
Zoom, rotate, drag image图片缩放链接

动态组件

有动就有静。静态组件(这是我自己用的一个概念,方便理解,实际开发环境中并没有这个称呼),就是我们在组件设计界面手动从左侧组件面板拖入工作面板,显示在组件列表中的,可以在组件属性面板对他的属性进行手动修改。

动态组件,是在逻辑设计界面,使用代码块来生成的,只有在调试或安装运行时可见的组件,他不会出现在设计界面的组件列表里面。

如何生成动态组件?

要生成动态组件,需要有两个参数,一个是新组件的父容器,一个是新组件的类型。

新组件要有个父容器,就是要把它显示在哪里?也就是说,必须是容器类的组件,才可以生成子组件。所以动态组件块的位置,只会出现在容器类组件抽屉里面。

何为容器类组件,就是比如屏幕、水平/垂直布局、水平/垂直滚动布局、表格布局、层叠布局,画布、地图等组件,可以生成相应的子组件。

比如屏幕1的动态组件块位置,非常简单,就一个积木块。

2020-12-31_135858

其他容器类组件下都有这样的创建块。

点击创建右边的下拉框,就可以选择要生成的新组件的类型(仅支持生成可视化组件)。

如何设置新组件的属性?

只要配合任意组件里面的积木块,就可以设置新组件的属性。

比如,我们需要生成10个按钮,每个按钮的文本就是他的编号,颜色设为随机,可以这样用:

2020-12-31_141222

错误用法:

2020-12-31_141326

如何获取/引用组件

上面的例子中,我们把新组件保存在一个局部变量中了,设置完属性后,后续操作那个局部变量就不管用了。如果还想操作这个组件怎么办?

1.是可以在创建时保存在一个全局变量中,但是如果创建很多组件,就要创建很多全局变量,这样动态组件的优点就荡然无存了。

2.是保存在一个列表中,但是需要知道组件在列表中的位置才能取出。

3.是保存在字典中,给每个组件起不重复的名字作为键名,组件本身作为键值。使用时通过键名取出组件。

2021-01-02_114008

4.是使用设置组件名称块,通过屏幕抽屉下的获取组件名称块来获取组件。

2021-01-02_114028

如何添加事件?

新组件生成了,如何与用户交互呢?可以响应用户的点击、按压等事件吗?有两个方法:

1 是对某一类组件使用任意组件里面的通用事件,比如:

2020-12-31_142753

这样的缺点是对屏幕上所有的同类的组件都适用这个事件,如果需要精确到某个或某几个就需要在事件中进行判断。或者在创建组件时,设置他的扩展属性,然后通过扩展属性值进行区分。

2 是对单个组件的某事件绑定回调函数:

2020-12-31_143340

还可以删除绑定的回调函数:

2020-12-31_143713

如何删除动态组件?

有些组件功能结束了,可以将它删除:

2020-12-31_143938

自删除功能不仅适用于动态组件,手动拖入的静态组件也可以使用。

如果他是个容器类组件,使用自删除后,他本身连同其内部的子组件也会一起被删除。

如果希望只是删除他的子组件,可以使用这个清空积木块:

2020-12-31_144310

举个例子1:国际象棋棋盘

我们要在屏幕上显示8行8列共64个标签,做成国际象棋棋盘样式。

这个可以通过设计界面拖入64个标签,并分别设置宽高颜色并设置点击事件来完成,但是比较累,比较傻。

blocks-20201231_152335

举个例子2:成绩排行榜

待续

举个例子3:模仿微信聊天界面

待续


扩展组件开发环境搭建

App Inventor 2允许我们自己开发扩展组件,但是MIT原生的编译环境搭建相对比较复杂,费时费力。本文介绍一个比较轻便的aix编译器。

本编译器由Zhangzq网友开发,在此对他的辛苦付出表示感谢。

  1. 下载java jdk,开发扩展只用jdk1.8就可以了。安装并配置好环境变量,参看这个教程

  2. 下载AIX Complier,并解压到电脑。下载地址,也是Zhangzq的Gitee仓库, 本例是解压到E盘aixcompiler文件夹下:

    2020-11-10_134622

  3. 双击aixc.bat文件,可以看到aixCompiler的用法如下:

    2020-11-10_133733

  4. 右键点击,另存这个模板文件,解压到E盘。它的目录结构是 Test AIX是项目名,下面有src,assets,jni,lib等目录。

    src文件夹是存放源码文件,在src内按照包名的顺序再建立文件夹和java文件,结构如图:

2020-11-10_134200

其中,TestAIX.java就是扩展的源码,是个文本文件,可以用很多的文本编辑器打开(比如notepad++, editplus等等,并且保存为utf8格式的文本。切记不要用windows自带的记事本和写字板打开。)。你可以在这个模板基础上修改成你需要的代码。注意包名和目录结构的对应关系。

如果要引用素材资源,需要把资源放在assets文件夹下,在源码中添加:

@UsesAssets(fileNames = "assets1.html,assets2.js")

如果要导入其他jar包,需要把jar文件放在lib文件夹下,在源码中添加:

@UsesLibraries(libraries = "someJarFile.jar")

如果要引用so包,需要把so文件放在jni文件夹下相应的类别中,并在源码中添加(官方文档是这样写的,但是测试并不成功):

@UsesNativeLibraries(v7aLibraries = "someSoFile.so")
  1. 打开命令行窗口(按win+R,运行cmd命令),执行如下命令:

    E:\aixcompiler\aixc.bat E:\TestAIX
    

    2020-11-10_135025

如果不想输入代码或者怕输入错误,可以直接拖动TestAIX文件夹到aixc.bat文件上,等同于执行上述命令。

  1. 如果没有错误的话,会显示编译完成及用时。如图:

    2020-11-10_135415

    如果看不到倒数第二行的“编译完成,累计用时”这几个字,说明有错误,请仔细查看窗口显示的提示信息,修改源码。

  2. 编译完成,会在TestAIX文件夹下生成一个build文件夹,aix扩展文件会保存在E:\TestAIX\build\outputs文件夹下。(同时还有个md文件,这个是同步生成的aix说明文件,可以配合gitbook生成html文件。有兴趣的自行研究,这里不作说明)

  3. 现在可以将aix导入wxbit(将aix文件直接拖动到wxbit的组件设计界面就可以导入),扩展导入后如下图。你可以对照源码,看看这些块是对应的源码中的哪一部分。

    2020-11-10_140102

  4. 记事本编辑源码虽然简便,但是没有代码提示,不能很好的组织文档,建议使用Eclipse或者其他高级的代码编写软件。

    2020-11-10_141809

  5. 多多查看其他的app inventor组件的源码,可以更好的了解如何写aix。

《完》


自己搭建网络微数据库后端

系统自带网络微数据库使用国外的服务器,速度太慢?使用比目微数据库,数据存在别人服务器上,不安全?下面介绍自己搭建简单的网络微数据库后端。不用复杂的mySQL知识。

准备工作

首先你要有自己的服务器,可以把相关文件上传,服务器要支持php。

下载文件 myTinyWebDB.zip ,解压,上传到你的服务器。

我是在本机测试(win10+wamp64),文件结构如下:

2020-04-14_104222

其中index.php文件内容如下:

<?php

	header("Content-Type: application/json");
	$file = "database.json";

	if ($_SERVER['REQUEST_METHOD'] != "POST" || !isset($_REQUEST['tag'])) {
		die("BadRequest");
	}

	if (isset($_REQUEST['value'])){
		
		$tag = trim($_REQUEST['tag']);
		$value = trim($_REQUEST['value']);

		$f = fopen($file, 'r');
		$data = fgets($f);
		fclose($f);

		$parsedData = json_decode($data, true);
		$parsedData[$tag] = $value;

		$f = fopen($file, 'w') or die("Can't open file");
		fwrite($f, json_encode($parsedData));
		fclose($f);

		$result = array("STORED", $tag, $value);
		echo json_encode($result);
		
	}else{

		$tag = trim($_REQUEST['tag']);

		$f = fopen($file, 'r');
		$data = json_decode(fgets($f), true);
		fclose($f);
		
		if(isset($data[$tag])){
			$result = array("VALUE", $tag, $data[$tag]);
		}else{
			$result = array("VALUE", $tag, "");
		}
		echo json_encode($result);
		
	}
?>

其中database.json文件内容如下(就一对括号):

{}

好了,运行你的服务器,已经可以开始用了。

逻辑设计

2020-04-14_104710

这里192.168.0.104是我本机的ip,你要换成你自己的服务器地址。

ok,网络微数据库就可以跟以前一样使用了。


Gitee做文件存储服务器

很多同学在制作app过程中,需要有很多的素材如图像啊、视频啊。如果都放入素材库,APP会超过服务器限制(一般是10m)。如果你没有自己的文件存储服务器,可以将文件存储在gitee上。

准备工作

  1. 注册Gitee账号点我,建议用邮箱号注册。

  2. 登录gitee,点右上角的加号,新建仓库。

  3. 仓库名称随便写,比如repo,或者store,这个随意。

  4. 是否开源选 公开

  5. 选中 使用Readme 文件初始化仓库

  6. 点 创建,完成创建仓库。

  7. 网页拉到最底下 打开OpenAPI这个链接,或者点这里进入api文档。

  8. 依次打开左侧的 api文档–-> 仓库 –> 新建文件,这里有新建文件(也就是上传文件到这个库)的接口文档。

  9. 点右上角 申请授权,同意授权,记下在access_token的值。

  10. 其他参数有:owner是注册时的用户名,repo就是仓库名,path就是你要上传的文件名,content就是要上传的文件的base64编码,message就是git中的commit,这里可以随便写。

  11. 在owner、repo、path、content、message中随便写上a/b/c/d/e ,点测试,下面会出现这个:

    mark

  12. 根据这个curl命令,就可以写出我们的http客户端请求了

逻辑设计

主要代码有:

  1. 选择文件,取得文件名(下图是filename,就是上面说的path)
  2. 对文件进行base64编码

mark

  1. 拼接http客户端网址
  2. 设置请求头
  3. 执行post文本。文本是json格式,可以用字典创建。

mark

  1. 将响应文件转为字典
  2. 如果响应代码=201,标明是成功上传了。
  3. 提取字典中的download_url的值,这个就是上传的文件的连接了。(其实返回值中还有其他几个网址,经试验,只有这个download_url是文件的直接连接。)

mark

有了文件url,就可以图像框显示出来,或者发送给朋友了。

其他

以上方法,只适用于图片。如果是其他格式,可以通过开启Gitee Pages来获取资源网址。


Goeasy实现实时网络聊天室

前期准备

本教程使用了GoEasy的网络消息实时推送技术。

  1. 注册账号。 GoEasy官网(https://goeasy.io)
  2. 登录到GoEasy的后台管理系统,创建您自己应用app.
  3. 应用创建好之后系统会自动为您生成appkey。有两个,一个是只能接受消息,一个是既可以发送,也可以接收消息。
  4. 免费版本有1年的试用期,可以推送100000条消息,对于学习试验应该是足够了

组件设计界面

4b5887fe9925bc313ebd54ef52df8db1ca137016

  1. 标签:聊天显示区。文本设为空,其他属性默认
  2. web浏览器。可见性设为否,其他属性默认
  3. 文本框:发送人ID 文本设为空,其他属性默认
  4. 文本框:发送内容 文本设为空,其他属性默认
  5. 按钮:发送按钮
  6. 计时器:计时间隔设为50,其他属性默认
  7. web客户端。属性都是默认

准备素材

将以下代码保存为goeasy.html,并上传到素材库:

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="http://cdn-hangzhou.goeasy.io/goeasy.js"></script>

</head>
<body>

</body>
<script type="text/javascript">
	var goEasy = new GoEasy({
		appkey: 'BC-7002587937f4419484a78fe674139818' //这里替换为自己的appkey
        
	});
	goEasy.subscribe({
		channel: "CH1",
		onMessage: function(message){
			window.AppInventor.setWebViewString(message.content);
		}
	});
</script>
</html>

实现的思路:

  1. 使用web浏览器访问goeasy.html文件,订阅某个频道(这里是CH1)。只要这个频道下的数据有变化,系统就自动将变化的内容写给web浏览器的页面交换字串。
  2. 使用web客户端来发布消息到CH1频道。这样,只要订阅了这个频道的人,都可以收到此消息。

逻辑设计界面

2018-11-22_121312

  1. 定义一个变量叫频道。这个变量的值可以修改,但必须与goeasy.html中的channel值相同
  2. 定义一个变量KEY。因为是聊天程序,使用的是超级key(可发可收)这里要替换为自己的key
  3. 定义个变量开发中。(注意:若要把本程序打包apk,必须先把这个变量设为假。若在手机伴侣中测试,设为真)
  4. 给用户一个随机ID
  5. 不用解释了
  6. web浏览器若要使用素材库中的文件作为网络地址,在开发时和打包时使用不同的路径,需要根据情况修改开发中的值,见第3条。
  7. 让web浏览器访问这个goeasy.html文件,就是订阅了CH1频道。
  8. 若两个文本框都不为空
  9. 这个网址在goeasy创建的应用后台管理里有。
  10. 把消息发送出去。post文本的组成:必须有三个参数:appkey、channel、content。content需要使用URI编码
  11. 不用解释
  12. 让计时器不停的去问web浏览器是否收到消息。若页面交换字串不为空,表明web浏览器接收到了新消息。
  13. 把新消息显示出来。
  14. 把页面交换字串设为空,方便下次访问

http客户端获取和风天气api接口数据

应用与外界交互,使用api接口是最常见的。现在利用wxbit解释下如何获取和风天气的天气预报api。

准备工作

  1. 和风天气网站(https://www.heweather.com)注册账号。
  2. 进入控制台,应用管理,新建应用。(貌似免费用户只能建一个免费账号。)
  3. 记住应用的key。

组件设计

组件设计界面,拖入3个可视组件:文本输入框、按钮、标签,1个非可视组件:http客户端。(这个是wxbit服务器新改名的组件,赞一个。原名叫web服务器,翻译的有些不知所云)

这里就不放组件设计图了,太简单了。主要是介绍原理,如何美化应用不在这里讨论。

逻辑设计

要使用api接口,就必须要看api接口文档。重要的事说3遍,看文档~~ 看文档~~ 看文档~~

我们打开这个文档(https://dev.heweather.com/docs/api/weather),有几个关键的点要看到:

  1. 获取方式:GET 方式

  2. 数据格式: JSON,这里是说返回的数据是JSON格式,就是键值对格式。

  3. 免费版的请求URL: https://free-api.heweather.net/s6/weather/{weather-type}?{parameters} 花括号中的东西就是我们要按我们的要求替换的,连带花括号也要换掉。

  4. weather-type参数,我们这里选forecast, 就是获取未来3天的数据

  5. parameters参数,就是我们要告诉接口的请求参数,这里有location就是城市名称,中文或者拼音都可以,key就是准备工作中记下的key。

我们现在开始来获取这个api,看看有什么返回值:

  1. 初始化一个变量,记录key

    mark

  2. 构造请求URL

    mark

    特别注意的就是url网址中的forecast后面有个?, key前面有个&

    ?用来分割主url和后面的参数,&是用来分割多个参数。而每个参数都是形如参数名=参数值这样的。

    设置好网址,就可以执行GET请求(还记得上面说的获取方式是GET吧)。

  3. 因为关系到网络的传输,速度不确定,所以get请求这个动作,有个异步的HTTP客户端.获得文本这个事件,我们就用它来接受返回的结果,并显示在调试窗口。

2020-10-17_174132

现在就可以连接手机,在文本框中填入城市名称,运行app看看返回值如何。(尽管文档中明确说参数如果是中文的,需要进行url编码,但是这里我们直接输入中文城市名,貌似也可以)

在设计界面右侧的调试信息窗口,显示如图:

2020-10-17_174614

哇~~什么鬼?密密麻麻的。其实这就是返回的json字符串了。

如果你的显示跟我的相差很多,比如像这样很短的:{"HeWeather6":[{"status":"invalid param"}]}, 说明你的参数设置有误,请检查key是不是有错误,url是不是拼接错误,也有可能是你的每月免费额度用完了。这里是具体的状态码的意义(https://dev.heweather.com/docs/refer/status-code)。

解析返回值

这里推荐一个网站,http://www.bejson.com/ 这个网站可以将json字串格式化,方便我们看清层级关系。

将调试窗口的信息复制(那个时间戳不要复制),在这个网站进行格式化。

格式化后的json字符串格式如下(数据太长了,后面省略一部分):

{
	"HeWeather6": [{
		"basic": {
			"cid": "CN101010100",
			"location": "北京",
			"parent_city": "北京",
			"admin_area": "北京",
			"cnty": "中国",
			"lat": "39.90498734",
			"lon": "116.4052887",
			"tz": "+8.00"
		},
		"update": {
			"loc": "2019-05-25 14:58",
			"utc": "2019-05-25 06:58"
		},
		"status": "ok",
		"daily_forecast": [{
			"cond_code_d": "101",
			"cond_code_n": "302",
			"cond_txt_d": "多云",
			"cond_txt_n": "雷阵雨",
			"date": "2019-05-25",
			"hum": "64",
			"mr": "00:12",
			"ms": "10:17",
			"pcpn": "0.0",
			"pop": "0",
			"pres": "998",
			"sr": "04:51",
			"ss": "19:32",
			"tmp_max": "35",
			"tmp_min": "22",
			"uv_index": "6",
			"vis": "13",
			"wind_deg": "185",
			"wind_dir": "南风",
			"wind_sc": "3-4",
			"wind_spd": "15"
		}, {
			...
		}, {
			...
		}]
	}]
}

json字串看起来复杂,其实只要记住2条就可以了

  1. 碰到{ 左侧花括号的,就用在键值列表...中查找... 提取

    mark

  2. 碰到 [ 左侧方括号,就用选择列表...第...项 提取

    mark

看上面的json字串,最外面是HeWeather6, 下面是个方括号,再里面是 4个平级的键basicupdatestatusdaily_forecast

我们关心的是后面两个。如果status是ok,说明没有出错,才能提取daily_forecast

接下来,我们从上到下,从外到内的一层层提取第一天的最低气温和最高气温。

mark

  1. 把返回的json字串解码为键值对列表。
  2. 获取HeWeather6 的值,注意HeWeather6 前是花括号, 用在键值列表...中查找... 提取
  3. 注意HeWeather6的值是个方括号,要用选择列表...第...项提取
  4. 判断返回的数据是不是我们想要的
  5. 如果返回的格式正确,就提取3天的天气预报数据
  6. 注意这里daily_forecast后面又是个方括号,第一项就是第一天你的数据,第二项就是第二天的数据啦。
  7. 现在就可以直接提取最低温和最高温了。

这里可以多初始化几个变量,分别记录第二天、第三天的数据。

有了这些数据,你就可以构造你的天气app啦


更新

20190525

我们可以自定义一个过程,更加方便的解析json字串:

mark

  • listInPairs 键值对列表

  • keyPath 要提取的键的路径,键名或索引值用半角逗号隔开

    像上面的json字串,我们要提取第3天的最高气温的值,

    最外层是HeWeather6, 然后是方括号要提取第一个,keyPath就是HeWeather6,1

    再提取daily_forecast下的第3项,keyPath就是HeWeather6,1,daily_forecast,3

    在往下就可以提取tmp_max的值,keyPath就是HeWeather6,1,daily_forecast,3,tmp_max

    可以这样组织代码:

    mark

    更新

    20200319

    wxibt已经更新增加了字典组件,有了以下两个改进:

    1. 上面的keypath概念,就不用自己写自定义函数(原来的过程,现在改名叫函数)了
    2. 解析json字串不用http客户端.解析json文本了,可以使用字典内置的json转字典

    现在,提取第3天的最高气温的值,可以这样写

    2020-10-17_175604


连接MySQL数据库

app inventor 要连接MySQL数据库,一般是通过在服务器上部署一个php作为连接的接口,然后app inventor中使用http客户端连接接口,获取或发送数据。

部署php文件

将以下内容的前几行中引号内文字修改为你的参数,保存为mysql.php文件,并上传到服务器。 请注意,此代码没有充分考虑安全性,请自行进行防注入等操作。

<?php

$servername = "这里输入你的mysql地址"; //若php文件和mysql在同一服务器,可以写为localhost 或者 127.0.0.1
$username = "这里输入用户名";
$password = "这里输入密码";
$database = "这里输入数据库名";

if (isset($_REQUEST['sql'])){
	
	$con = mysqli_connect($servername,$username,$password,$database);
	if ($con){
		$sql =$_REQUEST['sql'];
		$sql =urldecode($sql);
		$startwith = strtolower(substr($sql,0,6));
		$actions = array("select", "insert","update","delete");
		if (in_array($startwith,$actions)){
			
			$result=mysqli_query($con,$sql);			
			if($result){
				$data =array();
				if($startwith =="select"){
					$array = array();
					$inum = 0;
					while ($row=mysqli_fetch_assoc($result)){
						$array[$inum]=$row;
						$inum++;
					}
					$data['result'] = $array;
				}
				$data['affected'] = mysqli_affected_rows($con);
				$return = json_encode($data);
				header("HTTP/1.1 200 OK");
				echo $return;
			}
			else{
				header( "HTTP/1.1 400 Bad Request" );
				echo '{"error":"sql parse failed"}';
			}
		}else{
			header( "HTTP/1.1 400 Bad Request" );
				echo '{"error":"action not recognized"}';
		}
	}else{
		header("HTTP/1.1 500 Internal Server Error");
		echo '{"error":"connection failed"}';
	}
	mysqli_close($con);
}
else{
	header( "HTTP/1.1 400 Bad Request" );
    echo '{"error":"no sql specified"}';
}

?>
  • 为安全起见,以上代码只支持增改删查四项动作
  • 所有返回都是json格式。
  • 若有错误发生,返回值中会有error字段。
  • 若没有错误,返回值中总会有affected字段,表明返回数据或者受到影响的数据条数。
  • 若为select操作,返回值还包含result字段,包含所有返回记录的数组。

使用http客户端与服务器交互

mark

以上代码在win7 + wamp server 3.0.6下测试通过。


如何让中文按照拼音排序

我们现在有个列表

mark

想让他按照汉语拼音顺序排序,使用内置块排序如下:

mark

返回结果是:["陈八", "赵六", "田七", "王五", "李四", "张三"]

这个并不是我们想要的结果。

准备工作

想让列表按照拼音排序,首先要把汉字转成拼音,最简单的方法就是查字典。

点我下载字典文件,改名为pinyins.json,上传到项目的素材库。

在项目中放入一个按钮、一个标签、一个文件管理器、一个HTTP客户端

逻辑设计

将字典导入项目

mark

mark

mark

字典文件可以在电脑上用记事本打开查看内容,是个这样的JSON格式的文本:

mark

使用解码JSON文本,可以将他转换为键值对列表

查字典将汉字转为拼音

mark

查看字典文件内容可以发现,有些字是多音字,这里为了简便,我们只取第一个读音。

将一个字串(多个汉字或者字母数字)转为拼音

mark

mark

依次读取字串中的每个字符,如果是数字或者字母就原样输出,否则就转为拼音。

自定义排序方式

使用wxibt最新的排序列表 自定义排序方式

mark

现在可以按照拼音排序了

mark

输出为 ["陈八", "李四", "田七", "王五", "赵六", "张三"],正是我们想要的。

但是这样排序效率有点低(主要是因为频繁查字典),不要用它排序很长的列表。


使用网页浏览器显示表格

网页浏览器(Webviewer)除了可以显示现成的网页之外,我们还可以用来显示表格。

本文需要简单的html+javascript+css知识。

网页浏览器与html如何交互

在网页浏览器组件中,我们可以通过设置网页浏览框.页面交换字符串为块和执行javascript块来向html文件发送数据。

在html文件中使用javascript来设置页面交换字符串window.AppInventor.setWebViewString("str"), 或者设置页面标题document.title = "str"。这样就可以通过页面浏览器.页面交换字符串块或者当前页标题来获取返回的值。

准备html文件

新建一个html文件,在body中插入以下代码

< script type = "text/javascript" >
function showTable(jsonData) {

    var data = JSON.parse(jsonData);
    var head = data[0];

    var str = "<table>";
    str += "<tr>";
    for (var j = 0; j < head.length; j++) {
        str += "<th>" + head[j] + "</th>";
    }
    str += "</tr>";

    for (var i = 1; i < data.length; i++) {
        str += "<tr>";
        for (var j = 0; j < data[i].length; j++) {
            str += "<td>" + data[i][j] + "</td>";
        }
        str += "</tr>";
    }
    str += "</table>";

    document.body.innerHTML = "";
    var table = document.createElement("div");
    table.innerHTML = str;
    document.body.appendChild(table);
} < /script>/

<head></head>之间插入以下css片段,可以让表格显示的更加美观:

<style type="text/css">
table {
    font-family: verdana,arial,sans-serif;
    font-size:11px;
    color:#333333;
    border-width: 1px;
    border-color: #666666;
    border-collapse: collapse;
	width:100%;
}
th {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;

    
}
td {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
	text-align:center;
   
}

tr:nth-child(even){
	background:lightgreen;
}
</style>

将html文件另存为table.html文件,并上传到项目的素材中。

显示表格

在Screen1中添加一个按钮和一个网页浏览器。 首先,让网页浏览器打开素材中的table.html 2019-05-20_140918

假设我们要用表格显示的数据如下:

姓名性别年龄
张三23
李四34
王五45

我们就可以这样调用JS:

2019-05-22_104502

这里有个关键点: 组件设计界面,Screen1的右侧的组件属性最下面,有个是否将列表转为JSON,这个必须选中。

2019-05-22_104913

现在,就可以在手机伴侣中点击按钮,就看到如下效果:

2019-05-21_130414

返回选中结果

怎么才能让AppInventor获取我们点中的某行某列呢? 只要在html中添加以下js代码:

function tabClick(){
				var td = event.srcElement;
				var str = '{"row":"' + (td.parentElement.rowIndex+1) + '","col":"' + (td.cellIndex+1) + '","value":"' + td.innerHTML + '"}';
				//console.log(str);
				//window.AppInventor.setWebViewString(str);
				document.title = str; //将选中的行号和列号赋值为文档标题
			}

将showTable函数的第三行改为:

var str = "<table onclick='tabClick();'>";

记得要把html文件重新上传到素材

在ai中添加一个计时器,计时间隔设为100 然后,配合计时器就可以获取到选中的行和列了

2019-05-20_143417

点击表格,会返回行号、列号和单元格的值。

2019-05-21_130450

这个返回值是个json格式,可以配合Http客户端.解码JSON文本和列表的在键值列表...中查找来取得行号、列号等。

相关下载:

右键另存为table.html


小白接口发送邮件

准备工作

  • 小白接口网站注册账号:点我注册
  • 进入个人中心,记下你的接口域名和app_key
  • 为简单起见,关闭“App.Email.Send”接口的签名设置。点我查看方法
  • 配置邮箱服务。点我查看方法
  • 了解邮件发送接口文档:http://hb5.api.okayapi.com/docs-api-App.Email.Send.html

组件设计界面

mark

主要组件:

  1. 文本输入框,改名为收件人
  2. 文本输入框,改名为主题
  3. 文本输入框,改名为正文
  4. 按钮,改名为添加附件
  5. 标签,改名为附件名,文本设为空
  6. 按钮,改名为发送邮件
  7. HTTP客户端,用来负责与接口api通讯,解析服务器返回值
  8. 文本选择框,用来选择附件
  9. 文件管理器,用来将文件转为BASE64编码
  10. 信息对话框,提示发送成功与否

逻辑设计界面

==黑科技:以下代码可以直接拖拽到wxbit逻辑设计界面==

  1. 初始化几个全局变量,

mark

mark

mark

  1. 添加附件

    mark

    mark

  2. 发送邮件函数

    参照接口文档,几个必选参数有app_key,address(收件人,可以用英文逗号分隔),title(邮件标题),content(邮件正文,可以是html格式)。附件attachments是可选参数,如果是图片,需要base64编码。

mark

使用==合并文本==来拼接字串,拼出网址和POST文本,注意其中的文本格式,这里的附加内容是base64文本,需要URL编码。如果需要添加抄送、密送等,查看文档看参数。

  1. 发送邮件

    mark

如果没有附件(附件名.文本为空),就直接发送。如果有附件,就先将附件进行base64编码。

  1. 编码完成在发送

mark

  1. 提示是否发送成功

mark

根据接口文档,返回是个json文本,其中的data.err_code如果为0说明发送成功。如果发送错误,查看是否是ak或地址写错,或者附件太大。

若附件太大,建议使用

mark

将图片缩小到800*800后再发送。


贪吃蛇

贪吃蛇是一款非常经典的手机游戏,相信每个人都玩过这个游戏。下面我们利用APP INVENTOR 2来制作一款自己的贪吃蛇。

游戏运行界面:

92

界面设计

界面设计比较简单,如下图: 114

组件及属性(其他属性都默认就可以):

名称1名称2宽度高度窗口大小水平对齐间隔
画布1320320固定大小
水平布局1充满充满居中
上按钮30%充满
水平布局2充满充满居中
左按钮30%充满
开始按钮30%充满
右按钮30%充满
水平布局3充满充满居中
下按钮30%充满
计时器500

游戏代码:

几个自定义过程:

将画布分成20*20的小格子(上图中粗线方框区域),每个格子高16宽16。给每个格子编号。在显示区域之外也加上一层并编号,是为了更加方便的判断蛇头是否出界。行号(列号)从0开始到21结束。

340

根据编号求所在行或者列,根据行和列求出所在位置编号。

456

几个全局变量:

蛇身位置:记录当前状态下所有身体占据的格子位置。游戏开始时,蛇身位置列表(从蛇头到蛇尾的顺序)设为(250,249,248)

当前方向:取值为1到4。 1代表向右,2是向上,3是向左,4是向下。

偏移列表:分别是蛇头向右、向上、向左、向下时,新位置编号相对当前位置编号的变化。 466

显示蛇身

我们利用画布的画线方法,根据所在的位置编号来画出一个方框,并给他不同的颜色。灰色是蛇身,黑色是蛇头,红色是鸡蛋。

674

线宽设为14,x1和x2分别减去15和1,是为了每个方框中间空出2个单位。

714

716

点击开始按钮,运行后的画出的效果如图:

741

让蛇身动起来

我们以向右移动方向为例。当前蛇身位置(250,249,248),250是蛇头位置,若向右移动,就把右边的251加入列表第一项的位置,同时把尾巴的位置248从列表中删除,这样蛇身位置就变成了(251,250,249),再移动一格,就变成了(252,251,250). 这样,每次移动,就是把蛇身位置列表的最后一个删除,在列表第一位置插入一个新的编号。这个新的编号是根据当前的方向决定的。

889

蛇头新位置:根据当前方向,求出蛇头的偏移量,加上当前的位置,就是新位置。

929

931

每次计时器计时,把画布清空,重新计算蛇身位置,并根据新位置画出蛇身。 当然,现在蛇只能向右移动,且可以穿越边界。下面加上修改方向的代码

改变方向

因为蛇不允许原地180度转向,我们加一个判断,如果方向是4(向下),那么按向上的按钮就没有变化。只有在不等于4的时候,向上按钮才起作用。其他方向同理。

1012

禁止穿越边界

只要判断蛇头位置是否出界就可以了。如果蛇头的所在行或者列等于0或者21,就说明出界了(参考上面的编号图)。

1153

1157

1159

我们在计时器的计时事件中加上一个判断,如果出界,就停止计时,并给出提示。

显示鸡蛋。

1205

1208

1210

吃到鸡蛋

将移动蛇身的过程修改一下,加上判断语句。如果蛇头的新位置等于鸡蛋位置,就是吃到鸡蛋了,就把鸡蛋重新移动一个位置,并且不要删除蛇尾的位置,就相当于把鸡蛋的位置加到了原来蛇尾的位置了。如果没有碰到鸡蛋,就要把蛇尾删掉。

1325

碰到自己

现在基本的功能都实现了,就差一个检测是否碰到自己身体了。 继续修改 移动蛇身 过程。如果蛇身位置包含蛇头要去的新位置,说明碰到自己的身体了,就要游戏结束。 1405

附加功能

至此所有基本功能都实现了。 有兴趣的可以自己添加以下功能:

  • 游戏计时,
  • 吃到鸡蛋加分并显示,
  • 每隔一定时间没有吃到鸡蛋,鸡蛋就变换位置,
  • 鸡蛋新出现的位置不能出现在蛇的身体上,
  • 添加障碍物,
  • 修改为图像精灵版本(蛇头、蛇身、蛇尾用不同的图片代替)

这个是写的图像精灵版本的:

1534


俄罗斯方块

组件设计界面:

tetrix15

组件设计界面很简单(很简陋): 6个按钮:开始游戏、左移、右移、逆时针转、顺时针转、下落 1个画布:宽度设为240,高度设为480 1个计时器,1个对话框

设计思路:

我们将画布分为20行、10列的格子,俄罗斯方块就是在这200个格子内移动、旋转。 给每个格子编号(从0开始),如图:

tetrix164

图中的白色部分就是我们的画布,外面包围的灰色一圈,就代表画布的边框,俄罗斯方块不能移动到这些边框上。

tetrix218

所有的棋盘游戏,都是背后的数据支撑。

我们初始化一个棋盘数据变量,记录每个小格子上的颜色。

棋盘数据初始化时是这样的:

9,9,9,9,9,9,9,9,9,9,9,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,0,0,0,0,0,0,0,0,0,0,9,

9,9,9,9,9,9,9,9,9,9,9,9

这些数字应该是在一行上的,这里分为22行12列,是为了便于观察。

在画布的边框格子,我们都填上9。中间画布的位置都填上0。

以后如果这个位置被某个组合占据,就把这个位置标记为组合的编号。

tetrix921

给出每个方块的位置,我们可以求出他所在的行或者列。注意,这个行和列是从0开始的。

比如0号位置,就是0行0列。13号位置就是1行1列。250号位置就是20行10列。

相对于可见的画布来说,正好符合我们的习惯。

tetrix1027

初始化一个颜色列表变量,分别代表7种不同的组合的颜色,

tetrix1148

画出小方块:

每个俄罗斯方块的不同组合都是由4个小方块拼成。若需要画出组合,先需要画出小的方块。

每个小方块都有不同的编号,只要给定一个编号,我们就可以在这个位置画出小方块。

我们在设计界面把画布设为240宽480高,这样每个格子就是24宽24高。

首先根据方块的位置编号,求出他所在的行和列。把线段的长度和宽度都设为22,这样每两个格子之间有个空隙。

tetrix1271

好了,现在我们就可以连接手机伴侣,测试下我们的画方块过程了。

是不是正好画在画布的左上角?把13改成250,是不是正好画在右下角?

如果不是,说明你的画方块过程有错误,请仔细改正。

现在我们已经可以在任意位置画出小方块了,如何才能画出一个组合(4个方块)呢?

我们只要知道组合所占据的4个方块的编号就可以了。

俄罗斯方块共有7种不同的类型:分别是L型,J型,Z型,S型,T型,田字型,一字型。我们把他们称为7种组合。

每个组合可以旋转,每旋转90度是一个造型,共有4个造型(有的造型有重复)。这样,旋转组合就是切换不同的造型了

每个造型我们给他指定一个基点。这样,移动组合就是移动他的基点。

下面进入重点:造型的偏移表

举例来说,对于L型。

tetrix1566

如果我们把它放在19,31,43,44号位置上。

我们指定31是他的基点(也可以指定其他位置作为基点),这样四个位置减去基点31的差就是:-12,0,12,13。

我们把这个称为该造型的偏移表。

我们把它逆时针旋转90度,变为:

tetrix1684

这时,他占据的四个位置相对于31的位移变成了:-1,0,1,-11

我们把它再次逆时针旋转90度,变为

tetrix1739

这时,他占据的四个位置相对于31的位移变成了:-13,-12,0,12 (四个格子的顺序是可以打乱的)。

再次旋转90度

tetrix1803

位移变成了-1,0,1,11

注意,这个偏移表只跟这个组合的种类和造型(旋转)有关,跟她的位置(基点)无关。

比如第一种造型我们把他向左平移2格到:

tetrix1880

这时,基点移动到29,他的四个格子的偏移表还是:-12,0,12,13。

使用这个方法,我们记下7种组合每个造型的偏移表:

tetrix1945

同一种组合的不同偏移表之间用\n 连接。

注意这里用的是"csv转列表"块,而不是"csv行转列表"块。

对于田字形和一字型,可能部分造型有重复。为了跟其他组合都是4种造型相匹配,我们就把他写4次。

现在就可以画出某种组合的某种造型了:

tetrix2068

tetrix2197

确定了组合编号和组合造型,我们就确定了组合的偏移表。

偏移表中的每个偏移数值分别加上组合中心,就知道了组合所占据的位置编号了,这样就可以画出这个组合。

tetrix2199

生成新组合,我们都把它显示在画布上部中间位置(17号)。

即组合中心设为17,随机生成编号和造型

每次点开始,都在画布上方画出不同种类不同造型的组合了。

这样,左移、右移、顺转、逆转就简单了:

左移就是把组合中心向左移动一个,就是组合中心数值减1,

右移就是把组合中心向右移动一个,就是组合中心数值加1,

下移就是把组合中心向下移动一个,就是组合中心数值加12。

(记得先点开始,随机产生一个组合)

tetrix2353

tetrix2355

tetrix2417

逆时针转就是把造型加1,顺时针转就是把造型减1。

注意,组合造型只能在1-4之间切换。每次造型改变后必须更新偏移表。

有没有发现组合可能会移动或者旋转出了画布?如何避免呢?

tetrix2448

比如图中L型组合要往左移动,但是要前往的格子内保存的是9(非0值),这样就不能移动。

要前往的位置占据的格子只要有1个的值为非0,就不能移动(或者旋转)。

tetrix2528

之所以位置+1,是因为格子位置编号是从0开始,而列表取值索引是从1开始。

tetrix2568

为了要检测移动和旋转两种操作,需要传入两个参数。记住如果造型变了,就要更新新位置偏移表。

每次移动或者旋转前,先检测要去往或者旋转后占用的地方是不是可以到达的(都为空格)。只有可以到达才移动或者旋转。

修改移动和旋转事件:

tetrix2685

tetrix2687

tetrix2689

tetrix2691

怎么让组合自动下落呢?就必须请出计时器了。

tetrix2716

每次游戏开始,都让计时器开始计时。

tetrix2792

每次计时,判断可否向下移动(组合中心+12就是下移)。如果碰到底边或者其他组合,就重新在画布上部生成新组合。

如果你测试这个代码,就会发现触底的组合并没有留在那里,而是消失了。

因为我们没有把触底的组合保存到“棋盘数据”变量:

tetrix2854

添加后还要显示出来:

循环取出棋盘数据中的每个数(颜色,也是这格方块曾经被某个组合占据)。

如果这个数不是9(边框),也不是0(空白格),就在这个位置画方块。

tetrix2936

修改计时器事件:

生成新组合之前,保存数据到棋盘数据。

tetrix2967

修改”重绘画布”过程:

tetrix2982

现在我们的组合可以左右移动、顺转逆转、定时下落了。

那什么时候游戏结束呢?就在新生成的组合无法安放时:

tetrix3036

tetrix3039

有没有发现在生成新组合时经常莫名其妙就提示游戏结束了?

这是因为我们把初始的组合中心设为17,非常靠近上边缘,而有的组合造型就出了边界了。

为了解决这个问题,我们把棋盘数据的第一行,也就是上边缘数据由9,9,9,9,9,9,9,9,9,9,9,9共12个9,

改为9,0,0,0,0,0,0,0,0,0,0,9 也就是上边缘开放。因为我们没有上移的操作,不会影响程序其他部分运行。

下面是本游戏的另一个重点:

如何消除一行方块?

当棋盘数据某一行的所有位置都是非0值,这一行的方块就可以移除。

比如图示的倒数第二行,也就是画布的倒数第一行,分别是9,1,1,6,6,4,4,7,7,7,7,9,

这12个数没有0值,说明这一行可以消除,我们就把这一行从“棋盘数据”变量中删除。

重复检查第20行,第19行...到第1行,并统计一共删除的行数。最后在画布第一行插入12个数:

9,0,0,0,0,0,0,0,0,0,0,9,删除了几行,插入几行。

tetrix3462

tetrix3465

tetrix3468

tetrix3471

根据消除的行数计算得分:1行10分,2行30分,3行60分,4行100分。不可能同时消除5行及以上的。

tetrix3526

修改计时器计时事件,在生成新方块之前检测消除方块并计算得分:

tetrix3560

修改开始游戏事件,游戏开始时重新计分:

tetrix3583

最后一个,快速下落事件:

tetrix3599

重复检查可否下移一格(组合中心+12),若可以,再次下移一格,直到无法下移为止。

我们在回头看下“消除方块”这个过程:

实际上每次消除时不可能有20行都能消除,可以消除的行只可能在当前组合占据的行中产生。

我们只要找到当前组合占据的行,依次判断这几行可否消除就可以了。

tetrix3738

tetrix3741

tetrix3743

tetrix3746

tetrix3749

为什么在13位置插入呢?因为13位置就是棋盘数据第二行的第一个数字。