java实现俄罗斯方块小程序

2025-05-29 0 17

这是java课最后做的课程设计,由于java是初学的,所以做的时候有参考一些技术大牛的博客,在此表示感谢。

发在这里跟大家交流学习一下。

如需要完整工程文件、说明文档以及可运行jar文件,下载地址:点击打开链接

russianblocksgame.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

530

531

532

533

534

535

536

537

538

539

540

541

542

543

544

545

546

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561
package russiablocksgame;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.border.border;

import javax.swing.border.etchedborder;

/**

* 游戏主类,继承自jframe类,负责游戏的全局控制。 内含: 1.一个gamecanvas画布类的实例对象,

* 2.一个保存当前活动块(russiablock)实例的对象; 3.一个保存当前控制面板(controlpanel)实例的对象;

*/

public class russiablocksgame extends jframe {

private static final long serialversionuid = -7332245439279674749l;

/**

* 每填满一行计多少分

*/

public final static int per_line_score = 100;

/**

* 积多少分以后能升级

*/

public final static int per_level_score = per_line_score * 20;

/**

* 最大级数是10级

*/

public final static int max_level = 10;

/**

* 默认级数是2

*/

public final static int default_level = 2;

private gamecanvas canvas;

private ersblock block;

private boolean playing = false;

private controlpanel ctrlpanel;

//初始化菜单栏

private jmenubar bar = new jmenubar();

private jmenu mgame = new jmenu(" 游戏"),

mcontrol = new jmenu(" 控制"),

minfo = new jmenu("帮助");

private jmenuitem minewgame = new jmenuitem("新游戏"),

misetblockcolor = new jmenuitem("设置方块颜色..."),

misetbackcolor = new jmenuitem("设置背景颜色..."),

miturnharder = new jmenuitem("升高游戏难度"),

miturneasier = new jmenuitem("降低游戏难度"),

miexit = new jmenuitem("退出"),

miplay = new jmenuitem("开始"),

mipause = new jmenuitem("暂停"),

miresume = new jmenuitem("恢复"),

mistop = new jmenuitem("终止游戏"),

mirule = new jmenuitem("游戏规则"),

miauthor = new jmenuitem("关于本游戏");

/**

* 建立并设置窗口菜单

*/

private void creatmenu() {

bar.add(mgame);

bar.add(mcontrol);

bar.add(minfo);

mgame.add(minewgame);

mgame.addseparator();//在菜单中加水平分割线

mgame.add(misetblockcolor);

mgame.add(misetbackcolor);

mgame.addseparator();//在菜单中加水平分割线

mgame.add(miturnharder);

mgame.add(miturneasier);

mgame.addseparator();//在菜单中加水平分割线

mgame.add(miexit);

mcontrol.add(miplay);

miplay.setenabled(true);

mcontrol.add(mipause);

mipause.setenabled(false);

mcontrol.add(miresume);

miresume.setenabled(false);

mcontrol.add(mistop);

mistop.setenabled(false);

minfo.add(mirule);

minfo.add(miauthor);

setjmenubar(bar);

minewgame.addactionlistener(new actionlistener() {

@override

public void actionperformed(actionevent e) {

stopgame();

reset();

setlevel(default_level);

}

});

//设置方块颜色

misetblockcolor.addactionlistener(new actionlistener() {

@override

public void actionperformed(actionevent e) {

color newfrontcolor =

jcolorchooser.showdialog(russiablocksgame.this, "设置方块颜色", canvas.getblockcolor());

if (newfrontcolor != null) {

canvas.setblockcolor(newfrontcolor);

}

}

});

//设置背景颜色

misetbackcolor.addactionlistener(new actionlistener() {

@override

public void actionperformed(actionevent e) {

color newbackcolor =

jcolorchooser.showdialog(russiablocksgame.this, "设置背景颜色", canvas.getbackgroundcolor());

if (newbackcolor != null) {

canvas.setbackgroundcolor(newbackcolor);

}

}

});

//定义菜单栏"关于"的功能,弹出确认框。

miauthor.addactionlistener(new actionlistener() {

@override

public void actionperformed(actionevent e) {

joptionpane.showmessagedialog(null, "软件工程(4)班\\n3115005372\\n杨宇杰\\n©一切解释权归杨宇杰所有", "关于俄罗斯方块 - 2016", 1);

}

});

//游戏规则说明

mirule.addactionlistener(new actionlistener() {

@override

public void actionperformed(actionevent e) {

joptionpane.showmessagedialog(null, "由小方块组成的不同形状的板块陆续从屏幕上方落下来,\\n玩家通过调整板块的位置和方向,使它们在屏幕底部拼\\n出完整的一条或几条。这些完整的横条会随即消失,给新\\n落下来的板块腾出空间,与此同时,玩家得到分数奖励。\\n没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,\\n玩家便告输,游戏结束。", "游戏规则", 1);

}

});

//增加难度

miturnharder.addactionlistener(new actionlistener() {

@override

public void actionperformed(actionevent e) {

int curlevel = getlevel();

if (!playing && curlevel < max_level) {

setlevel(curlevel + 1);

}

}

});

//减少难度

miturneasier.addactionlistener(new actionlistener() {

@override

public void actionperformed(actionevent e) {

int curlevel = getlevel();

if (!playing && curlevel > 1) {

setlevel(curlevel - 1);

}

}

});

//退出按钮动作响应

miexit.addactionlistener(new actionlistener() {

@override

public void actionperformed(actionevent e) {

system.exit(0);

}

});

}

/**

* 主游戏类的构造方法

*

* @param title string ,窗口标题

*/

public russiablocksgame(string title) {

super(title); //设置标题

setsize(500, 600); //设置窗口大小

setlocationrelativeto(null); //设置窗口居中

creatmenu();

container container = getcontentpane(); //创建菜单栏

container.setlayout(new borderlayout(6, 0)); //设置窗口的布局管理器

canvas = new gamecanvas(20, 15); //新建游戏画布

ctrlpanel = new controlpanel(this); //新建控制面板

container.add(canvas, borderlayout.center); //左边加上画布

container.add(ctrlpanel, borderlayout.east); //右边加上控制面板

//注册窗口事件。当点击关闭按钮时,结束游戏,系统退出。

addwindowlistener(new windowadapter() {

@override

public void windowclosing(windowevent we) {

stopgame();

system.exit(0);

}

});

//根据窗口大小,自动调节方格的尺寸

addcomponentlistener(new componentadapter() {

@override

public void componentresized(componentevent ce) {

canvas.adjust();

}

});

setvisible(true);

canvas.adjust();

}

/**

* 让游戏复位

*/

public void reset() { //画布复位,控制面板复位

ctrlpanel.setplaybuttonenable(true);

ctrlpanel.setpausebuttonenable(false);

ctrlpanel.setpausebuttonlabel(true);

ctrlpanel.setstopbuttonenable(false);

ctrlpanel.setturnleveldownbuttonenable(true);

ctrlpanel.setturnlevelupbuttonenable(true);

miplay.setenabled(true);

mipause.setenabled(false);

miresume.setenabled(false);

mistop.setenabled(false);

ctrlpanel.reset();

canvas.reset();

}

/**

* 判断游戏是否还在进行

*

* @return boolean,true -还在运行,false-已经停止

*/

public boolean isplaying() {

return playing;

}

/**

* 得到当前活动的块

*

* @return ersblock,当前活动块的引用

*/

public ersblock getcurblock() {

return block;

}

/**

* 得到当前画布

*

* @return gamecanvas,当前画布的引用

*/

public gamecanvas getcanvas() {

return canvas;

}

/**

* 开始游戏

*/

public void playgame() {

play();

ctrlpanel.setplaybuttonenable(false);

ctrlpanel.setpausebuttonenable(true);

ctrlpanel.setpausebuttonlabel(true);

ctrlpanel.setstopbuttonenable(true);

ctrlpanel.setturnleveldownbuttonenable(false);

ctrlpanel.setturnlevelupbuttonenable(false);

mistop.setenabled(true);

miturnharder.setenabled(false);

miturneasier.setenabled(false);

ctrlpanel.requestfocus(); //设置焦点在控制面板上

}

/**

* 游戏暂停

*/

public void pausegame() {

if (block != null) {

block.pausemove();

}

ctrlpanel.setplaybuttonenable(false);

ctrlpanel.setpausebuttonlabel(false);

ctrlpanel.setstopbuttonenable(true);

miplay.setenabled(false);

mipause.setenabled(false);

miresume.setenabled(true);

mistop.setenabled(true);

}

/**

* 让暂停中的游戏继续

*/

public void resumegame() {

if (block != null) {

block.resumemove();

}

ctrlpanel.setplaybuttonenable(false);

ctrlpanel.setpausebuttonenable(true);

ctrlpanel.setpausebuttonlabel(true);

mipause.setenabled(true);

miresume.setenabled(false);

ctrlpanel.requestfocus();

}

/**

* 用户停止游戏

*/

public void stopgame() {

playing = false;

if (block != null) {

block.stopmove();

}

ctrlpanel.setplaybuttonenable(true);

ctrlpanel.setpausebuttonenable(false);

ctrlpanel.setpausebuttonlabel(true);

ctrlpanel.setstopbuttonenable(false);

ctrlpanel.setturnleveldownbuttonenable(true);

ctrlpanel.setturnlevelupbuttonenable(true);

miplay.setenabled(true);

mipause.setenabled(false);

miresume.setenabled(false);

mistop.setenabled(false);

miturnharder.setenabled(true);

miturneasier.setenabled(true);

reset();//重置画布和控制面板

}

/**

* 得到游戏者设置的难度

*

* @return int ,游戏难度1-max_level

*/

public int getlevel() {

return ctrlpanel.getlevel();

}

/**

* 用户设置游戏难度

*

* @param level int ,游戏难度1-max_level

*/

public void setlevel(int level) {

if (level < 11 && level > 0) {

ctrlpanel.setlevel(level);

}

}

/**

* 得到游戏积分

*

* @return int,积分

*/

public int getscore() {

if (canvas != null) {

return canvas.getscore();

}

return 0;

}

/**

* 得到自上次升级以来的游戏积分,升级以后,此积分清零

*

* @return int,积分

*/

public int getscoreforlevelupdate() {

if (canvas != null) {

return canvas.getscoreforlevelupdate();

}

return 0;

}

/**

* 当积分累积到一定数值时,升一次级

*

* @return boolean,true-update succeed,false-update fail

*/

public boolean levelupdate() {

int curlevel = getlevel();

if (curlevel < max_level) {

setlevel(curlevel + 1);

canvas.resetscoreforlevelupdate();

return true;

}

return false;

}

/**

* 游戏开始

*/

private void play() {

reset();

playing = true;

thread thread = new thread(new game());//启动游戏线程

thread.start();

}

/**

* 报告游戏结束了

*/

private void reportgameover() {

new gameoverdialog(this, "俄罗斯方块", "游戏结束,您的得分为" + canvas.getscore());

}

/**

* 一轮游戏过程,实现了runnable接口 一轮游戏是一个大循环,在这个循环中,每隔100毫秒, 检查游戏中的当前块是否已经到底了,如果没有,

* 就继续等待。如果到底了,就看有没有全填满的行, 如果有就删除它,并为游戏者加分,同时随机产生一个新的当前块并让它自动落下。

* 当新产生一个块时,先检查画布最顶上的一行是否已经被占了,如果是,可以判断game over 了。

*/

private class game implements runnable {

@override

public void run() {

int col = (int) (math.random() * (canvas.getcols() - 3));//随机生成方块出现的位置

int style = ersblock.styles[ (int) (math.random() * 7)][(int) (math.random() * 4)];//随机生成一种形状的方块

while (playing) {

if (block != null) { //第一次循环时,block为空

if (block.isalive()) {

try {

thread.currentthread();

thread.sleep(500);

} catch (interruptedexception ie) {

ie.printstacktrace();

}

continue;

}

}

checkfullline(); //检查是否有全填满的行

if (isgameover()) {

reportgameover();

miplay.setenabled(true);

mipause.setenabled(false);

miresume.setenabled(false);

mistop.setenabled(false);

ctrlpanel.setplaybuttonenable(true);

ctrlpanel.setpausebuttonlabel(false);

ctrlpanel.setstopbuttonenable(false);

return;

}

block = new ersblock(style, -1, col, getlevel(), canvas);

block.start();

col = (int) (math.random() * (canvas.getcols() - 3));

style = ersblock.styles[ (int) (math.random() * 7)][(int) (math.random() * 4)];

ctrlpanel.settipstyle(style);

}

}

//检查画布中是否有全填满的行,如果有就删之

public void checkfullline() {

for (int i = 0; i < canvas.getrows(); i++) {

int row = -1;

boolean fulllinecolorbox = true;

for (int j = 0; j < canvas.getcols(); j++) {

if (!canvas.getbox(i, j).iscolorbox()) {

fulllinecolorbox = false;

break;

}

}

if (fulllinecolorbox) {

row = i--;

canvas.removeline(row);

}

}

}

//根据最顶行是否被占,判断游戏是否已经结束了

//@return boolean ,true-游戏结束了,false-游戏未结束

private boolean isgameover() {

for (int i = 0; i < canvas.getcols(); i++) {

ersbox box = canvas.getbox(0, i);

if (box.iscolorbox()) {

return true;

}

}

return false;

}

}

/**

* 定义gameover对话框。

*/

@suppresswarnings("serial")

private class gameoverdialog extends jdialog implements actionlistener {

private jbutton againbutton, exitbutton;

private border border = new etchedborder(etchedborder.raised, color.white, new color(148, 145, 140));

public gameoverdialog(jframe parent, string title, string message) {

super(parent, title, true);

if (parent != null) {

setsize(240, 120);

this.setlocationrelativeto(parent);

jpanel messagepanel = new jpanel();

messagepanel.add(new jlabel(message));

messagepanel.setborder(border);

container container = this.getcontentpane();

container.setlayout(new gridlayout(2, 0, 0, 10));

container.add(messagepanel);

jpanel choosepanel = new jpanel();

choosepanel.setlayout(new gridlayout(0, 2, 4, 0));

container.add(choosepanel);

againbutton = new jbutton("再玩一局");

exitbutton = new jbutton("退出游戏");

choosepanel.add(new jpanel().add(againbutton));

choosepanel.add(new jpanel().add(exitbutton));

choosepanel.setborder(border);

}

againbutton.addactionlistener(this);

exitbutton.addactionlistener(this);

this.setvisible(true);

}

@override

public void actionperformed(actionevent e) {

if (e.getsource() == againbutton) {

this.setvisible(false);

reset();

} else if (e.getsource() == exitbutton) {

stopgame();

system.exit(0);

}

}

}

}

