import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.*;
public class Lt extends JFrame implements KeyListener{
//无参构造
public Lt() {//按顺序写 否则会有函数失效
initExplainPanel();//初始化说明(左右)面板
initGamePanel();//初始化面板
initWindow();//窗口初始化
game_begin();
}
public static void main(String[] args) {
new Lt();
}
/*方块左移和右移*/
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==37){
if(!isrunning){
return;
}
if(game_pause){
return;
}
if(y<=1){
return;
}
int temp = 0x8000;
for (int i = x; i <x+4 ; i++) {
for (int j = y; j <y+4 ; j++) {
if((rect&temp)!=0){
if(data[i][j-1]==1){
return;
}
}
temp>>=1;
}
}
//首先清除目前方块
clear(x,y);
y--;
draw(x,y);
}
//右移
if(e.getKeyCode()==39){
if(!isrunning){
return;
}
if(game_pause){
return;
}
if(y>=(game_y-2)){
return;
}
int temp = 0x8000;
for (int i = x; i <x+4 ; i++) {
for (int j = y; j <y+4 ; j++) {
if((rect&temp)!=0){
if(data[i][j+1]==1){
return;
}
}
temp>>=1;
}
}
//首先清除目前方块
clear(x,y);
y++;
draw(x,y);
}
if(e.getKeyCode()==40){
if(!isrunning){
return;
}
if(game_pause){
return;
}
if(!canFall(x,y)){
return;
}
clear(x,y);
x++;
draw(x,y);
}
}
/*方块左移和右移结束*/
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
/*游戏暂停和方块变形*/
int pause_times=0;
boolean game_pause=false;
@Override
public void keyTyped(KeyEvent e) {
//控制游戏暂停
if(e.getKeyChar()=='p'){
if(!isrunning){
return;
}
pause_times++;
//暂停
if(pause_times==1){
game_pause=true;
label1.setText("游戏状态:暂停中!");
}
//继续
if(pause_times==2){
game_pause=false;
pause_times=0;
label1.setText("游戏状态:正在进行中!");
}
}
//控制方块变形
if(e.getKeyChar()==KeyEvent.VK_SPACE){
if(!isrunning){
return;
}
//判断游戏是否暂停
if(game_pause){
return;
}
//定义变量 存储目前方块的索引
int old;
for (old = 0; old <allRect.length ; old++) {
//判断是否是当前方块
if(rect==allRect[old]){
break;
}
}
//定义变量存储变形后方块
int next;
//判断是方块
if(old==0){
return;
}
//清除当前方块
clear(x,y);
if (old == 1 || old == 2) {
next = allRect[old == 1 ? 2 : 1];
if (canTurn(next,x,y)) {
rect = next;
}
}
if (old >= 3 && old <= 6) {
next = allRect[old + 1 > 6 ? 3 : old + 1];
if (canTurn(next,x,y)) {
rect = next;
}
}
if (old >= 9 && old <= 12) {
next = allRect[old + 1 > 12 ? 9 : old + 1];
if (canTurn(next,x,y)) {
rect = next;
}
}
if (old == 7 || old == 8) {
next = allRect[old == 7 ? 8 : 7];
if (canTurn(next,x,y)) {
rect = next;
}
}
if (old == 13 || old == 14) {
next = allRect[old == 13 ? 14 : 13];
if (canTurn(next,x,y)) {
rect = next;
}
}
if (old >= 15 && old <= 18) {
next = allRect[old + 1 > 18 ? 15 : old + 1];
if (canTurn(next,x,y)) {
rect = next;
}
}
//重新绘制变形后方块
draw(x,y);
}
}
public boolean canTurn(int a,int m,int n){
int temp = 0x8000;
for (int i = 0; i <4 ; i++) {
for (int j = 0; j <4 ; j++) {
if((a&temp)!=0){
if(data[m][n]==1){
return false;
}
}
n++;
temp>>=1;
}
m++;
n=n-4;
}
return true;
}
/*游戏暂停和方块变形结束*/
/*创建游戏界面*/
private static final int game_x = 26;
private static final int game_y = 12;
JTextArea[][] text = new JTextArea[game_x][game_y];//文本域数组 每一个文本域对象相当于一个小方格子
int[][] data = new int[game_x][game_y]; //二维数组 填充面板的 0 1
/*创建游戏界面结束*/
/*编写刷新界面的方法*/
public 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);
}
}
}
}
/*编写刷新界面的方法*/
/*编写消除行的方法*/
int score=0;
//移除某一行的所有方块,令以上方块掉落
public 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);
score+=temp;
label.setText("游戏得分:"+score);
}
/*编写消除行的方法*/
/*改变不可下降方块区域值*/
public void changData(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){
data[m][n]=1;
}
n++;
temp>>=1;
}
m++;
n=n-4;
}
}
/*改变不可下降方块区域值结束*/
/*判断方块是否可以继续下落*/
public boolean canFall(int m,int n){
//定义一个变量
int temp = 0x8000;
//遍历4*4方格
for (int i = 0; i <4 ; i++) {
for (int j = 0; j <4 ; j++) {
if((temp&rect)!=0){
//判断该位置的下一行是否有方块
if(data[m+1][n]==1){
return false;
}
}
n++;
temp>>=1;
}
m++;
n=n-4;
}
return true;
}
/*判断方块是否可以继续下落结束*/
/*编写下落方法*/
//下落方法
public void fall(int m,int n){
if(m>0){
clear(m-1,n);
}
//重新绘制方块
draw(m,n);
}
//清除方块掉落后,上一层有颜色的地方
public 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>>=1;
}
m++;
n=n-4;
}
}
//绘制
public 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>>=1;
}
m++;
n=n-4;
}
}
/*编写下落方法结束*/
/*创建游戏运行方法*/
//运行游戏
int x;
int y;
//设置睡眠时间
int time=300;
public void game_run(){
Random random= new Random();
//产生随机数 产生随机方块
rect = allRect[random.nextInt(19)];
//方块下落位置
x=0;
y=5;
for (int i = 0; i <game_x ; i++) {
try {
Thread.sleep(time);
//判断是否可以下落
if(!canFall(x,y)){
//将data置为1,表示有方块占用
changData(x,y);
//循环遍历4层,看是否有行可以消除
for (int j = x; j <x+4 ; j++) {
int sum = 0;
for (int k = 1; k <=(game_y-2) ; k++) {
if(data[j][k]==1){
sum++;
}
}
//判断是否有一行可以被消除
if(sum==(game_y-2)){
//消除j这一行
removeRow(j);
}
}
//判断游戏是否失败
for (int j = 1; j <=(game_y-2) ; j++) {
if(data[3][j]==1){
isrunning=false;
break;
}
}
break;
}else{
x++;
fall(x,y);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/*创建游戏运行方法结束*/
/*开始游戏*/
//创建存放方块的数组
boolean isrunning = true;
int[] allRect = new int[]{
0x00cc,0x8888,0x000f,0x044c,
0x008e,0x0c88,0x00e2,0x00c6,
0x04c8,0x004e,0x04c4,0x00e4,
0x08c8,0x006c,0x08c4,0x088c,
0x00e8,0x0c44,0x002e,0x8888,
0x000f,0x008f,0x888a,0x444a,
0x001f
};
//存放当前方块的变量
int rect;
//开始游戏的方法
public void game_begin(){
while(true){
//判断游戏是否结束
if(!isrunning){
break;
}
//进行游戏
game_run();
}
label1.setText("游戏状态:游戏结束!");
}
/*开始游戏结束*/
/*初始化说明面板*/
//显示游戏状态
JLabel label1=new JLabel("游戏状态:正在游戏");
//显示游戏分数
JLabel label =new JLabel("游戏分数:0");
//初始化游戏说明面板
public void initExplainPanel(){
//创建游戏的左面板
JPanel left = new JPanel();
//创建游戏的右面板
JPanel right = new JPanel();
//设置行列
left.setLayout(new GridLayout(4,1));
right.setLayout(new GridLayout(2,1));
//左面板添加说明文字
left.add(new JLabel("按空格键,方块变形"));
left.add(new JLabel("按左箭头,方块左移"));
left.add(new JLabel("按右箭头,方块右移"));
left.add(new JLabel("按下箭头,方块下落"));
//设置标签内容为红色字体
label1.setForeground(Color.red);
//右面板添加状态和分数
right.add(label);
right.add(label1);
//将左面板添加到窗口的左侧
this.add(left,BorderLayout.WEST);
this.add(right,BorderLayout.EAST);
}
/*初始化说明面板结束*/
/*窗口初始化操作*/
public void initWindow() {
//设置窗口大小
this.setSize(600,850);
//设置窗口是否可见
this.setVisible(true);
//设置窗口居中
this.setLocationRelativeTo(null);
//设置释放窗体
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗口大小不可变
this.setResizable(false);
//设置标题
this.setTitle("俄罗斯方块");
}
/*窗口初始化操作结束*/
/*创建游戏面板*/
public void initGamePanel() {
JPanel game_main = new JPanel();
game_main.setLayout(new GridLayout(game_x,game_y,1,1));
//初始化面板
for (int i = 0; i <text.length ; i++) {
for (int j = 0; j <text[i].length ; j++) {
//设置文本域的对象
text[i][j] = new JTextArea();
//设置文本域的背景颜色
text[i][j].setBackground(Color.WHITE);
//设置键盘监听事件
text[i][j].addKeyListener(this);
//初始化游戏边界
if(j==0||j==text[i].length-1||i==text.length-1){
text[i][j].setBackground(Color.CYAN);
data[i][j]=1;
}
//设置文本域不可编辑
text[i][j].setEditable(false);
//文本区域添加到主面板上
game_main.add(text[i][j]);
}
}
//添加到窗口中
this.add(game_main,BorderLayout.CENTER);
}
/*创建游戏面板结束*/
}
俄罗斯方块(JAVA实训)
最新推荐文章于 2024-05-13 10:47:40 发布