99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

用Trae從0到1開發(fā)Flutter Web版2048游戲

用Trae從0到1開發(fā)Flutter Web版2048游戲 前陣子我一直想找個(gè)項(xiàng)目把 Trae 的完整工作流摸熟。對(duì)比了幾個(gè)方向之后我選了用 Trae 從 0 到 1 開發(fā)一個(gè) Flutter Web 小游戲 2048。這個(gè)項(xiàng)目體量不大但狀態(tài)管理、手勢(shì)交互、Web 構(gòu)建、動(dòng)畫反饋這些東西全都涉及非常適合練手。這篇文章既是我這次開發(fā)的完整復(fù)盤也會(huì)把最終整理好的可運(yùn)行代碼直接貼出來。想跟著做的人只要本地有 Flutter SDK就能把下面的代碼跑起來。如果沒有基礎(chǔ)也不慌我會(huì)先把 2048 本身的數(shù)據(jù)結(jié)構(gòu)講清楚再講怎么用 Trae 把代碼一步步生成出來最后再說 Web 端那些特別容易踩的坑。整個(gè)過程我盡量按真實(shí)開發(fā)的順序來寫而不是事后整理出的“標(biāo)準(zhǔn)答案”。1. 為什么做這個(gè)項(xiàng)目2048 用來練手比想象中劃算1.1 一個(gè)小游戲里藏著的完整前端基本功很多人練 Flutter 都是從待辦清單、計(jì)數(shù)器開始但那樣的項(xiàng)目只覆蓋了 UI 組件和 setState連鍵盤事件和頁面生命周期都碰不到。2048 不一樣它麻雀雖小五臟俱全。玩過 2048 的都知道規(guī)則4×4 的棋盤每次滑動(dòng)所有方塊朝同一個(gè)方向移動(dòng)相同數(shù)字碰撞后會(huì)合并成它們的和每次有效移動(dòng)后棋盤會(huì)隨機(jī)生成一個(gè)新方塊目標(biāo)是把數(shù)字堆到 2048。就這么幾條規(guī)則落到代碼層面你要處理的東西包括二維數(shù)組的狀態(tài)表達(dá)和更新四個(gè)方向移動(dòng)時(shí)“合并”算法的統(tǒng)一抽象隨機(jī)位置生成新方塊游戲結(jié)束和勝利條件判斷鍵盤方向鍵監(jiān)聽觸屏滑動(dòng)的手勢(shì)識(shí)別和閾值控制數(shù)字方塊的顏色映射、尺寸適配重新開始時(shí)的狀態(tài)重置Flutter Web 的構(gòu)建產(chǎn)物和部署。這些知識(shí)點(diǎn)分布在狀態(tài)管理、事件處理、UI 布局、工程構(gòu)建四個(gè)層面。做一遍 2048基本能把 Flutter 從界面到邏輯到打包的路線走通一遍比看十篇教程都管用。1.2 Trae 在項(xiàng)目里扮演的角色這次我特意全程用 Trae 來寫。Trae 這類 AI 編程工具很多人拿來問“這個(gè)報(bào)錯(cuò)怎么解決”“幫我寫個(gè)排序函數(shù)”但真讓它從空目錄開始搭一個(gè)完整的小項(xiàng)目時(shí)很多人反而不知道該怎么指揮。我自己總結(jié)出的用法是把 Trae 當(dāng)成一個(gè)“能馬上執(zhí)行代碼變更的結(jié)對(duì)程序員”而不是搜索引擎。你需要把需求拆成清晰的指令讓它生成初版代碼然后你自己審查、運(yùn)行、帶著報(bào)錯(cuò)回來追問。這個(gè)過程里最重要的是反復(fù)對(duì)話而不是一次性讓它給一個(gè)“完美文件”。2048 的代碼量不算大但邏輯分支很多。直接說“幫我寫一個(gè) 2048 游戲”Trae 大概率會(huì)返回一個(gè)能看的 Demo但未必能兼顧 Web 端的鍵盤事件、手勢(shì)判斷和狀態(tài)重置。所以我在動(dòng)手前先把數(shù)據(jù)建模想清楚了再去寫提示詞。2. 動(dòng)手前的數(shù)據(jù)建模棋盤、移動(dòng)、合并、判定2.1 棋盤用二維數(shù)組還是扁平列表2048 棋盤是 4×4最直覺的存儲(chǔ)方式是ListListint也就是二維數(shù)組。外層四個(gè)元素代表四行內(nèi)層四個(gè)元素代表每行的四個(gè)格子值為 0 表示空格值為 2、4、8 等表示數(shù)字方塊。有人可能會(huì)想既然移動(dòng)和合并只發(fā)生在行或列用一個(gè)長(zhǎng)度為 16 的扁平列表下標(biāo)從 0 到 15行操作和列操作用索引換算豈不是更省內(nèi)存省那幾字節(jié)對(duì)前端項(xiàng)目毫無意義。二維數(shù)組最大的好處是代碼可讀性高。board[1][2]一眼就知道是第 1 行第 2 列的內(nèi)容后續(xù)寫合并算法、隨機(jī)生成新方塊、判斷游戲結(jié)束都更不容易出錯(cuò)。在 AI 輔助編程的場(chǎng)景下可讀性更加重要因?yàn)槟阋汛a貼給 Trae 讓它做二次修改它讀起來也更快。2.2 四個(gè)方向的移動(dòng)怎么復(fù)用同一套邏輯2048 最核心的地方在于移動(dòng)合并。向左滑動(dòng)最簡(jiǎn)單對(duì)每一行從左到右去掉所有 0再把相鄰的相同數(shù)字合并最后補(bǔ) 0。舉個(gè)例子一行數(shù)據(jù)是[0, 2, 2, 4]去掉 0[2, 2, 4]從左開始合并2 和 2 相同合并成 4這一行變成[4, 4]補(bǔ) 0 到長(zhǎng)度 4[4, 4, 0, 0]這個(gè)例子里要注意一個(gè)細(xì)節(jié)一行中每個(gè)方塊在一次移動(dòng)里最多參與一次合并。比如[2, 2, 2, 2]左移之后應(yīng)該是[4, 4, 0, 0]而不是[8, 0, 0, 0]。很多人第一次寫合并算法會(huì)忽略這一點(diǎn)導(dǎo)致分?jǐn)?shù)和方塊數(shù)值都異常。向右移動(dòng)可以轉(zhuǎn)換成“把行反轉(zhuǎn)左移再反轉(zhuǎn)回來”。比如[0, 2, 2, 4]向右移動(dòng)先把行反轉(zhuǎn)成[4, 2, 2, 0]左移之后再反轉(zhuǎn)就得到了正確結(jié)果。向上和向下呢最省事的做法是轉(zhuǎn)置棋盤。把棋盤的行列互換之后“向上”就變成了“向左”。向下同理轉(zhuǎn)置后“向右”。這套抽象的意義在于你只需要寫好一個(gè)_slideAndMerge(Listint row)的純函數(shù)然后通過轉(zhuǎn)置和反轉(zhuǎn)的組合把四個(gè)方向全部映射到它身上。代碼量小正確性也容易驗(yàn)證。2.3 新方塊生成與終局判斷每次有效移動(dòng)后棋盤需要隨機(jī)生成一個(gè)新方塊。生成規(guī)則是先找到所有值為 0 的格子從中隨機(jī)選一個(gè)90% 概率生成 210% 概率生成 4。終局判斷分兩個(gè)方向勝利棋盤中出現(xiàn) 2048失敗棋盤滿格且任意相鄰格子上下左右都沒有相同數(shù)字。失敗判斷很多人寫錯(cuò)只檢查滿格是不夠的。因?yàn)闈M格時(shí)如果還存在可以合并的相鄰數(shù)字玩家仍能通過合并騰出空格游戲就不該結(jié)束。所以必須同時(shí)檢查空位和相鄰相等值。這些邏輯都不依賴 UI可以獨(dú)立成一個(gè)GameBoard類。這個(gè)類只負(fù)責(zé)修改棋盤數(shù)據(jù)不關(guān)心界面怎么渲染后續(xù)測(cè)試和復(fù)用都很方便。3. 提示詞才是關(guān)鍵用 Trae 生成第一版代碼3.1 我用的初始提示詞打開 Trae 新建一個(gè) Flutter 項(xiàng)目之后我在 Chat 模式里給的第一條指令是這樣的你是 Flutter 專家。請(qǐng)為我生成一個(gè)可直接運(yùn)行的 Flutter Web 2048 游戲代碼放在 /lib/main.dart。 要求 1. 只用一個(gè) main.dart 文件不依賴第三方庫 2. 4x4 棋盤使用 StatefulWidget setState 管理狀態(tài) 3. 支持方向鍵和 WASD 控制同時(shí)支持觸屏滑動(dòng)和鼠標(biāo)拖拽 4. 數(shù)字方塊顏色區(qū)分2、4、8、16 等不同數(shù)字用不同背景色 5. 有得分面板游戲結(jié)束和達(dá)到 2048 時(shí)顯示覆蓋層提示 6. 有重新開始按鈕 7. 生成方塊邏輯90% 生成 210% 生成 4 8. 每次移動(dòng)后判斷是否結(jié)束失敗條件包括滿格且無相鄰可合并項(xiàng)。這段提示詞的重點(diǎn)不是“幫我寫個(gè) 2048”而是把規(guī)則、文件路徑、技術(shù)選型、UI 要求全部說清楚。Trae 生成的初版代碼已經(jīng)能跑起來但我又在 Chat 里追加了幾輪修改包括“字體過大的問題”“重新開始時(shí)分?jǐn)?shù)沒有清零”“剛才這段鍵盤監(jiān)聽在 Web 上不生效”它都能針對(duì)性地改。我個(gè)人的感受是提示詞寫得越具體Trae 的產(chǎn)出越接近可用狀態(tài)。尤其是“不依賴第三方庫”和“用 setState”這兩個(gè)約束能避免它自作主張引入 provider 或者 flappy 之類的東西。3.2 Build 模式和 Chat 模式怎么配合Trae 有 Build 模式和 Chat 模式兩種用法。Chat 模式是純對(duì)話會(huì)給建議和代碼片段需要你自己手動(dòng)應(yīng)用。Build 模式會(huì)直接操作文件新建、覆蓋、重構(gòu)都能落地。我的習(xí)慣是剛起步時(shí)用 Chat先看它的方案和邏輯是否合理確認(rèn)沒問題再切到 Build 讓代碼落地。如果一開始就用 Build 模式它可能會(huì)一次性生成你并沒有完全理解的代碼出 bug 后反而不容易排查。到后期改動(dòng)很小的功能比如“把游戲結(jié)束彈窗改成頁面內(nèi)覆蓋層”“調(diào)整一下顏色”我直接切 Build 模式讓它改效率很高。因?yàn)樯舷挛拿鞔_改動(dòng)范圍可控它很少會(huì)碰壞別的地方。3.3 第一版代碼的問題與修正Trae 生成的第一版大體能玩但存在兩個(gè)明顯問題。第一個(gè)問題是分?jǐn)?shù)計(jì)算偏大。原因在于它寫的合并邏輯里一行[2, 2, 2, 2]左移后直接變成了[8, 0, 0, 0]還加了 8 分。這在 2048 規(guī)則里是不允許的一次移動(dòng)最多合并出兩個(gè)新方塊所以正確結(jié)果應(yīng)該是[4, 4, 0, 0]得分 8 不變。嚴(yán)格說[2,2,2,2]得分是 448結(jié)果一樣但它把兩個(gè)方塊合并成了一個(gè) 8棋盤狀態(tài)錯(cuò)了。第二個(gè)問題是鍵盤監(jiān)聽用的是RawKeyboard這在新的 Flutter 版本里已經(jīng)廢棄而且 Web 端經(jīng)常收不到事件必須換成HardwareKeyboard.instance.addHandler或者KeyboardListener。這兩類問題都不難改但很典型。AI 生成代碼拿過來直接跑細(xì)節(jié)上一定會(huì)有瑕疵你必須能看懂邏輯知道它哪里錯(cuò)才能讓它繼續(xù)改。這也是我一直堅(jiān)持“先自己建模再交給 AI”的原因。4. 完整實(shí)現(xiàn)可直接拼成一個(gè) main.dart 的核心代碼4.1 棋盤與游戲狀態(tài)下面是我最終整理出的核心代碼。模型層用了獨(dú)立的GameBoard類這樣界面重建時(shí)不會(huì)把游戲狀態(tài)搞亂。import dart:math; enum Direction { left, right, up, down } class GameBoard { static const int size 4; final Random _random Random(); ListListint grid; int score 0; bool won false; bool gameOver false; GameBoard() { grid List.generate(size, (_) List.filled(size, 0)); _spawnTile(); _spawnTile(); } void restart() { grid List.generate(size, (_) List.filled(size, 0)); score 0; won false; gameOver false; _spawnTile(); _spawnTile(); } bool move(Direction dir) { if (gameOver || won) return false; final before _copyGrid(grid); switch (dir) { case Direction.left: _moveLeft(); break; case Direction.right: _moveRight(); break; case Direction.up: _moveUp(); break; case Direction.down: _moveDown(); break; } if (_sameGrid(before, grid)) return false; _spawnTile(); if (_hasWon()) won true; if (_isGameOver()) gameOver true; return true; } Listint _slideAndMerge(Listint row) { final nums row.where((e) e ! 0).toList(); final merged int[]; for (var i 0; i nums.length; i) { if (i 1 nums.length nums[i] nums[i 1]) { merged.add(nums[i] * 2); score nums[i] * 2; i; } else { merged.add(nums[i]); } } while (merged.length size) { merged.add(0); } return merged; } void _moveLeft() { for (var r 0; r size; r) { grid[r] _slideAndMerge(grid[r]); } } void _moveRight() { for (var r 0; r size; r) { final reversed grid[r].reversed.toList(); grid[r] _slideAndMerge(reversed).reversed.toList(); } } ListListint _transposed() { return List.generate(size, (r) { return List.generate(size, (c) grid[c][r]); }); } void _storeTransposed(ListListint tGrid) { for (var r 0; r size; r) { for (var c 0; c size; c) { grid[c][r] tGrid[r][c]; } } } void _moveUp() { final tGrid _transposed(); for (var r 0; r size; r) { tGrid[r] _slideAndMerge(tGrid[r]); } _storeTransposed(tGrid); } void _moveDown() { final tGrid _transposed(); for (var r 0; r size; r) { final reversed tGrid[r].reversed.toList(); tGrid[r] _slideAndMerge(reversed).reversed.toList(); } _storeTransposed(tGrid); } void _spawnTile() { final empty Listint[]; for (var r 0; r size; r) { for (var c 0; c size; c) { if (grid[r][c] 0) empty.add([r, c]); } } if (empty.isEmpty) return; final pos empty[_random.nextInt(empty.length)]; grid[pos[0]][pos[1]] _random.nextDouble() 0.9 ? 2 : 4; } bool _hasWon() { for (var r 0; r size; r) { for (var c 0; c size; c) { if (grid[r][c] 2048) return true; } } return false; } bool _isGameOver() { for (var r 0; r size; r) { for (var c 0; c size; c) { if (grid[r][c] 0) return false; if (r 1 size grid[r][c] grid[r 1][c]) return false; if (c 1 size grid[r][c] grid[r][c 1]) return false; } } return true; } ListListint _copyGrid(ListListint source) { return List.generate(size, (r) Listint.from(source[r])); } bool _sameGrid(ListListint a, ListListint b) { for (var r 0; r size; r) { for (var c 0; c size; c) { if (a[r][c] ! b[r][c]) return false; } } return true; } }這段代碼要特別解釋幾個(gè)細(xì)節(jié)。_slideAndMerge里的循環(huán)用了i跳過一個(gè)已合并元素這是保證“一次移動(dòng)只能合并一次”的關(guān)鍵。score在合并時(shí)直接累加而不是留到 UI 層算省掉了遍歷計(jì)算分值的環(huán)節(jié)。移動(dòng)方法move里先復(fù)制了棋盤再執(zhí)行方向移動(dòng)。如果移動(dòng)前后一模一樣說明這次滑動(dòng)沒有改變?nèi)魏畏綁K位置就不允許生成新方塊。這一步很關(guān)鍵否則玩家往沒有空位的方向亂滑時(shí)棋盤會(huì)不斷生成新方塊很快把自己卡死。4.2 頁面交互鍵盤、鼠標(biāo)拖拽、觸屏接下來是 UI 層。我用HardwareKeyboard.instance.addHandler監(jiān)聽鍵盤因?yàn)樗灰蕾図撁胬锬硞€(gè)焦點(diǎn)組件在 Flutter Web 上更穩(wěn)。import package:flutter/material.dart; import package:flutter/services.dart; void main() runApp(const Game2048App()); class Game2048App extends StatelessWidget { const Game2048App({super.key}); override Widget build(BuildContext context) { return MaterialApp( title: 2048, debugShowCheckedModeBanner: false, theme: ThemeData( useMaterial3: true, scaffoldBackgroundColor: const Color(0xFFFAF8EF), ), home: const GamePage(), ); } } class GamePage extends StatefulWidget { const GamePage({super.key}); override StateGamePage createState() _GamePageState(); } class _GamePageState extends StateGamePage { final GameBoard _game GameBoard(); Offset? _dragStart; override void initState() { super.initState(); HardwareKeyboard.instance.addHandler(_handleKey); } override void dispose() { HardwareKeyboard.instance.removeHandler(_handleKey); super.dispose(); } bool _handleKey(KeyEvent event) { if (event is! KeyDownEvent) return false; if (event is KeyRepeatEvent) return false; setState(() { switch (event.logicalKey) { case LogicalKeyboardKey.arrowUp: case LogicalKeyboardKey.keyW: _game.move(Direction.up); break; case LogicalKeyboardKey.arrowDown: case LogicalKeyboardKey.keyS: _game.move(Direction.down); break; case LogicalKeyboardKey.arrowLeft: case LogicalKeyboardKey.keyA: _game.move(Direction.left); break; case LogicalKeyboardKey.arrowRight: case LogicalKeyboardKey.keyD: _game.move(Direction.right); break; } }); return false; } void _handlePanStart(DragStartDetails details) { _dragStart details.localPosition; } void _handlePanEnd(DragEndDetails details) { final start _dragStart; if (start null) return; final delta details.localPosition - start; if (delta.distance 20) return; setState(() { if (delta.dx.abs() delta.dy.abs()) { _game.move(delta.dx 0 ? Direction.right : Direction.left); } else { _game.move(delta.dy 0 ? Direction.down : Direction.up); } }); _dragStart null; } override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 480), child: Padding( padding: const EdgeInsets.all(16), child: GestureDetector( onPanStart: _handlePanStart, onPanEnd: _handlePanEnd, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ const Text( 2048, style: TextStyle( fontSize: 40, fontWeight: FontWeight.bold, color: Color(0xFF776E65), ), ), const Spacer(), _ScoreBoard(score: _game.score), const SizedBox(width: 8), FilledButton( onPressed: () setState(_game.restart), child: const Text(重開), ), ], ), const SizedBox(height: 16), AspectRatio( aspectRatio: 1, child: _buildBoard(), ), const SizedBox(height: 12), const Text( 方向鍵 / WASD / 滑動(dòng)棋盤控制, style: TextStyle(color: Colors.black54), ), ], ), ), ), ), ), ), ); }這段 UI 里我把整塊棋盤包在GestureDetector里用onPanStart記錄起點(diǎn)onPanEnd計(jì)算終點(diǎn)偏移再根據(jù) x 和 y 的絕對(duì)值大小判斷方向。這樣一次手勢(shì)只觸發(fā)一次移動(dòng)不會(huì)像onPanUpdate那樣連續(xù)觸發(fā)。HardwareKeyboard的 handler 里我判斷了event is! KeyDownEvent和event is KeyRepeatEvent。這兩行是為了屏蔽長(zhǎng)按鍵盤時(shí)的重復(fù)觸發(fā)避免玩家按住方向鍵不放導(dǎo)致棋盤快速亂動(dòng)。4.3 界面渲染與顏色映射棋盤渲染我用了GridView.builder通過itemCount: 16固定生成 16 個(gè)格子。每個(gè)格子的顏色由數(shù)字決定數(shù)字越大顏色越深文字顏色則從深色過渡到白色。Widget _buildBoard() { return Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: const Color(0xFFBBADA0), borderRadius: BorderRadius.circular(8), ), child: GridView.builder( padding: EdgeInsets.zero, physics: const NeverScrollableScrollPhysics(), itemCount: GameBoard.size * GameBoard.size, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: GameBoard.size, mainAxisSpacing: 8, crossAxisSpacing: 8, ), itemBuilder: (context, index) { final row index ~/ GameBoard.size; final col index % GameBoard.size; final value _game.grid[row][col]; return TweenAnimationBuilderdouble( tween: Tween(begin: 0, end: 1), duration: const Duration(milliseconds: 80), builder: (context, t, child) { return Transform.scale( scale: 0.9 0.1 * t, child: Container( alignment: Alignment.center, decoration: BoxDecoration( color: _cellColor(value), borderRadius: BorderRadius.circular(6), ), child: Text( value 0 ? : $value, style: TextStyle( fontSize: _fontSize(value), fontWeight: FontWeight.bold, color: _textColor(value), ), ), ), ); }, ); }, ), ); } Color _cellColor(int value) { switch (value) { case 0: return const Color(0xFFCDC1B4); case 2: return const Color(0xFFEEE4DA); case 4: return const Color(0xFFEDE0C8); case 8: return const Color(0xFFF2B179); case 16: return const Color(0xFFF59563); case 32: return const Color(0xFFF67C5F); case 64: return const Color(0xFFF65E3B); case 128: return const Color(0xFFEDCF72); case 256: return const Color(0xFFEDCC61); case 512: return const Color(0xFFEDC850); case 1024: return const Color(0xFFEDC53F); case 2048: return const Color(0xFFEDC22E); default: return const Color(0xFF3C3A32); } } Color _textColor(int value) { return (value 2 || value 4) ? const Color(0xFF776E65) : Colors.white; } double _fontSize(int value) { if (value 100) return 28; if (value 1000) return 22; return 16; } }這里我用TweenAnimationBuilder做了一次簡(jiǎn)單的新方塊出現(xiàn)動(dòng)畫。每次setState改變棋盤數(shù)據(jù)后格子的 scale 都會(huì)從 0.9 彈到 1.0視覺上能感到新方塊“冒”出來。這個(gè)動(dòng)畫很輕量不會(huì)影響 Web 性能。完整的代碼還需要補(bǔ)上分?jǐn)?shù)面板和結(jié)束覆蓋層。分?jǐn)?shù)面板我直接用Container加圓角覆蓋層放在Stack里壓在棋盤上方代碼如下class _ScoreBoard extends StatelessWidget { const _ScoreBoard({required this.score}); final int score; override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: const Color(0xFFBBADA0), borderRadius: BorderRadius.circular(6), ), child: Column( children: [ const Text( 分?jǐn)?shù), style: TextStyle(color: Colors.white, fontSize: 12), ), Text( $score, style: const TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold, ), ), ], ), ); } }至于結(jié)束覆蓋層做法是修改build里棋盤那一塊把棋盤包進(jìn)Stack當(dāng)_game.gameOver或_game.won為真時(shí)疊加一個(gè)半透明容器和文字提示。這里就不整段貼重復(fù)代碼了核心思路就是在棋盤上面蓋一層。5. 跑起來之后必須處理的 Web 端特有問題5.1 方向鍵沒反應(yīng)的真正原因我在本地用flutter run -d chrome測(cè)試時(shí)第一分鐘就發(fā)現(xiàn)了問題鼠標(biāo)點(diǎn)擊和按鈕都正常但方向鍵怎么按都沒反應(yīng)。排查詢問的路徑大概是這樣的先確認(rèn)鍵盤事件有沒有進(jìn)入到 Flutter。在_handleKey里加print(event.logicalKey)瀏覽器控制臺(tái)能打出按鍵值說明事件進(jìn)來了。確認(rèn)有沒有被前面的if (event is! KeyDownEvent)攔截。把回調(diào)參數(shù)改成event.runtimeType打印發(fā)現(xiàn)長(zhǎng)按時(shí)會(huì)有KeyRepeatEvent但按一次正常只有KeyDownEvent。繼續(xù)查發(fā)現(xiàn)是我的處理函數(shù)返回了false而HardwareKeyboard.instance.addHandler的規(guī)則是如果某個(gè) handler 返回 true事件就會(huì)被消費(fèi)返回 false事件會(huì)繼續(xù)傳給下一個(gè) handler。我的 handler 雖然執(zhí)行了移動(dòng)邏輯但返回 false 導(dǎo)致 Flutter 框架認(rèn)為“沒人處理這個(gè)事件”在 Web 端某些情況下會(huì)觸發(fā)默認(rèn)行為方向鍵就順帶滾動(dòng)了頁面。不過我這次遇到的問題其實(shí)是焦點(diǎn)。Flutter Web 應(yīng)用在瀏覽器里如果 canvas 沒有取得焦點(diǎn)鍵盤事件根本不會(huì)進(jìn)到 Flutter 的事件系統(tǒng)。解決辦法是在頁面加載后手動(dòng)請(qǐng)求焦點(diǎn)WidgetsBinding.instance.addPostFrameCallback((_) { FocusManager.instance.primaryFocus?.requestFocus(); });這個(gè)處理加在initState里頁面打開后會(huì)自動(dòng)把焦點(diǎn)放到 Flutter 視圖上。如果在 iframe 里嵌入游戲還需要先點(diǎn)擊一下頁面瀏覽器才肯把鍵盤事件交給 iframe。5.2 拖動(dòng)判斷閾值與誤觸Web 端最容易被忽略的是鼠標(biāo)拖動(dòng)和點(diǎn)擊按鈕的沖突。如果不加閾值玩家在棋盤上輕輕一晃鼠標(biāo)就觸發(fā)了一次移動(dòng)體驗(yàn)非常差。我設(shè)置的是 20 像素。具體在_handlePanEnd里如果起點(diǎn)和終點(diǎn)距離小于 20就什么都不做。這個(gè)數(shù)值不是拍腦袋定的而是根據(jù)棋盤在手機(jī)屏幕上約 350 像素寬度算出來的。手指按下去到抬起來稍有抖動(dòng)通常不超過 15 像素20 能避開誤觸如果棋盤更大比如平板上的 700 像素寬20 依然合理因?yàn)榕袛嗟氖墙^對(duì)距離不是比例。有人會(huì)用onPanUpdate的details.delta來判斷方向也就是位移增量。這種方法在每次回調(diào)里增量都很小比如一次滑動(dòng)會(huì)觸發(fā)幾十次回調(diào)每次只有 5、6 像素。如果要判斷最終方向就得自己累加非常麻煩。用onPanStart記錄起點(diǎn)、onPanEnd判斷終點(diǎn)的方案天然就拿到了整個(gè)手勢(shì)的總體位移。5.3 重新開始后棋盤狀態(tài)沒清干凈還有一個(gè)容易翻車的地方是重新開始按鈕。我讓_game.restart()把grid重建為全 0再生成兩個(gè)新方塊score、won、gameOver全部重置。按這個(gè)邏輯重開沒問題但如果你是在原GameBoard對(duì)象上直接修改而不是重建grid比如grid[r][c] 0這種原地賦值要注意把所有格子都清干凈。更隱蔽的是很多人只在 UI 層setState(() _game GameBoard())但鍵盤 handler 和手勢(shì)回調(diào)里持有的是舊_game對(duì)象點(diǎn)擊重開之后棋盤看起來重置了再一滑動(dòng)又操作了舊對(duì)象狀態(tài)就亂掉了。我這次刻意把_game聲明為final重開時(shí)調(diào)用它內(nèi)部的方法重置數(shù)據(jù)而不是換對(duì)象。這是個(gè)小細(xì)節(jié)但能避免一類非常詭異的 bug。5.4 動(dòng)畫閃爍和構(gòu)建體積Web 端還有一個(gè)性能相關(guān)的體驗(yàn)問題Flutter Web 首次加載時(shí)CanvasKit 渲染器體積不小如果不做優(yōu)化瀏覽器會(huì)白屏好幾秒。我在本地flutter build web之后看了下產(chǎn)物main.dart.js就有 2 MB 多加上 CanvasKit 的 wasm 文件首屏加載確實(shí)要等一會(huì)兒。如果只是開發(fā)自娛這個(gè)無所謂但如果要給別人玩建議做兩件事部署到支持 gzip 或 brotli 壓縮的靜態(tài)托管平臺(tái)能顯著減小傳輸體積在構(gòu)建參數(shù)里根據(jù) Flutter 版本選擇合適的渲染器新的版本可以嘗試flutter build web --wasm或--web-renderer canvaskit不同版本參數(shù)有差異先用flutter build web --help看一下當(dāng)前版本支持什么。至于動(dòng)畫閃爍往往是GridView子項(xiàng)被系統(tǒng)重建導(dǎo)致的。給每個(gè)格子加上穩(wěn)定的 key 能緩解比如ValueKey($row-$col)讓 Flutter 知道每個(gè)位置上是同一個(gè)組件而不是隨著數(shù)據(jù)變化銷毀重建。我用TweenAnimationBuilder的寫法天然避開了大部分重建問題如果自己手寫AnimatedContainer一定要留意 key。6. 構(gòu)建部署與后續(xù)擴(kuò)展從一個(gè) Demo 變成能給人玩的游戲6.1 flutter build web 構(gòu)建與部署當(dāng)代碼在flutter run -d chrome下跑通后執(zhí)行flutter build web --release構(gòu)建完成后產(chǎn)物在build/web目錄里。這個(gè)目錄就是一個(gè)純靜態(tài)站點(diǎn)包含index.html、main.dart.js、assets等文件。部署方式不限Nginx、GitHub Pages、對(duì)象存儲(chǔ) CDN 都可以。唯一要注意的是如果部署在子路徑下比如https://example.com/2048/構(gòu)建時(shí)要指定 base hrefflutter build web --release --base-href /2048/否則刷新頁面后資源路徑會(huì) 404。這個(gè)問題我在第一次部署時(shí)就踩過Flutter Web 默認(rèn)按根路徑生成資源引用放到子目錄必須顯式聲明。6.2 想讓 2048 更像樣可以從這幾個(gè)方向擴(kuò)展基礎(chǔ)版跑通之后我給自己列了幾個(gè)擴(kuò)展方向優(yōu)先級(jí)從高到低本地存檔用shared_preferences保存最高分和棋盤狀態(tài)刷新頁面不丟進(jìn)度。撤銷一步在每次移動(dòng)前把棋盤快照存進(jìn)歷史棧做一個(gè)Undo按鈕。棋盤大小可變把GameBoard.size改成可配置參數(shù)支持 3×3、5×5 等變體玩法。動(dòng)畫增強(qiáng)用AnimatedPositioned或自繪布局實(shí)現(xiàn)方塊滑動(dòng)動(dòng)畫而不是只做縮放過渡。排行榜如果部署到公網(wǎng)可以接一個(gè)后端或者云數(shù)據(jù)庫記錄全球玩家的最高分。這些功能里本地存檔和撤銷對(duì)代碼結(jié)構(gòu)的鍛煉價(jià)值最大。加本地存檔時(shí)你要處理序列化和反序列化加撤銷時(shí)你要想清楚撤銷的邊界條件比如已經(jīng) gameOver 之后撤銷是否允許、撤銷后是否要重新生成方塊等。6.3 關(guān)于 Trae 使用的一點(diǎn)點(diǎn)個(gè)人心得最后說回 Trae。這次項(xiàng)目做下來我用 AI 編程工具的心法又更新了一輪。第一AI 生成代碼的正確性要以“我能理解”為前提。如果一段代碼你完全看不懂那它出 bug 時(shí)你也沒法精準(zhǔn)地把它喂回給 AI 修復(fù)。所以我會(huì)先自己把數(shù)據(jù)結(jié)構(gòu)想明白再讓 AI 填充實(shí)現(xiàn)。第二報(bào)錯(cuò)信息是最佳的上下文。運(yùn)行時(shí)報(bào)錯(cuò)、控制臺(tái)輸出、lint 警告直接復(fù)制粘貼到 Trae 對(duì)話框比你自己描述半天的效果都好。它能精準(zhǔn)定位文件路徑和行號(hào)大部分情況一次就改對(duì)。第三不要讓它一口氣寫五百行。一次要一個(gè)模塊跑通再要下一個(gè)模塊。我用 Trae 從 0 到 1 開發(fā)這個(gè) Flutter Web 小游戲 2048 的過程中最順利的節(jié)奏是“給模型邏輯 → 生成核心算法 → 跑起來 → 讓它加 Web 事件 → 調(diào)樣式”。每一步之間都有運(yùn)行驗(yàn)證問題不會(huì)被拖到很后面才集中爆發(fā)?,F(xiàn)在這個(gè) 2048 游戲已經(jīng)部署上線我平時(shí)手機(jī)和電腦都會(huì)打開玩兩把?;仡櫿麄€(gè)過程最有價(jià)值的不是那 4×4 的棋盤而是我把一套“從規(guī)則到代碼再到部署”的流程完整走了一遍。如果你也想練手我建議別直接復(fù)制完整代碼跑完就結(jié)束而是自己從空白項(xiàng)目開始讓 Trae 輔助你把每一步都寫出來遇到問題再回頭對(duì)照這里的代碼排查收獲會(huì)大得多。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
五月丁香六月婷婷国产视频| 婷婷五月天VI| 五月婷婷丁香在线| 亚洲色欲欧美一区二区三区| 婷婷五月av| 久久大香蕉丁香| 91碰视频| xxxx久| 五月色无码| 欧美天天搞| 天天综合色| 丁香五月中文字幕色播| 色噜噜狠狠插综合| 国产乱妇乱子伦| 99碰超| 拳交大逼| 蜜桃五月天| 丁香五月花婷婷开心| 日本三级色| 公的粗大挺进了我的密道| 丁香五月偷拍| 亚洲成人色五月天| 婷婷色色欧美综合网| 亚洲成人一区| 97色啪| 色另类五月天| 依人大香蕉| 狠狠久久婷| 成人免费120分钟啪啪| 国产精品视频免费看| www一区二区三区| 99er免费在线观看| 综合网激情五月天| 婷婷成人综合免费视频| 伊人五月久久| 丁香五月成人在线| 天天天天爽爽天干| 亚洲综合色色色| 麻豆123区| 天天日天天狠狠操| 亚洲精品乱码久久久久99| 亚洲不卡| 久久综合丁香五月| 99热这里只有在线播放| 三十路磁力链接| 色五月激情五月丁香五月婷婷啪啪综合 | 婷婷五月天日日日干干干| 五月天堂色| 一级二级色大片| 亚洲综合欧美色丁香婷婷888月图片 | 色色五月天婷婷丁香| 天天日天天干天天天| 婷婷五月天日本无码| 91男女视频在线观看| www。狠狠干。com| 天天se在线视频| 黄色毛片精品| 婷婷爱爱蜜臀天天操| 久久视频婷婷| 久久这里只有精彩| 5月婷婷六月丁香| 亚洲小说欧美激情| 亚洲精品国产精品乱码视99| 色色色色综合网| 狼友超碰| 777影视理论片大全在线观看| 亚洲午夜AV| 久久久久9| WWW免费视频碰碰碰碰| 婷婷五月天AV在| 亚洲乱啪| 婷婷丁五月| 五月婷婷免费在线| 安息电影在线观看完整版| 狠狠色丁香久久综合婷婷亚洲成人福利| 激情久久丁香| 五月天自拍网| 天天做天天爱天天爽夜夜揉| 五月天成人伊人| 久久深爱激情网| 激情婷婷丁香色五月| 狠狠色丁香久久婷婷综合五月| 亚艹艹| 亚洲色99| 99色色网| 婷婷趴趴| 草操AV在线| 高清无码中文字幕aVDV| 超碰操网| 曰韩五月丁香色婷婷无码| 丁香五月婷婷综合激情啪啪啪| 九九色天堂| 色三级色三级| 五月天久久丁香| 色欧美影院| 欧美又粗又大一区二区在线观看| 五月丁香中文| 777米奇影视第四色| Caoub青青超碰 | 五月色亚洲| 99久久99九九九99九他书对| 成人电影丁香六月天| 成人网址在线观看| 牛牛澡牛牛爽| 久久久人妻人伦| 激情影院免费视频婷婷五月天| 亚洲视频图片婷婷五月| 日本色婷婷| 五月婷婷之综合激情在线| 色99网| 久久婷婷五月天蜜桃| 激情综合网五月丁香| 无码色| 九九精品re免费视频| 嫩草视频在线观看| 婷婷色五月在线视频| 久久金品黃色| 色婷婷色五月丁香| 综合激情在线视频| 丁香五月婷婷免费视频| 在线中文字幕视频| 五月丁香六月婷婷激情视频在线观看免费| 人妻丰满精品一区二区A片| 97丁香视频| 亚洲精品视频在线播放| 中文久久婷婷| 丁香伊人五月色婷婷五十路 | 婷婷六月中文字幕| 亚洲久久激情| 亚洲免费观看高清完整版AV线| 五月婷婷久久爱| 伊人干综合| 激情婷婷激情在线不卡| 伊人狠狠综合| 无码免费人妻A片AAA毛片西瓜| 五月天天堂久久| 五月天堂在线| 激情人妻蜜夜系列区| 婷婷亚洲天堂| 伊人久久五月天| 婷婷五月丁香色色| 狠狠草综合网| 午夜成人av在线| 天天日夜夜B久久| 99超级碰碰| 丁香五月伊人| 丁香婷婷在线| 99情色五月天| 色色 亚洲| 久久AAAA片一区二区| 伊人网欧美在线男人天堂五月丁香| 欧美性色视频| 国产精品操| 五月天日日操夜夜操 | 中国女人做爰A片| 97色干在线观看| 天天狠狠婷婷在线| 婷婷五月成人| 成人婷99最新| 99色在线观看| 日本ww亚洲| 综合激情视频| 欧美婷婷六月丁香综合色连续高潮抽搐| 天天干天天插| 五月婷婷人人人操| 思思热视频| AV无码免费| 第五色婷婷| 狠狠色色| 成人在线综合| 色色丁香五月天| 色一情一乱一乱91Av| 四色99久久| 2014天天爽| 色情五月丁香婷婷网| 国产精品电影网| 婷婷丁香五月天熟女丝袜| 丁香五月综合亚洲| 中文字幕天天干| 婷婷五月天激情在线| 丁香五月之久操视频| 婷婷五月综合在线视频| 九色1区视频在线| 色日本网| 人人操人人操919999| 久久与婷婷| 丁香久久综合| 午夜少妇在线观看视频| 一级操逼内射在线视频| 欧美日韩五月婷婷| 五月丁香婷婷成人网| 日本一级一级一级一级| www.色五月| 深爱激情AV| 欧美色片中文字幕久久久久| 99亚洲视频| 婷婷色婷婷| 亚洲视频五区| 国产伦亲子伦亲子视频观看| 激情婷婷五月社区| 激情综合五月| 日日夜夜九九| 97色片| 中文字幕婷婷五月天| 九九色逼| 国产激情综合五月久久| 婷婷久久久久久久| 免费观看2018www黄色操逼网站| 五月天成人免费视频| 超碰国产在线| 丁香亚洲色综合| 97超碰在线免费观看| 久久久激情| 色色热| 99在线精品在线视频| 庭庭久久内射| 懂色av粉嫩AV蜜臀AV| 26uuu日韩| 超碰免费在线| 黄网免费看| 亚洲综合另类| 婷婷丁香十月| 婷婷天天舔| 色97啪啪| 亚洲欧洲中文日韩久久AV乱码| a久久免费视频| 日韩av在线电影| 五月激情影院| 久久婷婷网站| 99性视频| 99热综合在线观看| 国产日产成人亚洲欧美国产VA| 97 天堂| 99只有精品| 亚洲无码成人网| 男女激情久久| 丁香五月综合| 久热人妻| 天天摸天天舔| 久久草婷婷丁香网站| 久久婷婷内射| 久久蜜臀婷婷| 亚洲妇女熟BBW| 丁香六月婷婷综合| 亚洲精品国产精品乱码不99| 精品国产va久久久久| 综合五月激情| 国产亚洲成AV人片在线观黄桃| 九九性爱网| 天天操天天操综合| Av性爱网| 伊人久久艹| 久热精彩视频98| 激情综合五月婷婷| 99热这里是精品| 激情综合丁香五月| 丁香婷婷色五月合集| 五月婷婷免费在线| 99久视频| 99热大香蕉| 久热精彩视频98| 激情六月天| 综合99视频| 天天爽免费视频| 婷婷丁香五月久久| 这里只有精品视频在线观看免费| 天天色天天搡| 九九人人操| www.色九月| 任我肏视频精品| 精品成人无码A片观看香草视频| 久色网址| 亚洲综合久| 婷婷五月天视频亚洲| 婷婷丁香激情五月| 五月婷婷之六月丁香| 97色婷婷| 亚洲一个色| 久久婷婷91| 人人妻人人澡人人爽| 九月激情婷婷丁香| 999热在线观看视频| 狠狠狠狠狠狠| 日本人人超碰| 久9精品视频在线| 思思久久99热只有频精品66| 99热在线观看| 亚洲中文AV| 国产1区2区3区| 9九色首页| 婷婷丁香五另类网站| 免费视频WWW在线观看网站| 久久视频婷婷| 五月天综合图片| 粉嫩av蜜桃av蜜臀av| 欧美日韩成人在线| www.伊人天堂偷偷婷婷| 婷婷丁香五| 日韩五月婷婷| 婷婷伊人激情婷婷| 思思热久久久久思思热| 激情综合色播| 99激情在线| 久久婷婷热| 日本久久精品| 亚洲精品一区中文字幕乱码| 色婷婷激情Av久久久| 亚洲综合色婷婷文学| 天天日中文| 综合色图婷婷| 国产综合久久久777777| 亚洲旡码| 蜜乳.comcom| 婷婷六月爽| 天天狠狠色噜噜| 秋霞影音91人妻久久| 武汉美女啪啪视频免费一级片| 99色在线观看| 久久综合播放| 婷婷亚洲综合| 青青草轻轻操| 这里只有精品视频在线观看免费| 极品五月天| 天天草比天天爽| 成人网址在线观看| 图片区 小说区 区 亚洲五月| 亚洲乱码日产精品BD| 日噜噜色| WWW,五月天| 丁香六月 人妻| 九九色热视频| 99ri视频| 婷婷五月激情综合网| jiujiujiuwuyuetian| 天天激情5月天亚洲| 五月婷婷激情色情网| 亭亭五月色男人| 激情五月丁香激情综合网| 91丁香五月| 国产1区2区3区在线观| 五月色婷婷综合丁香精品无遮挡| 久久婷婷五月免费视频| 天天爱天天操| 97伊人综合婷婷| av中文在线| 丁香五月婷婷天激情| 99热只有| 久久一级AV| 日韩一区二区A片免费观看| 色播五月婷婷| 欧美日韩中国| 综合99在线| 丁香六月色婷婷| 久久538| 国产九月婷婷| 精a品a视a频| 丁香五月精品| 99无码视频| 任你搞在线观看视频| 99热这里只有99| 婷婷丁香五月综合网上 | 国产肥白大熟妇BBBB视频| 九九久久五月天综合伊人| 婷婷六月网| 超碰在线中文字幕| 高清av在线国产| 五月婷婷啪啪| 久99久精品视频| WWW嗯嗯啊啊啊啊| www.黄色片-久久成人国产精品在线播放-999AV| 99热思思在线观看| 婷婷激情综合| 超碰97免费在线| 任你草| 亚洲男女激情| 亚洲一区国产传媒| 综合久久五月天| 裸体做A爰片毛片A片免费| 久9无码视频| 五月丁香狠狠| 九九99久久精品| 色啪影院| 久久99操| 婷婷五月天久久综合88| 国产亚洲精久久久久| 亚洲日韩一页精品发布| 色八月婷婷| 超碰人人操在线| 性生活久久朋友人妻| 丁香五月婷婷啪啪| 国产欧美日韩性爱| 九九色影视| 玖玖综合玖玖| 色女伊人| 97碰碰人人视频| 这里只有免费的精品| 996er热| 婷婷午夜丁香| 国产精品久久..4399| 丁香五月网络网络| 伊人干综合| 色五月五月天色婷婷色五月| 碰人人操| 五月激情在线| 精品99视频| 99热这里只有精品2| 伊人丁香五月天丁香在线婷| 五月天久久成人| 拍真实国产伦偷精品| 精品一区二区三区四区五区六区| 丁香六月啪啪| 色播五月婷婷| 亚洲俩性性爱图片久久第六页 | 久久九九激情五月天 | 国产毛片精品一区二区色欲黄A片| 久鲁鲁色网 | 97自拍99| 另类图片五月天婷婷| 67194国产| 就去涩涩丁香五月天| 热思思九九| 99热这里只有精品一| 成人无码精品1区2区3区免费看| 99er在线观看| 激情又色又爽又黄的A片 | 偷偷与邻居做爰完整视频| 狠狠操天天操| 国产性爱在线| 色婷亚洲五月丁香| 婷婷五月情| 色色综合网站| 无码成人AAAAA毛片AI换脸| 五月色 亚洲| 91 影音先锋| 成人九九视频| 色五月激情综合| www.日韩国产| 久久亚洲精品成人无码网站导航| 色九九综合色| 女人被男人吃奶到高潮| 激情四射五月天偷偷看婷婷| 精品人妻一区二区三区在| 免费播放99性爱视频| 久久全色| 26uuu成人网| WWW.桔色成人.COM入口| 日本在线观看91| 国产精品色婷婷99久久精品| 婷婷色五月天第7色| 久草婷婷在线| 国产.亚洲.欧洲视频在线| 337p大胆噜噜噜噜噜91Av| 丁香五月婷婷六月婷| 在线观看的av| 日韩精品超碰在线观看| 99热这里是精品| www.狠狠干| 九九无毛| 国产成人亚洲综合A∨婷婷| 亚洲激情高潮| 色婷婷激情五月天| www.夜夜操| 婷婷色欧美激情| 91久久精品无码一区二区三区| 狠狠干狠狠干| 精品久久久人妻| 色婷婷狠狠18禁| 亚洲日韩成人三级av| 狠狠干,狠狠操| 婷婷五月小说色综合| 久久这有这里精品| 丁香色五月天| 亚洲无码AV片| 这里只有精品视频在线| AA丁香综合激情| www.婷婷网| av五月丁香| 欧美日综合| 五月丁香中文字幕| 天天摸天天舔天天爽| 色五月婷婷伊人| 国产精品美女久久久久AV超清| 久久机热/这里只有精品| 婷激情五月天视频导航| 99亚洲视频| av高清无码| 婷婷五月天亚洲综合网| 婷婷丁香91综合| VA色婷婷| 国产欧洲欧洲精品久久| 婷婷色色播五月天| 丁香五月激情宗合网| 色婷婷香蕉丁丁网| 成人.在线日韩| 丁香五月欧美成人| 天天操天天干天天日| 插插干干干色| 激情五月婷黄版| 婷婷丁香色性爱| 激情五月丁香五月色| 激情五月天综合| 五月婷婷色五月| 五月天激情中文字幕| 超碰精品在线| 日本天堂爱爱| 激情五月婷黄版| 日韩人妻在线播放| av大片在线| 色吧五月| 九九色热| 性爱视频99| 91热网址| 久久综合影院 | 涩涩涩,com| 91AV婷婷| 色女人久久| 97ai婷婷| 人人干人人操外国| 热99一二三| 91re色综合视频| 天堂无码人妻精品AV一区| 五月婷婷丁香在线| 五月婷婷开心网| 亭亭色色五月天| 激情五月天啪啪| 狠狠爱五月婷婷| 免费观看2018www黄色操逼网站| 久久九久久| 婷婷伊人久久无码色五月| 免费视频WWW在线观看网站| 久久久久人妻网址| 激情av| 久久婷婷色| 99视频自拍| 国产精品涩涩涩视频网站| 五月婷婷综合网| 婷婷五月综合激情| 国产国产乱老熟女视频网站97| 亚洲精品无码一区二区| 亚洲黄色网址| 91啦丨九色丨刺激中文| 色婷婷五月综合色婷婷| 五月婷婷成人| 99热青青草| a网站免费观看| 久久只有精| 深爱五月激情网| 成人婷婷桔色| 激情久久综合网| 五月天激情无码| www婷婷| 久久激情五月婷婷| 久久综合五月天| 亚洲激情在线| 国产精品-第3页-91JQ就要激情网91JQ5.JQJQ926.XYZ | 大香蕉九九| 亚洲V国产V欧美V久久久久久| 欧美情色一区| 91亚洲免费片| 欧美日韩99| 丁香综合伊人| 99热成人在线观看| 久青操| 色偷偷五月天| 操操综合网婷婷| 久久综合五月天| 92久久精品一区二区| 丰满少妇乱A片无码| 99视频免费播放| 狠狠色丁香婷婷五月| 97人人操| 婷婷五月天色综合翘| 久8色色| 五月性色| 天天做天天干天天综合网| 91人久| 色噜噜狠狠色综合网| 五月天色色网站| 九九热在线精品视频| 六月五月天婷婷涩播在线| 日本在线wwww| 丁香五月激情综合| 五月深爱激情网| 日本激情91| 五月天婷婷影院影院| 五月丁香激情在线| 成人av播放| 久久人妻精品| 激情久久丁香| 九九综合久久丁香婷婷,开心激情综合网| 精品怡红九九九| 九月综合| 五月丁香六月激情网站| 天天久久狠狠色综合| 先锋资源 996| 狠狠干狠狠色| 激情五月瑟瑟| 这里只有在线精品| 婷婷射综合| 1024亚洲无码| 91久久久久久| 99热精品中文字幕| 国产暴力强伦轩1区二区小说| 综合网网欲色| 五月丁香在线偷拍视频| 99久久婷婷| 97在线日韩| 亚洲五月丁香综合网| 性爱视频99| 激情噜噜噜| 丁香婷婷社区| 1234操逼网| 天天色综合色| AV电影在线播放| 婷婷五月天激情四射| 99精品在这里| 色情五月天首页| 伊人久久大香蕉网| 综合在线观看99| 91五月天| 激情深爱综合网| www.激情在线| 色色色婷婷五月| 超碰69天堂| 亚洲天堂99| 丁香五月欧美色综合| 99久久思思| 日韩成人电影AV| 人人操大| chaopengdaxiangjiao| 色五月丁香网| 一区二区乱码视频| 天天操天天操天天操天天操天天操天天操| 人妻性爱| 超碰在线人妻| 九九人人自拍| 午夜色丁香| 婷婷伊人久久无码色五月| 久久九九免费视频| 天堂色婷婷| 激情六月综合| 中文国产五月天| 天天摸天天舔天天爽| 久久女人天堂| 色情五月婷| jiuse91在线| 六月婷综合| 202丰满熟女妇大| www.超碰| 亚洲综合无码| 9有码中文| 99热久| 99re热免费观看视频精品| 日本在线免费中文com.| 99热99ai| 噜噜噜噜噜在线| 青青草tp| 色五月婷婷在线| 亚洲AV无码一区二| 久久婷婷色综合老司机| 日韩久久日| 久久婷婷五月综合色丁香| 综合久久综合综合| 婷婷五月丁香四射| 九色成人AV在线| 性欧美大战久久久久久久83| 国产精品久久久久久久久久| 国产精品天天狠天天看| 欧美槡BBBB槡BBB少妇| 五月丁香啪啪| 97精品人人A片免费看| 色婷婷久久| av大香蕉| 亚洲最大成人综合网720P| 精品一二三区久久AAA片| 国产乱妇无乱码大黄AA片| 任你草| 少妇熟女视频一区二区三区| 亚洲精品又粗又大又爽A片 | 69超碰在线| 超碰成人黄色网| 丁香久久在线| 国产AV网页| 色站9/| 亚洲AV无码成人精品区电影网| www.99热这里精品| 亚洲一区国产传媒| 久热无码| 久久黄色免费视频| 久热视频这里只有精品68| 夜夜骑福利资源| 婷婷五月天在线观看免费| 色色色9| 色综合久久久久| 婷婷五月天黄色| 五月丁香六月色婷婷综合五月天 | 91无码视频| 成人看片网站| 五月婷婷影院| 影音先锋一区二区资源站| 亚洲在线播放| 久久99久久99精品免观看粉| 婷婷激情五月吧| 中国AV性爱观看| 五月婷婷啪啪啪啪| 伊人婷婷大香蕉| 开心五月深爱五月| 综合欧美五月婷婷| 激情久久丁香| 色热久资源| 免费观看的AV| 欧美成人日韩| 五月天社区| 任你弄在线视频免费| 久久亚洲天堂| 六月丁香婷婷综合色播| 五区毛片七区毛片| 五月综合丁香婷婷| h在线看免费版在线看| 日日操夜夜操不卡| 99色热视频| 色天天久婷婷| 日本丁香五月| 人妻久久久| 97午夜一区二区| 五月综合色| 九九9久九9国产视频| 97色婷婷| 五月婷婷婷| 91在线就要啪| 操日视频| 婷婷六月激情啪啪| www.9797国产| 亚洲乱码日产精品BD| 丁香五月婷婷婷桃花影院| 色五月天影视| 五月婷天天搞视频| www.五月天婷婷| 日韩中出视频| 伊人婷婷青青cao| 亚洲小视频| 婷婷激情五月| 五月激情久久| 久久一热免费视频| 五月综合视频| 黄桃AV无码免费一区二区三区| 色欧美影院| 麻豆123区| 中文字幕在线日亚洲9| 色婷另类| 性天天中文网| 亚洲av骚货| AV五月丁香| 色99日韩| 亚洲人操亚洲人| 色色五月丁香| 色欲操| 丁香五月成人网| 欧美丰满熟妇BBB久久久| 婷婷伊人75| 2025天天爽天天摸| 色5月婷婷| 丁香花五月天社区| 五月婷婷丁香五月亚洲色| 日日噜人人人做人| 丁香婷婷视频在线| 中文字幕1区2区。| 欧美日韩一a.无| 99激情视频| 欧美综合激情| 26uuu色噜噜精品一区| 99亚洲精品| 99热午夜精品| 99在线观看视频精品| 九九亚洲综合| 久久丁香九| WWW激情五月天| 五月婷婷综合在线| 国产 亚洲 在线| 人人爽天天爽| 亚洲成人日韩无码精品| 五月丁香啪啪拍| 老司机伊人| 成人视频在线免费播放| 丁香五月激情啪啪| 熟女色色一区二区| 国内婷婷丁香社区在线播放| 99热超碰在线| 久久婷婷网站| 9热在线观看| 亚洲激情Av| 婷婷五月综合激情小说| 国产精品一区在线观看你懂的| 色久九| 2017狠狠干| 欧美三级级99久久| 天天日天天爱天天噪| 人妻丰满精品一区二区A片| 欧美欧盟性爱网| 色情五月综合婷婷| 六月久久婷婷| 丁香五月综合| 亚洲黄3级片网站欧美| 亚洲欧美999| 一区二区无码视频| 国色天香伊人狠狠色| 9国产在线视频| 色综合xx| 大陆极品少妇内射AAAAAA| 成人精品免费在线观看| 五月婷在线色视频| 久久99婷婷| 91啦丨九色丨刺激中文| 九九机热| OYIWbGcPu8H| 天堂草在线观| 五月婷九月| 九九精品视频在线观看| 欧美日本不卡黄色片| 特级片神马电影| 五月天丁香婷婷视频网址 | 久久久av久av久片一区二区| 伊人国产婷婷五月天| 亚洲精品一区中文字幕乱码| 亚洲五月天狠狠| 九九色网专区| 79色色色色| 激情五月天婷婷色色色色色色色色色色色 | 中文av网| 五月天丁香综合久久国产| 精品久久9| 久久婷婷五月天懂色| 开心五月网| 人人操Av| 亚洲午夜在线视频| 狠狠插日日干撸| 色站9/| 性生活视频98791| 99热国产精品| 亚洲天堂热| 五月天色官网| 六月婷欧美丁香综合| 成人免费va| 伊人色综合久久久| www.91色| 久久久久久久久久久久久久人妻视频| 久久精品国产一区二区三区四区| 综合色综合| 亚洲第一影院高清无码网站| 成人电影在线免费试看| 天天狠狠婷婷在线| 久久综合久色欧美综合狠狠 | 亚洲综合成人网| 亚洲久久婷婷丁香五月天| 9久热在线视频| 日本婷婷在线| 爱之国产色情综合| 果冻传媒A片一二三区| 岛国av网站| 国产激情综合五月久久| 精品一二三区久久AAA片| 丁香五月欧美激情| 日本在线视频播放91| 激情九月婷婷| 五月婷导航| 激情六月天婷婷| 婷婷综合五月| 激情五月天www| 碰97久久| EEUSS鲁片一区二区三区| 婷婷九色| 五月丁香六月婷婷久久| 国产一级婬片毛片| 99综合熟女| 五月婷婷啪啪| 国产午夜一区二区三区| 色综合色色| 激情五月婷婷综合秋霞| 九月激情综合| 五月天色婷婷小说| 久综合色| www综合久久| 99视频在线精品| 五月天婷a| 91狠狠色色丁香婷婷综合久久| 99性爱| 国产va视频| 97在线精品视频| 超碰在线观看9| 日本婷婷丁香五月| 久久玖玖综合| 被男人添B超爽视频| 五月天婷婷社区| 夜夜骑操AV| 色涩影院六月丁香| 婷婷开心深爱五月天| 国产午夜一区二区三区| 久久香蕉网| 狠狠色中色| 久久久久er热| 天天激情| 色五月婷婷丁香国产在线| 91天堂网综合| 日韩中文字幕| 超碰操网| 亚洲视频图片婷婷五月| 第四色五月激情网| 久久综合伊人77777蜜臀| 亚洲国产精品VA在线看黑人| 欧美大香蕉视频| 五月丁香欧美| 婷婷五月在线免费| 久久99视频| 99热这里只有精品官网| 激情综合婷婷五月| 色九九综合热99| 五月婷婷综合激情小说| 色色色免费视频| 中文AV网| 五月丁香六月停停| 婷婷五月天激情网址| 色色丁香五月| 激情综合五月丁香六月婷婷| 99久久婷婷国产综合| 97干综合网| 欧美精品熟女一区二区| 色婷婷丁香五月天在线视频| 九色自拍| 在线超碰91| 国产97在线日韩亚洲女人被黑人巨大| 99热99色| 91九色精品熟女内射| 日狠狠| 午夜激情五月| 综合久久丁香婷婷,五月婷婷六月丁香,开心激情综合网,六月丁香在线观看,婷婷丁 | 婷婷深爱五月亚洲综合| 婷婷性爱影院| 色狠狠婷婷| 国产在线黄色| 天天干夜晚夜操| 欧美激情五月| 五月社区婷婷激情| 狠狠艹狠狠艹| 五月天大香蕉| 伊人网碰碰| 狠狠综合色网| 日韩三级视频一区二区| 日韩专区五月天婷婷丁香| 国产精品99久久久久久久女警| 殴美日比视频| 97色女人在线| 色五月婷婷老师| 六月丁香激情网| 人人爽亚洲| 99久久婷婷五月天| 激情五月天无码| 99热99热在线观看| 婷婷五月在线综合| 欧美久热| 99色在线视频| 婷色五月| 色亚洲无码| 九九成人精品免费视频| 亚洲黄色影视| 色色吧综合| www激情| 亚洲AV成人精品日韩在线播放| 五月婷婷人人人操| 亚洲第一成人无码A片| 久久丁香五月| 婷婷色婷婷| 九九热在线观看视频| 人人爽天天爽| 五月婷婷五月天| 色色婷婷丁香| 丁香六月婷婷| 内射人妻视频国内| 熟妇人妻中文字幕无码老熟妇| 大地资源色婷婷视频在线| 精国产品一区二区三区A片| 色狠狠色噜噜AV天堂五区| 99国产精品白浆在线观看免费| 白人荫道BBWBBB大荫道| 亚洲精品又粗又大又爽A片 | 婷色天堂| 日韩人妻在线播放| 激情五月天第四色| 超碰精品国产首页| 丁香狠狠色婷婷| 五月天激情图片| 99热九九这里只有精品| 热热久久精品视频| 激情狠狠丁香月| 亚洲sesesese| 免费成片在线观看| 六月大香蕉| 大香蕉网站,大香蕉综合| 丁香五月自拍| 深爱五月综合网| 99aese| 激情婷婷五月天日本系列 | 男人的天堂97| 五月丁香久久网| 欧美va亚洲va| 久久精品永久免费| 综合一本道| 国产免费一区二区三区三州老师F1F1.CC | 婷婷五月天成人导航| 天天做天天双| 五月丁香六月婷婷视频| 激情第四色| 五月天亭亭俺也| 人与禽A片啪啪| 97色碰碰公开视频| 久Se视频在线观看| 婷婷五月在线综合| 激情五月婷婷在线| 婷婷五月天亚洲综合| 婷婷丁香五月亚洲17cao| 香蕉人妻AV久久久久天天| 狠狠色狠狠色综合日日91| 婷婷综合97| 九九热再线九九视频免费在线观看 | 九九九九综合| 精品一二三区久久AAA片| 国产九月婷婷| 影音先锋一区二区三区| 五月婷婷综合网在线播放| 天天爽综合网| 亚洲AV成人片无码网站| 人妻内射一区二区在线视频| 天天做天天爱天天爽综合网| 99精品在| 噜噜在线| 玖玖在线视频| 日韩操啪| 亚洲婷婷五月天在线激情综合网| 日本在线噜噜| 任你搞网站| 国产成人片| 啪精品| 色色成人網| 五月天婷婷无码| 婷婷伊人网| 97sese婷婷| 久久久精品99亚洲综合| 色五月婷婷色五月| 五月丁香六月婷婷久久| 中文字幕成人版| 久久色情| 色情综合网| 丁香五月电影| 丰滿爆乳一区二区三区| 亚洲精品国产成人AV在线| 六月丁香激情综合| 久久久97| 九九中文字幕九| 色五月婷婷操逼| 亚洲一区先锋影音| 超碰在线9| 超级碰碰97在线| 99热播放| 狠狠色噜噜| 99热这里是精品| 色欧美日| 深爱激情小说五月婷婷| 久久婷五月综合| 天天爱天天操| WWW.国产| 99男人的天堂| 五月婷婷花| 色婷婷五月天偷拍| 大香蕉丁香| 五月婷婷 六月丁香| 婷婷九月激情| 久久九九一區| 综合狠狠干| 大香蕉综合在线| 操逼巨乳91| 大香蕉五月婷婷丁香| 欧美极品999| www.色婷婷| 97色射| 日日日日做夜夜夜夜无码| 精品女人九九九| 五月丁香激情综合网官网| 亚洲一色色色色色色色色| 久久久久激情| 色站9/| 婷婷色五月情| 婷婷五月花| 九九亚洲视频| 97超碰在线免费观看| www。五月,com| 亚洲色五月天是什么| 成人片在线播放| 欧美日韩国产一区二区| 天天摸人人摸| 欧美槡BBBB槡BBB少妇| 天天插天天狠| 大香蕉婷婷丁香天堂AV| 97超级操操| 91人人爽久久涩噜噜噜| 4438亚洲欧美| 翔田千里aV中文字幕| 直接看的av| 亚洲网视屏| 五月婷婷偷拍| 97五月综合网| 很很干夜夜干| 丁香操逼| 天天爽夜夜爽| 屁股翘好撅高迎合跪趴| 亚洲色色图片| AAA久久| 99re热精品视频国| 五月丁香成人网| 六月99天天婷婷激情综合| 色在线99| 国产婷婷综合| 99激情视频| 亚洲免费在线观看岛国| 久久婷婷六月综合| 国产乱轮一区二区三区| 人人噜天天上| AV操逼网| 欧美三级黄色片久久| 激情五月天综合网| 91婷婷五月丁香碰| 天天干电影| 久久影视婷婷五月| 五月天综合视频| 久热伊人在91| 青青草成人网| 色噜久| 5五月综合网亚洲| 日韩一级网站| 97超碰在线免费观看| 丁香五月综合激情性爱| 91凹凸在线| 久久精品63| 91精品久久久久久| 九九精品在线视频观看| 丁香五月婷婷六月| 99婷婷五月天| 91久久久久久| 亚洲九九免费| 国产精品久久久久久久久久| 欧美黑人巨大猛烈cuckold| 97超碰免费超级在线观看| 丁香色情五月综合网站| 玖玖九九9999在线观看视频精品| 亚洲成人婷婷| 九色无码| 99久久久久| 丁香五月综合激情久久潮喷| 午夜天堂一区人妻| 丁香五月天啪啪激情综合网| 中文字幕综合色| 丁香婷婷激情六月五月开心| 日本一级特黄大片AAAAA级| 九九碰九九爱97| av在线超清中文| 国产91资源在线| www.成人婷婷综合| 99热色婷婷| 久热99| 夜夜天天久久婷婷| 超碰免费观看| 婷婷中文字幕网| 超碰人人色| 四虎国产精品永久在线国在线| 亚洲综合婷婷六月丁香五月| 婷婷色偷拍| 色噜噜狠狠色综合日日| 99re久热只有精品6在线直播| 99热网精品| 亚洲热视频在线| 亚洲综合视频在线| 欧美成人精品三区综合A片| 亚洲综合色五月| 操久久精| 99热色精品| 天天檫天天爽| 日本色色网站| 日日日日日| 婷婷五月综合视频| 任你擦免费视频| 亚洲五月综合色播| 久久182| 丁香五月激情啪啪| 新激情五月开心五月婷婷五月丁香五月| 五月丁香六月婷婷成人电影| 日韩乱轮AV| 久久婷婷亚洲| 天天婷婷综合| 九九精品丁香花| 久久新地址| 颜射 精品性爱av| 99久在线视频| 五月天丁香网| 久久人人人人妻| 99热费观看| 色婷婷丁香五月| 五月丁香综合激情网| 久久婷婷五月综合97色一本| 日韩啪啪视品| 婷婷天堂综合| 99精品在线下载| 久久婷婷成人| 大香蕉色婷婷伊人在线| 中文字幕人妻在线| 激情五月亚洲综合网| 国产三级片91| 91 影音先锋| www.99久| AV79| 91中文在线| 爆乳熟女-区二区三区| 色色a| 五月性色| 色 丁香婷婷| 大香蕉五月天婷婷丁香91| 成人无码免费一区二区中文| 五月丁香婷婷综合久久| 五月丁香六月停停| 91欧美日韩综合| 国产av第一专区| 亚洲男女激情| 26UUU精品一区二区| 五月激情综合婷婷| 99热综合在线| 天堂在线伊久| 亚洲综合色网| 天天做天天爱天天爽| 操逼123网| 亚洲精品亚洲人成人网| 五月丁香综合久久夜夜| 婷婷五月天av| 狠狠久久婷五月| 五月婷六月婷婷| 亚洲视频在线观看99| 手机在线日韩视频中文字幕| 碰超亚洲| www99热| 久久综合丁香| 99re鈥哸鈥唙| 婷婷激情鹿城五月天| 亚洲色综合| 五月激情综合性爱| 色色欧美色色色| 五月色婷婷综合| 99人妻碰碰碰久久久久视| 情欲综合网| 国产免费AV网站| 免费观看2018www黄色操逼网站| 国产全是老熟女太爽了| 色婷丁香| 丁香五月人妻| 丁香五月婷婷综合网| 久久久久亚洲A∨成人乱码电影| 91丨九色丨白浆秘| 久久丁香社| 丁香五月激情五月| 男人操女人高潮91视频| 久99热|