gamecanvas.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229
package russiablocksgame;

import java.awt.color;

import java.awt.graphics;

import javax.swing.jpanel;

import javax.swing.border.etchedborder;

/**

* 画布类,内有<行数>*<列数> 个方格类实例。 继承自jpanel类。 ersblock线程类动态改变画布类的方格颜色,画布类通过

* 检查方格颜色来体现ersblock块的移动情况。

*/

public class gamecanvas extends jpanel {

private static final long serialversionuid = 6732901391026089276l;

private color backcolor = color.darkgray, frontcolor = color.white;

private int rows, cols, score = 0, scoreforlevelupdate = 0;

private ersbox[][] boxes;

private int boxwidth, boxheight;

/**

* 画布类的构造函数

*

* @param rows int,画布的行数

* @param cols int,画布的列数 行数和列数决定着画布拥有方格的数目

*/

public gamecanvas(int rows, int cols) {

this.rows = rows;

this.cols = cols;

boxes = new ersbox[rows][cols];

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

boxes[i][j] = new ersbox(false);

}

}

setborder(new etchedborder(etchedborder.raised, color.white, new color(148, 145, 140)));

}

/**

* 画布类的构造函数

*

* @param rows

* @param cols

* @param backcolor

* @param frontcolor

*/

public gamecanvas(int rows, int cols,

color backcolor, color frontcolor) {

this(rows, cols);

this.backcolor = backcolor;

this.frontcolor = frontcolor;

}

