Java---俄罗斯方块小游戏

举报
谙忆 发表于 2021/05/27 00:20:36 2021/05/27
【摘要】 去年就已经学了这个技术了,一直没去写,现在抽个时间写了个俄罗斯方块游戏。 只有简单的新游戏,暂停,继续,积分功能。简单的实现了俄罗斯的经典功能。 不介绍了,有兴趣的自己运行一下,后面贴出了图片。 代码: package cn.hncu; import java.awt.Color; import java.awt.Font; import java.awt.G...

去年就已经学了这个技术了,一直没去写,现在抽个时间写了个俄罗斯方块游戏。
只有简单的新游戏,暂停,继续,积分功能。简单的实现了俄罗斯的经典功能。
不介绍了,有兴趣的自己运行一下,后面贴出了图片。

代码:

package cn.hncu;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Tetris extends JFrame{ public static void main(String[] args) { Tetris te = new Tetris(); te.setVisible(true); //如果在界面中添加了编辑框等会抢占焦点的控件,则需要用下面的代码 //te.requestFocus(true);//让游戏面板获得焦点--抢到键盘的监听 } private TetrisPanel tp; JMenuItem itemPause; JMenuItem itemContinue; public Tetris() { this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setLocation(700, 200); this.setSize(220, 275); this.setResizable(false); tp = new TetrisPanel(); this.getContentPane().add(tp); //添加菜单 JMenuBar menubar = new JMenuBar(); this.setJMenuBar(menubar); JMenu menuGame = new JMenu("游戏"); menubar.add(menuGame); JMenuItem itemNew = new JMenuItem("新游戏"); itemNew.setActionCommand("new"); itemPause = new JMenuItem("暂停"); itemPause.setActionCommand("pause"); itemContinue = new JMenuItem("继续"); itemContinue.setActionCommand("continue"); itemContinue.setEnabled(false); menuGame.add(itemNew); menuGame.add(itemPause); menuGame.add(itemContinue); MenuListener menuListener = new MenuListener(); itemNew.addActionListener(menuListener); itemPause.addActionListener(menuListener); itemContinue.addActionListener(menuListener); //让整个JFrame添加键盘监听 this.addKeyListener( tp.listener ); } class MenuListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { //玩新游戏 if(e.getActionCommand().equals("new")){ tp.newGame(); } if(e.getActionCommand().equals("pause")){ timer.stop(); itemContinue.setEnabled(true); itemPause.setEnabled(false); } if(e.getActionCommand().equals("continue")){ timer.restart(); itemContinue.setEnabled(false); itemPause.setEnabled(true); } } } private Timer timer; class TetrisPanel extends JPanel{ // 方块的形状: // 第一维代表方块类型(包括7种:S、Z、L、J、I、O、T) // 第二维代表旋转次数 // 第三四维代表方块矩阵 // shapes[type][turnState][i] i--> block[i/4][i%4] int shapes[][][] = new int[][][] { /* * 模板 { {0,0,0,0,0,0,0,0, 0,0,0,0, 0,0,0,0}, {0,0,0,0,0,0,0,0, 0,0,0,0, * 0,0,0,0}, {0,0,0,0,0,0,0,0, 0,0,0,0, 0,0,0,0}, {0,0,0,0,0,0,0,0, * 0,0,0,0, 0,0,0,0} } */ // I (※把版本1中的横条从第1行换到第2行) { { 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 } }, // S { { 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, 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 } }, // 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, 0, 0, 0, 1, 1, 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, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // O { { 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 } }, // L { { 1, 0, 0, 0, 1, 0, 0, 0, 1, 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, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // 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 } } }; private int blockType;//方块类型 private int turnState;//旋转状态 private int x;//方块的位置x--列的位置--列号 private int y;//方块的位置y--行的位置--行号 private int map[][]=new int[13][23];//地图:12列22行。为防止越界,数组开成:13列23行 private int delay=1000; public TimerKeyLister listener=new TimerKeyLister(); private int score=0;//分数 public TetrisPanel(){ newGame(); nextBlock(); //timer = new Timer(delay,listener); //timer.start(); } public void newGame() { blockType = (int)(Math.random()*1000)%7; turnState = (int)(Math.random()*1000)%4; x=4; y=0; for( int i=0;i<12;i++){//走列 for(int j=0;j<21;j++){//走行 if(i==0 || i==11){//3为界面边框的格 map[i][j]=3;//按理只要用0和1以外的整数就可以,但这里用3有特殊作用--后面用 }else{ map[i][j]=0; } } map[i][21]=3;//3为界面边框的格 } if(timer!=null){ timer.stop(); } delay=1000; timer = new Timer(delay,listener); timer.start(); } private void nextBlock() { blockType = (int)(Math.random()*1000)%7; turnState = (int)(Math.random()*1000)%4; x=4; y=0; //game Over if(crash(x,y,blockType,turnState)==0){ timer.stop(); int option = JOptionPane.showConfirmDialog(this, "Game Over!!,还敢来吗..."); if (option == JOptionPane.OK_OPTION) { newGame(); } else if (option == JOptionPane.NO_OPTION) { System.exit(0); } } } private void down() { if( crash(x,y+1,blockType,turnState)==0 ){//注意,这里用y+1,是判断块往下掉一格后,map中对应位置是否为堆积块或框架 add(x,y,blockType,turnState);//把当前方块的信息保存到地图 nextBlock(); }else{ y++; } repaint(); } private void left() { if(x>=0){ x -= crash(x-1,y,blockType,turnState); } repaint(); } private void right() { if(x<8){ x += crash(x+1,y,blockType,turnState); } repaint(); } private void turn() { if(crash(x,y,blockType,(turnState+1)%4)==1 ){ turnState = (turnState+1)%4; } repaint(); } private void add(int x, int y, int blockType, int turnState) { for( int a=0; a<4; a++){ for(int b=0; b<4; b++){ if( shapes[blockType][turnState][a*4+b] ==1 ){ map[x+b+1][y+a] = 1; } } } tryDelLine(); } //消行 private void tryDelLine(){ for(int b=0;b<21;b++){ int c=1; for(int a=0;a<12;a++){ c &= map[a][b];//全部是1,c的结果才是1 } if(c==1){//有一行需要消 //依次往下移动一行 for(int d=b; d>0; d--){ for(int e=0;e<11;e++){ map[e][d] = map[e][d-1]; } } //加分 score +=100; delay /=1.05; timer.setDelay(delay); } } } //参数例子: 4,3,2,3 //判断有无碰撞 private int crash(int x, int y, int blockType, int turnState){ for( int a=0; a<4; a++){ for(int b=0; b<4; b++){
// if( (shapes[blockType][turnState][a*4+b]==1 && map[x+b+1][y+a] ==1) ||
// (shapes[blockType][turnState][a*4+b]==1 && map[x+b+1][y+a] ==3 ) ){
// } if( (shapes[blockType][turnState][a*4+b] & map[x+b+1][y+a]) ==1 ){ return 0;//碰撞 } } } return 1;//没有碰撞 } @Override public void paint(Graphics g) {
// blockType =6;
// turnState = 3;
// x=4;
// y=6; super.paint(g);//消除残影 g.setColor(new Color(153,51,205)); //画当前方块 for(int j=0;j<16;j++){ if(shapes[blockType][turnState][j]==1){ g.fillRect((j%4+x+1)*10, (j/4+y)*10, 10, 10); g.setColor(Color.cyan); g.drawRect((j%4+x+1)*10, (j/4+y)*10, 10, 10); g.setColor(new Color(153,51,205)); } } //画界面框架 以及 堆积块---整个地图 g.setColor(Color.red); for( int i=0;i<12;i++){//走列 for(int j=0;j<22;j++){//走行 if(map[i][j]==3){ g.drawRect(i*10, j*10, 10, 10); }else if(map[i][j]==1){ g.fillRect(i*10, j*10, 10, 10); g.setColor(Color.GREEN); g.drawRect(i*10, j*10, 10, 10); g.setColor(Color.red); } } } //显示分数,同时为版面美观,在界面上再加点东西 // 画方块区右侧部分 g.setColor(Color.red); g.setFont(new Font("aa", Font.BOLD, 11)); g.drawString("score=" + score, 130, 20); g.setFont(new Font("aa", Font.PLAIN, 13)); g.setColor(Color.blue); g.drawString("拒绝盗版游戏,", 125, 70); g.drawString("注意自我保护。", 125, 90); g.drawString("谨防受骗上当。", 125, 110); g.drawString("适度游戏益脑,", 125, 130); g.drawString("沉迷游戏伤身。", 125, 150); g.drawString("合理安排时间,", 125, 170); g.drawString("享受健康生活。", 125, 190); } class TimerKeyLister extends KeyAdapter implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { down(); } @Override public void keyPressed(KeyEvent e) { switch(e.getKeyCode()){ case KeyEvent.VK_DOWN: down(); break; case KeyEvent.VK_LEFT: left();break; case KeyEvent.VK_RIGHT: right();break; case KeyEvent.VK_UP: turn();break; case KeyEvent.VK_F1: plug(); case KeyEvent.VK_F2: time(); } } } public void plug() { score+=100; } public void time() { delay =1000; timer.setDelay(delay); } }


}

  
 
  • 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

运行界面:

文章来源: chenhx.blog.csdn.net,作者:谙忆,版权归原作者所有,如需转载,请联系作者。

原文链接:chenhx.blog.csdn.net/article/details/51636654

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。