去年就已经学了这个技术了,一直没去写,现在抽个时间写了个俄罗斯方块游戏。

只有简单的新游戏,暂停,继续,积分功能。简单的实现了俄罗斯的经典功能。

不介绍了,有兴趣的自己运行一下,后面贴出了图片。

代码:

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---俄罗斯方块小游戏的更多相关文章

  1. C#俄罗斯方块小游戏程序设计与简单实现

    C#俄罗斯方块小游戏程序设计与简单实现 相信90后或者80后都玩过这款小游戏,一直想干一票,琢磨一下,但又不太懂,于是网上搜集修改就有了以下效果!bug较多,多多包涵! 1.效果展示 2.实现方法 参 ...

  2. Java太阳系小游戏分析和源代码

    Java太阳系小游戏分析和源代码 -20150809 近期看了面向对象的一些知识.然后跟着老师的解说做了一个太阳系各行星绕太阳转的小游戏,来练习巩固一下近期学的知识: 用到知识点:类的继承.方法的重载 ...

  3. Java五子棋小游戏(控制台纯Ai算法)

    Java五子棋小游戏(控制台纯Ai算法) 继续之前的那个五子棋程序 修复了一些已知的小Bug 这里是之前的五子棋程序 原文链接 修复了一些算法缺陷 本次增加了AI算法 可以人机对战 也可以Ai对Ai看 ...

  4. js实现简单的俄罗斯方块小游戏

    js实现简单的俄罗斯方块小游戏 开始 1. 创建一个宽为 200px,高为 360px 的背景容器 <!DOCTYPE html> <html lang="en" ...

  5. Java猜拳小游戏(剪刀、石头、布)

    1.第一种实现方法,调用Random数据包,直接根据“1.2.3”输出“剪刀.石头.布”.主要用了9条输出判断语句. import java.util.Random; import java.util ...

  6. 从零开始学java(小游戏 石头剪刀布)

    Game.java package com.java;import java.util.Scanner;public class Game {        private Player player ...

  7. Java石头剪刀布小游戏

    package com.neusoft.test; import java.awt.BorderLayout; import java.awt.Choice; import java.awt.Colo ...

  8. Java开发小游戏 用键盘控制精灵在游戏中上下左右跑动 窗体小游戏可打包下载,解压后双击start运行

    package com.swift; import java.awt.Point; import java.awt.event.KeyEvent; import com.rupeng.game.Gam ...

  9. Java经典小游戏——贪吃蛇简单实现(附源码)

    一.使用知识 Jframe GUI 双向链表 线程 二.使用工具 IntelliJ IDEA jdk 1.8 三.开发过程 3.1素材准备 首先在开发之前应该准备一些素材,已备用,我主要找了一个图片以 ...

  10. Java 坦克小游戏心得

    原本是闲得慌无聊才去尝试做这个项目的,因为小时候玩小霸王的游戏机,那个时候经常玩这个游戏吧,特别是喜欢那种自定义地图的模式,觉得自由度非常不错.总之关于这个游戏,想说的一大堆.鉴于能有个空闲的时间,打 ...

随机推荐

  1. Leaflet交流

    GIS科研网 Leaflet交流 谢绝转载 http://www.3sbase.com欢迎加群交流  108299288 http://www.3sbase.com/3sbase/webgistest ...

  2. java对象初始化顺序的简单验证

    以下这段小程序对调用对象构造函数时,父类构造函数.成员变量初始化函数,以及非静态初始化块调用顺序进行验证,不考虑静态成员及静态初始化块. public class Derive extends Bas ...

  3. SVG

    目前SVG在国内的使用并不常见,并且关于svg的相关js库也不多,这里指出两款svg的库Snap.svg和svg.js,Snap.svg张鑫旭的博客上有关于他的使用APi http://www.zha ...

  4. PHP 读json文件并转php配置文件

    <?php$c = file_get_contents('./cities_v2.json');$s = "<?php return " . var_export(js ...

  5. java 各种排序算法

    各种排序算法的分析及java实现   排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强能写出个冒泡排序.由于下半年要准备工作了,也知道排序算法的重要性(据说 ...

  6. hadoop2.610集群配置(包含HA和Hbase )

    .修改Linux主机名2.修改IP3.修改主机名和IP的映射关系######注意######如果你们公司是租用的服务器或是使用的云主机(如华为用主机.阿里云主机等)/etc/hosts里面要配置的是内 ...

  7. Linux文件3个时间点(access time,modify time,change time)

    在Linux中使用stat命令来查看文件的详细信息. 如图所示,会出现3个类型的时间,分别是Access,Modify,Change. access time:表示最后一次访问(仅仅是访问,没有改动) ...

  8. C++ 11 笔记 (六) : 随机数

    以前生成一个随机数都是这样: srand(time(NULL)); rand(); 在C++11中,标准库中增加了随机数引擎 std::default_random_engine 这个好东西,然后我们 ...

  9. Spring之Spring MVC

    Spring调配半天没搞定,原来是web.xml应该放在WEB-INF的目录下,而不是webcontent目录下: java.lang.ClassNotFoundException: org.spri ...

  10. 被windows“折磨”了一个礼拜

    说是被windows折磨了一个礼拜,这话一点都不假!由于想彻底的卸载SQL Server而误删系统文件,导致系统重启之后持续蓝屏.无奈之下只能重装系统(心想,加入当初自己将系统备份的话,那该是多美好的 ...