想写一个俄罗斯方块,请大家来说说,要哪些类
说的好给高分搜索更多相关的解决方案:
俄罗斯方块
----------------解决方案--------------------------------------------------------
嘿嘿,应该有Math类,Graphics类
----------------解决方案--------------------------------------------------------
回复 2楼 kingyue
我的意思是应该自定义哪些类不是使用到的jdk里的类
----------------解决方案--------------------------------------------------------
import java.awt.*;
3.import java.awt.event.*;
4.
5.//俄罗斯方块类
6.public class ERS_Block extends Frame {
7. /**
8. *
9. */
10. private static final long serialVersionUID = -1443760309099067025L;
11.
12. public static boolean isPlay = false;
13.
14. public static int level = 1, score = 0;
15.
16. public static TextField scoreField, levelField;
17.
18. public static MyTimer timer;
19.
20. GameCanvas gameScr;
21.
22. public static void main(String[] argus) {
23. ERS_Block ers = new ERS_Block("俄罗斯方块游戏 V1.0 Author:Vincent");
24. WindowListener win_listener = new WinListener();
25. ers.addWindowListener(win_listener);
26. }
27.
28. // 俄罗斯方块类的构造方法
29. ERS_Block(String title) {
30. super(title);
31.
32. setSize(600, 480);
33. setLayout(new GridLayout(1, 2));
34.
35. gameScr = new GameCanvas();
36. gameScr.addKeyListener(gameScr);
37.
38. timer = new MyTimer(gameScr);
39. timer.setDaemon(true);
40. timer.start();
41. timer.suspend();
42.
43. add(gameScr);
44.
45. Panel rightScr = new Panel();
46. rightScr.setLayout(new GridLayout(2, 1, 0, 30));
47. rightScr.setSize(120, 500);
48. add(rightScr);
49.
50. // 右边信息窗体的布局
51. MyPanel infoScr = new MyPanel();
52. infoScr.setLayout(new GridLayout(4, 1, 0, 5));
53. infoScr.setSize(120, 300);
54. rightScr.add(infoScr);
55.
56. // 定义标签和初始值
57. Label scorep = new Label("分数:", Label.LEFT);
58. Label levelp = new Label("级数:", Label.LEFT);
59. scoreField = new TextField(8);
60. levelField = new TextField(8);
61. scoreField.setEditable(false);
62. levelField.setEditable(false);
63. infoScr.add(scorep);
64. infoScr.add(scoreField);
65. infoScr.add(levelp);
66. infoScr.add(levelField);
67. scorep.setSize(new Dimension(20, 60));
68. scoreField.setSize(new Dimension(20, 60));
69. levelp.setSize(new Dimension(20, 60));
70. levelField.setSize(new Dimension(20, 60));
71. scoreField.setText("0");
72. levelField.setText("1");
73.
74. // 右边控制按钮窗体的布局
75. MyPanel controlScr = new MyPanel();
76. controlScr.setLayout(new GridLayout(5, 1, 0, 5));
77. rightScr.add(controlScr);
78.
79. // 定义按钮play
80. Button play_b = new Button("开始游戏");
81. play_b.setSize(new Dimension(50, 200));
82. play_b.addActionListener(new Command(Command.button_play, gameScr));
83.
84. // 定义按钮Level UP
85. Button level_up_b = new Button("提高级数");
86. level_up_b.setSize(new Dimension(50, 200));
87. level_up_b.addActionListener(new Command(Command.button_levelup,
88. gameScr));
89.
90. // 定义按钮Level Down
91. Button level_down_b = new Button("降低级数");
92. level_down_b.setSize(new Dimension(50, 200));
93. level_down_b.addActionListener(new Command(Command.button_leveldown,
94. gameScr));
95.
96. // 定义按钮Level Pause
97. Button pause_b = new Button("游戏暂停");
98. pause_b.setSize(new Dimension(50, 200));
99. pause_b.addActionListener(new Command(Command.button_pause, gameScr));
100.
101. // 定义按钮Quit
102. Button quit_b = new Button("退出游戏");
103. quit_b.setSize(new Dimension(50, 200));
104. quit_b.addActionListener(new Command(Command.button_quit, gameScr));
105.
106. controlScr.add(play_b);
107. controlScr.add(level_up_b);
108. controlScr.add(level_down_b);
109. controlScr.add(pause_b);
110. controlScr.add(quit_b);
111. setVisible(true);
112. gameScr.requestFocus();
113. }
114.}
115.
116.// 重写MyPanel类,使Panel的四周留空间
117.class MyPanel extends Panel {
118. public Insets getInsets() {
119. return new Insets(30, 50, 30, 50);
120. }
121.}
122.
123.// 游戏画布类
124.class GameCanvas extends Canvas implements KeyListener {
125. final int unitSize = 30; // 小方块边长
126.
127. int rowNum; // 正方格的行数
128.
129. int columnNum; // 正方格的列数
130.
131. int maxAllowRowNum; // 允许有多少行未削
132.
133. int blockInitRow; // 新出现块的起始行坐标
134.
135. int blockInitCol; // 新出现块的起始列坐标
136.
137. int[][] scrArr; // 屏幕数组
138.
139. Block b; // 对方快的引用
140.
141. // 画布类的构造方法
142. GameCanvas() {
143. rowNum = 15;
144. columnNum = 10;
145. maxAllowRowNum = rowNum - 2;
146. b = new Block(this);
147. blockInitRow = rowNum - 1;
148. blockInitCol = columnNum / 2 - 2;
149. scrArr = new int[32][32];
150. }
151.
152. // 初始化屏幕,并将屏幕数组清零的方法
153. void initScr() {
154. for (int i = 0; i < rowNum; i++)
155. for (int j = 0; j < columnNum; j++)
156. scrArr[i][j] = 0;
157. b.reset();
158. repaint();
159. }
160.
161. // 重新刷新画布方法
162. public void paint(Graphics g) {
163. for (int i = 0; i < rowNum; i++)
164. for (int j = 0; j < columnNum; j++)
165. drawUnit(i, j, scrArr[i][j]);
166. }
167.
168. // 画方块的方法
169. public void drawUnit(int row, int col, int type) {
170. scrArr[row][col] = type;
171. Graphics g = getGraphics();
172. switch (type) { // 表示画方快的方法
173. case 0:
174. g.setColor(Color.black);
175. break; // 以背景为颜色画
176. case 1:
177. g.setColor(Color.blue);
178. break; // 画正在下落的方块
179. case 2:
180. g.setColor(Color.magenta);
181. break; // 画已经落下的方法
182. }
183. g.fill3DRect(col * unitSize, getSize().height - (row + 1) * unitSize,
184. unitSize, unitSize, true);
185. g.dispose();
186. }
187.
188. public Block getBlock() {
189. return b; // 返回block实例的引用
190. }
191.
192. // 返回屏幕数组中(row,col)位置的属性值
193. public int getScrArrXY(int row, int col) {
194. if (row < 0 || row >= rowNum || col < 0 || col >= columnNum)
195. return (-1);
196. else
197. return (scrArr[row][col]);
198. }
199.
200. // 返回新块的初始行坐标方法
201. public int getInitRow() {
202. return (blockInitRow); // 返回新块的初始行坐标
203. }
204.
205. // 返回新块的初始列坐标方法
206. public int getInitCol() {
207. return (blockInitCol); // 返回新块的初始列坐标
208. }
209.
210. // 满行删除方法
211. void deleteFullLine() {
212. int full_line_num = 0;
213. int k = 0;
214. for (int i = 0; i < rowNum; i++) {
215. boolean isfull = true;
216.
217. L1: for (int j = 0; j < columnNum; j++)
218. if (scrArr[i][j] == 0) {
219. k++;
220. isfull = false;
221. break L1;
222. }
223. if (isfull)
224. full_line_num++;
225. if (k != 0 && k - 1 != i && !isfull)
226. for (int j = 0; j < columnNum; j++) {
227. if (scrArr[i][j] == 0)
228. drawUnit(k - 1, j, 0);
229. else
230. drawUnit(k - 1, j, 2);
231. scrArr[k - 1][j] = scrArr[i][j];
232. }
233. }
234. for (int i = k - 1; i < rowNum; i++) {
235. for (int j = 0; j < columnNum; j++) {
236. drawUnit(i, j, 0);
237. scrArr[i][j] = 0;
238. }
239. }
240. ERS_Block.score += full_line_num;
241. ERS_Block.scoreField.setText("" + ERS_Block.score);
242. }
243.
244. // 判断游戏是否结束方法
245. boolean isGameEnd() {
246. for (int col = 0; col < columnNum; col++) {
247. if (scrArr[maxAllowRowNum][col] != 0)
248. return true;
249. }
250. return false;
251. }
252.
253. public void keyTyped(KeyEvent e) {
254. }
255.
256. public void keyReleased(KeyEvent e) {
257. }
258.
259. // 处理键盘输入的方法
260. public void keyPressed(KeyEvent e) {
261. if (!ERS_Block.isPlay)
262. return;
263. switch (e.getKeyCode()) {
264. case KeyEvent.VK_DOWN:
265. b.fallDown();
266. break;
267. case KeyEvent.VK_LEFT:
268. b.leftMove();
269. break;
270. case KeyEvent.VK_RIGHT:
271. b.rightMove();
272. break;
273. case KeyEvent.VK_SPACE:
274. b.leftTurn();
275. break;
276. }
277. }
278.}
279.
280.// 处理控制类
281.class Command implements ActionListener {
282. static final int button_play = 1; // 给按钮分配编号
283.
284. static final int button_levelup = 2;
285.
286. static final int button_leveldown = 3;
287.
288. static final int button_quit = 4;
289.
290. static final int button_pause = 5;
291.
292. static boolean pause_resume = true;
293.
294. int curButton; // 当前按钮
295.
296. GameCanvas scr;
297.
298. // 控制按钮类的构造方法
299. Command(int button, GameCanvas scr) {
300. curButton = button;
301. this.scr = scr;
302. }
303.
304. // 按钮执行方法
305. public void actionPerformed(ActionEvent e) {
306. switch (curButton) {
307. case button_play:
308. if (!ERS_Block.isPlay) {
309. scr.initScr();
310. ERS_Block.isPlay = true;
311. ERS_Block.score = 0;
312. ERS_Block.scoreField.setText("0");
313. ERS_Block.timer.resume();
314. }
315. scr.requestFocus();
316. break;
317. case button_levelup:
318. if (ERS_Block.level < 10) {
319. ERS_Block.level++;
320. ERS_Block.levelField.setText("" + ERS_Block.level);
321. ERS_Block.score = 0;
322. ERS_Block.scoreField.setText("" + ERS_Block.score);
323. }
324. scr.requestFocus();
325. break;
326. case button_leveldown:
327. if (ERS_Block.level > 1) {
328. ERS_Block.level--;
329. ERS_Block.levelField.setText("" + ERS_Block.level);
330. ERS_Block.score = 0;
331. ERS_Block.scoreField.setText("" + ERS_Block.score);
332. }
333. scr.requestFocus();
334. break;
335. case button_pause:
336. if (pause_resume) {
337. ERS_Block.timer.suspend();
338. pause_resume = false;
339. } else {
340. ERS_Block.timer.resume();
341. pause_resume = true;
342. }
343. scr.requestFocus();
344. break;
345. case button_quit:
346. System.exit(0);
347. }
348. }
349.}
350.
351.// 方块类
352.class Block {
353. static int[][] pattern = {
354. { 0x0f00, 0x4444, 0x0f00, 0x4444 },// 用十六进至表示,本行表示长条四种状态
355. { 0x04e0, 0x0464, 0x00e4, 0x04c4 },
356. { 0x4620, 0x6c00, 0x4620, 0x6c00 },
357. { 0x2640, 0xc600, 0x2640, 0xc600 },
358. { 0x6220, 0x1700, 0x2230, 0x0740 },
359. { 0x6440, 0x0e20, 0x44c0, 0x8e00 },
360. { 0x0660, 0x0660, 0x0660, 0x0660 } };
361.
362. int blockType; // 块的模式号(0-6)
363.
364. int turnState; // 块的翻转状态(0-3)
365.
366. int blockState; // 快的下落状态
367.
368. int row, col; // 块在画布上的坐标
369.
370. GameCanvas scr;
371.
372. // 块类的构造方法
373. Block(GameCanvas scr) {
374. this.scr = scr;
375. blockType = (int) (Math.random() * 1000) % 7;
376. turnState = (int) (Math.random() * 1000) % 4;
377. blockState = 1;
378. row = scr.getInitRow();
379. col = scr.getInitCol();
380. }
381.
382. // 重新初始化块,并显示新块
383. public void reset() {
384. blockType = (int) (Math.random() * 1000) % 7;
385. turnState = (int) (Math.random() * 1000) % 4;
386. blockState = 1;
387. row = scr.getInitRow();
388. col = scr.getInitCol();
389. dispBlock(1);
390. }
391.
392. // 实现“块”翻转的方法
393. public void leftTurn() {
394. if (assertValid(blockType, (turnState + 1) % 4, row, col)) {
395. dispBlock(0);
396. turnState = (turnState + 1) % 4;
397. dispBlock(1);
398. }
399. }
400.
401. // 实现“块”的左移的方法
402. public void leftMove() {
403. if (assertValid(blockType, turnState, row, col - 1)) {
404. dispBlock(0);
405. col--;
406. dispBlock(1);
407. }
408. }
409.
410. // 实现块的右移
411. public void rightMove() {
412. if (assertValid(blockType, turnState, row, col + 1)) {
413. dispBlock(0);
414. col++;
415. dispBlock(1);
416. }
417. }
418.
419. // 实现块落下的操作的方法
420. public boolean fallDown() {
421. if (blockState == 2)
422. return (false);
423. if (assertValid(blockType, turnState, row - 1, col)) {
424. dispBlock(0);
425. row--;
426. dispBlock(1);
427. return (true);
428. } else {
429. blockState = 2;
430. dispBlock(2);
431. return (false);
432. }
433. }
434.
435. // 判断是否正确的方法
436. boolean assertValid(int t, int s, int row, int col) {
437. int k = 0x8000;
438. for (int i = 0; i < 4; i++) {
439. for (int j = 0; j < 4; j++) {
440. if ((int) (pattern[t][s] & k) != 0) {
441. int temp = scr.getScrArrXY(row - i, col + j);
442. if (temp < 0 || temp == 2)
443. return false;
444. }
445. k = k >> 1;
446. }
447. }
448. return true;
449. }
450.
451. // 同步显示的方法
452. public synchronized void dispBlock(int s) {
453. int k = 0x8000;
454. for (int i = 0; i < 4; i++) {
455. for (int j = 0; j < 4; j++) {
456. if (((int) pattern[blockType][turnState] & k) != 0) {
457. scr.drawUnit(row - i, col + j, s);
458. }
459. k = k >> 1;
460. }
461. }
462. }
463.}
464.
465.// 定时线程
466.class MyTimer extends Thread {
467. GameCanvas scr;
468.
469. public MyTimer(GameCanvas scr) {
470. this.scr = scr;
471. }
472.
473. public void run() {
474. while (true) {
475. try {
476. sleep((10 - ERS_Block.level + 1) * 100);
477. } catch (InterruptedException e) {
478. }
479. if (!scr.getBlock().fallDown()) {
480. scr.deleteFullLine();
481. if (scr.isGameEnd()) {
482. ERS_Block.isPlay = false;
483. suspend();
484. } else
485. scr.getBlock().reset();
486. }
487. }
488. }
489.}
490.
491.class WinListener extends WindowAdapter {
492. public void windowClosing(WindowEvent l) {
493. System.exit(0);
494. }
495.}
----------------解决方案--------------------------------------------------------
大概想了一下
主类 (程序的开始 可以加入等级的选择项)
初始化类(图形,数据的初始化)
变形操作类(变形下移左移右移等操作)
事件类(程序的一些主要动作的响应)
算分类(得分的计算)
对应的每一个类可以去细分
----------------解决方案--------------------------------------------------------