add: 300 built-in icons

This commit is contained in:
hyb1996 committed 2018-03-28 10:52:04 +08:00
1 parent 9c43b1f41c
commit 9a61bbe64d
301 files changed
+237 -188

No files matched your search

@@ -1,188 +0,0 @@
"ui";
ui.layout(
<vertical>
<canvas id="board" layout_weight="1"/>
<relative h="120">
<button id="up" text="↑" w="60" h="60" layout_alignParentTop="true" layout_centerHorizontal="true"/>
<button id="left" text="←" w="60" h="60" layout_alignParentBottom="true" layout_toLeftOf="@id/down"/>
<button id="down" text="↓" w="60" h="60" layout_alignParentBottom="true" layout_centerHorizontal="true"/>
<button id="right" text="→" w="60" h="60" layout_alignParentBottom="true" layout_toRightOf="@id/down"/>
</relative>
</vertical>
);
//蛇的颜色
const SNAKE_COLOR = colors.parseColor("#9EDBB0");
//背景色
const BG_COLOR = colors.parseColor("#ffffff");
//苹果颜色
const APPLE_COLOR = colors.parseColor("#f44336");
//墙的颜色
const WALL_COLOR = colors.parseColor("#607d8b");
//文本颜色
const TEXT_COLOR = colors.parseColor("#03a9f4");
//蛇头图片
const SNAKE_HEAD = images.fromBase64("iVBORw0KGgoAAAANSUhEUgAAADIAAAArCAYAAAA65tviAAAACXBIWXMAAAsTAAALEwEAmpwYAAA57GlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwNjcgNzkuMTU3NzQ3LCAyMDE1LzAzLzMwLTIzOjQwOjQyICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTgtMDMtMjNUMjE6MTU6NTErMDg6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wMy0yM1QyMToyMDo1MiswODowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTgtMDMtMjNUMjE6MjA6NTIrMDg6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6YjkyNzMyZjMtMzg4ZC00YzQxLTlhMWMtMDI4NTFhNGYxZDQ0PC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6ZmE5OWVkOTEtMmU5Yy0xMWU4LTk1NjYtOGU4M2FkZTA3NzBhPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjEwYmQ3YzYtMzc5Ni03YTQ0LThkMmUtNGVjMmU4YjczN2Q0PC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjYxMGJkN2M2LTM3OTYtN2E0NC04ZDJlLTRlYzJlOGI3MzdkNDwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxOC0wMy0yM1QyMToxNTo1MSswODowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDpiOTI3MzJmMy0zODhkLTRjNDEtOWExYy0wMjg1MWE0ZjFkNDQ8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTgtMDMtMjNUMjE6MjA6NTIrMDg6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NDM8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgILine truncated
//蛇自动移动的时间间隔,调小可以增加难度
const MOVE_INTERVAL = 500;
//方块宽度
const BLOCK_WIDTH = 40;
//游戏区域宽高
const GAME_BORAD_HEIGHT = 20;
const GAME_BORAD_WIDTH = 15;
//蛇的四个移动方向
const DIRECTION_LFET = {x: -1, y: 0};
const DIRECTION_RIGHT = {x: 1, y: 0};
const DIRECTION_UP = {x: 0, y: -1};
const DIRECTION_DOWN = {x: 0, y: 1};
//蛇,是一个蛇身的坐标的数组
var snake = [{x: 4, y: 2}, {x: 3, y: 2}, {x: 2, y: 2}];
//苹果的坐标
var apple = generateApple();
//当前蛇的移动方向
var direction = DIRECTION_RIGHT;
//标记游戏是否结束
var isGameOver = false;
//分数
var score = 0;
var paint = new Paint();
ui.board.on("draw", function(canvas){
//绘制背景色
canvas.drawColor(BG_COLOR);
//绘制分数
paint.setColor(TEXT_COLOR);
paint.setTextSize(50);
canvas.drawText("分数: " + score, 30, 70, paint);
//如果游戏结束则绘制游戏结束字样
if(isGameOver){
canvas.drawText("游戏结束!", canvas.getWidth() - 280, 70, paint);
}
//计算坐标偏移,是的游戏区域绘制在画面的水平居中位置
var offset = {
x: (canvas.getWidth() - (GAME_BORAD_WIDTH + 2) * BLOCK_WIDTH) / 2,
y: 100
};
//偏移坐标
canvas.translate(offset.x, offset.y);
//绘制围墙
paint.setColor(WALL_COLOR);
for(var i = 0; i <= GAME_BORAD_WIDTH + 1; i++){
//上围墙
drawBlock(canvas, paint, i, 0);
//下围墙
drawBlock(canvas, paint, i, GAME_BORAD_HEIGHT + 1);
}
for(var i = 0; i <= GAME_BORAD_HEIGHT + 1; i++){
//左围墙
drawBlock(canvas, paint, 0, i);
//右围墙
drawBlock(canvas, paint, GAME_BORAD_WIDTH + 1, i);
}
//绘制蛇头
canvas.drawImage(SNAKE_HEAD, x * BLOCK_WIDTH, y * BLOCK_WIDTH, paint);
//绘制蛇身
paint.setColor(SNAKE_COLOR);
for(var i = 1; i < snake.length; i++){
drawBlock(canvas, paint, snake[i].x, snake[i].y);
}
//绘制苹果
paint.setColor(APPLE_COLOR);
drawBlock(canvas, paint, apple.x, apple.y);
});
//启动游戏线程
var gameThread = threads.start(game);
//按键点击时改变蛇的移动方向
ui.left.on("click", ()=> direction = DIRECTION_LFET);
ui.right.on("click", ()=> direction = DIRECTION_RIGHT);
ui.up.on("click", ()=> direction = DIRECTION_UP);
ui.down.on("click", ()=> direction = DIRECTION_DOWN);
function game(){
//每隔一段时间让蛇自动前进
setInterval(()=>{
move(direction.x, direction.y);
}, MOVE_INTERVAL);
}
function move(dx, dy){
log("move: %d, %d", dx, dy);
direction.x = dx;
direction.y = dy;
//蛇前进时把一个新的方块添加到蛇头前面
var head = snake[0];
snake.splice(0, 0, {
x: head.x + dx,
y: head.y + dy
});
//如果蛇头吃到了苹果
if(snakeEatsApple()){
//添加分数和重新生成苹果
score += 5;
apple = generateApple();
}else{
//没有吃到苹果的情况下把蛇尾去掉保持蛇身长度不变
snake.pop();
}
//碰撞检测
collisionTest();
}
function snakeEatsApple(){
return snake[0].x == apple.x && snake[0].y == apple.y;
}
function generateApple(){
//循环生成苹果直至苹果不会生成在蛇身上
var x, y;
do{
x = random(1, GAME_BORAD_WIDTH);
y = random(1, GAME_BORAD_HEIGHT);
}while(!isAppleValid(x, y));
log("generateApple: ", {x: x, y: y});
return {x: x, y: y};
}
function isAppleValid(x, y){
for (var i = 0; i < snake.length; i++) {
if (snake[i].x == x && snake[i].y == y) {
return false;
}
}
return true;
}
function collisionTest(){
//检测蛇有没有撞到墙上
var head = snake[0];
if(head.x < 1 || head.x > GAME_BORAD_WIDTH
|| head.y < 1 || head.y > GAME_BORAD_HEIGHT){
gameOver();
return;
}
//检测蛇有没有撞到自己
for(var i = 1; i < snake.length; i++){
if(snake[i].x == head && snake[i].y == head){
gameOver();
return;
}
}
}
function gameOver(){
gameThread.interrupt();
isGameOver = true;
}
function drawBlock(canvas, paint, x, y){
x *= BLOCK_WIDTH;
y *= BLOCK_WIDTH;
canvas.drawRect(x, y, x + BLOCK_WIDTH, y + BLOCK_WIDTH, paint);
}
@@ -0,0 +1,231 @@
"ui";
ui.layout(
<vertical>
<canvas id="board"/>
</vertical>
);
//蛇的颜色
const SNAKE_COLOR = colors.parseColor("#9EDBB0");
//背景色
const BG_COLOR = colors.parseColor("#ffffff");
//文本颜色
const TEXT_COLOR = colors.parseColor("#03a9f4");
//蛇头图片
const SNAKE_HEAD = images.fromBase64("iVBORw0KGgoAAAANSUhEUgAAADAAAAArCAYAAAA+EwvfAAAACXBIWXMAAAsTAAALEwEAmpwYAAA7pmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwNjcgNzkuMTU3NzQ3LCAyMDE1LzAzLzMwLTIzOjQwOjQyICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTgtMDMtMjNUMjE6MTU6NTErMDg6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wMy0yM1QyMTo0ODoyMiswODowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTgtMDMtMjNUMjE6NDg6MjIrMDg6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6M2UyZTBkZGUtOWY3Zi1hNTQ0LTk1NmQtN2MyMDEzNmJjOWRlPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6ZmE5OWVkOTEtMmU5Yy0xMWU4LTk1NjYtOGU4M2FkZTA3NzBhPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjEwYmQ3YzYtMzc5Ni03YTQ0LThkMmUtNGVjMmU4YjczN2Q0PC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjYxMGJkN2M2LTM3OTYtN2E0NC04ZDJlLTRlYzJlOGI3MzdkNDwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxOC0wMy0yM1QyMToxNTo1MSswODowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDpiOTI3MzJmMy0zODhkLTRjNDEtOWExYy0wMjg1MWE0ZjFkNDQ8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTgtMDMtMjNUMjE6MjA6NTIrMDg6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6M2UyZTBkZGUtOWY3Zi1hNTQ0LTk1NmQtN2MyMDEzNmJjOWRlPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE4LTAzLTIzVDIxOjQ4OjIyKzA4OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+NjU1MzU8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjQ4PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjQzPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgILine truncated
//苹果图片
const APPLE = images.fromBase64("iVBORw0KGgoAAAANSUhEUgAAAC0AAAArCAYAAADsQwGHAAAACXBIWXMAAC4jAAAuIwF4pT92AAA/YmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwNjcgNzkuMTU3NzQ3LCAyMDE1LzAzLzMwLTIzOjQwOjQyICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPmFkb2JlOmRvY2lkOnBob3Rvc2hvcDo1NjA1MGFhZS0yZWExLTExZTgtODY3ZC1iMDQ3Y2JkZjZmZjg8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6YTNmMzk5MjctZWJhYS0wYTRiLWJiMGUtZmQwNDk1ODRiYTRlPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPjlGNkI0QTAxN0E2RDg3M0I3RUE3MUU1MUFCNkYzMTk2PC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo3ZGE4N2U3Yi1kZWE0LTBkNGQtODhkYy0wNjY5MDI1ZWU1OGE8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTgtMDMtMjNUMjE6NTE6NTcrMDg6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNvbnZlcnRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6cGFyYW1ldGVycz5mcm9tIGltYWdlL2pwZWcgdG8gaW1hZ2UvcG5nPC9zdEV2dDpwYXJhbWV0ZXJzPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+ZGVyaXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6cGFyYW1ldGVycz5jb252ZXJ0ZWQgZnJvbSBpbWFnZS9qcGVnIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6YTNmMzk5MjctZWJhYS0wYTRiLWJiMGUtZmQwNDk1ODRiYTRlPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE4LTAzLTIzVDIxOjUxOjU3KzA4OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHhtcE1NOkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgPHN0UmVmOmluc3RhbmNlSUQ+eG1wLmlpZDo3ZGE4N2U3Yi1kZWE0LTBkNGQtODhkYy0wNjY5MDI1ZWU1OGE8L3N0UmVmOmluc3RhbmNlSUQ+CiAgICAgICAgICAgIDxzdFJlZjpkb2N1bWVudElEPjlGNkI0QTAxN0E2RDg3M0I3RUE3MUU1MUFCNkYzMTk2PC9zdFJlZjpkb2N1bWVudElEPgogICAgICAgICAgICA8c3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPjlGNkI0QTAxN0E2RDg3M0I3RUE3MUU1MUFCNkYzMTk2PC9zdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDwveG1wTU06RGVyaXZlZEZyb20+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDx4bXA6Q3JlYXRlRGF0ZT4yMDE4LTAzLTIzVDIxOjUwOjQ2KzA4OjAwPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTgtMDMtMjNUMjE6NTE6NTcrMDg6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8eG1wOk1ldGFkYXRhRGF0ZT4yMDE4LTAzLTIzVDIxOjUxOjU3KzA4OjAwPC94bXA6TWV0YWRhdGFEYXRlPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChXaW5kb3dzKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8dGlmZjpJbWFnZVdpZHRoPjEwMjQ8L3RpZmY6SW1hZ2VXaWR0aD4KICAgICAgICAgPHRpZmY6SW1hZ2VMZW5ndGg+OTc0PC90aWZmOkltYWdlTGVuZ3RoPgogICAgICAgICA8dGlmZjpCaXRzUGVyU2FtcGxlPgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaT44PC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGk+ODwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpPjg8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6U2VxPgogICAgICAgICA8L3RpZmY6Qml0c1BlclNhbXBsZT4KICAgICAgICAgPHRpZmY6UGhvdG9tZXRyaWNJbnRlcnByZXRhdGlvbj4yPC90aWZmOlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiLine truncated
//围墙方块图片
const WALL_BLOCK = images.fromBase64("iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAACXBIWXMAAAsTAAALEwEAmpwYAAA4JGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwNjcgNzkuMTU3NzQ3LCAyMDE1LzAzLzMwLTIzOjQwOjQyICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTgtMDMtMjNUMjE6NTc6MTArMDg6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wMy0yM1QyMTo1Nzo1OCswODowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTgtMDMtMjNUMjE6NTc6NTgrMDg6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6MDI2NmYzMzQtZTgyYy05OTQ2LThiNjItYzdlZTc2MjJmMmQyPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOjAyNjZmMzM0LWU4MmMtOTk0Ni04YjYyLWM3ZWU3NjIyZjJkMjwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjAyNjZmMzM0LWU4MmMtOTk0Ni04YjYyLWM3ZWU3NjIyZjJkMjwveG1wTU06T3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDowMjY2ZjMzNC1lODJjLTk5NDYtOGI2Mi1jN2VlNzYyMmYyZDI8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTgtMDMtMjNUMjE6NTc6MTArMDg6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NDA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NDA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgILine truncated
//蛇自动移动的时间间隔,调小可以增加难度
const MOVE_INTERVAL = 500;
//方块宽度
const BLOCK_WIDTH = 40;
//游戏区域宽高
const GAME_BORAD_HEIGHT = 20;
const GAME_BORAD_WIDTH = 15;
//蛇的四个移动方向
const DIRECTION_LEFT = {x: -1, y: 0, angle: 180};
const DIRECTION_RIGHT = {x: 1, y: 0, angle: 0};
const DIRECTION_UP = {x: 0, y: -1, angle:270};
const DIRECTION_DOWN = {x: 0, y: 1, angle: 90};
//蛇,是一个蛇身的坐标的数组
var snake = [{x: 4, y: 2}, {x: 3, y: 2}, {x: 2, y: 2}];
//苹果的坐标
var apple = generateApple();
//当前蛇的移动方向
var direction = DIRECTION_RIGHT;
//标记游戏是否结束
var isGameOver = false;
//分数
var score = 0;
//难度
var level = 5;
var gameThread = null;
dialogs.input("请输入难度(1~10)", level)
.then(function(l){
level = Math.max(1, Math.min(10, l));
MOVE_INTERVAL = 1000 - level * 100;
//启动游戏线程
gameThread = threads.start(game);
toast("通过重力感应来改变蛇的移动方向");
});
function game(){
//每隔一段时间让蛇自动前进
setInterval(()=>{
move(direction.x, direction.y);
}, MOVE_INTERVAL);
}
function move(dx, dy){
log("move: %d, %d", dx, dy);
direction.x = dx;
direction.y = dy;
//蛇前进时把一个新的方块添加到蛇头前面
var head = snake[0];
snake.splice(0, 0, {
x: head.x + dx,
y: head.y + dy
});
//如果蛇头吃到了苹果
if(snakeEatsApple()){
//添加分数和重新生成苹果
score += 5;
apple = generateApple();
}else{
//没有吃到苹果的情况下把蛇尾去掉保持蛇身长度不变
snake.pop();
}
//碰撞检测
collisionTest();
}
function snakeEatsApple(){
return snake[0].x == apple.x && snake[0].y == apple.y;
}
function generateApple(){
//循环生成苹果直至苹果不会生成在蛇身上
var x, y;
do{
x = random(1, GAME_BORAD_WIDTH);
y = random(1, GAME_BORAD_HEIGHT);
}while(!isAppleValid(x, y));
log("generateApple: ", {x: x, y: y});
return {x: x, y: y};
}
function isAppleValid(x, y){
for (var i = 0; i < snake.length; i++) {
if (snake[i].x == x && snake[i].y == y) {
return false;
}
}
return true;
}
function collisionTest(){
//检测蛇有没有撞到墙上
var head = snake[0];
if(head.x < 1 || head.x > GAME_BORAD_WIDTH
|| head.y < 1 || head.y > GAME_BORAD_HEIGHT){
gameOver();
return;
}
//检测蛇有没有撞到自己
for(var i = 1; i < snake.length; i++){
if(equals(snake[i], head)){
gameOver();
return;
}
}
}
function gameOver(){
gameThread.interrupt();
isGameOver = true;
}
//监听重力传感器实现重力改变蛇的移动方向
sensors.register("gravity", sensors.delay.game)
.on("change", function(event, gx, gy, gz){
if(Math.abs(gx) > Math.abs(gy) && Math.abs(gx) > 1.8){
setDirection(gx > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT);
}
if(Math.abs(gy) > Math.abs(gx) && Math.abs(gy) > 1.8){
setDirection(gy > 0 ? DIRECTION_DOWN: DIRECTION_UP);
}
});
function setDirection(d){
if(equals(d, DIRECTION_LEFT) && equals(direction, DIRECTION_RIGHT))
return;
if(equals(d, DIRECTION_RIGHT) && equals(direction, DIRECTION_LEFT))
return;
if(equals(d, DIRECTION_DOWN) && equals(direction, DIRECTION_UP))
return;
if(equals(d, DIRECTION_UP) && equals(direction, DIRECTION_DOWN))
return;
direction = d;
}
var paint = new Paint();
ui.board.on("draw", function(canvas){
//绘制背景色
canvas.drawColor(BG_COLOR);
//绘制分数等信息
paint.setColor(TEXT_COLOR);
paint.setTextSize(50);
canvas.drawText("分数: " + score, 30, 70, paint);
canvas.drawText("难度: " + level, 400, 70, paint);
//如果游戏结束则绘制游戏结束字样
if(isGameOver){
canvas.drawText("游戏结束!", canvas.getWidth() - 280, 70, paint);
}
//计算坐标偏移,是的游戏区域绘制在画面的水平居中位置
var offset = {
x: (canvas.getWidth() - (GAME_BORAD_WIDTH + 2) * BLOCK_WIDTH) / 2,
y: 100
};
//偏移坐标
canvas.translate(offset.x, offset.y);
//绘制围墙
drawWall(canvas, paint);
//绘制蛇头
drawSnakeHead(canvas, paint);
//绘制蛇身
drawSnakeBody(canvas, paint);
//绘制苹果
canvas.drawImage(APPLE, apple.x * BLOCK_WIDTH, apple.y * BLOCK_WIDTH, paint);
});
function drawWall(canvas, paint){
for(var i = 0; i <= GAME_BORAD_WIDTH + 1; i++){
//上围墙
drawBlock(canvas, paint, i, 0);
//下围墙
drawBlock(canvas, paint, i, GAME_BORAD_HEIGHT + 1);
}
for(var i = 0; i <= GAME_BORAD_HEIGHT + 1; i++){
//左围墙
drawBlock(canvas, paint, 0, i);
//右围墙
drawBlock(canvas, paint, GAME_BORAD_WIDTH + 1, i);
}
}
function drawBlock(canvas, paint, x, y){
x *= BLOCK_WIDTH;
y *= BLOCK_WIDTH;
canvas.drawImage(WALL_BLOCK, x, y, paint);
}
function drawSnakeHead(canvas, paint){
var x = snake[0].x * BLOCK_WIDTH;
var y = snake[0].y * BLOCK_WIDTH;
var matrix = new android.graphics.Matrix();
matrix.postRotate(direction.angle, SNAKE_HEAD.getWidth() / 2, SNAKE_HEAD.getHeight() / 2);
matrix.postTranslate(x, y);
canvas.drawImage(SNAKE_HEAD, matrix, paint);
}
function drawSnakeBody(canvas, paint){
paint.setColor(SNAKE_COLOR);
for(var i = 1; i < snake.length; i++){
var x = snake[i].x * BLOCK_WIDTH;
var y = snake[i].y * BLOCK_WIDTH;
canvas.drawCircle(x + BLOCK_WIDTH / 2, y + BLOCK_WIDTH / 2, BLOCK_WIDTH / 2, paint);
}
}
function equals(point1, point2){
return point1.x == point2.x && point1.y == point2.y;
}
@@ -10,6 +10,7 @@ import android.graphics.Xfermode;
import android.media.Image; import android.media.Image;
import android.os.Build; import android.os.Build;
import android.support.annotation.RequiresApi; import android.support.annotation.RequiresApi;
import android.view.KeyEvent;
import com.stardust.autojs.runtime.api.Images; import com.stardust.autojs.runtime.api.Images;
import com.stardust.pio.UncheckedIOException; import com.stardust.pio.UncheckedIOException;
@@ -5,6 +5,7 @@ import android.util.AttributeSet;
import com.makeramen.roundedimageview.RoundedImageView; import com.makeramen.roundedimageview.RoundedImageView;
import com.stardust.autojs.core.image.ImageWrapper;
import com.stardust.autojs.core.ui.inflater.util.Drawables; import com.stardust.autojs.core.ui.inflater.util.Drawables;
/** /**
@@ -43,6 +44,10 @@ public class JsImageView extends RoundedImageView {
getDrawables().setupWithImage(this, uri); getDrawables().setupWithImage(this, uri);
} }
public void setSource(ImageWrapper image) {
setImageBitmap(image.getBitmap());
}
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 945 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 638 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 994 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Loaded 100 of 301 files, more files were not shown because too many files have changed in this diff. Show more