欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java俄罗斯方块小游戏

程序员文章站 2024-03-13 20:02:51
去年就已经学了这个技术了,一直没去写,现在抽个时间写了个俄罗斯方块游戏。 只有简单的新游戏,暂停,继续,积分功能。简单的实现了俄罗斯的经典功能。 不介绍了,有兴趣的...

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

代码:

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);
 }

 }


}

运行界面:

Java俄罗斯方块小游戏

Java俄罗斯方块小游戏

更多精彩游戏,请参考专题《java经典小游戏》

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