/**

* 设置游戏背景色彩

*

* @param backcolor color,背景色彩

*/

public void setbackgroundcolor(color backcolor) {

this.backcolor = backcolor;

}

/**

* 取得游戏背景色彩

*

* @return color ,背景色彩

*/

public color getbackgroundcolor() {

return backcolor;

}

/**

* 设置游戏方块颜色

*

* @param frontcolor color,方块颜色

*/

public void setblockcolor(color frontcolor) {

this.frontcolor = frontcolor;

}

/**

* 取得游戏方块色彩

*

* @return color,方块颜色

*/

public color getblockcolor() {

return frontcolor;

}

/**

* 取得画布中方格的行数

*

* @return

*/

public int getrows() {

return rows;

}

/**

* 取得画布中方格的列数

*

* @return int,方格的列数

*/

public int getcols() {

return cols;

}

/**

* 取得游戏成绩

*

* @return int, 分数

*/

public int getscore() {

return score;

}

/**

* 取得自上一次升级后的积分

*

* @return int ,上一次升级后的积分

*/

public int getscoreforlevelupdate() {

return scoreforlevelupdate;

}

/**

* 升级后,将上一次升级以来的积分清零

*/

public void resetscoreforlevelupdate() {

scoreforlevelupdate -= russiablocksgame.per_level_score;

}

/**

* 得到某一行某一列的方格引用

*

* @return row int ,要引用的方格所在的行

* @param col int, 要引用的方格所在的行

* @return ersbox,在row行col列的方格的引用

*/

public ersbox getbox(int row, int col) {

if (row < 0 || row > boxes.length - 1 || col < 0 || col > boxes[0].length - 1) {

return null;

}

return (boxes[row][col]);

}

/**

* 覆盖jcomponent类的函数,画组件。

*

* @param g 图形设备环境

*/

@override

public void paintcomponent(graphics g) {

super.paintcomponent(g);

g.setcolor(frontcolor);

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

g.setcolor(boxes[i][j].iscolorbox() ? frontcolor : backcolor);

g.fill3drect(j * boxwidth, i * boxheight,

boxwidth, boxheight, true);

}

}

}

/**

* 根据窗口大小,自动调节方格的尺寸

*/

public void adjust() {

boxwidth = getsize().width / cols;

boxheight = getsize().height / rows;

}

/**

* 当一行被游戏者叠满后,将此行清除,并为游戏者加分

*

* @param row int,要清除的行,是由ersboxesgame类计算的

*/

public synchronized void removeline(int row) {

for (int i = row; i > 0; i--) {

for (int j = 0; j < cols; j++) {

boxes[i][j] = (ersbox) boxes[i - 1][j].clone(); //将上一行的方块颜色克隆下来,

} //即消去一行方块

}

score += russiablocksgame.per_level_score;

scoreforlevelupdate += russiablocksgame.per_level_score;

repaint();

}

/**

* 重置画布,置积分为零

*/

public void reset() {

score = 0;

scoreforlevelupdate = 0;

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

boxes[i][j].setcolor(false);

}

}

repaint();

}

}

controlpanel.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360
package russiablocksgame;

import java.awt.borderlayout;

import java.awt.color;

import java.awt.graphics;

import java.awt.gridlayout;

import java.awt.event.actionevent;

import java.awt.event.actionlistener;

import java.awt.event.componentadapter;

import java.awt.event.componentevent;

import java.awt.event.keyadapter;

import java.awt.event.keyevent;

import java.text.dateformat;

import java.text.simpledateformat;

import java.util.date;

import javax.swing.jbutton;

import javax.swing.jlabel;

import javax.swing.jpanel;

import javax.swing.jtextfield;

import javax.swing.timer;

import javax.swing.border.border;

import javax.swing.border.etchedborder;

/**

* 控制面板类,继承自jpanel。 上边安放预显窗口,等级,得分,控制按钮 主要用来控制游戏进程。

*/

class controlpanel extends jpanel {

private static final long serialversionuid = 3900659640646175724l;

private jtextfield tflevel = new jtextfield("" + russiablocksgame.default_level),

tfscore = new jtextfield(" 0"),

tftime = new jtextfield(" ");

private jbutton btplay = new jbutton(" 开始"),

btpause = new jbutton(" 暂停"),

btstop = new jbutton("终止游戏"),

btturnlevelup = new jbutton(" 增加难度"),

btturnleveldown = new jbutton(" 降低难度");

private jpanel pltip = new jpanel(new borderlayout());

private tippanel pltipblock = new tippanel();

private jpanel plinfo = new jpanel(new gridlayout(4, 1));

private jpanel plbutton = new jpanel(new gridlayout(6, 1));

private timer timer;

private border border = new etchedborder(etchedborder.raised, color.white, new color(148, 145, 140));

/**

* 控制面板类的构造函数

*

* @param game ersblocksgame,ersblocksgame 类的一个实例引用 方便直接控制ersblocksgame类的行为。

*/

public controlpanel(final russiablocksgame game) {

setlayout(new gridlayout(3, 1, 0, 2));

pltip.add(new jlabel(" 下一个方块"), borderlayout.north); //添加组件

pltip.add(pltipblock);

pltip.setborder(border);

plinfo.add(new jlabel(" 难度系数"));

plinfo.add(tflevel);

plinfo.add(new jlabel(" 得分"));

plinfo.add(tfscore);

plinfo.setborder(border);

plbutton.add(btplay);

btplay.setenabled(true);

plbutton.add(btpause);

btpause.setenabled(false);

plbutton.add(btstop);

btstop.setenabled(false);

plbutton.add(btturnlevelup);

plbutton.add(btturnleveldown);

plbutton.add(tftime);

plbutton.setborder(border);

tflevel.seteditable(false);

tfscore.seteditable(false);

tftime.seteditable(false);

add(pltip);

add(plinfo);

add(plbutton);

addkeylistener(new keyadapter() {

@override

public void keypressed(keyevent ke) {

if (!game.isplaying()) {

return;

}

ersblock block = game.getcurblock();

switch (ke.getkeycode()) {

case keyevent.vk_down:

block.movedown();

break;

case keyevent.vk_left:

block.moveleft();

break;

case keyevent.vk_right:

block.moveright();

break;

case keyevent.vk_up:

block.turnnext();

break;

default:

break;

}

}

});

btplay.addactionlistener(new actionlistener() { //开始游戏

@override

public void actionperformed(actionevent ae) {

game.playgame();

}

});

btpause.addactionlistener(new actionlistener() { //暂停游戏

@override

public void actionperformed(actionevent ae) {

if (btpause.gettext().equals(" 暂停")) {

game.pausegame();

} else {

game.resumegame();

}

}

});

btstop.addactionlistener(new actionlistener() { //停止游戏

@override

public void actionperformed(actionevent ae) {

game.stopgame();

}

});

btturnlevelup.addactionlistener(new actionlistener() { //升高难度

@override

public void actionperformed(actionevent ae) {

try {

int level = integer.parseint(tflevel.gettext());

if (level < russiablocksgame.max_level) {

tflevel.settext("" + (level + 1));

}

} catch (numberformatexception e) {

}

requestfocus();

}

});

btturnleveldown.addactionlistener(new actionlistener() { //降低游戏难度

@override

public void actionperformed(actionevent ae) {

try {

int level = integer.parseint(tflevel.gettext());

if (level > 1) {

tflevel.settext("" + (level - 1));

}

} catch (numberformatexception e) {

}

requestfocus();

}

});

addcomponentlistener(new componentadapter() {

@override

public void componentresized(componentevent ce) {

pltipblock.adjust();

}

});

timer = new timer(1000, new actionlistener() {

@override

public void actionperformed(actionevent ae) {

dateformat format = new simpledateformat("时间:hh:mm:ss"); //系统获得时间

date date = new date();

tftime.settext(format.format(date));

tfscore.settext("" + game.getscore());

int scoreforlevelupdate = //判断当前分数是否能升级

game.getscoreforlevelupdate();

if (scoreforlevelupdate >= russiablocksgame.per_level_score

&& scoreforlevelupdate > 0) {

game.levelupdate();

}

}

});

timer.start();

}

/**

* 设置预显窗口的样式

*

* @param style int,对应ersblock类的styles中的28个值

*/

public void settipstyle(int style) {

pltipblock.setstyle(style);

}

/**

* 取得用户设置的游戏等级。

*

* @return int ,难度等级,1-ersblocksgame.max_level

*/

public int getlevel() {

int level = 0;

try {

level = integer.parseint(tflevel.gettext());

} catch (numberformatexception e) {

}

return level;

}

/**

* 让用户修改游戏难度等级。

*

* @param level 修改后的游戏难度等级

*/

public void setlevel(int level) {

if (level > 0 && level < 11) {

tflevel.settext("" + level);

}

}

/**

* 设置“开始”按钮的状态。

*/

public void setplaybuttonenable(boolean enable) {

btplay.setenabled(enable);

}

public void setpausebuttonenable(boolean enable) {

btpause.setenabled(enable);

}

public void setpausebuttonlabel(boolean pause) {

btpause.settext(pause ? " 暂停" : " 继续");

}

public void setstopbuttonenable(boolean enable) {

btstop.setenabled(enable);

}

public void setturnlevelupbuttonenable(boolean enable) {

btturnlevelup.setenabled(enable);

}

public void setturnleveldownbuttonenable(boolean enable) {

btturnleveldown.setenabled(enable);

}

/**

* 重置控制面板

*/

public void reset() {

tfscore.settext(" 0");

pltipblock.setstyle(0);

}

/**

* 重新计算tippanel里的boxes[][]里的小框的大小

*/

public void adjust() {

pltipblock.adjust();

}

/**

* 预显窗口的实现细节类

*/

public class tippanel extends jpanel { //tippanel用来显示下一个将要出现方块的形状

private static final long serialversionuid = 5160553671436997616l;

private color backcolor = color.darkgray, frontcolor = color.white;

private ersbox[][] boxes = new ersbox[ersblock.boxes_rows][ersblock.boxes_cols];

private int style, boxwidth, boxheight;

private boolean istiled = false;

/**

* 预显示窗口类构造函数

*/

public tippanel() {

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

boxes[i][j] = new ersbox(false);

}

}

}

