Skip to content

Commit 6b45d0e

Browse files
committed
complete
1 parent bf5acc8 commit 6b45d0e

File tree

12 files changed

+769
-112
lines changed

12 files changed

+769
-112
lines changed

assets/music.mp3

53.1 KB
Binary file not shown.

lib/gamer/block.dart

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import 'gamer.dart';
2+
import 'dart:math' as math;
3+
4+
const BLOCK_SHAPES = {
5+
BlockType.I: [
6+
[1, 1, 1, 1]
7+
],
8+
BlockType.L: [
9+
[0, 0, 1],
10+
[1, 1, 1],
11+
],
12+
BlockType.J: [
13+
[1, 0, 0],
14+
[1, 1, 1],
15+
],
16+
BlockType.Z: [
17+
[1, 1, 0],
18+
[0, 1, 1],
19+
],
20+
BlockType.S: [
21+
[0, 1, 1],
22+
[1, 1, 0],
23+
],
24+
BlockType.O: [
25+
[1, 1],
26+
[1, 1]
27+
],
28+
BlockType.T: [
29+
[0, 1, 0],
30+
[1, 1, 1]
31+
]
32+
};
33+
34+
///方块初始化时的位置
35+
const START_XY = {
36+
BlockType.I: [3, 0],
37+
BlockType.L: [4, -1],
38+
BlockType.J: [4, -1],
39+
BlockType.Z: [4, -1],
40+
BlockType.S: [4, -1],
41+
BlockType.O: [4, -1],
42+
BlockType.T: [4, -1],
43+
};
44+
45+
///方块变换时的中心点
46+
const ORIGIN = {
47+
BlockType.I: [
48+
[1, -1],
49+
[-1, 1],
50+
],
51+
BlockType.L: [
52+
[0, 0]
53+
],
54+
BlockType.J: [
55+
[0, 0]
56+
],
57+
BlockType.Z: [
58+
[0, 0]
59+
],
60+
BlockType.S: [
61+
[0, 0]
62+
],
63+
BlockType.O: [
64+
[0, 0]
65+
],
66+
BlockType.T: [
67+
[0, 0],
68+
[0, 1],
69+
[1, -1],
70+
[-1, 0]
71+
],
72+
};
73+
74+
enum BlockType { I, L, J, Z, S, O, T }
75+
76+
class Block {
77+
final BlockType type;
78+
final List<List<int>> shape;
79+
final List<int> xy;
80+
final int rotateIndex;
81+
82+
Block(this.type, this.shape, this.xy, this.rotateIndex);
83+
84+
Block fall({int step = 1}) {
85+
return Block(type, shape, [xy[0], xy[1] + step], rotateIndex);
86+
}
87+
88+
Block right() {
89+
return Block(type, shape, [xy[0] + 1, xy[1]], rotateIndex);
90+
}
91+
92+
Block left() {
93+
return Block(type, shape, [xy[0] - 1, xy[1]], rotateIndex);
94+
}
95+
96+
Block rotate() {
97+
List<List<int>> result =
98+
List.filled(shape[0].length, null, growable: false);
99+
for (int row = 0; row < shape.length; row++) {
100+
for (int col = 0; col < shape[row].length; col++) {
101+
if (result[col] == null) {
102+
result[col] = List.filled(shape.length, 0, growable: false);
103+
}
104+
result[col][row] = shape[shape.length - 1 - row][col];
105+
}
106+
}
107+
final nextXy = [
108+
this.xy[0] + ORIGIN[type][rotateIndex][0],
109+
this.xy[1] + ORIGIN[type][rotateIndex][1]
110+
];
111+
final nextRotateIndex =
112+
rotateIndex + 1 >= ORIGIN[this.type].length ? 0 : rotateIndex + 1;
113+
114+
return Block(type, result, nextXy, nextRotateIndex);
115+
}
116+
117+
bool isValidInMatrix(List<List<int>> matrix) {
118+
if (xy[1] < 0 ||
119+
xy[1] + shape.length > GAME_PAD_MATRIX_H ||
120+
xy[0] < 0 ||
121+
xy[0] + shape[0].length > GAME_PAD_MATRIX_W) {
122+
return false;
123+
}
124+
for (var i = 0; i < matrix.length; i++) {
125+
final line = matrix[i];
126+
for (var j = 0; j < line.length; j++) {
127+
if (line[j] == 1 && get(j, i) == 1) {
128+
return false;
129+
}
130+
}
131+
}
132+
return true;
133+
}
134+
135+
///return null if do not show at [x][y]
136+
int get(int x, int y) {
137+
x -= xy[0];
138+
y -= xy[1];
139+
if (x < 0 || x >= shape[0].length || y < 0 || y >= shape.length) {
140+
return null;
141+
}
142+
return shape[y][x] == 1 ? 1 : null;
143+
}
144+
145+
static Block fromType(BlockType type) {
146+
final shape = BLOCK_SHAPES[type];
147+
return Block(type, shape, START_XY[type], 0);
148+
}
149+
150+
static Block getRandom() {
151+
final i = math.Random().nextInt(BlockType.values.length);
152+
return fromType(BlockType.values[i]);
153+
}
154+
}

0 commit comments

Comments
 (0)