List of commits:
Subject Hash Author Date (UTC)
添加基本界面 d55e6cae5b370bddc1b1786d47c55dbf447029e3 elapse 2020-08-26 15:24:52
修复移动效果 8acf2c120abae11d60f6d7dadf30531fa8617c78 elapse 2020-08-25 06:58:34
可以行棋,但还没检验着法 92583f6da175c40b1763e84f10ee87dfc454d381 elapse 2020-08-25 06:44:08
处理行棋 7d14a218394c3f36c4083cf14ddc8a3d8a108cc4 elapse 2020-08-25 05:55:39
绘制棋子 8c71acbdf851871a49471ecb0fe2eea407ebbbbb elapse 2020-08-25 01:39:21
项目说明 2cb5c8ce027018f0ad31c3c3c9194ed0d6a431be Luck 2020-08-25 01:31:01
Commit d55e6cae5b370bddc1b1786d47c55dbf447029e3 - 添加基本界面
Author: elapse
Author date (UTC): 2020-08-26 15:24
Committer name: elapse
Committer date (UTC): 2020-08-26 15:24
Parent(s): 8acf2c120abae11d60f6d7dadf30531fa8617c78
Signing key:
Tree: db8b6f25d4981495d27f0cb45ba443dd5ee27392
File Lines added Lines deleted
lib/main.dart 34 5
lib/routes/battle-page.dart 199 12
lib/routes/main-menu.dart 77 0
File lib/main.dart changed (mode: 100644) (index d9d9093..2b290d1)
1 1 import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
2 import 'package:flutter/services.dart';
2 3 import 'routes/battle-page.dart'; import 'routes/battle-page.dart';
4 import './routes/main-menu.dart';
5 import 'dart:io';
3 6
4 7 void main() { void main() {
5 8 // runApp(MyApp()); // runApp(MyApp());
6 9 runApp(ChessApp()); runApp(ChessApp());
10
11 /* 设置公支持竖屏 */
12 SystemChrome.setPreferredOrientations(
13 [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown],
14 );
15
16 /* 不显示状态栏(全屏显示) */
17 if (Platform.isAndroid) {
18 //判断是否为Android系统
19 SystemChrome.setSystemUIOverlayStyle(
20 SystemUiOverlayStyle(statusBarColor: Colors.transparent),
21 );
22 }
23
24 SystemChrome.setEnabledSystemUIOverlays([]);
7 25 } }
8 26
9 27 class ChessApp extends StatelessWidget { class ChessApp extends StatelessWidget {
28 static const StatusBarHeight = 28.0;
29
10 30 @override @override
11 31 Widget build(BuildContext context) { Widget build(BuildContext context) {
32 // return MaterialApp(
33 // title: '中国象棋',
34 // theme: ThemeData(
35 // primarySwatch: Colors.lime,
36 // visualDensity: VisualDensity.adaptivePlatformDensity,
37 // ),
38 // debugShowCheckedModeBanner: false, //禁止显示 App 右上角的一个「Debug」字样的条幅
39 // home: BattlePage(),
40 // );
12 41 return MaterialApp( return MaterialApp(
13 title: '中国象棋',
14 42 theme: ThemeData( theme: ThemeData(
15 primarySwatch: Colors.lime,
16 visualDensity: VisualDensity.adaptivePlatformDensity,
43 // primarySwatch: Colors.brown, //主题为棕色
44 primarySwatch: Colors.red,
45 fontFamily: 'ChessTTF',
17 46 ), ),
18 debugShowCheckedModeBanner: false, //禁止显示 App 右上角的一个「Debug」字样的条幅
19 home: BattlePage(),
47 home: MainMenu(),
48 debugShowCheckedModeBanner: false, //不显示"Debug"
20 49 ); );
21 50 } }
22 51 } }
File lib/routes/battle-page.dart changed (mode: 100644) (index 98a595b..eb7cac2)
1 1 import 'package:chinese_chess/cchess/cc-base.dart'; import 'package:chinese_chess/cchess/cc-base.dart';
2 import 'package:chinese_chess/common/color-consts.dart';
2 3 import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
3 4 import '../board/board-widget.dart'; import '../board/board-widget.dart';
4 5 import '../game/battle.dart'; import '../game/battle.dart';
6 import '../main.dart';
5 7
6 8 class BattlePage extends StatefulWidget { class BattlePage extends StatefulWidget {
7 static const BoardMarginV = 10.0, BoardMarginH = 10.0;
9 static double boardMargin = 10.0, screenPaddingH = 10.0;
8 10 @override @override
9 11 _BattlePageState createState() => _BattlePageState(); _BattlePageState createState() => _BattlePageState();
10 12 } }
 