/**

* 设置预显示窗口的方块样式

*

* @param style int,对应ersblock类的styles中的28个值

*/

public void setstyle(int style) {

this.style = style;

repaint();

}

/**

* 覆盖jcomponent类的函数,画组件。

*

* @param g 图形设备环境

*/

@override

public void paintcomponent(graphics g) {

super.paintcomponent(g);

if (!istiled) {

adjust();

}

int key = 0x8000;

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

color color = ((key & style) != 0 ? frontcolor : backcolor);

g.setcolor(color);

g.fill3drect(j * boxwidth, i * boxheight,

boxwidth, boxheight, true);

key >>= 1;

}

}

}

/**

* g根据窗口的大小,自动调整方格的尺寸

*/

public void adjust() {

boxwidth = getsize().width / ersblock.boxes_cols;

boxheight = getsize().height / ersblock.boxes_rows;

istiled = true;

}

}

}

ersbox.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84
package russiablocksgame;

import java.awt.dimension;

/**

* 方格类,是组成块的基本元素,用自己的颜色来表示块的外观

*/

public class ersbox implements cloneable {

private boolean iscolor;

private dimension size = new dimension();

/**

* 方格类的构造函数,

*

* @param iscolor 是不是用前景色来为此方格着色 true前景色,false 用背景色

*/

public ersbox(boolean iscolor) {

this.iscolor = iscolor;

}

/**

* 此方格是不是用前景色表现

*

* @return boolean ,true用前景色表现,false 用背景色表现

*/

public boolean iscolorbox() {

return iscolor;

}

/**

* 设置方格的颜色,

*

* @param iscolor boolean ,true用前景色表现,false 用背景色表现

*/

public void setcolor(boolean iscolor) {

this.iscolor = iscolor;

}

/**

* 得到此方格的尺寸

*

* @return dimension ,方格的尺寸

*/

public dimension getsize() {

return size;

}

/**

* 设置方格的尺寸,

*

* @param size dimension ,方格的尺寸

*/

public void setsize(dimension size) {

this.size = size;

}

/**

* 覆盖object的object clone(),实现克隆

*

* @return object,克隆的结果

*/

@override

public object clone() {

object cloned = null;

try {

cloned = super.clone();

} catch (exception ex) {

ex.printstacktrace();

}

return cloned;

}

}

