200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > java俄罗斯方块简单代码_Java简易俄罗斯方块

java俄罗斯方块简单代码_Java简易俄罗斯方块

时间:2023-05-19 10:37:21

相关推荐

java俄罗斯方块简单代码_Java简易俄罗斯方块

目前学到Swing第二章,这两天没有学新知识,写了个俄罗斯方块。

写之前想不好怎么实现,找来别人的程序看了一下,再加上自己的想法,做了下面这个半成品,接下来可以加上各种菜单、按钮贴图等美化,都是些锦上添花的动作,繁琐但不难。

我觉得写俄罗斯方块,难点在于如何将方块的形状(七种)、状态(四种翻转)、动作(左、右、下落)等提炼成数组。 这里采用四维数组来表示每一种方块:【种类】【翻转】【X坐标】【Y坐标】,每种方块都画在一个4*4的大方块中,把这个大方块作为一个整体进行移动。再写了一个方法遍历大方块,判断该方块的位置是否合法。

有了合适的模型,再把每个步骤转化成代码,就不难了。

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.image.BufferedImage;

import java.util.Arrays;

import java.util.Random;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JCheckBox;

import javax.swing.Timer;

import javax.swing.JOptionPane;

public class KingTetris{

// 20行,10列

private final int ROW = 20;

private final int COL = 10;

// 每个方块边长,单位为像素

private final int LEN = 35;

// 游戏区域的左、上边距

private final int LEFT_MARGIN = LEN*2;

private final int UP_MARGIN = LEN;

// 面布大小,单位为像素

private final int AREA_WIDTH = LEN*22;

private final int AREA_HEIGHT = LEN*22;

// 是否需要网格

private boolean showGrid = true;

// 是否彩色,将来可以作为贴图控制

private boolean isColor = true;

// 得分

private int score = 0;

// 画布

private MyCanvas drawArea = new MyCanvas();

// 窗口

private JFrame f = new JFrame("俄罗斯方块");

// 画图用的image

private BufferedImage image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_RGB);

private Graphics g = image.createGraphics();

// 数组,用于保存背景

private int[][] map = new int[COL][ROW];

// 数组,用于保存颜色

private Color[] color = new Color[]{Color.green, Color.red, Color.orange, Color.blue, Color.cyan, Color.yellow, Color.magenta, Color.gray};

//默认灰色

private final int DEFAULT = 7;

private Color[][] mapColor = new Color[COL][ROW];

//组件的横坐标

int wordX = LEN*14;// 组件的横坐标

int wordY = LEN*9; // 字的初始纵坐标

//shape的四个参数

private int type, state, x, y, nextType, nextState;

//如果刚开始游戏,由于无nextType,先给type等随机一个,下为首次开始游戏的标志

private boolean newBegin = true;

// 用数组来代表不同形状的下坠物,四维分别是类型Type、旋转状态State、横坐标X、纵坐标Y。画示意图即可得出坐标

// 方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名

private int[][][][] shape = new int[][][][]{

// S的四种翻转状态:

{ { {0,1,0,0}, {1,1,0,0}, {1,0,0,0}, {0,0,0,0} },

{ {0,0,0,0}, {1,1,0,0}, {0,1,1,0}, {0,0,0,0} },

{ {0,1,0,0}, {1,1,0,0}, {1,0,0,0}, {0,0,0,0} },

{ {0,0,0,0}, {1,1,0,0}, {0,1,1,0}, {0,0,0,0} } },

// Z:

{ { {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,0} },

{ {0,1,1,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} } },

// L:

{ { {0,0,0,0}, {1,1,1,0}, {0,0,1,0}, {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,0,0}, {0,1,1,1}, {0,0,0,0} },

{ {0,0,1,0}, {0,0,1,0}, {0,1,1,0}, {0,0,0,0} } },

// J:

{ { {0,0,0,0}, {0,0,1,0}, {1,1,1,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,1,1,1}, {0,1,0,0}, {0,0,0,0} },

{ {0,1,0,0}, {0,1,0,0}, {0,1,1,0}, {0,0,0,0} } },

// I:

{ { {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} },

{ {0,0,0,0}, {1,1,1,1}, {0,0,0,0}, {0,0,0,0} } },

// O:

{ { {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,1,1,0}, {0,1,1,0}, {0,0,0,0} } },

// T:

{ { {0,1,0,0}, {1,1,0,0}, {0,1,0,0}, {0,0,0,0} },

{ {0,0,0,0}, {1,1,1,0}, {0,1,0,0}, {0,0,0,0} },

{ {0,1,0,0}, {0,1,1,0}, {0,1,0,0}, {0,0,0,0} },

{ {0,1,0,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0} } },

};

/**

* 初始化界面

*/

private void init(){

drawArea.setPreferredSize(new Dimension(AREA_WIDTH, AREA_HEIGHT));

f.add(drawArea);

JCheckBox gridCB = new JCheckBox("显示网格",true);

JCheckBox colorCB = new JCheckBox("彩色方块", false);

gridCB.setBounds(wordX, wordY-LEN,LEN,LEN);

colorCB.setBounds(wordX, wordY-2*LEN,LEN,LEN);

// paintArea();

// 加键盘监听器

f.addKeyListener(new KeyAdapter(){

public void keyPressed(KeyEvent e){

switch (e.getKeyCode()) {

case KeyEvent.VK_UP:

turn();

break;

case KeyEvent.VK_LEFT:

left();

break;

case KeyEvent.VK_RIGHT:

right();

break;

case KeyEvent.VK_DOWN:

down();

break;

}

}

});

Timer timer = new Timer(1000, new timerListener());

newShape();

timer.start();

// 窗口显示在屏幕正中

// Toolkit是抽象类,只能用getDefaultToolkit()方法来获取实例。

// getScreenSize()方法返回的是一个Dimension对象,还须用getWidth()获取宽度

f.pack();

int screenSizeX = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();

int screenSizeY = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();

int fSizeX = (int)f.getSize().getWidth();

int fSizeY = (int)f.getSize().getHeight();

f.setResizable(false);// 禁止改变Frame大小

f.setBounds((screenSizeX-fSizeX)/2, (screenSizeY-fSizeY)/2, fSizeX,fSizeY );

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setVisible(true);

}

/**

* 绘图

*/

private void paintArea(){

// 默认黑色,填充白色

g.setColor(Color.white);

g.fillRect(0, 0, AREA_WIDTH, AREA_HEIGHT);

// 方格线

// 先画最外围

g.setColor(Color.gray);

for (int offset = 0; offset <= 2; offset++){

g.drawRect(LEFT_MARGIN-offset, UP_MARGIN-offset, COL*LEN+offset*2, ROW*LEN+offset*2);

}

// 如果showGrid为true则显示网格

if(showGrid){

g.setColor(Color.gray);

// 9条竖线

for (int i = 1 ; i <= 9; i++){

g.drawLine(LEFT_MARGIN+LEN*i, UP_MARGIN, LEFT_MARGIN+LEN*i, UP_MARGIN+ROW*LEN);

}

// 19条横线

for(int i = 1; i <= 19; i++){

g.drawLine(LEFT_MARGIN, UP_MARGIN+LEN*i, LEFT_MARGIN+COL*LEN, UP_MARGIN+LEN*i);

}

}

// 右上角显示下一个shape

int offset2 = 3;// 边框粗细

int col = 4;// 右上角方框的列数

int row = 4;// 行数

g.setColor(Color.gray);

g.setFont(new Font("Microsoft YaHei Mono", Font.BOLD, 20));

g.drawString("下一个:", wordX, LEN*2);

int nextX = wordX;

int nextY = LEN*2;

//暂不画方框

// for (int offset = 0; offset <= 2; offset++){

// g.drawRect(nextX-offset+10, nextY+10-offset, col*LEN+offset*2, row*LEN+offset*2);

// }

//画下一次出现的下坠方块

g.setColor(isColor?color[nextType]:color[DEFAULT]);

for(int i = 0; i < 4; i++){

for(int j = 0; j < 4; j++){

if (shape[nextType][nextState][i][j]==1) {

g.fill3DRect(nextX+10+i*LEN, nextY+10+j*LEN, LEN, LEN,true);

}

}

}

g.setColor(Color.gray);

g.setFont(new Font("Times", Font.BOLD, 15));

g.drawString("玩法:", wordX, wordY+LEN*2);

g.drawString("上箭头:翻转", wordX, wordY+LEN*3);

g.drawString("左箭头:左移", wordX, wordY+LEN*4);

g.drawString("右箭头:右移", wordX, wordY+LEN*5);

g.drawString("下箭头:下落", wordX, wordY+LEN*6);

g.setFont(new Font("Times", Font.BOLD, 25));

g.drawString("得分:" + score, wordX, wordY+LEN*8);

//画下坠物shape

g.setColor(isColor?color[type]:color[DEFAULT]);

for(int i = 0; i < 4; i++){

for(int j = 0; j < 4; j++){

if (shape[type][state][i][j]==1) {

g.fill3DRect(LEFT_MARGIN+(x+i)*LEN, UP_MARGIN+(y+j)*LEN, LEN, LEN,true);

}

}

}

//画背景map

for(int i = 0; i < COL; i++){

for(int j = 0; j < ROW; j++){

if (map[i][j] == 1) {

g.setColor(mapColor[i][j]);

g.fill3DRect(LEFT_MARGIN+i*LEN, UP_MARGIN+j*LEN, LEN, LEN,true);

}

}

}

drawArea.repaint();

}

/**

* 自定义画布,重写paint()方法

*/

private class MyCanvas extends JPanel{

public void paint(Graphics g){

g.drawImage(image, 0, 0, null);

}

}

/**

* 判断位置是否合法

*/

private boolean check(int type, int state, int x, int y){

for(int i = 0; i < 4; i++){

for(int j = 0; j < 4; j++){

if ( (shape[type][state][i][j] == 1) && ( (x+i>=COL) || (x+i<0 ) || (y+j>=ROW) || (map[x+i][y+j]==1) ) ) {

return false;

}

}

}

return true;

}

/**

* 判断游戏是否结束

*/

private boolean isGameOver(int type, int state, int x, int y){

return !check(type, state, x, y);

}

/**

* 新建方块

*/

private void newShape(){

Random rand = new Random();

if(newBegin){

type = rand.nextInt(7);

state = rand.nextInt(4);

newBegin = false;

}

else{

type = nextType;

state = nextState;

}

nextType = rand.nextInt(7);

nextState = rand.nextInt(4);

x = 3;

y = 0;

// 如果游戏已结束,则重新开始

if(isGameOver(type, state, x, y)){

JOptionPane.showMessageDialog(f, "GAME OVER!");

newGame();

}

paintArea();

}

/**

* 新建游戏

*/

private void newGame(){

newMap();

score = 0;

newBegin = true;

}

/**

* 清空背景图

*/

private void newMap(){

for(int i = 0; i < COL; i++){

Arrays.fill(map[i],0);

}

}

/**

* 消行

*/

private void delLine(){

boolean flag = true;

int addScore = 0;

for(int j = 0; j < ROW; j++){

flag = true;

for( int i = 0; i < COL; i++){

if (map[i][j]==0){

flag = false;

break;

}

}

if(flag){

addScore += 10;

for(int t = j; t > 0; t--){

for(int i = 0; i

map[i][t] = map[i][t-1];

}

}

}

}

score += addScore*addScore/COL;

}

/**

* 计时器所用的事件监听器

*/

private class timerListener implements ActionListener{

public void actionPerformed(ActionEvent e){

if(check(type, state , x, y+1) ){

y = y +1;

}

else{

add(type, state, x, y);

delLine();

newShape();

}

paintArea();

}

}

/**

* 把shape存到map的add方法

*/

private void add(int type, int state, int x, int y){

for(int i = 0; i < 4; i++){

for(int j = 0; j < 4 ; j++){

if((y+j=0)&&(map[x+i][y+j]==0)){

map[x+i][y+j]=shape[type][state][i][j];

mapColor[x+i][y+j]=color[isColor?type:DEFAULT];

}

}

}

}

/**

* 下面为四个方向键对应的方法

*/

private void turn(){

int tmpState = state;

state = (state + 1)%4;

if (!check(type,state, x, y )) {

state = tmpState; //不能转就什么都不做

}

paintArea();

}

private void left(){

if(check(type,state, x-1, y)){

--x;

}

paintArea();

}

private void right(){

if (check(type,state, x+1, y)) {

++x;

}

paintArea();

}

private void down(){

if (check(type,state, x, y+1)) {

++y;

}

//如果下不去则固定之

else{

add(type, state, x, y);

delLine();

newShape();

}

paintArea();

}

/**

* 主函数

*/

public static void main(String[] args){

new KingTetris().init();

}

}

版权声明:本文为博主原创文章,未经博主允许。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。