Java俄罗斯方块小游戏

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

代码:

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

 }

}

运行界面:

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

(0)

相关推荐

  • Java 小游戏开发之俄罗斯方块

    Java项目 俄罗斯方块 一.心得 二.游戏实例 游戏截图 目录结构 三.代码 1.主界面 Tetris.java package com.fry.tetris; import java.util.Arrays; import java.util.Random; /** * 4格方块 */ public class Tetromino { protected Cell[] cells = new Cell[4]; /** 保存旋转的相对于轴位置状态 */ protected State[] st

  • Java游戏俄罗斯方块的实现实例

    Java游戏俄罗斯方块的实现实例 java小游戏主要理解应用java Swing,awt等基础组件的知识,通过本例应当掌握面向对象的知识. 实现代码: package cn.hncu.games; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import

  • Java俄罗斯方块小游戏

    去年就已经学了这个技术了,一直没去写,现在抽个时间写了个俄罗斯方块游戏. 只有简单的新游戏,暂停,继续,积分功能.简单的实现了俄罗斯的经典功能. 不介绍了,有兴趣的自己运行一下,后面贴出了图片. 代码: package cn.hncu; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.Act

  • Java实现俄罗斯方块小游戏源码

    本文实例为大家分享了Java实现俄罗斯方块小游戏的具体代码,供大家参考,具体内容如下 一.最终效果 二.功能需求 1. 在二维平面里面用各种随机产生的方块堆积木,每满一行消去一行,当达到顶部时,游戏结束.2. 通过方向键来控制方块转动,左移,右移和直落.3. 方块下落统一设置蓝色,接触底部变粉色.4. 计算分数,分数是由方块的类型决定的,每堆积一个方块就把分数累加到总分中.5. 游戏有开始.重新开始.降低提高级数(速度).暂停.退出 三.程序实现 这个是最基础的方块素材 package 俄罗斯方

  • python实现俄罗斯方块小游戏

    回顾我们的python制作小游戏之路,几篇非常精彩的文章 我们用python实现了坦克大战 python制作坦克大战 我们用python实现了飞船大战 python制作飞船大战 我们用python实现了两种不同的贪吃蛇游戏 200行python代码实现贪吃蛇游戏 150行代码实现贪吃蛇游戏 我们用python实现了扫雷游戏 python实现扫雷游戏 我们用python实现了五子棋游戏 python实现五子棋游戏 今天我们用python来实现小时候玩过的俄罗斯方块游戏吧 具体代码与文件可以访问我的

  • Java太阳系小游戏分析和源码详解

    最近看了面向对象的一些知识,然后跟着老师的讲解做了一个太阳系各行星绕太阳转的小游戏,来练习巩固一下最近学的知识: 用到知识点:类的继承.方法的重载与重写.多态.封装等 分析: 1.需要加载图片.画图 2.建一个面板,主页面 3.行星类 效果图: 先看一下源码结构图: 现在逐步分析各个类的功能: 1)工具类-----util包中 --Constant类   封装了游戏中用到的常量 --GameUtil类  封装了游戏的图片加载功能 --MyFrame类  封装了游戏面板的构造,用于各面板的父类 -

  • C语言实现俄罗斯方块小游戏

    C语言实现俄罗斯方块小游戏的制作代码,具体内容如下 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define TTY_PATH "/dev/tty" #define STTY_ON "stty raw -echo -F" #define STTY_OFF "stty -raw echo -F" int map[21][14]; char

  • java桌球小游戏 小球任意角度碰撞

    本文实例为大家分享了java桌球小游戏的具体代码,供大家参考,具体内容如下 import javax.swing.*; import java.awt.*; public class BallGame extends JFrame { /** *继承swing里面的窗口类 */ //加载图片 Image ball = Toolkit.getDefaultToolkit().getImage("images/ball.jpg.png");/*得到系统默认的工具包*/ Image desk

  • pygame库实现俄罗斯方块小游戏

    本文实例为大家分享了pygame库实现俄罗斯方块小游戏的具体代码,供大家参考,具体内容如下 import random,time,pygame,sys from pygame.locals import *#导pygame内定义的一些常量 FPS=25#每秒传输帧数(刷新率),此处一秒内在屏幕上连续投射出24张静止画面 WINDOWWIDTH=640#窗口宽 WINDOWHEIGHT=480#窗口高 BOXSIZE=20#游戏框大小 BOARDWIDTH=10#游戏框宽度 BOARDHEIGHT

  • java弹幕小游戏1.0版本

    java 弹幕小游戏的最初版本,供大家参考,具体内容如下 最近在学习javaSE,根据b站视频老师的讲解,也参考了他的代码,做了一个弹幕小游戏,也增添了一些自己的代码进去,因为只是最简单的游戏体,以后会慢慢做完整,所以如果有错误,或者代码不够整洁的话,可以帮我改正,谢谢啦. 父类 import java.awt.*; public class GameObject { //游戏物体的父类 Image img; double x,y; int speed = 3; int width,height

  • java简易小游戏制作代码

    java简易小游戏制作 游戏思路:设置人物移动,游戏规则,积分系统,随机移动的怪物,游戏胜负判定,定时器. 游戏内容部分 package 代码部分; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyList

  • C++实现俄罗斯方块小游戏

    本文实例为大家分享了C++实现俄罗斯方块小游戏的具体代码,供大家参考,具体内容如下 操作说明: D F:左右旋转 J  L:左右移动 E(一堆键都行): 加快下落速度 空格: 开始游戏 与 一落到底 上代码! #include <cstdio> #include <cstdlib> #include <cstring> #include <windows.h> #include <ctime> #include <conio.h> #

随机推荐