Step1:先画面板
主要是三个方法:initWindow()初始化窗口,initGameInit()初始化面板;initExplainPanel()初始化解释面板,init()初始化参数
public void initWindow(){ this.setSize(600, 850); this.setLocationRelativeTo(null); this.setResizable(false); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); this.setTitle("俄罗斯方块"); } public void initGameInit(){ JPanel game_main=new JPanel(); game_main.setLayout(new GridLayout(game_x,game_y,1,1)); for(int i=0;i
Step2:参数设定以及生成方块
参数:
private static final int game_x=26; private static final int game_y=12; JTextArea[][] text; int[][] data; JLabel label1; JLabel label; boolean isRunning; int[] allRect;//存放所有方块 int rect;//存储当前方块的变量 //当前方块的坐标 int x,y; //线程休眠时间 int time=1000; int score=0; boolean game_pause=false; int pause_time=0;方块:
方块的表示方法我是用十六进制数进行表示
首先看一下一个方块:
其他的方块都可以这样表示:
public void ranRect(){ Random random=new Random(); rect=allRect[random.nextInt(22)]; }
Step3:设置游戏开始:
其中包括的方法主要是:game_run(),先随机生成方块,再判断方块是否可以下落,如果可以下落,先改变data的值表示这里有方块,再判断移除的条件,最后判断游戏失败的条件
public void game_begin(){ while(true){ if(!isRunning){ break; } game_run(); } label1.setText("游戏状态:游戏结束!"); } private void game_run() { ranRect(); x=0; y=5; for(int i=0;i方块是否可以下落:直接通过data数组进行判断,之间在下落的时间会将data数组的i,j位置置于1,如果此时该位置的data数组不为1就可以下落
private boolean canFall(int x, int y) { int temp=0x8000; for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ if((temp& rect) !=0){ //判断该位置的下一行是否有方块 if(data[x+1][y]==1){ return false; } } y++; temp = temp >> 1; } x++; y=y-4; } return true; }下落的方法:直接清除掉上一层的方块,再重新绘制下一层的方块
private void fall(int m,int n) { if(m>0){ //清除上一层的方块 clear(m-1,n); } //重新绘制 draw(m,n); } private void draw(int m, int n) { int temp=0x8000; for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ if((temp& rect) !=0){ text[m][n].setBackground(Color.BLUE); } n++; temp = temp >> 1; } m++; n=n-4; } } private void clear(int m, int n) { int temp=0x8000; for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ if((temp& rect) !=0){ text[m][n].setBackground(Color.WHITE); } n++; temp = temp >> 1; } m++; n=n-4; } }当有一行可以消除时,移除某一行方法:主要是通过改变文本块颜色进行移除
private void removeRow(int row) { int temp=100; for(int i=row;i>=1;i--){ for(int j=1;j<(game_y-2);j++){ data[i][j]=data[i-1][j]; } } //刷新游戏区域 reflesh(row); //游戏加速 if(time>temp){ time-=temp; } score+=temp; label.setText("游戏得分: "+score); } private void reflesh(int row) { for(int i=row;i>=1;i--){ for(int j=1;j<(game_y-2);j++){ if(data[i][j]>=1){ text[i][j].setBackground(Color.BLUE); }else{ text[i][j].setBackground(Color.WHITE); } } } }改变data值:
private void changData(int x, int y) { int temp=0x8000; for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ if((temp& rect) !=0){ data[x][y]=1; } y++; temp = temp >> 1; } x++; y=y-4; } }
Step4:鼠标监听事件:
通过进行鼠标的左移、右移、下移、变形进行操作,主要是继承KeyListener重写三个方法
这里主要是进行变形的时候需要注意
@Override public void keyTyped(KeyEvent e) { if(e.getKeyChar()=='p'){ if(! isRunning){ return; } pause_time++; if(pause_time==1){ game_pause=true; label1.setText("游戏暂停"); } if(pause_time==2){ game_pause=false; pause_time=0; label1.setText("游戏继续"); } } if(e.getKeyChar()==KeyEvent.VK_SPACE){ if(! isRunning){ return; } if(game_pause){ return; } int old; for(old=0;old=3 && old<=6){ next=allRect[old+1>6 ? 3:old+1]; if(canTurn(next,x,y)){ rect =next; } } if(old==10 || old==11){ next=allRect[old==10 ?11:10]; if(canTurn(next,x,y)){ rect =next; } } if(old==12 || old==13){ next=allRect[old==12 ?13:12]; if(canTurn(next,x,y)){ rect =next; } } if(old>=14 && old<=17){ next=allRect[old+1>17 ? 14:old+1]; if(canTurn(next,x,y)){ rect =next; } } if(old==18 || old==19){ next=allRect[old==18 ?19:18]; if(canTurn(next,x,y)){ rect =next; } } if(old==20 || old==21){ next=allRect[old==20 ?21:20]; if(canTurn(next,x,y)){ rect =next; } } draw(x,y); } } @Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if(keyCode==KeyEvent.VK_LEFT){ if(!isRunning){ return; } if(y<=1){ return; } if(game_pause){ return; } int temp=0x8000; for(int i=x;i>=1; } } clear(x,y); y--; draw(x,y); } if(keyCode==KeyEvent.VK_RIGHT){ if(!isRunning){ return; } if(game_pause){ return; } int temp=0x8000; int m=x; int n=y; int num=1; for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ if((temp&rect)!=0){ if(n>num){ num=n; } } n++; temp>>=1; } m++; n=n-4; } if(num>=(game_y-2)){ return; } temp=0x8000; for(int i=x;i >=1; } } clear(x,y); y++; draw(x,y); } if(keyCode==KeyEvent.VK_DOWN){ System.out.println("down"); if(!isRunning){ return; } if(!canFall(x,y)){ return; } if(game_pause){ return; } clear(x,y); x++; draw(x,y); } } private boolean canTurn(int next, int x, int y) { int temp=0x8000; for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ if((temp&next)!=0){ if(data[x][y]==1){ return false; } } y++; temp>>=1; } x++; y=y-4; } System.out.println("ttur"); return true; } @Override public void keyReleased(KeyEvent e) { }
Step5:主函数调用
public static void main(String[] args) {
MyTertris myTertris=new MyTertris();
myTertris.game_begin();
}
3.完整代码
package com.tetris.study;
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.KeyListener;
import java.util.Random;
public class MyTertris extends JFrame implements KeyListener{
private static final int game_x=26;
private static final int game_y=12;
JTextArea[][] text;
int[][] data;
JLabel label1;
JLabel label;
boolean isRunning;
int[] allRect;//存放所有方块
int rect;//存储当前方块的变量
//当前方块的坐标
int x,y;
//线程休眠时间
int time=1000;
int score=0;
boolean game_pause=false;
int pause_time=0;
public MyTertris() {
init();
initGameInit();
initExplainPanel();
initWindow();
}
public void initWindow(){
this.setSize(600, 850);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setTitle("俄罗斯方块");
}
public void initGameInit(){
JPanel game_main=new JPanel();
game_main.setLayout(new GridLayout(game_x,game_y,1,1));
for(int i=0;i0){
//清除上一层的方块
clear(m-1,n);
}
//重新绘制
draw(m,n);
}
private void draw(int m, int n) {
int temp=0x8000;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if((temp& rect) !=0){
text[m][n].setBackground(Color.BLUE);
}
n++;
temp = temp >> 1;
}
m++;
n=n-4;
}
}
private void clear(int m, int n) {
int temp=0x8000;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if((temp& rect) !=0){
text[m][n].setBackground(Color.WHITE);
}
n++;
temp = temp >> 1;
}
m++;
n=n-4;
}
}
private void removeRow(int row) {
int temp=100;
for(int i=row;i>=1;i--){
for(int j=1;j<(game_y-2);j++){
data[i][j]=data[i-1][j];
}
}
//刷新游戏区域
reflesh(row);
//游戏加速
if(time>temp){
time-=temp;
}
score+=temp;
label.setText("游戏得分: "+score);
}
private void reflesh(int row) {
for(int i=row;i>=1;i--){
for(int j=1;j<(game_y-2);j++){
if(data[i][j]>=1){
text[i][j].setBackground(Color.BLUE);
}else{
text[i][j].setBackground(Color.WHITE);
}
}
}
}
private void changData(int x, int y) {
int temp=0x8000;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if((temp& rect) !=0){
data[x][y]=1;
}
y++;
temp = temp >> 1;
}
x++;
y=y-4;
}
}
private boolean canFall(int x, int y) {
int temp=0x8000;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if((temp& rect) !=0){
//判断该位置的下一行是否有方块
if(data[x+1][y]==1){
return false;
}
}
y++;
temp = temp >> 1;
}
x++;
y=y-4;
}
return true;
}
public void ranRect(){
Random random=new Random();
rect=allRect[random.nextInt(22)];
}
public static void main(String[] args) {
MyTertris myTertris=new MyTertris();
myTertris.game_begin();
}
@Override
public void keyTyped(KeyEvent e) {
if(e.getKeyChar()=='p'){
if(! isRunning){
return;
}
pause_time++;
if(pause_time==1){
game_pause=true;
label1.setText("游戏暂停");
}
if(pause_time==2){
game_pause=false;
pause_time=0;
label1.setText("游戏继续");
}
}
if(e.getKeyChar()==KeyEvent.VK_SPACE){
if(! isRunning){
return;
}
if(game_pause){
return;
}
int old;
for(old=0;old=3 && old<=6){
next=allRect[old+1>6 ? 3:old+1];
if(canTurn(next,x,y)){
rect =next;
}
}
if(old==10 || old==11){
next=allRect[old==10 ?11:10];
if(canTurn(next,x,y)){
rect =next;
}
}
if(old==12 || old==13){
next=allRect[old==12 ?13:12];
if(canTurn(next,x,y)){
rect =next;
}
}
if(old>=14 && old<=17){
next=allRect[old+1>17 ? 14:old+1];
if(canTurn(next,x,y)){
rect =next;
}
}
if(old==18 || old==19){
next=allRect[old==18 ?19:18];
if(canTurn(next,x,y)){
rect =next;
}
}
if(old==20 || old==21){
next=allRect[old==20 ?21:20];
if(canTurn(next,x,y)){
rect =next;
}
}
draw(x,y);
}
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode==KeyEvent.VK_LEFT){
if(!isRunning){
return;
}
if(y<=1){
return;
}
if(game_pause){
return;
}
int temp=0x8000;
for(int i=x;i>=1;
}
}
clear(x,y);
y--;
draw(x,y);
}
if(keyCode==KeyEvent.VK_RIGHT){
if(!isRunning){
return;
}
if(game_pause){
return;
}
int temp=0x8000;
int m=x;
int n=y;
int num=1;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if((temp&rect)!=0){
if(n>num){
num=n;
}
}
n++;
temp>>=1;
}
m++;
n=n-4;
}
if(num>=(game_y-2)){
return;
}
temp=0x8000;
for(int i=x;i>=1;
}
}
clear(x,y);
y++;
draw(x,y);
}
if(keyCode==KeyEvent.VK_DOWN){
System.out.println("down");
if(!isRunning){
return;
}
if(!canFall(x,y)){
return;
}
if(game_pause){
return;
}
clear(x,y);
x++;
draw(x,y);
}
}
private boolean canTurn(int next, int x, int y) {
int temp=0x8000;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if((temp&next)!=0){
if(data[x][y]==1){
return false;
}
}
y++;
temp>>=1;
}
x++;
y=y-4;
}
System.out.println("ttur");
return true;
}
@Override
public void keyReleased(KeyEvent e) {
}
}