... ... class _BattlePageState extends State<BattlePage> {
16 18 Battle.shared.init(); //使用默认“新局”初始化棋子分布 Battle.shared.init(); //使用默认“新局”初始化棋子分布
17 19 } }
18 20
21 void calcScreenPaddingH() {
22 /* 当屏幕的纵横比小于16/9时,限制棋盘的宽度 */
23 final windowSize = MediaQuery.of(context).size;
24 double height = windowSize.height, width = windowSize.width;
25
26 if (height / width < 16.0 / 9.0) {
27 width = height * 9 / 16;
28 /* 横盘宽度之外的空间,分左右两边,由 screenPaddingH 来持有,布局时添加到 BoardWidget 外围水平边距 */
29 BattlePage.screenPaddingH =
30 (windowSize.width - width) / 2 - BattlePage.boardMargin;
31 }
32 }
33
19 34 /* 由 BattlePage 的 State 类来处理棋盘的点击事件 */ /* 由 BattlePage 的 State 类来处理棋盘的点击事件 */
20 35 onBoardTap(BuildContext context, int pos) { onBoardTap(BuildContext context, int pos) {
21 36 // print('棋盘的index: $pos'); // print('棋盘的index: $pos');
 
... ... class _BattlePageState extends State<BattlePage> {
48 63 setState(() {}); //更新状态,重新绘制棋子 setState(() {}); //更新状态,重新绘制棋子
49 64 } }
50 65
51 @override
52 Widget build(BuildContext context) {
66 /* 标题、活动状态、顶部按钮等 */
67 Widget createPageHeader() {
68 final titleStyle =
69 TextStyle(fontSize: 28, color: ColorConsts.DarkTextPrimary);
70 final subTitleStyle =
71 TextStyle(fontSize: 16, color: ColorConsts.DarkTextSecondary);
72
73 return Container(
74 margin: EdgeInsets.only(top: ChessApp.StatusBarHeight),
75 child: Column(
76 children: [
77 Row(
78 children: [
79 IconButton(
80 icon:
81 Icon(Icons.arrow_back, color: ColorConsts.DarkTextPrimary),
82 onPressed: () => Navigator.of(context).pop(),
83 ),
84 Expanded(child: SizedBox()),
85 Text('单机对战', style: titleStyle),
86 Expanded(child: SizedBox()),
87 IconButton(
88 icon: Icon(Icons.settings, color: ColorConsts.DarkTextPrimary),
89 onPressed: () {},
90 )
91 ],
92 ),
93 Container(
94 height: 4.0,
95 width: 180.0,
96 margin: EdgeInsets.only(bottom: 10),
97 decoration: BoxDecoration(
98 color: ColorConsts.BoardBackground,
99 borderRadius: BorderRadius.circular(2),
100 ),
101 ),
102 Container(
103 padding: EdgeInsets.symmetric(horizontal: 16),
104 child: Text('[游戏状态]', maxLines: 1, style: subTitleStyle),
105 ),
106 ],
107 ),
108 );
109 }
110
111 Widget createBoard() {
53 112 final windowSize = MediaQuery.of(context).size; final windowSize = MediaQuery.of(context).size;
54 final boardHeight = windowSize.width - BattlePage.BoardMarginH * 2;
55 113
56 return Scaffold(
57 appBar: AppBar(
58 title: Text('棋盘'),
114 return Container(
115 margin: EdgeInsets.symmetric(
116 horizontal: BattlePage.screenPaddingH,
117 vertical: BattlePage.boardMargin,
118 ),
119 decoration: BoxDecoration(
120 borderRadius: BorderRadius.circular(5),
121 color: ColorConsts.BoardBackground,
122 ),
123 child: BoardWidget(
124 /* 这里将 screenPaddingH 作为边距,放置在 BoardWidget 左右,这样棋盘将水平居中显示 */
125 width: windowSize.width - BattlePage.screenPaddingH * 2,
126 onBoardTap: onBoardTap,
59 127 ), ),
60 body: Container(
61 margin: const EdgeInsets.symmetric(
62 horizontal: BattlePage.BoardMarginH,
63 vertical: BattlePage.BoardMarginV,
128 );
129 }
130
131 /* 操作菜单栏 */
132 Widget createOperatorBar() {
133 final buttonStyle = TextStyle(color: ColorConsts.Primary, fontSize: 20);
134 return Container(
135 decoration: BoxDecoration(
136 borderRadius: BorderRadius.circular(5),
137 color: ColorConsts.BoardBackground,
138 ),
139 margin: EdgeInsets.symmetric(horizontal: BattlePage.screenPaddingH),
140 padding: EdgeInsets.symmetric(vertical: 2),
141 child: Row(
142 children: [
143 Expanded(child: SizedBox()),
144 FlatButton(onPressed: () {}, child: Text('新对局', style: buttonStyle)),
145 Expanded(child: SizedBox()),
146 FlatButton(onPressed: () {}, child: Text('悔棋', style: buttonStyle)),
147 Expanded(child: SizedBox()),
148 FlatButton(onPressed: () {}, child: Text('分析局面', style: buttonStyle)),
149 Expanded(child: SizedBox()),
150 ],
151 ),
152 );
153 }
154
155 /* 对于底部的空间的弹性处理 */
156 Widget buildFooter() {
157 final size = MediaQuery.of(context).size;
158 final manualText = '<暂无棋谱>';
159
160 if (size.height / size.width > 16 * 9) {
161 /* 长屏幕,显示着法列表 */
162 return buildManualPanel(manualText);
163 } else {
164 /* 短屏幕显示一个按钮,点击它后弹出着法列表 */
165 return buildExpandableManaulPanel(manualText);
166 }
167 }
168
169 /* 短屏幕显示一个按钮,点击它后弹出着法列表 */
170 Widget buildExpandableManaulPanel(String text) {
171 final manualStyle = TextStyle(fontSize: 18, height: 1.5);
172
173 return Expanded(
174 child: IconButton(
175 icon: Icon(Icons.expand_less, color: ColorConsts.DarkTextPrimary),
176 onPressed: () {
177 showDialog(
178 context: context,
179 barrierDismissible: false,
180 builder: (BuildContext context) {
181 return AlertDialog(
182 title: Text('棋谱', style: TextStyle(color: ColorConsts.Primary)),
183 content: SingleChildScrollView(
184 child: Text(text, style: manualStyle)),
185 actions: [
186 FlatButton(
187 child: Text('好的'),
188 onPressed: () => Navigator.of(context).pop(),
189 ),
190 ],
191 );
192 },
193 );
194 },
195 ),
196 );
197 }
198
199 /* 长屏幕显示着法列表 */
200 Widget buildManualPanel(String text) {
201 final manualStyle = TextStyle(
202 fontSize: 18,
203 color: ColorConsts.DarkTextSecondary,
204 height: 1.5,
205 );
206
207 return Expanded(
208 child: Container(
209 margin: EdgeInsets.symmetric(vertical: 16),
210 child: SingleChildScrollView(
211 child: Text(text, style: manualStyle),
64 212 ), ),
65 child: BoardWidget(width: boardHeight, onBoardTap: onBoardTap),
213 ),
214 );
215 }
216
217 // @override
218 // Widget build(BuildContext context) {
219 // final windowSize = MediaQuery.of(context).size;
220 // final boardHeight = windowSize.width - BattlePage.BoardMarginH * 2;
221
222 // return Scaffold(
223 // appBar: AppBar(
224 // title: Text('棋盘'),
225 // ),
226 // body: Container(
227 // margin: const EdgeInsets.symmetric(
228 // horizontal: BattlePage.BoardMarginH,
229 // vertical: BattlePage.BoardMarginV,
230 // ),
231 // child: BoardWidget(width: boardHeight, onBoardTap: onBoardTap),
232 // ),
233 // );
234 // }
235
236 @override
237 Widget build(BuildContext context) {
238 calcScreenPaddingH(); //先计算一次,确定
239
240 final header = createPageHeader();
241 final board = createBoard();
242 final operatorBar = createOperatorBar();
243 final footer = buildFooter();
244 return Scaffold(
245 backgroundColor: ColorConsts.DarkBackground,
246 body: Column(
247 children: [
248 header,
249 board,
250 operatorBar,
251 footer,
252 ],
66 253 ), ),
67 254 ); );
68 255 } }
File lib/routes/main-menu.dart added (mode: 100644) (index 0000000..3912510)
1 import 'package:flutter/material.dart';
2 import '../common/color-consts.dart';
3 import '../main.dart';
4 import 'battle-page.dart';
5
6 /* 游戏主菜单页 */
7 class MainMenu extends StatelessWidget {
8 @override
9 Widget build(BuildContext context) {
10 final nameStyle = TextStyle(
11 fontSize: 64,
12 color: Colors.black,
13 );
14
15 final menuItemStyle = TextStyle(
16 fontSize: 28,
17 color: ColorConsts.Primary,
18 );
19
20 /* 标题及菜单项的布局 */
21 final menuItems = Center(
22 child: Column(
23 children: [
24 Expanded(child: SizedBox(), flex: 4),
25 Text(
26 '中国象棋',
27 style: nameStyle,
28 textAlign: TextAlign.center,
29 ),
30 Expanded(child: SizedBox()),
31 FlatButton(
32 onPressed: () {},
33 child: Text('单机对战', style: menuItemStyle),
34 ),
35 Expanded(child: SizedBox()),
36 FlatButton(
37 onPressed: () {
38 Navigator.of(context).push(
39 MaterialPageRoute(builder: (context) => BattlePage()),
40 );
41 },
42 child: Text('挑战云主机', style: menuItemStyle),
43 ),
44 Expanded(child: SizedBox()),
45 FlatButton(
46 onPressed: () {},
47 child: Text('排行榜', style: menuItemStyle),
48 ),
49 Expanded(child: SizedBox(), flex: 3),
50 Text(
51 '欲速不达,冰冻三尺',
52 style: TextStyle(color: Colors.black54, fontSize: 16),
53 ),
54 Expanded(child: SizedBox()),
55 ],
56 ),
57 );
58
59 return Scaffold(
60 backgroundColor: ColorConsts.LightBackground,
61 body: Stack(
62 children: [
63 menuItems,
64 /* 设置按纽 */
65 Positioned(
66 top: ChessApp.StatusBarHeight,
67 left: 10,
68 child: IconButton(
69 icon: Icon(Icons.settings, color: ColorConsts.Primary),
70 onPressed: () {},
71 ),
72 ),
73 ],
74 ),
75 );
76 }
77 }
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/elapse/chinese_chess

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/elapse/chinese_chess

Clone this repository using git:
git clone git://git.rocketgit.com/user/elapse/chinese_chess

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main