Flutter七日遊次日----2018-12-17----天氣晴朗
昨天講了一下Flutter的基礎項目,介紹了一下Dart語言,簡單的用Canvas繪個圖
原本打算今天把內置控件看一下的,不過既然昨天把圖都畫了,今天不玩動畫豈不惋惜
今天主要是把動畫理一下,順便把Android-java粒子運動復刻到Flutter-Dart裏
最後會實現一個粒子時鐘,Java版詳見:Android原生繪圖之炫酷倒計時
因此這篇會挺好玩的,瓜子,飲料,花生米備好,開始看吧前端
運動盒 | 粉碎球 |
---|---|
星與芒 | 星擴動 |
---|---|
五角星的長大
按照昨天的Flutter初始項目,咱們來本身寫一個
本人是喜歡分包的,Javaer的優良習慣。至少邏輯清晰,分工明確,我建立了一個pager包
主頁面內容用AnimaPage,雖然暫時還不知道StatefulWidget是什麼,反正按照套路出牌就好了
仿照初始項目的套路寫,這裏繪圖區自定義AnimaView,打算對五角星的外接圓半徑R進行動畫java
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:toly/view/anima_view.dart';
class AnimaPage extends StatefulWidget {
@override
_AnimaPageState createState() => _AnimaPageState();
}
class _AnimaPageState extends State<AnimaPage>{
double _R = 25;//五角星的外接圓半徑
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("張風捷特烈"),
),
body: CustomPaint(
painter: AnimaView(context, _R),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
複製代碼
n角星的路徑第一天已經封裝好了,不會的能夠去看一下git
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:toly/helper/common_path.dart';
import 'package:toly/helper/help_view.dart';
class AnimaView extends CustomPainter {
Paint mPaint;
BuildContext context;
double _R;
AnimaView(this.context, double r) {
mPaint = new Paint();
mPaint.color = Colors.deepOrange;
_R = r;
}
@override
void paint(Canvas canvas, Size size) {
var winSize = MediaQuery.of(context).size;
drawGrid(canvas, winSize);
drawCoo(canvas, new Size(160, 320), winSize);
canvas.translate(160, 320);
canvas.drawPath(nStarPath(5, _R, 50), mPaint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
複製代碼
如今萬事俱備,只欠東風把R的值吹動就好了,下面有請Animation登場
vsync須要with SingleTickerProviderStateMixi
Tween:補間動畫----這裏即:在 25.0, ~ 150.0之間在2000ms以內均勻變化 (PS:因爲程序運行狀況不一樣,並不是絕對均勻,但總體上是均勻的)
..
:是級聯運算,至關於再使用此對象,這裏..
也就表明animation.
github
class AnimaPage extends StatefulWidget {
@override
_AnimaPageState createState() => _AnimaPageState();
}
class _AnimaPageState extends State<AnimaPage>
with SingleTickerProviderStateMixin {
AnimationController controller;
Animation<double> animation;
double _R = 25;
@override
void initState() {
super.initState();
// 建立 AnimationController 對象
//|----vsync時會防止屏幕外動畫(動畫的UI不在當前屏幕時)消耗沒必要要的資源
controller = AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
animation = Tween(begin: 25.0, end: 150.0).animate(controller)
..addListener(() {
setState(() {
_R = animation.value;
});
});
}
@override
void dispose() {
super.dispose();
controller.dispose(); // 資源釋放
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("張風捷特烈"),
),
body: CustomPaint(
painter: AnimaView(context, _R),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.forward(); //執行動畫
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
複製代碼
這樣最簡單的動畫就動起來了編程
把源碼翻一翻,感受整個動畫體系也不是很是複雜
套路就是:Animatable用animate方法,把一個Animation包裹一下,造成一個更厲害的Animation
至於他們的n個兒子,也就是對數據的處理不一樣,產生的效果不一樣罷了,套路知道了,一切好辦canvas
能夠看出api並無想象中的那麼多,因此別怕api
五角星的綻開
前面用了補間動畫Tween,並且只動了一下,下面帶來連續運動的不均勻動畫數組
勻速往復動 | 自定義曲線 | bounceInOut |
---|---|---|
你能夠想象成一我的在一個範圍數字跑道上跑步:bash
enum AnimationStatus {
/// The animation is stopped at the beginning
dismissed,//在正在開始時中止了
/// The animation is running from beginning to end
forward,//運動中
/// The animation is running backwards, from end to beginning
reverse,//跑到終點,再跑回來的時候
/// The animation is stopped at the end
completed,//跑到終點是
}
複製代碼
addStatusListener
:能夠監聽當前運動狀態:只要讓它跑完了,再往回跑就好了微信
animation = Tween(begin: 25.0, end: 150.0).animate(controller)
..addListener(() {
setState(() {
_R = animation.value;
});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
controller.forward();
}
});
複製代碼
就像運動員變速跑同樣,感受就像遊戲里加buff,原本是勻速的Animation
給價格變速的buff就變速起來了,加buff的類就是Animatable
,它的子類有一個CurveTween
:
animation = Tween(begin: 25.0, end: 150.0).animate(
CurveTween(curve: Curves.bounceInOut).animate(controller))
複製代碼
就這麼簡單,Curves裏有幾個內置的變速器,給原來的animation裝上就好了
---->[CurveTween]---------控件只有一參Curve------------------------
class CurveTween extends Animatable<double> {
/// Creates a curve tween.
///
/// The [curve] argument must not be null.
CurveTween({ @required this.curve })
: assert(curve != null);
/// The curve to use when transforming the value of the animation.
Curve curve;
---->[Curve]--------抽象的,找兒子去--------------------
@immutable
abstract class Curve {
---->[Curve]--------四參構造的曲線,整合我意--------------------
class Cubic extends Curve {
/// Creates a cubic curve.
///
/// Rather than creating a new instance, consider using one of the common
/// cubic curves in [Curves].
///
/// The [a], [b], [c], and [d] arguments must not be null.
const Cubic(this.a, this.b, this.c, this.d)
複製代碼
做爲一名前端業餘愛好者,Chrome裏有個小東西頗有用,
曲線生成,自帶預覽,簡直無意插柳柳成蔭。(記得掘金的頭像能夠轉,有translate屬性)
animation = Tween(begin: 25.0, end: 150.0).animate(
CurveTween(curve: Cubic(0.96, 0.13, 0.1, 1.2)).animate(controller))
複製代碼
Ok,基本上就這樣,你get了嗎?
太陽的誕生
紅太陽 | 星與陽 |
---|---|
套路學會了,這些動態改變一下n角星的尖角數,看看效果
Animation<int> numAnima;//n角星的尖角數動畫
int _num = 5;//n角星的尖角數動畫
controller = AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
numAnima = IntTween(begin: 5, end: 220).animate(controller)
..addListener(() {
setState(() {
_num = numAnima.value;//設置屬性,刷新界面
});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
controller.forward();
}
});
複製代碼
int _num;
AnimaView(this.context, {double R, int num, Color color}) {
_num = num;
}
//繪製時使用_num便可
canvas.drawPath(nStarPath(_num, 100, 50), mPaint);
複製代碼
ColorTween
至關於添加顏色改變的buff,入參的本身加吧,和上面同樣,給畫筆填色就好了
colorAnima =
ColorTween(begin: Colors.yellow, end: Colors.red).animate(controller)
..addListener(() {
setState(() {
_color = colorAnima.value;
});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
controller.forward();
}
});
複製代碼
本身玩玩吧,隨便改些屬性
星與芒 | 星擴動 |
---|---|
星與芒:固定五角星內接圓半徑,外接圓半徑變大,角數變多,顏色變紅
星擴動:五角星內接圓半徑爲外接圓一半,外接圓半徑變大,角數變多,顏色變紅
好了,預熱完了,下面進入正題
不管什麼語言只有能模擬
時間流
就能夠有粒子動畫
粒子動畫的基礎在Android原生繪圖之讓你瞭解View的運動裏講的很詳細
思想對於全部語言都是通用的,不只限於java,有興趣的能夠詳細瞭解下
運動盒
再說
運動盒
就是小球在盒子裏不斷彈跳的動畫,就像這樣
run_ball_view.dart----->RunBallView + Ball
先把小球的實體類寫一下
class Ball {
double aX; //加速度
double aY; //加速度Y
double vX; //速度X
double vY; //速度Y
double x; //點位X
double y; //點位Y
Color color; //顏色
double r;//小球半徑
Ball({this.x, this.y, this.color, this.r, this.aX, this.aY, this.vX, this.vY});
}
複製代碼
class RunBallView extends CustomPainter {
Paint mPaint;
BuildContext context;
Ball _ball;
Rect _limit;
RunBallView(this.context, Ball ball, Rect limit) {
mPaint = new Paint();
_ball = ball;
_limit = limit;
}
@override
void paint(Canvas canvas, Size size) {
var winSize = MediaQuery.of(context).size;
canvas.translate(160, 320);
mPaint.color = Color.fromARGB(148, 198, 246, 248);
canvas.drawRect(_limit, mPaint);
canvas.save();
drawBall(canvas, _ball);
canvas.restore();
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
//繪製小球
void drawBall(Canvas canvas, Ball ball) {
mPaint.color = ball.color;
canvas.drawCircle(Offset(ball.x, ball.y), ball.r, mPaint);
}
}
複製代碼
這是咱們須要的字段
var limit = Rect.fromLTRB(-140, -100, 140, 100);
print("width:${limit.width}");
print("height:${limit.height}");
print("left:${limit.left}");
print("top:${limit.top}");
print("right:${limit.right}");
print("bottom:${limit.bottom}");
I/flutter (28755): width:280.0
I/flutter (28755): height:200.0
I/flutter (28755): left:-140.0
I/flutter (28755): top:-100.0
I/flutter (28755): right:140.0
I/flutter (28755): bottom:100.0
複製代碼
run_ball_pager.dart---->RunBallPage
這裏只須要一個時間流,用
AnimationController
一我的就夠了
class RunBallPage extends StatefulWidget {
@override
_RunBallPageState createState() => _RunBallPageState();
}
class _RunBallPageState extends State<RunBallPage>
with SingleTickerProviderStateMixin {
AnimationController controller;
Ball _ball;
var _limit = Rect.fromLTRB(-140, -100, 140, 100);//矩形邊界
@override
void initState() {
super.initState();
//初始化小球
_ball = Ball(x: 0, y: 0, color: Colors.blue, r: 10, aX: 0, aY: 0, vX: 0, vY: 2);
// 建立 AnimationController 對象
//|----vsync時會防止屏幕外動畫(動畫的UI不在當前屏幕時)消耗沒必要要的資源
controller = AnimationController(
duration: const Duration(milliseconds: 200000), vsync: this);
controller.addListener(() {
updateBall();//更新小球
setState(() {});
});
controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
controller.forward();
}
});
}
@override
void dispose() {
super.dispose();
controller.dispose(); // 資源釋放
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("張風捷特烈"),
),
body: CustomPaint(
painter: RunBallView(context, _ball,_limit),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.forward(); //執行動畫
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
//更新小球
void updateBall() {}
}
複製代碼
這樣靜態小球就完成了
RunBallPage#updateBall
//更新小球位置
void updateBall() {
//運動學公式
_ball.x += _ball.vX;
_ball.y += _ball.vY;
_ball.vX += _ball.aX;
_ball.vY += _ball.aY;
//限定下邊界
if (_ball.y > _limit.bottom - _ball.r) {
_ball.y = _limit.bottom - _ball.r;
_ball.vY = -_ball.vY;
_ball.color=randomRGB();//碰撞後隨機色
}
//限定上邊界
if (_ball.y < _limit.top + _ball.r) {
_ball.y = _limit.top + _ball.r;
_ball.vY = -_ball.vY;
_ball.color=randomRGB();//碰撞後隨機色
}
}
複製代碼
//初始時附加信息
_ball = Ball(x: 0, y: 0, color: Colors.blue, r: 10, aX: 0, aY: 0.1, vX: 2, vY: -2);
//更新小球位置
void updateBall() {
//運動學公式
_ball.x += _ball.vX;
_ball.y += _ball.vY;
_ball.vX += _ball.aX;
_ball.vY += _ball.aY;
//限定下邊界
if (_ball.y > _limit.bottom - _ball.r) {
_ball.y = _limit.bottom - _ball.r;
_ball.vY = -_ball.vY;
_ball.color=randomRGB();//碰撞後隨機色
}
//限定上邊界
if (_ball.y < _limit.top + _ball.r) {
_ball.y = _limit.top + _ball.r;
_ball.vY = -_ball.vY;
_ball.color=randomRGB();//碰撞後隨機色
}
//限定左邊界
if (_ball.x < _limit.left + _ball.r) {
_ball.x = _limit.left + _ball.r;
_ball.vX = -_ball.vX;
_ball.color=randomRGB();//碰撞後隨機色
}
//限定右邊界
if (_ball.x > _limit.right - _ball.r) {
_ball.x = _limit.right - _ball.r;
_ball.vX= -_ball.vX;
_ball.color=randomRGB();//碰撞後隨機色
}
}
複製代碼
思路就是:用List把球裝一下,碰撞的時候,建立一個方向相反,半徑減半的球,加入集合
並將當前的球半徑減半,效果挺不錯的,實現起來也不麻煩。Android-java版可見
RunBallPage
半徑小於0.3就移除,爲了避免讓小球無限增長,小於0.3基本上也就卡不見了
固然你也能夠自定義移除的時機
var _balls = List<Ball>();//將_ball換成集合
var ball = Ball(x: 0, y: 0, color: Colors.blue, r: 40, aX: 0.05, aY: 0.1, vX: 3, vY: -3);
_balls.add(ball);//添加一個
//更新方法
for (int i = 0; i < _balls.length; i++) {
var ball = _balls[i];
if (ball.r < 0.3) {
//半徑小於0.3就移除
_balls.removeAt(i);
}
//運動學公式
ball.x += ball.vX;
ball.y += ball.vY;
ball.vX += ball.aX;
ball.vY += ball.aY;
//限定下邊界
if (ball.y > _limit.bottom) {
var newBall = Ball.fromBall(ball);
newBall.r = newBall.r / 2;
newBall.vX = -newBall.vX;
newBall.vY = -newBall.vY;
_balls.add(newBall);
ball.r = ball.r / 2;
ball.y = _limit.bottom;
ball.vY = -ball.vY;
ball.color = randomRGB(); //碰撞後隨機色
}
//限定上邊界
if (ball.y < _limit.top) {
ball.y = _limit.top;
ball.vY = -ball.vY;
ball.color = randomRGB(); //碰撞後隨機色
}
//限定左邊界
if (ball.x < _limit.left) {
ball.x = _limit.left;
ball.vX = -ball.vX;
ball.color = randomRGB(); //碰撞後隨機色
}
//限定右邊界
if (ball.x > _limit.right) {
var newBall = Ball.fromBall(ball);
newBall.r = newBall.r / 2;
newBall.vX = -newBall.vX;
newBall.vY = -newBall.vY;
_balls.add(newBall);
ball.r = ball.r / 2;
ball.x = _limit.right;
ball.vX = -ball.vX;
ball.color = randomRGB(); //碰撞後隨機色
}
}
}
//傳入畫布也變成小球集合
body: CustomPaint(
painter: RunBallView(context, _balls, _limit),
),
複製代碼
RunBallView
:把小球都繪製出來就好了
//複製一個小球
Ball.fromBall(Ball ball) {
this.x = ball.x;
this.y = ball.y;
this.color = ball.color;
this.r = ball.r;
this.aX = ball.aX;
this.aY = ball.aY;
this.vX = ball.vX;
this.vY = ball.vY;
}
//------paint方法中-----------
_balls.forEach((ball) {
drawBall(canvas, ball);
});
複製代碼
這樣就完成了,是否是沒有想象中的那麼複雜
這裏就不詳細分析,這裏的Java版已經分析的很細緻了,直接上代碼(基本上是Java的翻譯版)
這個效果新建了一個頁面來作,digit三維數組Dart版附在文尾
/**
* 渲染數字
* @param num 要顯示的數字
* @param canvas 畫布
*/
void renderDigit(int num, Canvas canvas) {
if (num > 10) {
return;
}
for (int i = 0; i < digit[num].length; i++) {
for (int j = 0; j < digit[num][j].length; j++) {
if (digit[num][i][j] == 1) {
canvas.save();
double rX = j * 2 * (_radius + 1) + (_radius + 1); //第(i,j)個點圓心橫座標
double rY = i * 2 * (_radius + 1) + (_radius + 1); //第(i,j)個點圓心縱座標
canvas.translate(rX, rY);
mPaint.color = Colors.blue;
canvas.drawPath(mStarPath, mPaint);
canvas.restore();
}
}
}
}
複製代碼
1994
canvas.save();
renderDigit(1, canvas);
canvas.translate(80, 0);
renderDigit(9, canvas);
canvas.translate(80, 0);
renderDigit(9, canvas);
canvas.translate(80, 0);
renderDigit(4, canvas);
canvas.restore();
複製代碼
DateTime now = new DateTime.now();
var hour = now.hour;
var second = now.second;
var minute = now.minute;
print("hour$hour");//15
print("second$second");//57
print("minute$minute");//27
複製代碼
//時
renderDigit(_now.hour ~/ 10, canvas);
canvas.translate(19 * _radius, 0);
renderDigit(_now.hour % 10, canvas);
//:
canvas.translate(19 * _radius, 0);
renderDigit(10, canvas);
//分
canvas.translate(11 * _radius, 0);
renderDigit(_now.minute ~/ 10, canvas);
canvas.translate(19 * _radius, 0);
renderDigit(_now.minute % 10, canvas);
//:
canvas.translate(18 * _radius, 0);
renderDigit(10, canvas);
//秒
canvas.translate(11 * _radius, 0);
renderDigit(_now.second ~/ 10, canvas);
canvas.translate(19 * _radius, 0);
renderDigit(_now.second % 10, canvas);
複製代碼
方法基本上是Java版改些的,這裏不分析了,能夠看Java版的分析,基本上一致
//在類的外部定義全局的變量
var currTime = new DateTime.now();
var tagOfBall = new DateTime.now().millisecondsSinceEpoch;
var _balls = new List<Ball>();
//構造方法中刷新小球
ClockView(this.context) {
mPaint = new Paint();
mStarPath = nStarPath(5, _radius, _radius / 2);
_now = new DateTime.now();
addBallsChanged();
updateBalls();
}
/**
* 添加倒計時中改動的點---變更加球
*/
void addBallsChanged() {
var now = new DateTime.now();
if (currTime.second != now.second) {
//判斷當前時間是否改變,再將點位放到集合中
if ((currTime.hour ~/ 10) != (now.hour ~/ 10)) {
addBalls((-17 * 5 - 11 * 2) * _radius.toInt(), currTime.hour ~/ 10);
}
if ((currTime.hour % 10) != (now.hour % 10)) {
addBalls((-17 * 4 - 11 * 2) * _radius.toInt(), currTime.hour % 10);
}
if ((currTime.minute ~/ 10) != (now.minute ~/ 10)) {
addBalls((-18 * 3 - 11) * _radius.toInt(), currTime.minute ~/ 10);
}
if ((currTime.minute % 10) != (now.minute % 10)) {
addBalls((-18 * 2 - 11) * _radius.toInt(), currTime.minute % 10);
}
if ((currTime.second ~/ 10) != (now.second ~/ 10)) {
addBalls(-18 * _radius.toInt(), currTime.second ~/ 10);
}
if ((currTime.second % 10) != (now.second % 10)) {
addBalls(0, currTime.second % 10);
currTime = now;
}
}
}
//添加小球
addBalls(int offsetX, int num) {
Random random = new Random();
for (int i = 0; i < digit[num].length; i++) {
for (int j = 0; j < digit[num][i].length; j++) {
if (digit[num][i][j] == 1) {
Ball ball = new Ball();
ball.aY = 0.1;
ball.vX = pow(-1, random.nextInt(1000)) * 6 * random.nextDouble();
ball.vY = 4 * random.nextDouble();
ball.x =
offsetX + j * 2 * (_radius + 1) + (_radius + 1); //第(i,j)個點圓心橫座標
ball.y = i * 2 * (_radius + 1) + (_radius + 1); //第(i,j)個點圓心縱座標
ball.color = randomRGB();
ball.r = _radius;
_balls.add(ball);
}
}
}
}
/**
* 更新全部球的位置---讓球運動
* 而且越界移除
*/
void updateBalls() {
double maxX = 400; //限定x範圍大值
for (Ball ball in _balls) {
ball.x += ball.vX; //x=xo+v*t-----t=1
ball.y += ball.vY;
ball.y += ball.aY; //v=vo+a*t-----t=1
if (ball.y >= 160) {
//超過Y底線,反彈
ball.y = 160;
ball.vY = -ball.vY * 0.99;
}
if (ball.x > maxX) {
//超過X最大值,反彈
ball.x = maxX;
ball.vX = -ball.vX * 0.99;
}
}
//5秒清一次屏
if (new DateTime.now().millisecondsSinceEpoch - tagOfBall > 5000) {
_balls.clear();
tagOfBall = new DateTime.now().millisecondsSinceEpoch;
}
}
複製代碼
好了,今天就這樣,內容有點多,如今Dart的語法越用越熟練了
項目源碼 | 日期 | 備註 |
---|---|---|
V0.1-github | 2018-12-17 | Flutter第2天--Animation動畫+粒子運動 |
筆名 | 微信 | 愛好 | |
---|---|---|---|
張風捷特烈 | 1981462002 | zdl1994328 | 語言 |
個人github | 個人簡書 | 個人掘金 | 我的網站 |
1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大編程愛好者共同交流
3----我的能力有限,若有不正之處歡迎你們批評指證,一定虛心改正
4----看到這裏,我在此感謝你的喜歡與支持
//顏色常量
import 'dart:ui';
const colors = [
Color(0x8833B5E5),
Color(0x880099CC),
Color(0x889933CC),
Color(0x8899CC00),
Color(0x88669900),
Color(0x88FFBB33),
Color(0x88FF8800),
Color(0x88FF4444),
Color(0x88CC0000)
];
const digit = [
[
[0, 0, 1, 1, 1, 0, 0],
[0, 1, 1, 0, 1, 1, 0],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[0, 1, 1, 0, 1, 1, 0],
[0, 0, 1, 1, 1, 0, 0]
], //0
[
[0, 0, 0, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[1, 1, 1, 1, 1, 1, 1]
], //1
[
[0, 1, 1, 1, 1, 1, 0],
[1, 1, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 1, 1, 1, 1, 1]
], //2
[
[1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 1, 1, 0]
], //3
[
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 1, 1, 1, 0],
[0, 0, 1, 1, 1, 1, 0],
[0, 1, 1, 0, 1, 1, 0],
[1, 1, 0, 0, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 1, 1, 1, 1]
], //4
[
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 1, 1, 0]
], //5
[
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 1, 1, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 1, 1, 0],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 1, 1, 0]
], //6
[
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0]
], //7
[
[0, 1, 1, 1, 1, 1, 0],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 1, 1, 0],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 1, 1, 0]
], //8
[
[0, 1, 1, 1, 1, 1, 0],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 1, 1, 0, 0, 0, 0]
], //9
[
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
] //:
];
複製代碼