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);
}
}
}
运行界面:
Java---俄罗斯方块小游戏的更多相关文章
- C#俄罗斯方块小游戏程序设计与简单实现
C#俄罗斯方块小游戏程序设计与简单实现 相信90后或者80后都玩过这款小游戏,一直想干一票,琢磨一下,但又不太懂,于是网上搜集修改就有了以下效果!bug较多,多多包涵! 1.效果展示 2.实现方法 参 ...
- Java太阳系小游戏分析和源代码
Java太阳系小游戏分析和源代码 -20150809 近期看了面向对象的一些知识.然后跟着老师的解说做了一个太阳系各行星绕太阳转的小游戏,来练习巩固一下近期学的知识: 用到知识点:类的继承.方法的重载 ...
- Java五子棋小游戏(控制台纯Ai算法)
Java五子棋小游戏(控制台纯Ai算法) 继续之前的那个五子棋程序 修复了一些已知的小Bug 这里是之前的五子棋程序 原文链接 修复了一些算法缺陷 本次增加了AI算法 可以人机对战 也可以Ai对Ai看 ...
- js实现简单的俄罗斯方块小游戏
js实现简单的俄罗斯方块小游戏 开始 1. 创建一个宽为 200px,高为 360px 的背景容器 <!DOCTYPE html> <html lang="en" ...
- Java猜拳小游戏(剪刀、石头、布)
1.第一种实现方法,调用Random数据包,直接根据“1.2.3”输出“剪刀.石头.布”.主要用了9条输出判断语句. import java.util.Random; import java.util ...
- 从零开始学java(小游戏 石头剪刀布)
Game.java package com.java;import java.util.Scanner;public class Game { private Player player ...
- Java石头剪刀布小游戏
package com.neusoft.test; import java.awt.BorderLayout; import java.awt.Choice; import java.awt.Colo ...
- Java开发小游戏 用键盘控制精灵在游戏中上下左右跑动 窗体小游戏可打包下载,解压后双击start运行
package com.swift; import java.awt.Point; import java.awt.event.KeyEvent; import com.rupeng.game.Gam ...
- Java经典小游戏——贪吃蛇简单实现(附源码)
一.使用知识 Jframe GUI 双向链表 线程 二.使用工具 IntelliJ IDEA jdk 1.8 三.开发过程 3.1素材准备 首先在开发之前应该准备一些素材,已备用,我主要找了一个图片以 ...
- Java 坦克小游戏心得
原本是闲得慌无聊才去尝试做这个项目的,因为小时候玩小霸王的游戏机,那个时候经常玩这个游戏吧,特别是喜欢那种自定义地图的模式,觉得自由度非常不错.总之关于这个游戏,想说的一大堆.鉴于能有个空闲的时间,打 ...
随机推荐
- webui layout like desktop rich client
similarity similarlike desktop js frameworklike extj js frameworklike rich client js frameworkjs lay ...
- 08_一个java.lang.NullPointException报错
[报错代码] public class UserDaoTest{ private SqlSessionFactory sqlSessionFactory; //此方法在执行testFindUserBy ...
- Asp.net Mvc HTTP 404。
asp.net mvc 设置完起始页的时候会出现以下Error 此错误的原因是在MVC中设置完起始页 会改变 的 值 从而使服务器找不到 相对应的路径 解决方案: 通过 路由设置,解决web ...
- 【实习记】2014-09-26恢复linux下误删的ntfs盘中的文件
情景,ubuntu下把NTFS格式的盘中的“实习记”文件夹彻底删除了,追毁莫及,粗心觉不是一件好的事情. linux下回复ntfs盘下的文件不能用ext3grep,而使用debugfs命令实在 ...
- mod_wsgi
配置: WSGIScriptAlias /var/www/wsgi-scripts/simple.wsgi def application(environ, start_response): outp ...
- Yii Swiftmailer 发送中文附件
所用的是Yii2 的basic框架.它本身集成了邮件发送插件swiftmailer,发送邮件是很方便的,但是当发送的邮件带有中文名称的附件时,就出现了问题,邮件所带的附件显示名称错误.比如原名&quo ...
- ajax GET和POST请求web api 的几种方式
GET请求 1.无参数get请求 一般get请求有两种写法,一种是 $.get() 一种是$.ajax({type:"get"}), 我个人比较喜欢用后者. 下面例子主要是ge ...
- php表单发送到邮箱V1.0
html表单代码: <form action="index.php" name="form" method="POST"> &l ...
- linux正确重启MySQL的方法
修改了my.cnf,需要重启MySQL服务,正确重启MYSQL方法请看下面的文章 由于是从源码包安装的Mysql,所以系统中是没有红帽常用的servcie mysqld restart这个脚本 只好手 ...
- 解决cocos2d 热更是连不上https服务器
最近苹果宣布所有上架应用都要用https,我们后端走的是同一个函数,导致Android也要连接https. 百度了下,网上说客户端不需要做什么特殊处理,因为cocos本身是支持https的.但是服务端 ...