ersblock.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318
package russiablocksgame;

/**

* 块类,继承自线程类(thread) 由4 × 4个方块(ersbox)构成一个方块, 控制块的移动·下落·变形等

*/

class ersblock extends thread {

/**

* 一个块占的行数是4行

*/

public final static int boxes_rows = 4;

/**

* 一个块占的列数是4列

*/

public final static int boxes_cols = 4;

/**

* 让升级变化平滑的因子,避免最后几级之间的速度相差近一倍

*/

public final static int level_flatness_gene = 3;

/**

* 相近的两级之间,块每下落一行的时间差别为多少(毫秒)

*/

public final static int between_levels_degress_time = 50;

/**

* 方块的样式数目为7

*/

public final static int block_kind_number = 7;

/**

* 每一个样式的方块的反转状态种类为4

*/

public final static int block_status_number = 4;

/**

* 分别对应7种模型的28种状态

*/

public final static int[][] styles = { //共28种状态

{0x0f00, 0x4444, 0x0f00, 0x4444}, //长条型的四种状态

{0x04e0, 0x0464, 0x00e4, 0x04c4}, //t型的四种状态

{0x4620, 0x6c00, 0x4620, 0x6c00}, //反z型的四种状态

{0x2640, 0xc600, 0x2640, 0xc600}, //z型的四种状态

{0x6220, 0x1700, 0x2230, 0x0740}, //7型的四种状态

{0x6440, 0x0e20, 0x44c0, 0x8e00}, //反7型的四种状态

{0x0660, 0x0660, 0x0660, 0x0660}, //方块的四种状态

};

private gamecanvas canvas;

private ersbox[][] boxes = new ersbox[boxes_rows][boxes_cols];

private int style, y, x, level;

private boolean pausing = false, moving = true;

/**

* 构造函数,产生一个特定的块

*

* @param style 块的样式,对应styles的28个值中的一个

* @param y 起始位置,左上角在canvas中的坐标行

* @param x 起始位置,左上角在canvas中的坐标列

* @param level 游戏等级,控制块的下落速度

* @param canvas 画板

*/

public ersblock(int style, int y, int x, int level, gamecanvas canvas) {

this.style = style;

this.y = y;

this.x = x;

this.level = level;

this.canvas = canvas;

int key = 0x8000;

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

boolean iscolor = ((style & key) != 0);

boxes[i][j] = new ersbox(iscolor);

key >>= 1;

}

}

display();

}

/**

* 线程类的run()函数覆盖,下落块,直到块不能再下落

*/

