中秋快樂!!!
前言:放假期間,小T打算回顧一下經典,想用Flutter做一下小游戲,做什么好呢,從打飛機到坦克大戰,最后還是想做一款貪吃蛇,依稀還記得,小時候第一次玩游戲是在父母的小靈通上玩貪吃蛇哈哈,但是光光一個貪吃蛇太單調了,我們就加一個陀螺儀吧~
話不多說,先上效果圖,有圖有真相!!(陀螺儀好難操控)

開發步驟:
非常簡單,就是玩起來有點費手~
原始碼在最后哦,直接運行即可
1.定義蛇和豆子
2.讓蛇動起來
3.使用陀螺儀來控制蛇
4.讓蛇吃掉豆子
5.吃掉豆子隨機生成一個豆子
1.定義蛇和豆子
///蛇的每一塊的大小
const double size = 10;
Offset ball = Offset.zero;//豆子
List<Offset> snakeList = [Offset(50, 0), Offset(60, 0)];//蛇的長度
顯示豆子和蛇:
使用Stack是因為豆子在被蛇吃的時候會重疊
使用Positioned來進行定位
body: Stack(
children: snakeList
.map((snake) => Positioned.fromRect(
rect: Rect.fromCenter(
center: adjust(snake), width: size, height: size),
child: Container(margin:const EdgeInsets.all(1),color: Colors.black)))//加個外邊距使每一塊更清晰
.toList()
..add(Positioned.fromRect(
rect: Rect.fromCenter(
center: adjust(ball), width: size, height: size),
child: Container(color: Colors.orange))),
)
Offset adjust(Offset offset) {
return Offset(offset.dx + size / 2, offset.dy + size / 2); //使每一塊更好的展示出來
}
2.讓蛇動起來
在這里我們要先給蛇來一個狀態定義:
///控制蛇的狀態
enum Direction { Up, Down, Left, Right }
因為蛇要一直動,所以給一個周期函式:
1.定義200毫秒動一次
2.處理更新蛇的長度
3.求余的好處在于優化吃豆子,因為隨機生成豆子時,可能是個不會被整除的,
Direction direction = Direction.Left; //給蛇設定一個狀態,默認向左移動
///周期函式
void didChangeDependencies() {
///兩百毫秒的周期函式
var period = Duration(milliseconds: 200);
///對蛇的長度進行優化
double maxWidth = MediaQuery.of(context).size.width;
double widthPad = maxWidth % size;
maxWidth -= widthPad;
double maxHeight = MediaQuery.of(context).size.height;
double heigthPad = maxHeight % size; //這里除于是為了更好的游戲體驗
maxHeight -= heigthPad;
///周期呼叫
///用于貪吃蛇的自己移動,以及碰撞檢測
Timer.periodic(period, (timer) {
final snakeHead = snakeList[0];
List<Offset> newSnakeList = List.generate(snakeList.length, (index) {
if (index > 0) {
return snakeList[index - 1];
} else {
///移動處理
switch (direction) {
case Direction.Up:
return Offset(snakeHead.dx,
(snakeHead.dy - size + maxHeight) % maxHeight); //求余是保證不會超標
case Direction.Down:
return Offset(
snakeHead.dx, (snakeHead.dy + size + maxHeight) % maxHeight);
case Direction.Left:
return Offset(
(snakeHead.dx - size + maxWidth) % maxWidth, snakeHead.dy);
case Direction.Right:
return Offset(
(snakeHead.dx + size + maxWidth) % maxWidth, snakeHead.dy);
}
}
});
setState(() {
snakeList = newSnakeList; //更新蛇的狀態
});
});
super.didChangeDependencies();
}
3.使用陀螺儀來控制蛇
Flutter使用陀螺儀需要借助一個庫:sensors 或者sensors_plus,兩者沒有太大的區別
這個demo使用:
sensors: any
官方給的例子:
import 'package:sensors/sensors.dart';
accelerometerEvents.listen((AccelerometerEvent event) {
print(event);
});
// [AccelerometerEvent (x: 0.0, y: 9.8, z: 0.0)] 加速度
userAccelerometerEvents.listen((UserAccelerometerEvent event) {
print(event);
});
// [UserAccelerometerEvent (x: 0.0, y: 0.0, z: 0.0)]
gyroscopeEvents.listen((GyroscopeEvent event) {
print(event);
});
// [GyroscopeEvent (x: 0.0, y: 0.0, z: 0.0)] 陀螺儀
我們在initState對陀螺儀進行監聽:
這里有x,y,z的三個引數,也可以自己優化除錯,5.0是當手機傾斜>=45°
@override
void initState() {
super.initState();
accelerometerEvents.listen((AccelerometerEvent event) {
setState(() {
_accelerometerValues = <double>[event.x, event.y, event.z];
if(_accelerometerValues[0] >= 5.0){
direction = Direction.Left;
}else if(_accelerometerValues[1] >= 5.0){
direction = Direction.Down;
}else if(_accelerometerValues[0] <= -5.0){
direction = Direction.Right;
}else if(_accelerometerValues[1] <= -5.0){
direction = Direction.Up;
}
});
});
}
4.讓蛇吃掉豆子
還是在剛剛的周期函式里添加:
當蛇頭碰到豆子時,給蛇加一格
if(newSnakeList[0] == ball){
newSnakeList..add(snakeList[snakeList.length - 1]);
setState(() {
ball = randoowPositon(maxWidth, maxHeight); //隨機生成一個豆子,randoowPositon方法在后面
});
}
5.吃掉豆子隨機生成一個豆子
對豆子的生成也需要優化一下
Offset randoowPositon (double widthRange,double heigthRange){
///隨機生成豆子
var rng = Random();
double widthPad = widthRange % size;
widthRange -= widthPad;
double heigthPad = heigthRange % size; //這里除于是為了更好的游戲體驗
heigthRange -= heigthPad;
return Offset(rng.nextInt(widthRange.toInt()).toDouble(),rng.nextInt(heigthRange.toInt()).toDouble());
}
ok到這里就完成了,需要原始碼的,給該文章點個贊,在我的主頁有交流群,原始碼已經上傳~
這游戲好玩是好玩,就是費手,哈哈,來個大神優化一下吧
添加我為你的好友,領取原始碼以及Flutter學習資料~

加入我們吧,一起學習,一起進步~

我是小T,我們下期再見~
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/301798.html
標籤:其他
