Java游戲開發(fā)之俄羅斯方塊的實現(xiàn)
俄羅斯方塊小游戲
簡單的實現(xiàn)俄羅斯方塊,只有一個主代碼,很好理解的,有暫停/繼續(xù)、重新開始、結(jié)束游戲的簡單功能。這里就不多說實現(xiàn)的原理了,可以在網(wǎng)上進(jìn)行相關(guān)的查詢。這里就直接給出了源代碼,這個也是我參考網(wǎng)上的,自己進(jìn)行了相關(guān)的更改,增加了一些功能。
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;
import javax.swing.Timer;
public class MyGame extends JFrame {
public MyGame(){
GameBody gamebody=new GameBody();
gamebody.setBounds(5,10,500,600); //
gamebody.setOpaque(false);
gamebody.setLayout(null);
addKeyListener(gamebody);
add(gamebody);
int w=Toolkit.getDefaultToolkit().getScreenSize().width;
int h=Toolkit.getDefaultToolkit().getScreenSize().height;
JLabel image=new JLabel(new ImageIcon("13.jpg"));
image.setBounds(0,0,500,600);
getLayeredPane().setLayout(null);
getLayeredPane().add(image,new Integer(Integer.MIN_VALUE));
((JPanel)getContentPane()).setOpaque(false);
final JButton login=new JButton(new ImageIcon("login4.PNG"));
login.setContentAreaFilled(false);
login.setMargin(new Insets(0,0,0,0));
login.setBorderPainted(false);
login.setBounds(340,320,120,26);
gamebody.add(login);
login.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) { //登錄的按鈕
if(e.getSource()==login){
requestFocus(true); //獲得焦點(diǎn),不用失去焦點(diǎn)
gamebody.resetMap(); //重置地圖
gamebody.drawWall(); //沖重新繪制邊界墻體
gamebody.createshape(); //重新產(chǎn)生新的地圖
gamebody.setStart(false); //喚醒定時下落的線程
gamebody.score=0; //將分?jǐn)?shù)置為零
repaint();
}
}
});
final JButton pauselogin=new JButton(new ImageIcon("login6.PNG"));
pauselogin.setContentAreaFilled(false);
pauselogin.setMargin(new Insets(0,0,0,0));
pauselogin.setBorderPainted(false);
pauselogin.setBounds(340,370,120,26);
gamebody.add(pauselogin);
pauselogin.addMouseListener(new MouseListener(){ //暫停的按鈕
/* public void actionPerformed(ActionEvent e) { //用事件監(jiān)聽,沒用實現(xiàn)再次按暫停鍵后繼續(xù)游戲
//while(true){
if (e.getSource()==pauselogin)
{
gamebody.setStart(true);
requestFocus(true);
}if(e.getSource()==login){
new GameBody.setStart(false);
requestFocus(true);
}
//}
}*/
//鼠標(biāo)點(diǎn)擊事件,可以分別判斷不同的事件,做出不同的反應(yīng)
public void mouseClicked(MouseEvent e){
if(e.getButton()==e.BUTTON1 ){ //單擊左鍵暫停
gamebody.setStart(true); //將自動下落線程關(guān)閉
//requestFocus(true); //同時整個JFrame失去焦點(diǎn),無法操作,但可以點(diǎn)擊按鈕
}
else if(e.getButton()==e.BUTTON3 ){ //右擊暫停,繼續(xù)游戲
gamebody.setStart(false); //喚醒自動下落線程
requestFocus(true);
}
if(e.getClickCount()==2){ //左鍵雙擊,也可以繼續(xù)游戲
gamebody.setStart(false);
requestFocus(true);
}
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
});
final JButton overlogin=new JButton(new ImageIcon("login5.PNG")); //退出的按鈕
overlogin.setMargin(new Insets(0,0,0,0));
overlogin.setContentAreaFilled(false);
overlogin.setBounds(340,420,120,26);
overlogin.setBorderPainted(false);
add(overlogin);
overlogin.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(1);
}
});
setTitle("俄羅斯方塊 V.1.0");
setResizable(false);
setFocusable(true);
setBounds((w-500)/2,(h-600)/2,500,600);
setLayout(null);
setVisible(true);
setDefaultCloseOperation(3);
}
public static void main(String[] args) {
new MyGame();
}
//創(chuàng)建需要定義的局部變量和游戲類
class GameBody extends JPanel implements KeyListener{
private int shapeType=-1; //定義方塊的類型 定義的為7中
private int shapeState=-1; //定義方塊為何種狀態(tài),每種都有四種狀態(tài)
private int nextshapeType=-1; //定義下一塊產(chǎn)生的類型
private int nextshapeState=-1; //定義下一塊的方塊的狀態(tài)
private final int CELL=25; //定義方格的大小
private int score=0; //定義顯示的成績
private int left; //定義初始圖形與兩邊的墻的距離
private int top; //定義初始圖形與上下墻的距離
private int i=0; //表示列
private int j=0; //表示行
public int flag=0;
public volatile boolean start=false; //暫停的判斷條件,為輕量鎖,保持同步的
//public boolean start=false;
//Timer t;
Random randomcolor=new Random();
Random random=new Random();
//定義地圖的大小,創(chuàng)建二位的數(shù)組
int[][] map=new int[13][23];
//初始化地圖
public void resetMap(){
for(i=0;i<12;i++){
for(j=0;j<22;j++){ //遍歷的范圍不能小
map[i][j]=0;
}
}
}
//畫圍墻的方法
public void drawWall(){
for(j=0;j<22;j++) //0到21行
{
map[0][j]=2;
map[11][j]=2; //第0行和第11行為墻
}
for(i=0;i<12;i++){ //0到11列
map[i][21]=2; //第21行劃墻
}
}
//定義隨機(jī)的圖形種類
private final int[][][] shapes=new int[][][]{
// i
{ { 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 },
{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 } },
// s
{ { 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 },
{ 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } },
// z
{ { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } },
// j
{ { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 1, 1, 1, 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, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
// o
{ { 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, 0, 0, 0, 0, 0 } },
// l
{ { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 1, 0, 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 },
{ 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
// t
{ { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }
};
//產(chǎn)生新圖形的方法
public void createshape(){
if(shapeType==-1&&shapeState==-1){
shapeType = random.nextInt(shapes.length);
shapeState = random.nextInt(shapes[0].length);
}else{
shapeType=nextshapeType;
shapeState=nextshapeState;
}
nextshapeType = random.nextInt(shapes.length);
nextshapeState = random.nextInt(shapes[0].length);
//shapeType=(int)(Math.random()*1000)%7; //在7中類型中隨機(jī)選取
//shapeState=(int)(Math.random()*1000)%4; //在四種狀態(tài)中隨機(jī)選取
left=4; top=0; //圖形產(chǎn)生的初始位置為(4,0)\
if(gameOver(left,top)==1){
//判斷游戲
resetMap();
drawWall();
score=0;
JOptionPane.showMessageDialog(null, "GAME OVER");
}
}
//遍歷[4][4]數(shù)組產(chǎn)生的方塊并判斷狀態(tài)
public int judgeState(int left,int top,int shapeType,int shapeState){
for(int a=0;a<4;a++){
for(int b=0;b<4;b++){
if(((shapes[shapeType][shapeState][a*4+b]==1 && //遍歷數(shù)組中為1的個數(shù),即判斷是否有圖形
map[left+b+1][top+a]==1))|| //判斷地圖中是否還有障礙物
((shapes[shapeType][shapeState][a*4+b]==1 && //遍歷數(shù)組中為1的個數(shù),即判斷是否有圖形
map[left+b+1][top+a]==2))){ //判斷是否撞墻
return 0; //表明無法不能正常運(yùn)行
}
}
}
return 1;
}
//創(chuàng)建鍵盤事件監(jiān)聽
public void keyPressed(KeyEvent e){
//if (start){
switch(e.getKeyCode()){
case KeyEvent.VK_LEFT:
leftMove();//調(diào)用左移的方法
repaint();
break;
case KeyEvent.VK_RIGHT:
rightMove();//調(diào)用右移的方法
repaint();
break;
case KeyEvent.VK_DOWN:
downMove();//調(diào)用左移的方法
repaint();
break;
case KeyEvent.VK_UP:
turnShape();//調(diào)用變形的方法
repaint();
break;
}
// }
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
//創(chuàng)建左移的方法
public void leftMove(){
if(judgeState(left-1,top,shapeType,shapeState)==1){
left-=1;
}
}
//創(chuàng)建右移的方法
public void rightMove(){
if(judgeState(left+1,top,shapeType,shapeState)==1){
left+=1;
};
}
//創(chuàng)建下移的方法
public void downMove(){
if(judgeState(left,top+1,shapeType,shapeState)==1){ //判斷有圖形
top+=1;
deleteLine(); //判斷下移后是否有滿行
}
if(judgeState(left,top+1,shapeType,shapeState)==0){ //判斷沒有圖形
addshape(left,top,shapeType,shapeState);
createshape();
deleteLine();
}
}
//創(chuàng)建旋轉(zhuǎn)變形的方法
public void turnShape(){
int tempshape=shapeState;
shapeState=(shapeState+1)%4; //在四中的狀態(tài)中選取
if(judgeState(left,top,shapeType,shapeState)==1){
}
if(judgeState(left,top,shapeType,shapeState)==0){
shapeState=tempshape; //沒有圖形,不能進(jìn)行旋轉(zhuǎn),還原原來狀態(tài)
}
repaint();
}
//繪圖方法
public void paintComponent(Graphics g){
super.paintComponent(g);
int t=randomcolor.nextInt(5);
int count=randomcolor.nextInt(5);
Color[] color=new Color[]{Color.pink,Color.green,Color.red,Color.yellow,Color.blue};
/* Image image = null;
try {
image = ImageIO.read(new File("1.jpg"));
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
g.drawImage(image, 0, 0,this);
}*/
//繪制圍墻
for(j=0;j<22;j++){
for(i=0;i<12;i++){
if(map[i][j]==2){//判斷是否為墻并繪制
g.setColor(Color.blue);
g.fill3DRect(i*CELL,j*CELL,CELL,CELL,true);
}
if(map[i][j]==0){//判斷是否為墻并繪制
g.setColor(Color.red);
g.drawRoundRect(i*CELL,j*CELL,CELL,CELL,6,6);}
}
}
//繪制正在下落的圖形
for(int k=0;k<16;k++){
if(shapes[shapeType][shapeState][k]==1){
g.setColor(Color.red);
g.fill3DRect((left+k%4+1)*CELL,(top+k/4)*CELL,CELL,CELL,true); //left\top為左上角的坐標(biāo)
}
}
//繪制落下的圖形
for(j=0;j<22;j++){
for(i=0;i<12;i++){
if(map[i][j]==1){
g.setColor(Color.green);
g.fill3DRect(i*CELL,j*CELL,CELL,CELL,true);
}
}
}
//顯示右邊預(yù)覽圖形
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++){
if(shapes[nextshapeType][nextshapeState][i*4+j] == 1) {
g.setColor(Color.red);
g.fill3DRect(375+(j*(CELL-10)),190+(i*(CELL-10)), CELL-10, CELL-10,true);
}
}
}
//添加右邊預(yù)覽圖形方格
for(int i = 0; i < 5; i++) {
for(int j = 0; j < 5; j++){
g.setColor(Color.blue);
g.drawRoundRect(360+(j*(CELL-10)),175+(i*(CELL-10)),CELL-10, CELL-10,3,3);
}
}
g.setFont(new Font("楷書",Font.BOLD,20));
g.setColor(Color.BLUE);
g.drawString("游戲分?jǐn)?shù):", 310, 70);
g.setColor(Color.RED);
g.drawString(score+" ", 420, 70);
g.setColor(Color.BLUE);
g.drawString(" 分", 450, 70);
}
//創(chuàng)建添加新圖形到地圖的方法、
public void addshape(int left,int top,int shapeType,int shapeState){
int temp=0;
for(int a=0;a<4;a++){
for(int b=0;b<4;b++){ //對存儲方塊隊的[4][4]數(shù)組遍歷
if(map[left+b+1][top+a]==0){ //表明[4][4]數(shù)組沒有方塊
map[left+b+1][top+a]=shapes[shapeType][shapeState][temp];
}
temp++;
}
}
}
//創(chuàng)建消行的方法,即將滿行以上的部分整體下移
public void deleteLine(){
int tempscore=0; //定義滿行的列個數(shù)滿足1
for(int a=0;a<22;a++){ //對地圖進(jìn)行遍歷
for(int b=0;b<12;b++){
if(map[b][a]==1){ //表示找到滿行
tempscore++; // 記錄一行有多少個1
if(tempscore==10){
score+=10;
for(int k=a;k>0;k--){ //從滿行開始回歷
for(int c=1;c<12;c++){
map[c][k]=map[c][k-1]; //將圖形整體下移一行
}
}
}
}
}
tempscore=0;
}
}
//判斷游戲結(jié)束,1、判斷新塊的狀態(tài)是否不存在,即judgeState()==0
//2、判斷初始產(chǎn)生的位置是否一直為1;
public int gameOver(int left,int top){
if(judgeState(left,top,shapeType,shapeState)==0){
return 1;
}
return 0;
}
//創(chuàng)建構(gòu)造方法
public GameBody(){
resetMap();
drawWall();
createshape();
//Timer timer=new Timer(1000,new TimeListener());
Thread timer=new Thread(new TimeListener());
timer.start();
}
public void setStart(boolean start){ //改變start值的方法
this.start=start;
}
//創(chuàng)建定時下落的監(jiān)聽器
class TimeListener implements Runnable{
public void run(){
while(true){
if(!start){
try{
repaint();
if(judgeState(left,top+1,shapeType,shapeState)==1){
top+=1;
deleteLine();}
if(judgeState(left,top+1,shapeType,shapeState)==0){
if(flag==1){
addshape(left,top,shapeType,shapeState);
deleteLine();
createshape();
flag=0;
}
flag=1;
}
Thread.sleep(800);
}catch(Exception e){
e.getMessage();
}
}
}
}
}
}
} //外層
下面是游戲演示的一些界面效果圖:

這里說一下,我是把圖片和源代碼直接放在了一個文件夾下,對于初學(xué)者很好理解,這也是很好的練手項目。圖片什么的大家可以在網(wǎng)上直接找一個,然后重命名一下就可了。
以上就是Java游戲開發(fā)之俄羅斯方塊的實現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Java俄羅斯方塊的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用sharding-jdbc實現(xiàn)水平分庫+水平分表的示例代碼
本文主要介紹了使用sharding-jdbc實現(xiàn)水平分庫+水平分表,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12
java string類型轉(zhuǎn)換boolean類型的方法
下面小編就為大家?guī)硪黄猨ava string類型轉(zhuǎn)換boolean類型的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11
SpringBoot整合WebService服務(wù)的實現(xiàn)代碼
WebService是一個SOA(面向服務(wù)的編程)的架構(gòu),它是不依賴于語言,不依賴于平臺,可以實現(xiàn)不同的語言間的相互調(diào)用,通過Internet進(jìn)行基于Http協(xié)議的網(wǎng)絡(luò)應(yīng)用間的交互,這篇文章主要介紹了SpringBoot整合WebService服務(wù)的實例代碼,需要的朋友可以參考下2022-02-02
關(guān)于spring依賴注入的方式以及優(yōu)缺點(diǎn)
這篇文章主要介紹了關(guān)于spring依賴注入的方式以及優(yōu)缺點(diǎn),依賴注入,是IOC的一個方面,是個通常的概念,它有多種解釋,這概念是說你不用創(chuàng)建對象,而只需要描述它如何被創(chuàng)建,需要的朋友可以參考下2023-07-07
java使用篩選法求n以內(nèi)的素數(shù)示例(java求素數(shù))
這篇文章主要介紹了java使用篩選法求n以內(nèi)的素數(shù)示例(java求素數(shù)),需要的朋友可以參考下2014-04-04
springboot+thymeleaf+druid+mybatis 多模塊實現(xiàn)用戶登錄功能
這篇文章主要介紹了springboot+thymeleaf+druid+mybatis 多模塊實現(xiàn)用戶登錄功能,本文通過示例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07

