java代码实现俄罗斯方块

2025-05-29 0 31

本文实例为大家分享了java实现俄罗斯方块的具体代码,供大家参考,具体内容如下

俄罗斯方块设计思想

俄罗斯方块都从小玩到大吧,什么规则大家都知道了吧,以前感觉那玩意贼好玩,但是就是老赢不了,现在学会了自己写一个天天练!

键盘操作:

左键:左移; 右键:右移;
上键:变换造型 下键:加速下掉(没毛病吧,没有继续整)

任意一行的方块满格,这一行就消除,消除一行方块得10分,目前小主我还没有设置关卡,各位喜欢的宝宝们可以自己设置关卡哦;

那么那些方块的造型到底从哪里来的呢,那就是我们自己设计的,常见的几种造型就是:i型,t型,l型,田字格型等等吧,自己个加呗!
那么到底咋整的咧?其实啊就是一个4*4的数组,当然了你开心设计n*n也可以,你牛皮你说了算!
那么下面举了一个例子,用来告诉你们为啥你们看见的造型可以变换的原因就是这样提前设计好,0为空,1为填充格,这样你就可以在你的游戏里面凹造型了!

java代码实现俄罗斯方块

算了:直接放图先看代码运行结果吧:

java代码实现俄罗斯方块

喜欢吗?喜欢就直接做吧,可能代码写的不够好,请各位大神多多包涵,我回头也会多总结,会不断更新代码的;

gamepanel类:游戏界面类,整个方块掉落和显示,游戏的逻辑斯洛都在这个类里面实现;

?

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
package tetris;

import java.awt.graphics;

import java.awt.event.actionevent;

import java.awt.event.actionlistener;

import java.awt.event.keyevent;

import java.awt.event.keylistener;

import java.util.random;

import javax.swing.joptionpane;

import javax.swing.jpanel;

import javax.swing.timer;

public class gamepanel extends jpanel implements keylistener{

private int maprow = 21;

private int mapcol = 12;

private int mapgame[][] = new int[maprow][mapcol];//开辟一个二维数组空间,用来存放我们的地图信息

private timer timer;

private int score = 0;//记录成绩

random random = new random();

private int curshapetype = -1;

private int curshapestate = -1;//设置当前的形状类型和当前的形状状态

private int nextshapetype = -1;

private int nextshapestate = -1;//设置下一次出现的方块组的类型和状态

private int posx = 0;

private int posy = 0;

private final int shapes[][][] = new int[][][]{

//t字形按逆时针的顺序存储

{

{0,1,0,0, 1,1,1,0, 0,0,0,0, 0,0,0,0},

{0,1,0,0, 1,1,0,0, 0,1,0,0, 0,0,0,0},

{1,1,1,0, 0,1,0,0, 0,0,0,0, 0,0,0,0},

{0,1,0,0, 0,1,1,0, 0,1,0,0, 0,0,0,0}

},

//i字形按逆时针的顺序存储

{

{0,0,0,0, 1,1,1,1, 0,0,0,0, 0,0,0,0},

{0,1,0,0, 0,1,0,0, 0,1,0,0, 0,1,0,0},

{0,0,0,0, 1,1,1,1, 0,0,0,0, 0,0,0,0},

{0,1,0,0, 0,1,0,0, 0,1,0,0, 0,1,0,0}

},

//倒z形按逆时针的顺序存储

{

{0,1,1,0, 1,1,0,0, 0,0,0,0, 0,0,0,0},

{1,0,0,0, 1,1,0,0, 0,1,0,0, 0,0,0,0},

{0,1,1,0, 1,1,0,0, 0,0,0,0, 0,0,0,0},

{1,0,0,0, 1,1,0,0, 0,1,0,0, 0,0,0,0}

},

//z形按逆时针的顺序存储

{

{1,1,0,0, 0,1,1,0, 0,0,0,0, 0,0,0,0},

{0,1,0,0, 1,1,0,0, 1,0,0,0, 0,0,0,0},

{1,1,0,0, 0,1,1,0, 0,0,0,0, 0,0,0,0},

{0,1,0,0, 1,1,0,0, 1,0,0,0, 0,0,0,0}

},

//j字形按逆时针的顺序存储

{

{0,1,0,0, 0,1,0,0, 1,1,0,0, 0,0,0,0},

{1,1,1,0, 0,0,1,0, 0,0,0,0, 0,0,0,0},

{1,1,0,0, 1,0,0,0, 1,0,0,0, 0,0,0,0},

{1,0,0,0, 1,1,1,0, 0,0,0,0, 0,0,0,0}

},

//l字形按逆时针的顺序存储

{

{1,0,0,0, 1,0,0,0, 1,1,0,0, 0,0,0,0},

{0,0,1,0, 1,1,1,0, 0,0,0,0, 0,0,0,0},

{1,1,0,0, 0,1,0,0, 0,1,0,0, 0,0,0,0},

{1,1,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0}

},

//田字形按逆时针的顺序存储

{

{1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0},

{1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0},

{1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0},

{1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0}

}

};

private int rowrect = 4;

private int colrect = 4;//这里我们把存储的图像看成是一个4*4的二维数组,虽然在上面我们采用一维数组来存储,但实际还是要看成二维数组来实现

private int rectwidth = 10;

public gamepanel()//构造函数----创建好地图

{

createrect();

initmap();//初始化这个地图

setwall();//设置墙

// createrect();

timer = new timer(500,new timerlistener());

timer.start();

}

class timerlistener implements actionlistener{

public void actionperformed(actionevent e)

{

movedown();

}

}

public void setwall()//第0列和第11列都是墙,第20行也是墙

{

for(int i = 0; i < maprow; i++)//先画列

{

mapgame[i][0] = 2;

mapgame[i][11] = 2;

}

for(int j = 1; j < mapcol-1; j++)//画最后一行

{

mapgame[20][j] = 2;

}

}

public void initmap()//初始化这个地图,墙的id是2,空格的id是0,方块的id是1

{

for(int i = 0; i < maprow; i++)

{

for(int j = 0; j < mapcol; j++)

{

mapgame[i][j] = 0;

}

}

}

public void createrect()//创建方块---如果当前的方块类型和状态都存在就设置下一次的,如果不存在就设置当前的并且设置下一次的状态和类型

{

if(curshapetype == -1 && curshapestate == -1)//当前的方块状态都为1,表示游戏才开始

{

curshapetype = random.nextint(shapes.length);

curshapestate = random.nextint(shapes[0].length);

}

else

{

curshapetype = nextshapetype;

curshapestate = nextshapestate;

}

nextshapetype = random.nextint(shapes.length);

nextshapestate = random.nextint(shapes[0].length);

posx = 0;

posy = 1;//墙的左上角创建方块

if(gameover(posx,posy,curshapetype,curshapestate))

{

joptionpane.showconfirmdialog(null, "游戏结束!", "提示", joptionpane.ok_option);

system.exit(0);

}

}

public boolean gameover(int x, int y, int shapetype, int shapestate)//判断游戏是否结束

{

if(isornomove(x,y,shapetype,shapestate))

{

return false;

}

return true;

}

public boolean isornomove(int x, int y, int shapetype, int shapestate)//判断当前的这个图形是否可以移动,这里重点强调x,y的坐标是指4*4的二维数组(描述图形的那个数组)的左上角目标

{

for(int i = 0; i < rowrect ; i++)

{

for(int j = 0; j < colrect; j++)

{

if(shapes[shapetype][shapestate][i*colrect+j] == 1 && mapgame[x+i][y+j] == 1

|| shapes[shapetype][shapestate][i*colrect+j] == 1 && mapgame[x+i][y+j] == 2)

{

return false;

}

}

}

return true;

}

public void turn()//旋转

{

int temp = curshapestate;

curshapestate = (curshapestate+1) % shapes[0].length;

if(isornomove(posx,posy,curshapetype,curshapestate))

{

}

else

{

curshapestate = temp;

}

repaint();

}

public void movedown()//向下移动

{

if(isornomove(posx+1,posy,curshapetype,curshapestate))

{

posx++;

}

else

{

addtomap();//将此行固定在地图中

checkline();

createrect();//重新创建一个新的方块

}

repaint();

}

public void moveleft()//向左移动

{

if(isornomove(posx,posy-1,curshapetype,curshapestate))

{

posy--;

}

repaint();

}

public void moveright()//向右移动

{

if(isornomove(posx,posy+1,curshapetype,curshapestate))

{

posy++;

}

repaint();

}

public void addtomap()//固定掉下来的这一图像到地图中

{

for(int i = 0; i < rowrect; i++)

{

for(int j = 0; j < colrect; j++)

{

if(shapes[curshapetype][curshapestate][i*colrect+j] == 1)

{

mapgame[posx+i][posy+j] = shapes[curshapetype][curshapestate][i*colrect+j];

}

}

}

}

public void checkline()//检查一下这些行中是否有满行的

{

int count = 0;

for(int i = maprow-2; i >= 0; i--)

{

count = 0;

for(int j = 1; j < mapcol-1; j++)

{

if(mapgame[i][j] == 1)

{

count++;

}

else

break;

}

if(count >= mapcol-2)

{

for(int k = i; k > 0; k--)

{

for(int p = 1; p < mapcol-1; p++)

{

mapgame[k][p] = mapgame[k-1][p];

}

}

score += 10;

i++;

}

}

}

public void paint(graphics g)//重新绘制窗口

{

super.paint(g);

for(int i = 0; i < rowrect; i++)//绘制正在下落的方块

{

for(int j = 0; j < colrect; j++)

{

if(shapes[curshapetype][curshapestate][i*colrect+j] == 1)

{

g.fillrect((posy+j+1)*rectwidth, (posx+i+1)*rectwidth, rectwidth, rectwidth);

}

}

}

for(int i = 0; i < maprow; i++)//绘制地图上面已经固定好的方块信息

{

for(int j = 0; j < mapcol; j++)

{

if(mapgame[i][j] == 2)//画墙

{

g.drawrect((j+1)*rectwidth, (i+1)*rectwidth, rectwidth, rectwidth);

}

if(mapgame[i][j] == 1)//画小方格

{

g.fillrect((j+1)*rectwidth, (i+1)*rectwidth, rectwidth, rectwidth);

}

}

}

g.drawstring("score = "+ score, 225, 15);

g.drawstring("下一个方块:", 225, 50);

for(int i = 0; i < rowrect; i++)

{

for(int j = 0; j < colrect; j++)

{

if(shapes[nextshapetype][nextshapestate][i*colrect+j] == 1)

{

g.fillrect(225+(j*rectwidth), 100+(i*rectwidth), rectwidth, rectwidth);

}

}

}

}

public void newgame()//游戏重新开始

{

score = 0;

initmap();

setwall();

createrect();

repaint();

}

public void stopgame()//游戏暂停

{

timer.stop();

}

public void continuegame()

{

timer.start();

}

@override

public void keytyped(keyevent e) {

}

@override

public void keypressed(keyevent e) {

switch(e.getkeycode())

{

case keyevent.vk_up://上----旋转

turn();

break;

case keyevent.vk_down://下----向下移动

movedown();

break;

case keyevent.vk_left://左----向左移动

moveleft();

break;

case keyevent.vk_right://右----向右移动

moveright();

break;

}

}

@override

public void keyreleased(keyevent e) {

// todo auto-generated method stub

}

}

gameframe类:整个游戏的进入口,好吧,说白了就是有main()函数的类,这个类里面实现游戏界面的一些设计,你可以理解为一个小小小小的ui;

?

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
package tetris;

import java.awt.event.actionevent;

import java.awt.event.actionlistener;

import javax.swing.jframe;

import javax.swing.jmenu;

import javax.swing.jmenubar;

import javax.swing.jmenuitem;

import javax.swing.joptionpane;

public class gameframe extends jframe implements actionlistener{

private int widthframe = 500;

private int heightframe = 600;

private jmenu menuone = new jmenu("游戏");//创建一个菜单

private jmenuitem newgame = menuone.add("重新开始");//创建一个内置菜单选项

private jmenuitem exitgame = menuone.add("游戏退出");

private jmenuitem stopgame = menuone.add("游戏暂停");

private jmenuitem goongame = menuone.add("游戏继续");

private jmenu menutwo = new jmenu("帮助");//创建第二个菜单

private jmenuitem aboutgame = menutwo.add("关于游戏");

gamepanel gamepanel = new gamepanel();

public gameframe()//构造函数

{

addkeylistener(gamepanel);

newgame.addactionlistener(this);

exitgame.addactionlistener(this);

stopgame.addactionlistener(this);

goongame.addactionlistener(this);

aboutgame.addactionlistener(this);

this.add(gamepanel);

jmenubar menu = new jmenubar();

menu.add(menuone);

menu.add(menutwo);

this.setjmenubar(menu);

this.settitle("俄罗斯方块");

this.setbounds(50, 10, widthframe, heightframe);

this.setvisible(true);

this.setdefaultcloseoperation(jframe.exit_on_close);

}

public void actionperformed(actionevent e)

{

if(e.getsource() == newgame)//游戏重新开始

{

gamepanel.newgame();

}

if(e.getsource() == exitgame)//游戏退出

{

system.exit(0);

}

if(e.getsource() == stopgame)//游戏暂停

{

gamepanel.stopgame();

}

if(e.getsource() == goongame)//游戏继续

{

gamepanel.continuegame();

}

if(e.getsource() == aboutgame)//关于游戏信息

{

joptionpane.showmessagedialog(null, "左右键移动,向上建旋转", "提示", joptionpane.ok_option);

}

}

public static void main(string[] args) {

new gameframe();

}

}

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

原文链接:https://blog.csdn.net/angry_youth/article/details/74619096

收藏 (0) 打赏

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

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

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

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

相关文章

发表评论
暂无评论