浮云小站
欢迎来到浮云小站。
这里有关于App Inventor 2 的常见问题、扩展插件、教程案例等。。。
有什么疑问,欢迎在下面留言。
常见问题
如何正确打开屏幕
打开新屏幕前,需要关闭当前屏幕。否则多次打开新屏幕,可能会造成系统内存耗尽,app崩溃。
三种打开屏幕的方法:
如何获取本机IP地址
如何判断当前有无网络
如何实现滑动屏幕效果
新版的wxbit服务器增强了布局的点击和拖动效果,可以在不使用外部插件的情况下,实现滑动屏幕效果。
-
在屏幕内拖入一个垂直布局,宽高都设为充满。
-
每次按下布局时,记录下点击的x位置和y位置
-
每次松开布局时,对比松开点的位置与原来按下的位置变化,就可以判断滑动方向了
如何发送邮件
1.使用活动启动器发送(不会直接发送,需要手机配置邮箱。打开手机邮箱服务,手动点发送)
2.使用小白接口发送 (详见这里)
联系方式
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
- fix bug of "can not update value with space", now in the formula, use " and " to quote the value with space.
- add perperty of FetchIdAndTime. if set to true, in the SelectFinished event you will get 'id' and 'createdTime' for each record.
-
add method 'UpdateById' and 'DeleteById' for update or delete one record, which is faster than by filter.
V1:
Add a picture of all the blocks
Initialize the extension
Same like other Airtable component, get your API Key, BaseId, TableName from the airtable website.
Select records
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
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
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
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
message: String. Error reason.
Download link here
<结束>
AgoraRTC实时音视频扩展
本扩展基于AgoraRTC(实时音视频)技术开发。提供在同一频道内的多人语音和/或视频通讯功能。若想实现两个人的私聊,请自行在应用层控制进入频道的权限。
AgoraRTC提供每个账号每月10000分钟的免费额度,具体怎么计算时间,请参照这里。
index.html
准备工作:
- 注册agora账号,网址:https://www.agora.io/cn/
- 进入控制面板
- 创建新项目,建议鉴权机制选择AppId(开发更简单,但安全性稍弱)
- 记下appId (这个很重要,注意保密)
代码块介绍
组件初始化
初始化之前需要设置appId。(如果准备工作中选择了鉴权方式为appId, 这里就不用设置token)
加入频道
所有音视频通讯都在频道内进行。只有相同的appId和相同的频道名channel,才能互相通讯。
本扩展默认只开启语音通讯。
若需要开启视频,需要在加入频道前设置enableVideo(开启视频)为逻辑真,并且设置localLayout(本地视频显示布局)为某个垂直布局(或水平布局)。加入频道成功后,该布局原来内容会被清空,仅只能显示本次视频。
加入频道是个异步操作,加入成功后在本地会收到OnJoinChannel事件。并返回一个uid(系统分配的用户编号)。
因为默认开启音频,收到本事件,表明你就可以开始音频通讯了。
每次有其他用户加入频道,本地会收到OnRemoteUserJoin事件,并返回一个用户uid和userName(用户名)
如果其他用户开启了视频,本地还会收到OnGetRemoteVideo事件,并返回一个用户uid
在OnGetRemoteVideo事件中,使用setupRemoteVideo方法设置远程用户的视频显示在哪个布局里面。注意:一个布局只能显示一个用户的视频,多个用户需要设置多个布局。
离开频道
离开频道,就会结束实时通讯,关闭所有视频。
离开频道是个异步操作,成功后本地会收到OnLeaveChannel事件。
频道内其他用户会收到OnRemoteUserLeave事件,并关闭相关的视频。
发生错误
如发生错误,会返回一个错误代码,具体错误原因,可以在这里查找
切换摄像头
切换本地视频前后摄像头
开启关闭扬声器
开启或关闭扬声器
其他
若想赞助其他功能,请直接联系我。
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
Token
This property will be no use if you choose "App Id" for authentication when you create the project.
EnableVideo
default value is false, which means only voice talk enabled. Set it to true if video talk wanted.
LibUrl
the location where the agorartc sdk stored. Use this only when you want to host your own sdk. Contact me for more information.
Init
initialize the sdk.
if the app is running for first time, it will download the sdk from libUrl automaticly.
JoinChannel
try to join channel. If success, this will fire the OnJoinChannel event, and other user in the channel will get OnRemoteUserJoin event.
LeaveChannel
try to leave channel. if success, this will fire the OnLeaveChannel event, and other user in the channel will get OnRemoteUserLeave event.
SetupLocalVideo
set one layout (arrangemetn) to be the container of the local video.
Its' s to be called before JoinChannel
SetupRemoteVideo
set one layout (arrangemetn) to be the container of the remote video.
Its' s to be called inside the OnGetRemoteVideo event
EnableSpeakerphone
SwitchCamera
事件
OnRemoteUserJoin:
when other user joined the channel.
OnRemoteUserLeave
when other user left channel
OnJoinCnannel
OnLeaveChannel
OnGetRemoteVideo
Call SetupRemoteVideo method here
OnError
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:数据集合,二维列表(列表的列表)
使用方法
- 目前支持8种图表:折线图,条状图,水平条状图,堆叠条状图,雷达图,饼图,甜甜圈图,极坐标图
- 其中前5种支持多套数据,后3种支持一套数据。
- 参看以下图片,可以看出代码和图表的对应关系。
百度翻译扩展
下载
cn.kevinkun.KevinkunBaiduFanyi.aix
方法
- 方法描述:
- 翻译内容:待翻译的文字,语言种类自动识别。
- 翻译语言:需要翻译到的语言,可以是zh,en,jp,fra,it等等,具体参看这里
- 成功回调:回调函数需要1个参数 translation文本
- 失败回调:回调函数需要1个参数reason文本型
属性
-
属性描述:设置appid
-
属性描述:设置appkey
EXCEL扩展
直接读取素材或者sdcard上的excel文件,无需转为csv文件。
仅支持xls格式,暂不支持xlsx格式
下载链接
方法
导入扩展后,将鼠标放到紫色块上停留,就会出现详情介绍。
读取工作表
读取行
读取列
读取单元格
其他功能
如果想赞助其他功能,请直接联系我。
比目微数据库扩展
内置的网络微数据库,服务器是国外公用服务器,速度慢,不安全。
比目微数据库可以代替内置的网络微数据库,但是更高效,更安全。
更新记录
- v3 改为回调函数版本
- v2 修复了返回值全部为文本的bug, 更名为BmobDB。自带默认appid,apikey和tablename,可以不用设置就直接使用(仅做测试之用,默认key随时可能失效)。
- v1 新发布
下载链接
准备工作
- 注册比目账号 http://www.bmob.cn;
- 进入“我的控制台”,创建应用,进入应用,添加表,记住表名;
- 进入设置,记住 Application Id, Rest Api Key;
使用方法
V3:
保存数据
获取数据
如果数据不存在,会引发失败回调
V2:
跟内置的网络微数据库功能基本相同:
注意:有点不同的是,保存数字、逻辑值、列表时,都会保存为文本格式。获取数据时,返回值也是个文本。
所以如果想保存列表的话,在组件设计界面,Screen1组件属性最下面,有个是否将列表转为JSON
,这个必须选中。然后获取返回值后,可以使用Http客户端.解码json文本
,变成列表格式。
手机联系人
下载链接
更新历史
- 2019/05/23 发布
方法
根据姓名返回手机号
根据手机号返回姓名
exactMatch 是否精确查找
返回值是个列表的列表
KevinkunTools扩展
下载链接
方法
获取手机的UniqueID
返回前n个自然数组成的列表
中文字符和unicode互相转换
LeanCloud扩展
更少的代码,做更多的事。。。
简介
包含6个部分,分别是
组件名 | 中文 | 具体描述 |
---|---|---|
LeanStorage | 数据存储 | 添加、查询、更新、删除 (本组件已经单独免费发布) |
LeanUser | 用户管理 | 用户注册、登录、修改密码、重置密码等 |
LeanLeaderBoard | 排行榜功能 | 添加成绩、获取成绩、获取前10,获取我前后成绩等 |
LeanFile | 上传文件 | 上传文件 |
LeanCaptcha | 图形验证码 | 获取和验证图形验证码 |
LeanMessage | 实时聊天 | 发送文消息、接受消息,获取历史消息。不只是聊天 |
购买链接
- v3版: 购买链接
准备工作
- 注册LeanCloud账号,网址是 https://www.leancloud.cn;
- 可能需要实名认证;
- 进入控制台,新建应用(相当于关系型数据库中的数据库)。;
- 进入应用,点设置,点应用Keys,将右侧的Appid,AppKey,Rest Api服务器地址记下,初始化时用到;
代码示例
LeanUser 用户管理
LeanLeaderBoard 排行榜
需要配合LeanUser先注册用户,需要事先创建排行榜:
进入LeanCloud控制台,进入应用,点左边游戏,点排行榜下的数据,新建排行榜。按你的要求输入相关参数,完成创建。
排行榜参数:
1.名称,不解释
2.排序,你的排行榜按升序ascending还是 降序descending排列
3.更新策略,better(提交多次成绩只记录最好的),last(多次记录只记录最后提交的),sum(所有提交的记录相加。)
4.自动重置频率,每个相应的时间,排行榜就重置。可以设为从不重置。
LeanFile 文件上传
仅支持Leancloud华北节点,限制10m以下文件。
LeanMessage 实时通讯
这个初始化,不能直接在屏幕初始化中进行,需要延时一段时间比如500毫秒。
需要配合LeanUser先注册用户。
LeanCaptcha 验证码
LeanStorage扩展
LeanStorage扩展可以作为app inventor应用的后端数据支撑。进行数据的增加、修改、删除、查询等功能。
更新记录
2020.3.22 支持回调函数,已部署在Wxbit服务器 的存储模块,不用下载,直接使用。
下载链接
准备工作
- 注册LeanCloud账号,网址是 https://www.leancloud.cn;
- 可能需要实名认证;
- 进入控制台,新建应用(相当于关系型数据库中的数据库)。我这里是新建了个应用 Jiaocheng;
- 进入应用,点设置,点应用Keys,将右侧的Appid,AppKey,Rest Api服务器地址记下;
- 创建一个新的Class(相当于关系型数据库中的表)。我这里新建一个Class,叫Scores。
相关功能
扩展初始化
使用上面准备工作中的数据初始化扩展。
插入数据
- 数据json:要写入的数据
假设我们要在Scores中保存班级里面学生的考试成绩。要添加学生的一条考试记录(包括学生姓名、语文成绩、数学成绩),数据Json可以这样写
{"xingming":"张三","yuwen":89,"shuxue":96}
如果同时添加多名学生成绩,可以这样写
[
{"xingming":"张三","yuwen":56,"shuxue":89},
{"xingming":"李四","yuwen":69,"shuxue":83},
{"xingming":"王五","yuwen":98,"shuxue":87}
]
注意要加方括号(一条记录可以不用)。
-
成功回调:若成功,返回插入成功的记录数。
-
失败回调:若失败,返回失败原因。
查询数据
-
字段名字:需要返回的记录中包含的字段。比如你想返回姓名和数学,就写xingming,shuxue,中间用半角逗号分隔。如果是想取回全部字段,可以设为空字串。如果全部返回,返回记录中除去我们手动添加的xingming、shuxue、yuwen等字段外,还有三个系统自己添加的:objectId(每条记录的id号)、createdAt(记录添加时间)、updatedAt(记录修改事件)。
-
条件json:记录符合的条件。为json格式。比如查询姓名是老王的纪录,可以写为{“xingming“:”老王“}。也可以使用字典组件构建,请参照leancloud文档查看写法。推荐用下面的构造条件json来构造。如果想取回全部记录,可以设为空字串。
-
排序字段: 返回的记录按照哪个字段排序。比如我们要按照数学成绩降序排列,可以这样写:-shuxue。负号表示降序,正号或者没有符号表示升序。多个字段用半角逗号分隔。
-
起始记录:从第几条开始返回。默认1
-
最大记录数:一次最多返回记录的条数。默认100
-
成功回调:若成功,返回查询成功的记录数和数据json。
-
失败回调:若失败,返回失败原因。
更新数据
-
条件json:见上面查询数据部分
-
更新json:要修改的数据,json格式。例如
- {"xinging":"zhang san"} 表示将符合条件的记录xingming字段改为zhangsan,
- 或者{"shuxue":{"__op":"Increment","amount":5}} 表示将shuxe字段的值自增加5。
- 具体请查看leancloud文档学习更多写法。推荐使用下面的构造更新json来构建。
-
成功回调:若成功,返回更新成功的记录数。
-
失败回调:若失败,返回失败原因
删除数据
-
条件json:见上面查询数据部分
-
成功回调:若成功,返回删除成功的记录数。
-
失败回调:若失败,返回失败原因
构造条件json
这个辅助块可以构造查询(或者更新或者删除)命令的条件json。可以更快速、更简洁的写出查询条件,减少出错率。
比如我们要查询“数学成绩大于等于60 或者 语文成绩小于等于80”的学生记录,手动写json这样写:
{"$and":[{"shuxue":{"$gte":60}},{"yuwen":{"$lte":80}}]}
如果用字典组件来写,是这样:
如果使用这个生成器,可以这样写:
是不是非常的精炼,更加的符合自然语言。
- 条件表达式:半角空格(至少一个空格)隔开的字符串表达式,必须为三段。第一段为字段名,两侧不要有引号,第三段为要比较的值(文本或者列表需要用半角双引号括起来。其中有"双引号要写为\"。\要转义为\\),第二段为比较符号,数字时支持=,<,<=,>,>=,!=,文本时支持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
这个辅助块可以构造更新命令的更新json,更快速、简洁的写出数据更新json,减少出错率。
比如,我们要将姓名为‘张三’的学生的yuwen成绩和shuxue成绩分别加10分。我们可以这样手动写json格式的更新json:
{"shuxue":{"__op":"Increment","amount":10},"yuwen":{"__op":"Increment","amount":10}}
如果用字典构造,可以这样写:
用本构造器来写,可以非常简单的用两个块来这样写:
更新表达式: 半角空格(一个或以上)隔开的字符串表达式,需要为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\"]" | 数组字段 |
数据格式转换
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
下载链接
准备工作
- 注册小白账号 http://www.okayapi.com
- 进入"我的套餐",记下接口域名、app_key、app_secret。
- 进入“我的数据库”,创建一个新模型(自定义数据库),记下数据库名和各字段名。
属性
设置接口域名
设置appKey
设置appSecret
设置是否显示隐藏错误信息。默认是否(不隐藏)。
方法
以下方法的接口参数格式,可以参照这里的接口文档 http://api.okayapi.com/docs.php自定义数据模型部分
查询数据库
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.
插入记录
table:数据库名
datas:插入的数据,需要json格式。形式如[{"username":"lee","score":80}]
。如果是多条记录,用半角逗号隔开。注意必须有方括号
更新记录(文本方式)
data:要修改的数据,需要json格式。形式如{"username":"lee","score":80}
。官方文档中不能有方括号,这里可有可无。
其他插口说明见以上方法
更新记录(批量四则运算)
field:要更新的字段
op:取值范围add/sub/mul/div,即加/减/乘/除
number: 待运算的数字,例如加多少,减多少,乘多少,除多少。必须为合法的数字,可以是小数
field=gongzi&op=add&number=500 就是gongzi=gongzi+500
删除记录
插口说明见以上方法
将csv格式转化为json格式
比如shuxue,yuwen,yingyu\n78,89,78\n90,95,94
转化为
[{"shuxue":" 78","yuwen":"89","yingyu":"78"},{"shuxue":" 90","yuwen":"95","yingyu":"94"}]
事件
查询结束事件
recordCount:符合条件的记录条数
recordList:查询结果,列表格式,第一行为字段名,第二行开始是数据
数据变化事件
添加、修改、删除后引发此事件。
affectedRowNum: 收到影响的记录条数
action:引发此事件的方法:insert/update/delete
规则表达式插件
下载地址
方法
GetMatches方法可以返回符合条件的字符串列表
SplitWith方法可以使用规则表达式对字符串进行分割,并返回列表
ReplaceFirst方法和ReplaceAll方法可以返回替换第一个或所有符合条件的子字符串后的新字符串
IndexOf方法可以返回符合条件的第一个字串的位置
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.
设置存储空间 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.
连接服务器 Connect
用户名必须是独一的
Try to connect with the server. the username should be unique underwater the same namespace.
After connected, you will get a connected event.
断开连接 Disconnect
因网络原因断开连接,也会引发 已断开连接 事件 (和离开房间事件,如果在房间内)
Disconnect with the server manually.
Fired when the internet lost connection, or you leave the room manually (if you are in a room).
自动匹配房间/取消匹配房间 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
主动加入房间 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.
主动离开房间 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.
发送消息 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.
设置房间容量 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.
发生错误事件 Got Error
如何自己部署服务器 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 第一次发布
下载链接
示例截图
实时调整布局外观(感谢ldtxinkai提供截图)
属性块
设置背景颜色及圆角
背景颜色fillColor、边框宽度borderWidth、边框颜色borderColor、圆角半径roundRadius。
"圆角半径可以是一个数字(同时设置四个角),或者是四个数字用逗号隔开(顺时针分别设置左上、右上、右下、左下)。
设置背景图片及圆角
背景图片imagePath、边框宽度borderWidth、边框颜色borderColor、圆角半径roundRadius。
imagePath:以//开始表明是素材,以/sdcard/开始表明是在外部存储卡。
"圆角半径可以是一个数字(同时设置四个角),或者是四个数字用逗号隔开(顺时针分别设置左上、右上、右下、左下)。
设置外边距
设置组件的外边距margin。外边距可以是一个数字(同时设置四个方向),或者是四个数字用逗号隔开(分别设置左、上、右、下)。
设置内边距
设置组件的内边距padding。内边距可以是一个数字(同时设置四个方向),或者是四个数字用逗号隔开(分别设置左、上、右、下)。
设置高程
设置组件的高程elevation。会在组件周围显示阴影效果(必须提前设置背景)
设置自定义字体
设置组件字体。fontName字体名以//开始表明字体在素材库,以/sdcard/开始表明在外部存储卡。
其他
组件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 bg | gif动画 | 链接 |
Animation Color background extension | 背景颜色动画 | 链接 |
Another AES encryption extension | 加密与解密 | 链接 |
AppyEcho mic to speaker with pitch control | 声音有关 设置音高、音量等 | 链接 |
Arduino USB Serial Extension | Arduino Arduino相关 | 链接 |
AsyncImageLoader | 异步图片加载器 | 链接 |
Audio Player Extension | 音频播放器 | 链接 |
Augmented Reality Plugin on Scene3D | Scene3D插件 | 链接 |
AutoCompleteBox | 文本输入框提示 | 链接 |
BaiduFanyi | 百度翻译Api | 链接 |
Barometer Sensor Extension | 气压传感器 | 链接 |
Battery Manager Extension | 电池管理 | 链接 |
Bitwise Extension | 位运算 | 链接 |
BluetoothLE | BLE | 链接 |
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 | 自定义列表显示 | 链接 |
ColinTreeNinePatch | 9-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 Extension | JSON工具集 | 链接 |
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 AirtableClassic | airtable数据库 保存 查询数据 | 链接 |
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 Esp8266 | Mqtt通讯 | 链接 |
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 | 位置 根据经纬度求位置 | 链接 |
GetAllIp | wifi 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 | 游戏手柄 | 链接 |
JsonUtils | JSON工具 | 链接 |
Kawa Parser Extension | kawa字串解析 | 链接 |
LableImageClick | 标签、图片点击事件 | 链接 |
LED View Extension | LED灯视图 | 链接 |
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 View | pdf查看 | 链接 |
PedrozaThumbnail Extension | 缩略图 | 链接 |
QR Code Extension | 二维码 | 链接 |
QuizMaker Extension | 测试出题 | 链接 |
Radio Buttons Extension | 单选按钮 | 链接 |
Rating Bar Dialog | 评分条 | 链接 |
Rating Bar Extension | 评分条 | 链接 |
ReadMoreLabel Extension | 显示更多文字 可以在显示部分文字和全部文字间切换 | 链接 |
RippleEffect Extension | 波纹效果 | 链接 |
Root Checker Extension | ROOT检查 | 链接 |
ScaleDetector | 画布缩放比例探测 | 链接 |
Scene3D | Scene3D | 链接 |
ScrollArrangementHandlers | 滚动布局管理器 | 链接 |
ScrollBar Extension | 滚动条样式 | 链接 |
Security Extension | 安全加密与解密 ASS, BASE64, MD5, RSA, SHA256, SHA1 | 链接 |
Settings Extension | 设置 | 链接 |
Sharing Extension | 分享 | 链接 |
Sidebar Navigation | 侧边导航栏 | 链接 |
Simple Notification Extension | 桌面通知 | 链接 |
Simple Pdf Tools extension | pdf工具 提取文字、图片等 | 链接 |
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 | 特殊工具 | 链接 |
SQLite | sqlite | 链接 |
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 extension | UDP客户端 | 链接 |
UDP Extension | udp通讯 | 链接 |
VectorArithmetic | 向量运算 | 链接 |
Vibrate extension | 震动 | 链接 |
VU Beta. Free beta Extension | 声音 振幅 | 链接 |
WaveAudioTools extension | 音频 声音有关 | 链接 |
WavRecorder extension | 录音 | 链接 |
WavSoundRecorderExtension | 录音 | 链接 |
Web Viewer Dialog | 网页浏览器对话框 | 链接 |
WebSocket Client Extension | WebSocket客户端 | 链接 |
WebViewer Interact Extension | 网络浏览器增强 可以与网页浏览器交互 | 链接 |
WEBVIEWTOOLS Extension | 网页浏览器功能扩展 | 链接 |
Welcome Screen Extension | 欢迎屏幕 | 链接 |
WheelView Extension | 拨盘视图 | 链接 |
WiFi Manager Extension | wifi相关 | 链接 |
Zip/Unzip Extension | 压缩与解压缩 | 链接 |
Zoom, rotate, drag image | 图片缩放 | 链接 |
动态组件
有动就有静。静态组件(这是我自己用的一个概念,方便理解,实际开发环境中并没有这个称呼),就是我们在组件设计界面手动从左侧组件面板拖入工作面板,显示在组件列表中的,可以在组件属性面板对他的属性进行手动修改。
动态组件,是在逻辑设计界面,使用代码块来生成的,只有在调试或安装运行时可见的组件,他不会出现在设计界面的组件列表里面。
如何生成动态组件?
要生成动态组件,需要有两个参数,一个是新组件的父容器,一个是新组件的类型。
新组件要有个父容器,就是要把它显示在哪里?也就是说,必须是容器类的组件,才可以生成子组件。所以动态组件块的位置,只会出现在容器类组件抽屉里面。
何为容器类组件,就是比如屏幕、水平/垂直布局、水平/垂直滚动布局、表格布局、层叠布局,画布、地图等组件,可以生成相应的子组件。
比如屏幕1的动态组件块位置,非常简单,就一个积木块。
其他容器类组件下都有这样的创建块。
点击创建右边的下拉框,就可以选择要生成的新组件的类型(仅支持生成可视化组件)。
如何设置新组件的属性?
只要配合任意组件里面的积木块,就可以设置新组件的属性。
比如,我们需要生成10个按钮,每个按钮的文本就是他的编号,颜色设为随机,可以这样用:
错误用法:
如何获取/引用组件
上面的例子中,我们把新组件保存在一个局部变量中了,设置完属性后,后续操作那个局部变量就不管用了。如果还想操作这个组件怎么办?
1.是可以在创建时保存在一个全局变量中,但是如果创建很多组件,就要创建很多全局变量,这样动态组件的优点就荡然无存了。
2.是保存在一个列表中,但是需要知道组件在列表中的位置才能取出。
3.是保存在字典中,给每个组件起不重复的名字作为键名,组件本身作为键值。使用时通过键名取出组件。
4.是使用设置组件名称块,通过屏幕抽屉下的获取组件名称块来获取组件。
如何添加事件?
新组件生成了,如何与用户交互呢?可以响应用户的点击、按压等事件吗?有两个方法:
1 是对某一类组件使用任意组件里面的通用事件,比如:
这样的缺点是对屏幕上所有的同类的组件都适用这个事件,如果需要精确到某个或某几个就需要在事件中进行判断。或者在创建组件时,设置他的扩展属性,然后通过扩展属性值进行区分。
2 是对单个组件的某事件绑定回调函数:
还可以删除绑定的回调函数:
如何删除动态组件?
有些组件功能结束了,可以将它删除:
自删除功能不仅适用于动态组件,手动拖入的静态组件也可以使用。
如果他是个容器类组件,使用自删除后,他本身连同其内部的子组件也会一起被删除。
如果希望只是删除他的子组件,可以使用这个清空积木块:
举个例子1:国际象棋棋盘
我们要在屏幕上显示8行8列共64个标签,做成国际象棋棋盘样式。
这个可以通过设计界面拖入64个标签,并分别设置宽高颜色并设置点击事件来完成,但是比较累,比较傻。

举个例子2:成绩排行榜
待续
举个例子3:模仿微信聊天界面
待续
扩展组件开发环境搭建
App Inventor 2允许我们自己开发扩展组件,但是MIT原生的编译环境搭建相对比较复杂,费时费力。本文介绍一个比较轻便的aix编译器。
本编译器由Zhangzq网友开发,在此对他的辛苦付出表示感谢。
-
下载AIX Complier,并解压到电脑。下载地址,也是Zhangzq的Gitee仓库, 本例是解压到E盘aixcompiler文件夹下:
-
双击aixc.bat文件,可以看到aixCompiler的用法如下:
-
右键点击,另存这个模板文件,解压到E盘。它的目录结构是 Test AIX是项目名,下面有src,assets,jni,lib等目录。
src文件夹是存放源码文件,在src内按照包名的顺序再建立文件夹和java文件,结构如图:
其中,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")
-
打开命令行窗口(按win+R,运行cmd命令),执行如下命令:
E:\aixcompiler\aixc.bat E:\TestAIX
如果不想输入代码或者怕输入错误,可以直接拖动TestAIX文件夹到aixc.bat文件上,等同于执行上述命令。
-
如果没有错误的话,会显示编译完成及用时。如图:
如果看不到倒数第二行的“编译完成,累计用时”这几个字,说明有错误,请仔细查看窗口显示的提示信息,修改源码。
-
编译完成,会在TestAIX文件夹下生成一个build文件夹,aix扩展文件会保存在E:\TestAIX\build\outputs文件夹下。(同时还有个md文件,这个是同步生成的aix说明文件,可以配合gitbook生成html文件。有兴趣的自行研究,这里不作说明)
-
现在可以将aix导入wxbit(将aix文件直接拖动到wxbit的组件设计界面就可以导入),扩展导入后如下图。你可以对照源码,看看这些块是对应的源码中的哪一部分。
-
记事本编辑源码虽然简便,但是没有代码提示,不能很好的组织文档,建议使用Eclipse或者其他高级的代码编写软件。
-
多多查看其他的app inventor组件的源码,可以更好的了解如何写aix。
《完》
自己搭建网络微数据库后端
系统自带网络微数据库使用国外的服务器,速度太慢?使用比目微数据库,数据存在别人服务器上,不安全?下面介绍自己搭建简单的网络微数据库后端。不用复杂的mySQL知识。
准备工作
首先你要有自己的服务器,可以把相关文件上传,服务器要支持php。
下载文件 myTinyWebDB.zip ,解压,上传到你的服务器。
我是在本机测试(win10+wamp64),文件结构如下:
其中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文件内容如下(就一对括号):
{}
好了,运行你的服务器,已经可以开始用了。
逻辑设计
这里192.168.0.104是我本机的ip,你要换成你自己的服务器地址。
ok,网络微数据库就可以跟以前一样使用了。
Gitee做文件存储服务器
很多同学在制作app过程中,需要有很多的素材如图像啊、视频啊。如果都放入素材库,APP会超过服务器限制(一般是10m)。如果你没有自己的文件存储服务器,可以将文件存储在gitee上。
准备工作
-
注册Gitee账号点我,建议用邮箱号注册。
-
登录gitee,点右上角的加号,新建仓库。
-
仓库名称随便写,比如repo,或者store,这个随意。
-
是否开源选 公开
-
选中 使用Readme 文件初始化仓库
-
点 创建,完成创建仓库。
-
网页拉到最底下 打开OpenAPI这个链接,或者点这里进入api文档。
-
依次打开左侧的 api文档–-> 仓库 –> 新建文件,这里有新建文件(也就是上传文件到这个库)的接口文档。
-
点右上角 申请授权,同意授权,记下在access_token的值。
-
其他参数有:owner是注册时的用户名,repo就是仓库名,path就是你要上传的文件名,content就是要上传的文件的base64编码,message就是git中的commit,这里可以随便写。
-
在owner、repo、path、content、message中随便写上a/b/c/d/e ,点测试,下面会出现这个:
-
根据这个curl命令,就可以写出我们的http客户端请求了
逻辑设计
主要代码有:
- 选择文件,取得文件名(下图是filename,就是上面说的path)
- 对文件进行base64编码
- 拼接http客户端网址
- 设置请求头
- 执行post文本。文本是json格式,可以用字典创建。
- 将响应文件转为字典
- 如果响应代码=201,标明是成功上传了。
- 提取字典中的download_url的值,这个就是上传的文件的连接了。(其实返回值中还有其他几个网址,经试验,只有这个download_url是文件的直接连接。)
有了文件url,就可以图像框显示出来,或者发送给朋友了。
其他
以上方法,只适用于图片。如果是其他格式,可以通过开启Gitee Pages来获取资源网址。
Goeasy实现实时网络聊天室
前期准备
本教程使用了GoEasy的网络消息实时推送技术。
- 注册账号。 GoEasy官网(https://goeasy.io)
- 登录到GoEasy的后台管理系统,创建您自己应用app.
- 应用创建好之后系统会自动为您生成appkey。有两个,一个是只能接受消息,一个是既可以发送,也可以接收消息。
- 免费版本有1年的试用期,可以推送100000条消息,对于学习试验应该是足够了
组件设计界面
- 标签:聊天显示区。文本设为空,其他属性默认
- web浏览器。可见性设为否,其他属性默认
- 文本框:发送人ID 文本设为空,其他属性默认
- 文本框:发送内容 文本设为空,其他属性默认
- 按钮:发送按钮
- 计时器:计时间隔设为50,其他属性默认
- 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>
实现的思路:
- 使用web浏览器访问goeasy.html文件,订阅某个频道(这里是CH1)。只要这个频道下的数据有变化,系统就自动将变化的内容写给web浏览器的页面交换字串。
- 使用web客户端来发布消息到CH1频道。这样,只要订阅了这个频道的人,都可以收到此消息。
逻辑设计界面
- 定义一个变量叫频道。这个变量的值可以修改,但必须与goeasy.html中的channel值相同
- 定义一个变量KEY。因为是聊天程序,使用的是超级key(可发可收)这里要替换为自己的key
- 定义个变量开发中。(注意:若要把本程序打包apk,必须先把这个变量设为假。若在手机伴侣中测试,设为真)
- 给用户一个随机ID
- 不用解释了
- web浏览器若要使用素材库中的文件作为网络地址,在开发时和打包时使用不同的路径,需要根据情况修改开发中的值,见第3条。
- 让web浏览器访问这个goeasy.html文件,就是订阅了CH1频道。
- 若两个文本框都不为空
- 这个网址在goeasy创建的应用后台管理里有。
- 把消息发送出去。post文本的组成:必须有三个参数:appkey、channel、content。content需要使用URI编码
- 不用解释
- 让计时器不停的去问web浏览器是否收到消息。若页面交换字串不为空,表明web浏览器接收到了新消息。
- 把新消息显示出来。
- 把页面交换字串设为空,方便下次访问
http客户端获取和风天气api接口数据
应用与外界交互,使用api接口是最常见的。现在利用wxbit解释下如何获取和风天气的天气预报api。
准备工作
- 和风天气网站(https://www.heweather.com)注册账号。
- 进入控制台,应用管理,新建应用。(貌似免费用户只能建一个免费账号。)
- 记住应用的key。
组件设计
组件设计界面,拖入3个可视组件:文本输入框、按钮、标签,1个非可视组件:http客户端。(这个是wxbit服务器新改名的组件,赞一个。原名叫web服务器,翻译的有些不知所云)
这里就不放组件设计图了,太简单了。主要是介绍原理,如何美化应用不在这里讨论。
逻辑设计
要使用api接口,就必须要看api接口文档。重要的事说3遍,看文档~~ 看文档~~ 看文档~~
我们打开这个文档(https://dev.heweather.com/docs/api/weather),有几个关键的点要看到:
-
获取方式:GET 方式
-
数据格式: JSON,这里是说返回的数据是JSON格式,就是键值对格式。
-
免费版的请求URL:
https://free-api.heweather.net/s6/weather/{weather-type}?{parameters}
花括号中的东西就是我们要按我们的要求替换的,连带花括号也要换掉。 -
weather-type参数,我们这里选forecast, 就是获取未来3天的数据
-
parameters参数,就是我们要告诉接口的请求参数,这里有location就是城市名称,中文或者拼音都可以,key就是准备工作中记下的key。
我们现在开始来获取这个api,看看有什么返回值:
-
初始化一个变量,记录key
-
构造请求URL
特别注意的就是url网址中的forecast后面有个
?
, key前面有个&
。?用来分割主url和后面的参数,&是用来分割多个参数。而每个参数都是形如
参数名=参数值
这样的。设置好网址,就可以执行GET请求(还记得上面说的获取方式是GET吧)。
-
因为关系到网络的传输,速度不确定,所以get请求这个动作,有个异步的
HTTP客户端.获得文本
这个事件,我们就用它来接受返回的结果,并显示在调试窗口。
现在就可以连接手机,在文本框中填入城市名称,运行app看看返回值如何。(尽管文档中明确说参数如果是中文的,需要进行url编码,但是这里我们直接输入中文城市名,貌似也可以)
在设计界面右侧的调试信息窗口,显示如图:
哇~~什么鬼?密密麻麻的。其实这就是返回的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条就可以了
-
碰到
{
左侧花括号的,就用在键值列表...中查找...
提取 -
碰到
[
左侧方括号,就用选择列表...第...项
提取
看上面的json字串,最外面是HeWeather6
, 下面是个方括号,再里面是 4个平级的键basic
,update
,status
,daily_forecast
。
我们关心的是后面两个。如果status
是ok,说明没有出错,才能提取daily_forecast
。
接下来,我们从上到下,从外到内的一层层提取第一天的最低气温和最高气温。
- 把返回的json字串解码为键值对列表。
- 获取
HeWeather6
的值,注意HeWeather6
前是花括号, 用在键值列表...中查找...
提取 - 注意
HeWeather6
的值是个方括号,要用选择列表...第...项
提取 - 判断返回的数据是不是我们想要的
- 如果返回的格式正确,就提取3天的天气预报数据
- 注意这里
daily_forecast
后面又是个方括号,第一项就是第一天你的数据,第二项就是第二天的数据啦。 - 现在就可以直接提取最低温和最高温了。
这里可以多初始化几个变量,分别记录第二天、第三天的数据。
有了这些数据,你就可以构造你的天气app啦
更新
20190525
我们可以自定义一个过程,更加方便的解析json字串:
-
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
可以这样组织代码:
更新
20200319
wxibt已经更新增加了字典组件,有了以下两个改进:
- 上面的keypath概念,就不用自己写自定义函数(原来的过程,现在改名叫函数)了
- 解析json字串不用http客户端.解析json文本了,可以使用字典内置的json转字典
现在,提取第3天的最高气温的值,可以这样写
连接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客户端与服务器交互
以上代码在win7 + wamp server 3.0.6下测试通过。
如何让中文按照拼音排序
我们现在有个列表
想让他按照汉语拼音顺序排序,使用内置块排序如下:
返回结果是:["陈八", "赵六", "田七", "王五", "李四", "张三"]
这个并不是我们想要的结果。
准备工作
想让列表按照拼音排序,首先要把汉字转成拼音,最简单的方法就是查字典。
点我下载字典文件,改名为pinyins.json,上传到项目的素材库。
在项目中放入一个按钮、一个标签、一个文件管理器、一个HTTP客户端
逻辑设计
将字典导入项目
字典文件可以在电脑上用记事本打开查看内容,是个这样的JSON格式的文本:
使用解码JSON文本,可以将他转换为键值对列表
查字典将汉字转为拼音
查看字典文件内容可以发现,有些字是多音字,这里为了简便,我们只取第一个读音。
将一个字串(多个汉字或者字母数字)转为拼音
依次读取字串中的每个字符,如果是数字或者字母就原样输出,否则就转为拼音。
自定义排序方式
使用wxibt最新的排序列表
自定义排序方式
现在可以按照拼音排序了
输出为 ["陈八", "李四", "田七", "王五", "赵六", "张三"],正是我们想要的。
但是这样排序效率有点低(主要是因为频繁查字典),不要用它排序很长的列表。
使用网页浏览器显示表格
网页浏览器(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
假设我们要用表格显示的数据如下:
姓名 | 性别 | 年龄 |
---|---|---|
张三 | 男 | 23 |
李四 | 女 | 34 |
王五 | 男 | 45 |
我们就可以这样调用JS:
这里有个关键点:
组件设计界面,Screen1的右侧的组件属性最下面,有个是否将列表转为JSON
,这个必须选中。
现在,就可以在手机伴侣中点击按钮,就看到如下效果:
返回选中结果
怎么才能让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 然后,配合计时器就可以获取到选中的行和列了
点击表格,会返回行号、列号和单元格的值。
这个返回值是个json格式,可以配合Http客户端.解码JSON文本
和列表的在键值列表...中查找
来取得行号、列号等。
相关下载:
小白接口发送邮件
准备工作
- 小白接口网站注册账号:点我注册
- 进入个人中心,记下你的接口域名和app_key
- 为简单起见,关闭“App.Email.Send”接口的签名设置。点我查看方法
- 配置邮箱服务。点我查看方法
- 了解邮件发送接口文档:http://hb5.api.okayapi.com/docs-api-App.Email.Send.html
组件设计界面
主要组件:
- 文本输入框,改名为收件人
- 文本输入框,改名为主题
- 文本输入框,改名为正文
- 按钮,改名为添加附件
- 标签,改名为附件名,文本设为空
- 按钮,改名为发送邮件
- HTTP客户端,用来负责与接口api通讯,解析服务器返回值
- 文本选择框,用来选择附件
- 文件管理器,用来将文件转为BASE64编码
- 信息对话框,提示发送成功与否
逻辑设计界面
==黑科技:以下代码可以直接拖拽到wxbit逻辑设计界面==
- 初始化几个全局变量,
-
添加附件
-
发送邮件函数
参照接口文档,几个必选参数有app_key,address(收件人,可以用英文逗号分隔),title(邮件标题),content(邮件正文,可以是html格式)。附件attachments是可选参数,如果是图片,需要base64编码。
使用==合并文本==来拼接字串,拼出网址和POST文本,注意其中的文本格式,这里的附加内容是base64文本,需要URL编码。如果需要添加抄送、密送等,查看文档看参数。
-
发送邮件
如果没有附件(附件名.文本为空),就直接发送。如果有附件,就先将附件进行base64编码。
- 编码完成在发送
- 提示是否发送成功
根据接口文档,返回是个json文本,其中的data.err_code如果为0说明发送成功。如果发送错误,查看是否是ak或地址写错,或者附件太大。
若附件太大,建议使用
将图片缩小到800*800后再发送。
贪吃蛇
贪吃蛇是一款非常经典的手机游戏,相信每个人都玩过这个游戏。下面我们利用APP INVENTOR 2来制作一款自己的贪吃蛇。
游戏运行界面:
界面设计
界面设计比较简单,如下图:
组件及属性(其他属性都默认就可以):
名称1 | 名称2 | 宽度 | 高度 | 窗口大小 | 水平对齐 | 间隔 |
---|---|---|---|---|---|---|
画布1 | 320 | 320 | 固定大小 | |||
水平布局1 | 充满 | 充满 | 居中 | |||
上按钮 | 30% | 充满 | ||||
水平布局2 | 充满 | 充满 | 居中 | |||
左按钮 | 30% | 充满 | ||||
开始按钮 | 30% | 充满 | ||||
右按钮 | 30% | 充满 | ||||
水平布局3 | 充满 | 充满 | 居中 | |||
下按钮 | 30% | 充满 | ||||
计时器 | 500 |
游戏代码:
几个自定义过程:
将画布分成20*20的小格子(上图中粗线方框区域),每个格子高16宽16。给每个格子编号。在显示区域之外也加上一层并编号,是为了更加方便的判断蛇头是否出界。行号(列号)从0开始到21结束。
根据编号求所在行或者列,根据行和列求出所在位置编号。
几个全局变量:
蛇身位置:记录当前状态下所有身体占据的格子位置。游戏开始时,蛇身位置列表(从蛇头到蛇尾的顺序)设为(250,249,248)
当前方向:取值为1到4。 1代表向右,2是向上,3是向左,4是向下。
偏移列表:分别是蛇头向右、向上、向左、向下时,新位置编号相对当前位置编号的变化。
显示蛇身
我们利用画布的画线方法,根据所在的位置编号来画出一个方框,并给他不同的颜色。灰色是蛇身,黑色是蛇头,红色是鸡蛋。
线宽设为14,x1和x2分别减去15和1,是为了每个方框中间空出2个单位。
点击开始按钮,运行后的画出的效果如图:
让蛇身动起来
我们以向右移动方向为例。当前蛇身位置(250,249,248),250是蛇头位置,若向右移动,就把右边的251加入列表第一项的位置,同时把尾巴的位置248从列表中删除,这样蛇身位置就变成了(251,250,249),再移动一格,就变成了(252,251,250). 这样,每次移动,就是把蛇身位置列表的最后一个删除,在列表第一位置插入一个新的编号。这个新的编号是根据当前的方向决定的。
蛇头新位置:根据当前方向,求出蛇头的偏移量,加上当前的位置,就是新位置。
每次计时器计时,把画布清空,重新计算蛇身位置,并根据新位置画出蛇身。 当然,现在蛇只能向右移动,且可以穿越边界。下面加上修改方向的代码
改变方向
因为蛇不允许原地180度转向,我们加一个判断,如果方向是4(向下),那么按向上的按钮就没有变化。只有在不等于4的时候,向上按钮才起作用。其他方向同理。
禁止穿越边界
只要判断蛇头位置是否出界就可以了。如果蛇头的所在行或者列等于0或者21,就说明出界了(参考上面的编号图)。
我们在计时器的计时事件中加上一个判断,如果出界,就停止计时,并给出提示。
显示鸡蛋。
吃到鸡蛋
将移动蛇身的过程修改一下,加上判断语句。如果蛇头的新位置等于鸡蛋位置,就是吃到鸡蛋了,就把鸡蛋重新移动一个位置,并且不要删除蛇尾的位置,就相当于把鸡蛋的位置加到了原来蛇尾的位置了。如果没有碰到鸡蛋,就要把蛇尾删掉。
碰到自己
现在基本的功能都实现了,就差一个检测是否碰到自己身体了。
继续修改 移动蛇身 过程。如果蛇身位置包含蛇头要去的新位置,说明碰到自己的身体了,就要游戏结束。
附加功能
至此所有基本功能都实现了。 有兴趣的可以自己添加以下功能:
- 游戏计时,
- 吃到鸡蛋加分并显示,
- 每隔一定时间没有吃到鸡蛋,鸡蛋就变换位置,
- 鸡蛋新出现的位置不能出现在蛇的身体上,
- 添加障碍物,
- 修改为图像精灵版本(蛇头、蛇身、蛇尾用不同的图片代替)
这个是写的图像精灵版本的:
俄罗斯方块
组件设计界面:
组件设计界面很简单(很简陋): 6个按钮:开始游戏、左移、右移、逆时针转、顺时针转、下落 1个画布:宽度设为240,高度设为480 1个计时器,1个对话框
设计思路:
我们将画布分为20行、10列的格子,俄罗斯方块就是在这200个格子内移动、旋转。 给每个格子编号(从0开始),如图:
图中的白色部分就是我们的画布,外面包围的灰色一圈,就代表画布的边框,俄罗斯方块不能移动到这些边框上。
所有的棋盘游戏,都是背后的数据支撑。
我们初始化一个棋盘数据变量,记录每个小格子上的颜色。
棋盘数据初始化时是这样的:
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。
以后如果这个位置被某个组合占据,就把这个位置标记为组合的编号。
给出每个方块的位置,我们可以求出他所在的行或者列。注意,这个行和列是从0开始的。
比如0号位置,就是0行0列。13号位置就是1行1列。250号位置就是20行10列。
相对于可见的画布来说,正好符合我们的习惯。
初始化一个颜色列表变量,分别代表7种不同的组合的颜色,
画出小方块:
每个俄罗斯方块的不同组合都是由4个小方块拼成。若需要画出组合,先需要画出小的方块。
每个小方块都有不同的编号,只要给定一个编号,我们就可以在这个位置画出小方块。
我们在设计界面把画布设为240宽480高,这样每个格子就是24宽24高。
首先根据方块的位置编号,求出他所在的行和列。把线段的长度和宽度都设为22,这样每两个格子之间有个空隙。
好了,现在我们就可以连接手机伴侣,测试下我们的画方块过程了。
是不是正好画在画布的左上角?把13改成250,是不是正好画在右下角?
如果不是,说明你的画方块过程有错误,请仔细改正。
现在我们已经可以在任意位置画出小方块了,如何才能画出一个组合(4个方块)呢?
我们只要知道组合所占据的4个方块的编号就可以了。
俄罗斯方块共有7种不同的类型:分别是L型,J型,Z型,S型,T型,田字型,一字型。我们把他们称为7种组合。
每个组合可以旋转,每旋转90度是一个造型,共有4个造型(有的造型有重复)。这样,旋转组合就是切换不同的造型了
每个造型我们给他指定一个基点。这样,移动组合就是移动他的基点。
下面进入重点:造型的偏移表
举例来说,对于L型。
如果我们把它放在19,31,43,44号位置上。
我们指定31是他的基点(也可以指定其他位置作为基点),这样四个位置减去基点31的差就是:-12,0,12,13。
我们把这个称为该造型的偏移表。
我们把它逆时针旋转90度,变为:
这时,他占据的四个位置相对于31的位移变成了:-1,0,1,-11
我们把它再次逆时针旋转90度,变为
这时,他占据的四个位置相对于31的位移变成了:-13,-12,0,12 (四个格子的顺序是可以打乱的)。
再次旋转90度
位移变成了-1,0,1,11
注意,这个偏移表只跟这个组合的种类和造型(旋转)有关,跟她的位置(基点)无关。
比如第一种造型我们把他向左平移2格到:
这时,基点移动到29,他的四个格子的偏移表还是:-12,0,12,13。
使用这个方法,我们记下7种组合每个造型的偏移表:
同一种组合的不同偏移表之间用\n 连接。
注意这里用的是"csv转列表"块,而不是"csv行转列表"块。
对于田字形和一字型,可能部分造型有重复。为了跟其他组合都是4种造型相匹配,我们就把他写4次。
现在就可以画出某种组合的某种造型了:
确定了组合编号和组合造型,我们就确定了组合的偏移表。
偏移表中的每个偏移数值分别加上组合中心,就知道了组合所占据的位置编号了,这样就可以画出这个组合。
生成新组合,我们都把它显示在画布上部中间位置(17号)。
即组合中心设为17,随机生成编号和造型
每次点开始,都在画布上方画出不同种类不同造型的组合了。
这样,左移、右移、顺转、逆转就简单了:
左移就是把组合中心向左移动一个,就是组合中心数值减1,
右移就是把组合中心向右移动一个,就是组合中心数值加1,
下移就是把组合中心向下移动一个,就是组合中心数值加12。
(记得先点开始,随机产生一个组合)
逆时针转就是把造型加1,顺时针转就是把造型减1。
注意,组合造型只能在1-4之间切换。每次造型改变后必须更新偏移表。
有没有发现组合可能会移动或者旋转出了画布?如何避免呢?
比如图中L型组合要往左移动,但是要前往的格子内保存的是9(非0值),这样就不能移动。
要前往的位置占据的格子只要有1个的值为非0,就不能移动(或者旋转)。
之所以位置+1,是因为格子位置编号是从0开始,而列表取值索引是从1开始。
为了要检测移动和旋转两种操作,需要传入两个参数。记住如果造型变了,就要更新新位置偏移表。
每次移动或者旋转前,先检测要去往或者旋转后占用的地方是不是可以到达的(都为空格)。只有可以到达才移动或者旋转。
修改移动和旋转事件:
怎么让组合自动下落呢?就必须请出计时器了。
每次游戏开始,都让计时器开始计时。
每次计时,判断可否向下移动(组合中心+12就是下移)。如果碰到底边或者其他组合,就重新在画布上部生成新组合。
如果你测试这个代码,就会发现触底的组合并没有留在那里,而是消失了。
因为我们没有把触底的组合保存到“棋盘数据”变量:
添加后还要显示出来:
循环取出棋盘数据中的每个数(颜色,也是这格方块曾经被某个组合占据)。
如果这个数不是9(边框),也不是0(空白格),就在这个位置画方块。
修改计时器事件:
生成新组合之前,保存数据到棋盘数据。
修改”重绘画布”过程:
现在我们的组合可以左右移动、顺转逆转、定时下落了。
那什么时候游戏结束呢?就在新生成的组合无法安放时:
有没有发现在生成新组合时经常莫名其妙就提示游戏结束了?
这是因为我们把初始的组合中心设为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,删除了几行,插入几行。
根据消除的行数计算得分:1行10分,2行30分,3行60分,4行100分。不可能同时消除5行及以上的。
修改计时器计时事件,在生成新方块之前检测消除方块并计算得分:
修改开始游戏事件,游戏开始时重新计分:
最后一个,快速下落事件:
重复检查可否下移一格(组合中心+12),若可以,再次下移一格,直到无法下移为止。
我们在回头看下“消除方块”这个过程:
实际上每次消除时不可能有20行都能消除,可以消除的行只可能在当前组合占据的行中产生。
我们只要找到当前组合占据的行,依次判断这几行可否消除就可以了。
为什么在13位置插入呢?因为13位置就是棋盘数据第二行的第一个数字。