@override

public void run() {

while (moving) {

try {

sleep(between_levels_degress_time

* (russiablocksgame.max_level - level + level_flatness_gene));

} catch (interruptedexception ie) {

ie.printstacktrace();

}

//后边的moving是表示在等待的100毫秒间,moving没有被改变

if (!pausing) {

moving = (moveto(y + 1, x) && moving);

}

}

}

/**

* 块向左移动一格

*/

public void moveleft() {

moveto(y, x - 1);

}

/**

* 块向右移动一格

*/

public void moveright() {

moveto(y, x + 1);

}

/**

* 块向下移动一格

*/

public void movedown() {

moveto(y + 1, x);

}

/**

* 块变型

*/

public void turnnext() {

for (int i = 0; i < block_kind_number; i++) {

for (int j = 0; j < block_status_number; j++) {

if (styles[i][j] == style) {

int newstyle = styles[i][(j + 1) % block_status_number];

turnto(newstyle);

return;

}

}

}

}

public void startmove() {

pausing = false;

moving = true;

}

/**

* 暂停块的下落,对应游戏暂停

*/

public void pausemove() {

pausing = true;

// moving = false;

}

/**

* 继续块的下落,对应游戏继续

*/

public void resumemove() {

pausing = false;

moving = true;

}

/**

* 停止块的下落,对应游戏停止

*/

public void stopmove() {

pausing = false;

moving = false;

}

/**

* 将当前块从画布的对应位置移除,要等到下次重画画布时才能反映出来

*/

private void erase() {

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

if (boxes[i][j].iscolorbox()) {

ersbox box = canvas.getbox(i + y, j + x);

if (box == null) {

continue;

}

box.setcolor(false);

}

}

}

}

/**

* 让当前块放置在画布的对因位置上,要等到下次重画画布时才能看见

*/

private void display() {

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

if (boxes[i][j].iscolorbox()) {

ersbox box = canvas.getbox(i + y, j + x);

if (box == null) {

continue;

}

box.setcolor(true);

}

}

}

}

/**

* 当前块能否移动到newrow/newcol 所指定的位置

*

* @param newrow int,目的地所在行

* @param newcol int,目的地所在列

* @return boolean,true-能移动,false-不能移动

*/

public boolean ismoveable(int newrow, int newcol) {

erase();

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

if (boxes[i][j].iscolorbox()) {

ersbox box = canvas.getbox(i + newrow, j + newcol);

if (box == null || (box.iscolorbox())) {

display();

return false;

}

}

}

}

display();

return true;

}

/**

* 将当前块移动到newrow/newcol 所指定的位置

*

* @param newrow int,目的地所在行

* @param newcol int,目的地所在列

* @return boolean,true-移动成功,false-移动失败

*/

private synchronized boolean moveto(int newrow, int newcol) {

if (!ismoveable(newrow, newcol) || !moving) {

return false;

}

erase();

y = newrow;

x = newcol;

display();

canvas.repaint();

return true;

}

/**

* 当前块能否变成newstyle所指定的块样式,主要是考虑 边界以及被其他块挡住,不能移动的情况

*

* @param newsytle int,希望改变的块样式,对应styles的28个值中的一个

* @return boolean,true-能改变,false-不能改变

*/

private boolean isturnable(int newstyle) {

int key = 0x8000;

erase();

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

if ((newstyle & key) != 0) {

ersbox box = canvas.getbox(i + y, j + x);

if (box == null || (box.iscolorbox())) {

display();

return false;

}

}

key >>= 1;

}

}

display();

return true;

}

/**

* 将当前块变成newstyle所指定的块样式

*

* @param newstyle int,希望改变的块样式,对应styles的28个值中的一个

* @return true-改变成功,false-改变失败

*/

private boolean turnto(int newstyle) {

if (!isturnable(newstyle) || !moving) {

return false;

}

erase();

int key = 0x8000;

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

boolean iscolor = ((newstyle & key) != 0);

boxes[i][j].setcolor(iscolor);

key >>= 1;

}

}

style = newstyle;

display();

canvas.repaint();

return true;

}

}

main.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13
package russiablocksgame;

/**

* 程序入口函数

*

* @param args string[],附带的命令行参数

*/

public class main {

public static void main(string[] args) {

new russiablocksgame("俄罗斯方块:杨宇杰");

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

原文链接:https://blog.csdn.net/OnlyLove_KD/article/details/53813612

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 java实现俄罗斯方块小程序 https://www.kuaiidc.com/111288.html

相关文章

发表评论
暂无评论