📄 gamepanel.java
字号:
package like.els;
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.*;
import java.text.*;
import java.io.*;
public class GamePanel extends Panel implements Runnable, KeyListener
{
//当前方块和下一个方块
FangKuai curr;
FangKuai next;
//是否向下移动
boolean down;
boolean first,first2;
//游戏图片和声音
static Image blue,qin,red,yellow,zi,g;
//static AudioClip change,move,fall,levelUp;
//游戏状态控制
boolean gaming;
boolean gameOver;
//游戏速度、等级、分数
long speed;
int level;
int score;
//游戏线程
Thread game;
//游戏格子
int [][] geZi = new int[21][12];
Image [][] images = new Image[21][12];
//绘制图片
Image nextImage,currImage;
//屏外缓冲图片
Image offscreen;
//高分榜
Record [] records = new Record[6];
File f = null;
ObjectInputStream oin;
ObjectOutputStream oout;
//隐藏模式
boolean fuck;
public GamePanel()
{
this.setSize(300,344);
this.first2 = true;
gameStart();
this.addKeyListener(this);
//this.addAudio();
}
//开始游戏
public void gameStart()
{
fuck = false;
for(int i=0;i<=5;i++)
{
this.records[i] = new Record();
}
//-------------文件信息处理------------
try
{
f = new File("records.wzq");
if(f.exists())
{
oin = new ObjectInputStream(new FileInputStream(f));
for(int i=0;i<=5;i++)
{
this.records[i] = (Record)oin.readObject();
}
oin.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
//-------------END文件信息处理------------
for(int i=0;i<21;i++)
for(int j=0;j<12;j++)
{
this.geZi[i][j] = 0;
this.images[i][j] = null;
}
this.addImage();
next = this.createFangKuai();
curr = this.createFangKuai();
this.down = false;
this.gameOver = false;
this.first = true;
//时刻变换的东西
score = 0;
level = 1;
this.speed = 300 - 30*level;
//启动游戏线程
game = new Thread(this);
game.start();
}
//结束游戏时的扫尾工作
public void gameOver()
{//System.out.println("gameover()");
this.gaming = false;
this.gameOver = true;
this.game = null;
if(this.score<=records[5].score)
return;
f.delete();
//高手榜
try
{
f = new File("records.wzq");
f.createNewFile();
oout = new ObjectOutputStream(new FileOutputStream(f));
}catch(Exception e){f.delete();}
String str = JOptionPane.showInputDialog(this,"请输入你的大名","高手风云榜",JOptionPane.DEFAULT_OPTION);
if(str==null||str.equals(" "))
str = "匿名";
Record temp = new Record(str,this.score);
for(int i=0;i<=5;i++)
{
if(temp.score>records[i].score)
{
for(int j=5;j>=i+1;j--)
records[j] = records[j-1];
records[i] = temp;
for(int j=0;j<=5;j++)
{
try
{
oout.writeObject(this.records[j]);
}
catch(Exception e)
{
}
}
break;
}
}
try
{
oout.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//随机创建一个方块
public FangKuai createFangKuai()
{
return new FangKuai((int)(7*Math.random()+1));
}
//暂停继续游戏
public void stop()
{
this.gaming = false;
}
public void start()
{
this.gaming = true;
}
//加载方块图片
public void addImage()
{
if(offscreen==null||offscreen.getWidth(this)<0||offscreen.getHeight(this)<0)
offscreen = this.createImage(300,344);
if(blue==null||blue.getWidth(this)<0||blue.getHeight(this)<0)
blue = this.getToolkit().getImage("images\\blue.jpg");
if(g==null||g.getWidth(this)<0||g.getHeight(this)<0)
g = this.getToolkit().getImage("images\\game.jpg");
if(qin==null||qin.getWidth(this)<0||qin.getHeight(this)<0)
qin = this.getToolkit().getImage("images\\qin.jpg");
if(red==null||red.getWidth(this)<0||red.getHeight(this)<0)
red = this.getToolkit().getImage("images\\red.jpg");
if(yellow==null||yellow.getWidth(this)<0||yellow.getHeight(this)<0)
yellow = this.getToolkit().getImage("images\\yellow.jpg");
if(zi==null||zi.getWidth(this)<0||zi.getHeight(this)<0)
zi = this.getToolkit().getImage("images\\zi.jpg");
}
//更新系列函数
public void update(Graphics g)
{
this.addImage();
if(!this.gameOver)
{
if(down)
{
down = false;
if(canGo(3))
{
this.curr.move(3);
}
else
{
if(curr.han<=0)
{
gameOver();
}
else
{
score += 10*level;
int [][] temp = curr.fangKuai;
for(int x=0;x<4;x++)
for(int y=0;y<4;y++)
{
if(temp[x][y]==1)
{
this.geZi[x+curr.han][y+curr.lie] = 1;
this.images[x+curr.han][y+curr.lie] = curr.getImage();
}
}
curr = this.next;
next = this.createFangKuai();
}
}
}
}
updateLevel();
updateOffscreen();
paint(g);
}
public void updateOffscreen()
{
Graphics g = this.offscreen.getGraphics();
g.drawImage(this.g,0,0,this);
if(this.gaming)
{
//消去全满行
boolean xiao = true;
int m = 1;
for(int i=0;i<21;i++)
{
for(int j=0;j<12;j++)
if(this.geZi[i][j]==0)
{
xiao = false;
break;
}
if(xiao==true)
{
score += 100*level*(m++);
for(int j=0;j<12;j++)
geZi[i][j] = 0;
for(int k=i-1;k>=0;k--)
for(int j=0;j<12;j++)
{
geZi[k+1][j] = geZi[k][j];
images[k+1][j] = images[k][j];
if(k==0)
geZi[k][j] = 0;
}
}
else
xiao = true;
}
//画游戏区192*336
for(int i=0;i<21;i++)
{
for(int j=0;j<12;j++)
{
if(this.geZi[i][j]==1)
{
if(this.images[i][j]!=null)
{
g.drawImage(this.images[i][j],5+j*16,5+i*16,this);
if(i==0)
System.out.print("("+i+","+j+")");
}
//遗忘图象数组的更新导致的问题
else
{
g.setColor(Color.black);
g.fillRect(2+j*16,i*16,16,16);
System.out.println("图片丢失"+i+":"+j);
}
}
}
}
//画当前方块
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(curr.fangKuai[i][j]==1)
g.drawImage(curr.getImage(),5+(j+curr.lie)*16,5+(i+curr.han)*16,this);
}
}
if(this.gameOver)
{
g.setColor(Color.BLACK);
g.setFont(new Font(null,Font.PLAIN,25));
g.drawString("GAME OVER!!",10,150);
}
FangKuai temp = next;
if(first)
{
temp = curr;
first = false;
}
//下一个方块
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(next.fangKuai[i][j]==1)
g.drawImage(temp.getImage(),192+(100-16*temp.width)/2+j*16,(100-16*temp.heith)/2+i*16,this);
}
//分数和等级
g.setColor(Color.blue.darker());
g.setFont(new Font(null,Font.PLAIN,20));
g.drawString(" level",192,125);
g.drawString(" score",192,165);
g.setFont(new Font(null,Font.PLAIN,15));
g.drawString(" "+this.level,192,145);
g.drawString(""+new DecimalFormat("000000").format(this.score),216,185);
//说明部分
g.drawString("s键开始",205,230);
g.drawString("t键暂停",205,250);
g.drawString("c键继续",205,270);
g.drawString("空格直接下落",205,290);
g.drawString("向上键变",205,310);
g.drawString("A加级B减级",205,330);
}
public void updateLevel()
{
speed = 300 - 30*level;
if(score<1200*(1+level)*level/2)
return;
else
{
level++;
speed -= 30;
}
}
//冲突检测1左2右3下4原地
public boolean canGo(int way)
{
if(way==4)
{
if(curr.lie<0)
curr.lie=0;
if(curr.lie+curr.width>12)
curr.lie = 12 - curr.width;
if(curr.han<0)
curr.han = 0;
if(curr.han+curr.heith>21)
curr.han = 21 - curr.heith;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(curr.fangKuai[i][j]==1&&this.geZi[i+curr.han][j+curr.lie]==1)
return false;
}
return true;
}
if(way==3)
{
if(curr.han+curr.getHeith()>20)
return false;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(curr.fangKuai[i][j]==1&&this.geZi[i+curr.han+1][j+curr.lie]==1)
return false;
}
return true;
}
else if(way==1)
{
if(curr.lie<1)
return false;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(curr.fangKuai[i][j]==1&&this.geZi[i+curr.han][j+curr.lie-1]==1)
return false;
}
return true;
}
else if(way==2)
{
if(curr.lie+curr.getWidth()>11)
return false;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(curr.fangKuai[i][j]==1&&this.geZi[i+curr.han][j+curr.lie+1]==1)
return false;
}
return true;
}
return false;
}
public void paint(Graphics g)
{
this.addImage();
g.drawImage(this.offscreen,0,0,this);
}
//重绘线程
public void run()
{
while(!this.gameOver)
{
Thread tt = Thread.currentThread();
long start = 0;
long end = 0;
if(this.gaming)
{
start = System.currentTimeMillis();
repaint();
down = true;
end = System.currentTimeMillis();
}
try
{
long time = speed+start-end;
if(time<=0)
time = 5;
tt.sleep(time);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public void keyTyped(KeyEvent e)
{
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
this.stop();
String str = "";
str = JOptionPane.showInputDialog(this,"","",JOptionPane.YES_OPTION);
if(str == null)
return;
if(str.equalsIgnoreCase("FUCK"))
{
if(this.records[0].score<40000)
JOptionPane.showMessageDialog(this,"别开玩笑了,这点分数也想玩隐藏,回去再练练吧","",JOptionPane.DEFAULT_OPTION);
else
{
JOptionPane.showMessageDialog(this,"开启隐藏模式","",JOptionPane.DEFAULT_OPTION);
this.fuck = true;
System.out.println("开启隐藏模式");
}
}
else if(str.equalsIgnoreCase("iamafraid"))
{
if(this.fuck)
{
JOptionPane.showMessageDialog(this,"关闭隐藏模式","",JOptionPane.DEFAULT_OPTION);
this.fuck = false;
System.out.println("关闭隐藏模式");
}
}
this.start();
}
if(e.getKeyCode()==KeyEvent.VK_S)
{
if(first2)
{
this.start();
first2 = false;
}
else if(this.gameOver)
{
this.gameStart();
this.start();
}
return;
}
if(!this.gaming)
{
if(e.getKeyCode()==KeyEvent.VK_C)
{
this.start();
return;
}
else if(e.getKeyCode()==KeyEvent.VK_G)
{
String output = "";
for(int i=0;i<=5;i++)
output += "第"+(i+1)+"名: "+records[i].name+" "+records[i].score+"\n";
JOptionPane.showMessageDialog(this,output,"高手风云榜",JOptionPane.DEFAULT_OPTION);
}
else if(e.getKeyCode()==KeyEvent.VK_A)
{
if(level==10)
return;
this.level++;
this.speed -= 30;
repaint();
}
else if(e.getKeyCode()==KeyEvent.VK_B)
{
if(level!=1)
{
this.level--;
this.speed += 30;
repaint();
}
}
}
//gaming状态下才起作用的热键
else
{
if(e.getKeyCode()==KeyEvent.VK_LEFT)
{
if(this.canGo(1))
{
this.curr.move(1);
repaint();
}
}
else if(e.getKeyCode()==KeyEvent.VK_RIGHT)
{
if(this.canGo(2))
{
this.curr.move(2);
repaint();
}
}
else if(e.getKeyCode()==KeyEvent.VK_UP)
{
FangKuai temp = new FangKuai();
temp.fangKuai = curr.fangKuai;
temp.width = curr.width;
temp.heith = curr.heith;
temp.han = curr.han;
temp.lie = curr.lie;
temp.image = curr.image;
curr.change();
if(this.canGo(4))
{
repaint();
}
else
curr = temp;
}
else if(e.getKeyCode()==KeyEvent.VK_DOWN)
{
if(this.canGo(3))
{
curr.move(3);
repaint();
}
}
else if(e.getKeyCode()==KeyEvent.VK_SPACE)
{
while(this.canGo(3))
curr.move(3);
curr.canMove = false;
repaint();
}
else if(e.getKeyCode()==KeyEvent.VK_T)
{
this.stop();
}
}
}
public void keyReleased(KeyEvent e)
{
// TODO: 在这添加你的代码
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -