📄 tetrics.java~2~
字号:
package ct;//包
//头文件
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
//游戏类
public class Tetrics extends Panel implements Runnable//主游戏类
{
//每个小方块的大小:宽,高
int m_nSqLength;
//定位游戏区位置(x轴)
final int XOFFSET=0;
//游戏区域内的列和行
static int m_nCols;
static int m_nRows;
int m_nOldScore;//存放分数,供每个等级累加使用
//游戏窗体大小
public static int WIDTH=250;
public static int HEIGHT=450;
//当前的界面情况
int m_nField[][];//本页游戏画面
int m_nOldField[][];//上页游戏画面
//当前移动的方块
Square m_curPiece[]=new Square[4];
boolean m_bGameInPlay;//是否在游戏中
boolean m_bPaused=false;//初始游戏暂停状态(假,即不暂停)
Thread m_theThread=null;//游戏线程
int m_nPieceValue,m_nTheScore=0;//方块价值和游戏总分
int m_nPlayLevel;//游戏难度
int m_nTotalPieces;//下落的方块总数
private java.applet.AudioClip audioClip;
java.net.URL url;
int m_nDelayMap[]={0,675,625,575,525,475,425,375,325,275,225,175,125,75,50,25};//SPF值数组
final Color BAKCOLOR=new Color(31,58,173);//背景颜色深蓝
int b;//标注游戏状态,0为游戏开始,1为暂停,-1为结束
Graphics m_gOffGraph;//声名绘图变量
Frame1 m_tFrame;//声名主窗体变量
nextSquare nextPiece;
oGameField oGameArea;//对手游戏区域
public Tetrics()
{//构造游戏方法
super();//将本窗体设置为容器
// setBackground(BAKCOLOR);//设置背景色
initParam();//游戏初始化
}
public Tetrics(Frame1 tFrame)
{//重载构造游戏方法
super();//将本窗体设置为容器
m_tFrame=tFrame;//将游戏状态传给主窗体
//setBackground(BAKCOLOR);//设置背景色
initParam();//游戏初始化
}
public void initParam()
{
nextPiece = new nextSquare(this);
oGameArea = new oGameField(this);
//设置初始参数
m_nSqLength=25;
m_nCols=nextPiece.m_nCols;
m_nRows=nextPiece.m_nRows;
m_nField=new int [m_nCols][m_nRows+4];
m_nOldField=new int[m_nCols][m_nRows+4];
m_nPlayLevel=5;
}
//线程开始
public synchronized void start()
{ b=0;//游戏状态为开始
if(m_theThread!=null)
//游戏是被暂停,而不是重新开始
{
m_bPaused=false;//停止暂停状态
m_theThread.resume();//线程继续
return;
}
//重新开始赋上游戏的状态
for(int i=0;i<m_nCols;i++)
{//绘制游戏区画面
for(int j=0;j<m_nRows+4;j++)
{
m_nField[i][j]=0;//当前游戏区无方块
m_nOldField[i][j]=-1;//上一页游戏区全部为方块
oGameArea.m_nField[i][j]=0;
}
}
m_nTheScore=0;//总分初始为0
m_nTotalPieces=0;//下落总方块数初始为0
nextPiece.m_bNeedNewPiece=true;//需生成新方块
m_bGameInPlay=true;//游戏状态(游戏中)
m_nOldScore=0;//每个等级累加的分数初始为0
m_theThread=new Thread(this);//声名新线程
nextPiece.newPrePiece();//预览区方块
m_theThread.start();//线程开始
requestFocus();//控制游戏焦点在游戏区
m_repaint();
}
//更新游戏界面
public void update(Graphics g)
{
nextPiece.m_bJustupdating=true;//游戏更新中
paint(g);//绘制新游戏页面
}
//绘制游戏界面
public synchronized void paint(Graphics g)
{
Image img1=createImage(m_nSqLength*10,m_nSqLength*18);
//用来画自己的游戏区域
Graphics g1=img1.getGraphics();
for(int i=0;i<m_nCols;i++)
for(int j=0;j<m_nRows;j++)
{
g1.setColor(nextPiece.m_colors[m_nField[i][m_nRows-1-j]]);//设置方块颜色
g1.fill3DRect(m_nSqLength*i,m_nSqLength*j,m_nSqLength,m_nSqLength,true);//绘制立体效果方块
}
g.drawImage(img1,0,0,this);//绘制游戏画面
nextPiece.m_bJustupdating=false;//更新状态为假
}
public void run()
{//启动线程
while(m_bGameInPlay){//游戏状态下
try
{
int t;
if(m_nPlayLevel>15) {
m_nPlayLevel=1;//等级回1
t=m_nDelayMap[0];//设置SPF
}
else t=m_nDelayMap[m_nPlayLevel];
Thread.sleep(t);//延迟
}catch(InterruptedException e){e.printStackTrace();}//追踪检错
if(nextPiece.m_bNeedNewPiece)
{//需要产生方块
removelines();//消行
transferPreToCur();//将预览区方块传到游戏区
//等级变化
if(m_nOldScore%100>=0&&m_nOldScore!=0){
m_nPlayLevel++; //若累加分数为10000 的倍数则等级+1
m_nOldScore=0;//累加分数清0
}
if(m_nTotalPieces%(27-m_nPlayLevel)==0)addRandomLine();//添加随机行
nextPiece.start();//产生新方块
nextPiece.m_bNeedNewPiece=false;//不需产生新方块
}
else
{//不需要新方块处理
nextPiece.m_bNeedNewPiece=!moveCurPiece(0,-1,false);//将预览区方块传到游戏区,方块自动下落
if(!nextPiece.m_bNeedNewPiece) m_nPieceValue-=5;//游戏中方块价值累减5
}
m_repaint();
//////////////////////////////////////////////////////////////////////////////////////
sendStatus();
}
m_theThread=null;//停止线程
}
public void m_repaint(){
repaint();//刷新游戏画面
nextPiece.repaint();
oGameArea.repaint();
}
private void sendStatus()
{//若是连机把玩家游戏区域的信息发送给对手
if(m_tFrame!=null){
if (m_tFrame.m_nNetStatus == Frame1.NOCONNECT)
return;
String str = "Status:";
for (int nCol = 0; nCol < m_nCols; nCol++)
for (int nRow = 0; nRow < m_nRows; nRow++) {
str += m_nField[nCol][nRow] + "|";
}
m_tFrame.sendStr(str);
}
}//连机时候使用
/**
*移动方块
*@param nDx 左右移动,向左为-1
*@param nDy 上下移动,向下为-1
*@param bRotate 是否转动
*/
private synchronized boolean moveCurPiece(int nDx,int nDy,boolean bRotate)
{
Square newpos[]=new Square[4];//声名新方块
for(int i=0;i<4;i++){
if(bRotate)//若需转动
{//定位的中心方块与准备移动的小方块间的位移
int dx=m_curPiece[i].m_nColumn-m_curPiece[0].m_nColumn;
int dy=m_curPiece[i].m_nRow-m_curPiece[0].m_nRow;
//绘制转动后的方块
newpos[i]=new Square(m_curPiece[0].m_nColumn-dy,m_curPiece[0].m_nRow+dx,m_curPiece[i].m_nColor);
}
else
{//若不转动则方块随按键移动
newpos[i]=new Square(m_curPiece[i].m_nColumn+nDx,m_curPiece[i].m_nRow+nDy,m_curPiece[i].m_nColor);
}
}
//若方块不能移动则返回假
if(moveSquares(m_curPiece,newpos)==false) return false;//不移动方块
m_curPiece=newpos;//将转动后方块传到游戏区
return true;//移动方块
}
/**
* 移动方块,如果不能移动,则返回假
*/
boolean moveSquares(Square from[],Square to[])
{
//判断是否能移动
outerlable://定义标识变量
for (int i=0;i<to.length;i++)
{
if(to[i].InBounds()==false) return false;
//如果不在可玩区域,则返回假,不能移动
if(m_nField[to[i].m_nColumn][to[i].m_nRow]!=0)//判断有障碍
{
for(int j=0;j<from.length;j++)
if(to[i].IsEqual(from[j]))//要移动位置与移动方块比较
continue outerlable;//返回至标识处并继续
return false;//不能移动
}
}
//移动
for(int i=0;i<from.length;i++)//让上一次显示的方块消失
if(from[i].InBounds())//方块在游戏区
m_nField[from[i].m_nColumn][from[i].m_nRow]=0;//将原位置方块擦掉
for(int i=0;i<to.length;i++)//在下一位置绘制方块
m_nField[to[i].m_nColumn][to[i].m_nRow]=to[i].m_nColor;
return true;//可以移动
}
/**
* 将预览的方块转变成正在动的方块
*/
private void transferPreToCur()
{
Square old[]=new Square[4];//声名新方块实例
for(int i=0;i<4;i++)
old[i]=new Square(-1,-1,0);//定位新生成的方块
for(int i=0;i<4;i++)
{
m_curPiece[i]=nextPiece.m_prePiece[i];//将预览区方块移到游戏区
m_nTotalPieces++;//下落的方块+1
}
m_bGameInPlay=moveSquares(old,m_curPiece);//若方块可移动则游戏可进行
//if(!m_bGameInPlay && m_tFrame.m_nNetStatus!=TFrame.NOCONNECT)m_tFrame.sendStr("GameOver:"+m_nTheScore);
//else if(!m_bGameInPlay && m_tFrame!=null)m_tFrame.insertScoreReport(m_nTheScore);
}
//去掉可以消去的行
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -