Java游戲開發(fā)拼圖游戲經典版
游戲介紹:
拼圖游戲是一款經典的益智游戲,游戲難度分為 簡單、正常、困難 三種難度,分別對應3*3,4*4,5*5布局,游戲開始前圖片被隨機打亂,空塊位于最右下角,玩家通過點擊空塊周圍圖片或者按鍵方式對圖片和空塊進行相互交換,直到所有圖片都回到原位即為游戲勝利。
本次制作的拼圖游戲運行界面如下:

使用素材文件夾:

鏈接: https://pan.baidu.com/s/10qE7yq6IwU-vWprvc5Axgw 提取碼: p16e
游戲設計的思路
對拼圖界面的圖像信息可以采用二維數組map進行存儲,數組存儲的是圖片ID,拼圖完成的map數組存儲的內容應該為從左到右,從上到下,圖片ID順序為1~8,最右下角的數 組元素存儲的圖片ID為-1(BLANK_STATE)。所有的移動操作可以簡化為對map的移動操作,每次移動完成調用repaint()對圖片按ID進行繪畫即可。使用文本存儲歷史記錄,每次過關對當前步數和歷史記錄進行比較和更新??紤]到數組map要求打亂后可以通過移動被還原,所以對數組的打亂必須有所講究,這里我們采用系統對原有圖片執(zhí)行10000次上下左右按鍵事件來對圖片進行打亂,最后再將空塊移動到最右下角,這樣圖片就順利地做到了隨機打亂。
圖片的獲取及顯示:
先根據關卡level來獲取關卡圖片,不同的關卡將分成不同數量的小塊,假如是簡單難度3*3地圖,小圖片的寬w是大圖片的寬的三分之一,小圖片的高h是大圖片的高的三分之一,第i張圖片的左上角起點的x值為圖片所在列數*小圖片寬(i%3*w),y值為圖片所在行數*小圖片高(i/3*h):
private void getPics() {
BufferedImage bufferedImage = null;
int width = 0,height = 0;
try {
bufferedImage = ImageIO.read(new File("D:/Game/JigsawGame/pic"+level+".png"));
width = bufferedImage.getWidth();
height = bufferedImage.getHeight();
} catch (IOException e) {
e.printStackTrace();
}
if(level==EASY){
pics = new Image[9];
int w = width/3;
int h = height/3;
for(int i=0;i<8;i++){
int x = i%3*w;
int y = i/3*h;
pics[i] = bufferedImage.getSubimage(x, y, w, h);
}
}else if(level==NORMAL){
pics = new Image[16];
int w = width/4;
int h = height/4;
for(int i=0;i<15;i++){
int x = i%4*w;
int y = i/4*h;
pics[i] = bufferedImage.getSubimage(x, y, w, h);
}
}else{
pics = new Image[25];
int w = width/5;
int h = height/5;
for(int i=0;i<24;i++){
int x = i%5*w;
int y = i/5*h;
pics[i] = bufferedImage.getSubimage(x, y, w, h);
}
}
}
public void paint(Graphics g){
g.clearRect(0, 0, this.getWidth(), this.getHeight());
for(int i=0;i<map.length;i++)
for(int j=0;j<map.length;j++){
if(map[i][j]!=BLANK_STATE){
//畫圖
g.drawImage(pics[map[i][j]-1],leftX+j*W,leftY+i*W,W,W,this);
}
}
}
游戲邏輯
對玩家執(zhí)行不同的操作進行分別處理:
①當玩家鼠標點擊
當玩家鼠標點擊的小圖片位于空塊上下左右方時,點擊的小圖片與空塊交換位置,否則點擊無效。
②當玩家按鍵移動
當空塊位于第一行時,moveDown()無效;
當空塊位于最后一行時,moveUp()無效;
當空塊位于第一列時,moveRight()無效;
當空塊位于最后一列時,moveLeft()無效;
此處的moveLeft()指的是小圖片移動的方向,也就是空塊移動的反方向。鼠標點擊事件的移動可以復用按鍵事件的移動方法,只需要將點擊的小圖片與數組下標進行轉換,再判斷下調用哪個方法即可。
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
int x = e.getX()-leftX;
int y = e.getY()-leftY;
if(x<0||y<0||x>600||y>600){//超出地圖范圍
return ;
}
//存儲數組行列下標
int i = y/W;
int j = x/W;
if(blank_x == i-1&&blank_y == j){//空塊在當前點擊塊的上側
moveUp();
}else if(blank_x == i+1&&blank_y == j){//空塊在當前點擊塊的下側
moveDown();
}else if(blank_x == i&&blank_y == j-1){//空塊在當前點擊塊的左側
moveLeft();
}else if(blank_x == i&&blank_y == j+1){//空塊在當前點擊塊的右側
moveRight();
}else{
return ;
}
repaint();
isWin();
}
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if(e.getKeyCode() == KeyEvent.VK_UP&&blank_x!=level+1){//上
moveUp();
}else if(e.getKeyCode() == KeyEvent.VK_DOWN&&blank_x!=0){//下
moveDown();
}else if(e.getKeyCode() == KeyEvent.VK_LEFT&&blank_y!=level+1){//左
moveLeft();
}else if(e.getKeyCode() == KeyEvent.VK_RIGHT&&blank_y!=0){//右
moveRight();
}else{
return ;
}
repaint();
isWin();
}
小圖片的移動
交換小圖片與空塊的值,并對空塊的數組下標重新賦值:
//空塊與上一格交換
private void moveDown(){
map[blank_x][blank_y] = map[blank_x-1][blank_y];
map[blank_x-1][blank_y] = BLANK_STATE;
blank_x = blank_x-1;
step++;
HelpPanel.nowStep.setText(step+"");
}
//空塊與下一格交換
private void moveUp(){
map[blank_x][blank_y] = map[blank_x+1][blank_y];
map[blank_x+1][blank_y] = BLANK_STATE;
blank_x = blank_x+1;
step++;
HelpPanel.nowStep.setText(step+"");
}
//空塊與左一格交換
private void moveRight(){
map[blank_x][blank_y] = map[blank_x][blank_y-1];
map[blank_x][blank_y-1] = BLANK_STATE;
blank_y = blank_y-1;
step++;
HelpPanel.nowStep.setText(step+"");
}
//空塊與右一格交換
private void moveLeft(){
map[blank_x][blank_y] = map[blank_x][blank_y+1];
map[blank_x][blank_y+1] = BLANK_STATE;
blank_y = blank_y+1;
step++;
HelpPanel.nowStep.setText(step+"");
}
打亂地圖信息
使用Math.Random()獲取隨機值,各個方向按鍵事件的概率是1/4,當符合條件時執(zhí)行移動方法并且移動次數+1,移動10000次實現隨機打亂地圖。
private void RandomTheMap() {
int i =0;
//嘗試移動一萬次
while(i<10000){
int rate = (int) (Math.random()*100);
if(rate<25&&blank_x!=level+1){
moveUp();
i++;
}else if(rate<50&&blank_x!=0){
moveDown();
i++;
}else if(rate<75&&blank_y!=level+1){
moveLeft();
i++;
}else if(rate<100&&blank_y!=0){
moveRight();
i++;
}
}
//再將空塊移動到最右下角
while(blank_x<level+1){
moveUp();
}
while(blank_y<level+1){
moveLeft();
}
step=0;
}
判斷輸贏
將現有map信息與正確的map信息一一對比,如果都相等,過關,比較當前記錄和歷史記錄,如果刷新歷史記錄進行記錄的更新,然后詢問是否開始下一關。如果開始下一關,進行l(wèi)evel++并對地圖及面板信息進行初始化:
private void isWin() {
boolean flag = true;
for(int i=0;i<successMap.length;i++){
for(int j=0;j<successMap.length;j++){
if(map[i][j] != successMap[i][j]){
flag = false;
break;
}
}
}
if(flag){
String msg;
int type;
int choice;
int record;
String title;
switch(level){//通關,是否進入下一關
case EASY:
this.removeKeyListener(this);
this.removeMouseListener(this);
record = mapUtil.getRecord(level);//歷史記錄
if(step<record){
msg = "恭喜你通過簡單關卡并刷新歷史記錄,完成步數是"+step+"\n歷史記錄是"+record+",是否要進入下一關?";
mapUtil.writeRecord(level, step);//更新歷史記錄
}else{
msg = "恭喜你通過簡單關卡,完成步數是"+step+"\n是否要進入下一關?";
}
type = JOptionPane.YES_NO_OPTION;
title = "過關";
choice = 0;
choice = JOptionPane.showConfirmDialog(null, msg,title,type);
if(choice==1){
System.exit(0);
}else if(choice == 0){
level++;
map = mapUtil.getMap(level);
successMap = mapUtil.getMap(level);
record = mapUtil.getRecord(level);//獲取正常難度的歷史記錄
initializeMap();//初始化地圖相關變量信息
RandomTheMap();//打亂圖案順序
step = 0;
HelpPanel.histotyStep.setText(record+"");
HelpPanel.panelCenter.setSuccessPic(level);
HelpPanel.nowLevel.setText("正常");
HelpPanel.nowStep.setText(step+"");
getPics();
this.addKeyListener(this);
this.addMouseListener(this);
repaint();
}
;break;
case NORMAL:
this.removeKeyListener(this);
this.removeMouseListener(this);
record = mapUtil.getRecord(level);//歷史記錄
if(step<record){
msg = "恭喜你通過正常關卡并刷新歷史記錄,完成步數是"+step+"\n歷史記錄是"+record+",是否要進入下一關?";
mapUtil.writeRecord(level, step);//更新歷史記錄
}else{
msg = "恭喜你通過正常關卡,完成步數是"+step+"\n是否要進入下一關?";
}
type = JOptionPane.YES_NO_OPTION;
title = "過關";
choice = 0;
choice = JOptionPane.showConfirmDialog(null, msg,title,type);
if(choice==1){
System.exit(0);
}else if(choice == 0){
level++;
map = mapUtil.getMap(level);
successMap = mapUtil.getMap(level);
initializeMap();//初始化地圖相關變量信息
RandomTheMap();//打亂圖案順序
getPics();
step = 0;
record = mapUtil.getRecord(level);//獲取困難難度的歷史記錄。
HelpPanel.histotyStep.setText(record+"");
HelpPanel.panelCenter.setSuccessPic(level);
HelpPanel.nowStep.setText(step+"");
HelpPanel.nowLevel.setText("困難");
this.addKeyListener(this);
this.addMouseListener(this);
repaint();
}
;break;
case HARD:
this.removeKeyListener(this);
this.removeMouseListener(this);
record = mapUtil.getRecord(level);//歷史記錄
if(step<record){
msg = "恭喜你通過困難關卡并刷新歷史記錄,完成步數是"+step+"\n歷史記錄是"+record;
JOptionPane.showMessageDialog(this, msg);
mapUtil.writeRecord(level, step);//更新歷史記錄
}else{
msg = "恭喜通過困難關卡,完成步數是"+step;
JOptionPane.showMessageDialog(this, msg);
}
;break;
}
}
}
歷史記錄的讀寫
采用文本形式對記錄進行保存,初始情況下,讀取記錄的時候如果沒有記錄文件進行文件的新建并初始所有歷史記錄為9999步;記錄的保存采用兩個逗號對三個關卡的歷史記錄進行分割,讀取后進行array.split(",")分割操作;寫入時,先清空原有文本信息,再將記錄合成字符串寫入文件。
//獲取關卡歷史記錄
public int getRecord(int level){
File file = new File("D://GameRecordAboutSwing");
if(!file.exists()){
file.mkdirs();
}
File record = new File("D://GameRecordAboutSwing/recordJigsawGame.txt");
try{
if(!record.exists()){//如果不存在,新建文本
record.createNewFile();
fos = new FileOutputStream(record);
dos = new DataOutputStream(fos);
String s = "9999,9999,9999";
dos.writeBytes(s);
System.out.println(record.isFile());;
}
//讀取記錄
fis = new FileInputStream(record);
dis = new DataInputStream(fis);
String str = dis.readLine();
array = str.split(",");
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if(fis!=null)
fis.close();
if(dis!=null)
dis.close();
if(fos!=null)
fos.close();
if(dos!=null)
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return Integer.parseInt(array[level-1]);
}
//更新關卡歷史記錄
public void writeRecord(int level,int step){
File record = new File("D://GameRecordAboutSwing/recordJigsawGame.txt");
try {
//清空原有記錄
FileWriter fileWriter =new FileWriter(record);
fileWriter.write("");
fileWriter.flush();
fileWriter.close();
//重新寫入文本
fos = new FileOutputStream(record);
dos = new DataOutputStream(fos);
array[level-1] = step+"";
String s = array[0]+","+array[1]+","+array[2];
dos.writeBytes(s);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(fos!=null)
fos.close();
if(dos!=null)
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
到這里核心的游戲邏輯及游戲面板的相關內容已經說明完了,涉及輔助面板類的東西會有些錯綜復雜,這里就不詳細介紹了。
完整源碼如下:
MapUtil類:
package 人物拼圖;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
public class MapUtil {
int[][] map;
FileInputStream fis = null;
FileOutputStream fos = null;
DataInputStream dis = null;
DataOutputStream dos = null;
String array[] = null;
int level = 1;
public static final int EASY = 1,NORMAL = 2,HARD = 3,BLANK_STATE = -1;
public int[][] getMap(int level){
switch(level){
case EASY:
map = new int[3][3];
for(int i=0;i<3;i++)
for(int j=0;j<3;j++){
map[i][j] = 3*i+j+1;
}
map[2][2] = BLANK_STATE;
;break;
case NORMAL:
map=new int[4][4];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++){
map[i][j] = 4*i+j+1;
}
map[3][3] = BLANK_STATE;
break;
case HARD:
map=new int[5][5];
for(int i=0;i<5;i++)
for(int j=0;j<5;j++){
map[i][j] = 5*i+j+1;
}
map[4][4] = BLANK_STATE;
break;
}
return map;
}
//獲取關卡歷史記錄
public int getRecord(int level){
File file = new File("D://GameRecordAboutSwing");
if(!file.exists()){
file.mkdirs();
}
File record = new File("D://GameRecordAboutSwing/recordJigsawGame.txt");
try{
if(!record.exists()){//如果不存在,新建文本
record.createNewFile();
fos = new FileOutputStream(record);
dos = new DataOutputStream(fos);
String s = "9999,9999,9999";
dos.writeBytes(s);
System.out.println(record.isFile());;
}
//讀取記錄
fis = new FileInputStream(record);
dis = new DataInputStream(fis);
String str = dis.readLine();
array = str.split(",");
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if(fis!=null)
fis.close();
if(dis!=null)
dis.close();
if(fos!=null)
fos.close();
if(dos!=null)
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return Integer.parseInt(array[level-1]);
}
//更新關卡歷史記錄
public void writeRecord(int level,int step){
File record = new File("D://GameRecordAboutSwing/recordJigsawGame.txt");
try {
//清空原有記錄
FileWriter fileWriter =new FileWriter(record);
fileWriter.write("");
fileWriter.flush();
fileWriter.close();
//重新寫入文本
fos = new FileOutputStream(record);
dos = new DataOutputStream(fos);
array[level-1] = step+"";
String s = array[0]+","+array[1]+","+array[2];
dos.writeBytes(s);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(fos!=null)
fos.close();
if(dos!=null)
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
MapUtil類主要用做對地圖數組信息的初始化以及歷史記錄的讀寫。
GamePanel類
package 人物拼圖;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements ActionListener ,MouseListener,KeyListener{
Image pics[];
int leftX=50,leftY=50;
int level,W;
int[][] map;
int[][] successMap;//最后結果
int blank_x,blank_y;//記錄空白塊的數組下標
int step = 0;
MapUtil mapUtil = new MapUtil();
int record;//存儲當前關卡記錄
public static final int EASY = 1,NORMAL = 2,HARD = 3,BLANK_STATE = -1;
public GamePanel(int level){
setSize(600, 600);
this.level = level;
map = mapUtil.getMap(level);
successMap = mapUtil.getMap(level);
initializeMap();//初始化地圖相關變量信息
RandomTheMap();//打亂圖案順序
this.setVisible(true);
this.addKeyListener(this);
this.addMouseListener(this);
this.setFocusable(true);
getPics();
record = mapUtil.getRecord(level);
HelpPanel.histotyStep.setText(record+"");
HelpPanel.nowStep.setText(step+"");
repaint();
}
public void paint(Graphics g){
g.clearRect(0, 0, this.getWidth(), this.getHeight());
for(int i=0;i<map.length;i++)
for(int j=0;j<map.length;j++){
if(map[i][j]!=BLANK_STATE){
//畫圖
g.drawImage(pics[map[i][j]-1],leftX+j*W,leftY+i*W,W,W,this);
}
}
}
private void initializeMap(){
switch(level){
case EASY:
blank_x=2;blank_y=2;
W = 200;
;break;
case NORMAL:
blank_x=3;blank_y=3;
W = 150;
;break;
case HARD:
blank_x=4;blank_y=4;
W = 120;
;break;
}
}
private void RandomTheMap() {
int i =0;
//嘗試移動一萬次
while(i<10000){
int rate = (int) (Math.random()*100);
if(rate<25&&blank_x!=level+1){
moveUp();
i++;
}else if(rate<50&&blank_x!=0){
moveDown();
i++;
}else if(rate<75&&blank_y!=level+1){
moveLeft();
i++;
}else if(rate<100&&blank_y!=0){
moveRight();
i++;
}
}
//再將空塊移動到最右下角
while(blank_x<level+1){
moveUp();
}
while(blank_y<level+1){
moveLeft();
}
step=0;
}
//空塊與上一格交換
private void moveDown(){
map[blank_x][blank_y] = map[blank_x-1][blank_y];
map[blank_x-1][blank_y] = BLANK_STATE;
blank_x = blank_x-1;
step++;
HelpPanel.nowStep.setText(step+"");
}
//空塊與下一格交換
private void moveUp(){
map[blank_x][blank_y] = map[blank_x+1][blank_y];
map[blank_x+1][blank_y] = BLANK_STATE;
blank_x = blank_x+1;
step++;
HelpPanel.nowStep.setText(step+"");
}
//空塊與左一格交換
private void moveRight(){
map[blank_x][blank_y] = map[blank_x][blank_y-1];
map[blank_x][blank_y-1] = BLANK_STATE;
blank_y = blank_y-1;
step++;
HelpPanel.nowStep.setText(step+"");
}
//空塊與右一格交換
private void moveLeft(){
map[blank_x][blank_y] = map[blank_x][blank_y+1];
map[blank_x][blank_y+1] = BLANK_STATE;
blank_y = blank_y+1;
step++;
HelpPanel.nowStep.setText(step+"");
}
private void getPics() {
BufferedImage bufferedImage = null;
int width = 0,height = 0;
try {
bufferedImage = ImageIO.read(new File("D:/Game/JigsawGame/pic"+level+".png"));
width = bufferedImage.getWidth();
height = bufferedImage.getHeight();
} catch (IOException e) {
e.printStackTrace();
}
if(level==EASY){
pics = new Image[9];
int w = width/3;
int h = height/3;
for(int i=0;i<8;i++){
int x = i%3*w;
int y = i/3*h;
pics[i] = bufferedImage.getSubimage(x, y, w, h);
}
}else if(level==NORMAL){
pics = new Image[16];
int w = width/4;
int h = height/4;
for(int i=0;i<15;i++){
int x = i%4*w;
int y = i/4*h;
pics[i] = bufferedImage.getSubimage(x, y, w, h);
}
}else{
pics = new Image[25];
int w = width/5;
int h = height/5;
for(int i=0;i<24;i++){
int x = i%5*w;
int y = i/5*h;
pics[i] = bufferedImage.getSubimage(x, y, w, h);
}
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if(e.getKeyCode() == KeyEvent.VK_UP&&blank_x!=level+1){//上
moveUp();
}else if(e.getKeyCode() == KeyEvent.VK_DOWN&&blank_x!=0){//下
moveDown();
}else if(e.getKeyCode() == KeyEvent.VK_LEFT&&blank_y!=level+1){//左
moveLeft();
}else if(e.getKeyCode() == KeyEvent.VK_RIGHT&&blank_y!=0){//右
moveRight();
}else{
return ;
}
repaint();
isWin();
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
int x = e.getX()-leftX;
int y = e.getY()-leftY;
if(x<0||y<0||x>600||y>600){//超出地圖范圍
return ;
}
//存儲數組行列下標
int i = y/W;
int j = x/W;
if(blank_x == i-1&&blank_y == j){//空塊在當前點擊塊的上側
moveUp();
}else if(blank_x == i+1&&blank_y == j){//空塊在當前點擊塊的下側
moveDown();
}else if(blank_x == i&&blank_y == j-1){//空塊在當前點擊塊的左側
moveLeft();
}else if(blank_x == i&&blank_y == j+1){//空塊在當前點擊塊的右側
moveRight();
}else{
return ;
}
repaint();
isWin();
}
private void isWin() {
boolean flag = true;
for(int i=0;i<successMap.length;i++){
for(int j=0;j<successMap.length;j++){
if(map[i][j] != successMap[i][j]){
flag = false;
break;
}
}
}
if(flag){
String msg;
int type;
int choice;
int record;
String title;
switch(level){//通關,是否進入下一關
case EASY:
this.removeKeyListener(this);
this.removeMouseListener(this);
record = mapUtil.getRecord(level);//歷史記錄
if(step<record){
msg = "恭喜你通過簡單關卡并刷新歷史記錄,完成步數是"+step+"\n歷史記錄是"+record+",是否要進入下一關?";
mapUtil.writeRecord(level, step);//更新歷史記錄
}else{
msg = "恭喜你通過簡單關卡,完成步數是"+step+"\n是否要進入下一關?";
}
type = JOptionPane.YES_NO_OPTION;
title = "過關";
choice = 0;
choice = JOptionPane.showConfirmDialog(null, msg,title,type);
if(choice==1){
System.exit(0);
}else if(choice == 0){
level++;
map = mapUtil.getMap(level);
successMap = mapUtil.getMap(level);
record = mapUtil.getRecord(level);//獲取正常難度的歷史記錄
initializeMap();//初始化地圖相關變量信息
RandomTheMap();//打亂圖案順序
step = 0;
HelpPanel.histotyStep.setText(record+"");
HelpPanel.panelCenter.setSuccessPic(level);
HelpPanel.nowLevel.setText("正常");
HelpPanel.nowStep.setText(step+"");
getPics();
this.addKeyListener(this);
this.addMouseListener(this);
repaint();
}
;break;
case NORMAL:
this.removeKeyListener(this);
this.removeMouseListener(this);
record = mapUtil.getRecord(level);//歷史記錄
if(step<record){
msg = "恭喜你通過正常關卡并刷新歷史記錄,完成步數是"+step+"\n歷史記錄是"+record+",是否要進入下一關?";
mapUtil.writeRecord(level, step);//更新歷史記錄
}else{
msg = "恭喜你通過正常關卡,完成步數是"+step+"\n是否要進入下一關?";
}
type = JOptionPane.YES_NO_OPTION;
title = "過關";
choice = 0;
choice = JOptionPane.showConfirmDialog(null, msg,title,type);
if(choice==1){
System.exit(0);
}else if(choice == 0){
level++;
map = mapUtil.getMap(level);
successMap = mapUtil.getMap(level);
initializeMap();//初始化地圖相關變量信息
RandomTheMap();//打亂圖案順序
getPics();
step = 0;
record = mapUtil.getRecord(level);//獲取困難難度的歷史記錄。
HelpPanel.histotyStep.setText(record+"");
HelpPanel.panelCenter.setSuccessPic(level);
HelpPanel.nowStep.setText(step+"");
HelpPanel.nowLevel.setText("困難");
this.addKeyListener(this);
this.addMouseListener(this);
repaint();
}
;break;
case HARD:
this.removeKeyListener(this);
this.removeMouseListener(this);
record = mapUtil.getRecord(level);//歷史記錄
if(step<record){
msg = "恭喜你通過困難關卡并刷新歷史記錄,完成步數是"+step+"\n歷史記錄是"+record;
JOptionPane.showMessageDialog(this, msg);
mapUtil.writeRecord(level, step);//更新歷史記錄
}else{
msg = "恭喜通過困難關卡,完成步數是"+step;
JOptionPane.showMessageDialog(this, msg);
}
;break;
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
GamePanel類主要涉及游戲面板的小圖片的讀取和顯示,以及全部游戲的邏輯。
SuccessPanel類:
package 人物拼圖;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class SuccessPanel extends JPanel{
int level;
Image[] pics;
int[][] map;
int W ;
MapUtil mapUtil;
private int leftX=10;
private int leftY=150;
public static final int EASY=1,NORMAL=2,HARD=3,BLANK_STATE=-1;
public SuccessPanel(int level){
setSuccessPic(level);
}
public void setSuccessPic(int level) {
mapUtil = new MapUtil();
this.level = level;
BufferedImage bufferedImage = null;
int width = 0,height = 0;
try {
bufferedImage = ImageIO.read(new File("D:/Game/JigsawGame/pic"+level+".png"));
width = bufferedImage.getWidth();
height = bufferedImage.getHeight();
} catch (IOException e) {
e.printStackTrace();
}
if(level == EASY){
pics = new Image[9];
map = mapUtil.getMap(level);
W = 40;
int w = width/3;
int h = height/3;
for(int i=0;i<8;i++){
int x = i%3*w;
int y = i/3*h;
pics[i] = bufferedImage.getSubimage(x, y, w, h);
}
}else if(level == NORMAL){
pics = new Image[16];
map = mapUtil.getMap(level);
W = 30;
int w = width/4;
int h = height/4;
for(int i=0;i<15;i++){
int x = i%4*w;
int y = i/4*h;
pics[i] = bufferedImage.getSubimage(x, y, w, h);
}
}else{
pics = new Image[25];
map = mapUtil.getMap(level);
W = 24;
int w = width/5;
int h = height/5;
for(int i=0;i<24;i++){
int x = i%5*w;
int y = i/5*h;
pics[i] = bufferedImage.getSubimage(x, y, w, h);
}
}
repaint();
}
public void paint(Graphics g){
for(int i=0;i<map.length;i++)
for(int j=0;j<map.length;j++){
if(map[i][j]!=BLANK_STATE){
//畫圖
g.drawImage(pics[map[i][j]-1],leftX+j*W,leftY+i*W,W,W,this);
}
}
}
}
SuccessPanel類負責游戲運行界面右下角完整拼圖順序的小圖片顯示;
HelpPanel類:
package 人物拼圖;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class HelpPanel extends JPanel {
private int level = 1;
public static final int EASY = 1,NORMAL = 2,HARD = 3,BLANK_STATE = -1;
static JLabel nowStep = new JLabel("0");
static JLabel histotyStep = new JLabel("9999");
static JLabel nowLevel = new JLabel();
JLabel levelLabel = new JLabel("當前難度:");
JLabel nowStepLabel = new JLabel("當前步數:");
JLabel historyStepLabel = new JLabel("歷史記錄:");
JButton button1 = new JButton("退出");
BorderLayout panel1 = new BorderLayout();//右側
JPanel panelNorth = new JPanel(new GridLayout(4,2,10,30));
static SuccessPanel panelCenter = new SuccessPanel(1);
public HelpPanel(int level){
setLevel(level);
this.setVisible(true);
this.setLayout(new BorderLayout());//當前面板
panelNorth.add(levelLabel);
panelNorth.add(nowLevel);
panelNorth.add(nowStepLabel);
panelNorth.add(nowStep);
panelNorth.add(historyStepLabel);
panelNorth.add(histotyStep);//歷史記錄
panelNorth.add(button1);
this.add(panelNorth,BorderLayout.NORTH);
this.add(panelCenter,BorderLayout.CENTER);
button1.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
System.exit(1);
}
});;
}
public void setLevel(int level){
this.level = level;
panelCenter.setSuccessPic(level);
if(level == EASY){
nowLevel.setText("簡單");
}else if(level == NORMAL){
nowLevel.setText("正常");
}else{
nowLevel.setText("困難");
}
}
}
HelpPanel類負責游戲運行界面右邊輔助面板的顯示,其中裝載了SuccessPanel;
GameClient類:
package 人物拼圖;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GameClient extends JFrame{
GamePanel panel2;
public GameClient(){
HelpPanel panel = new HelpPanel(1);
panel2 = new GamePanel(1);//難度簡單
panel2.setLayout(new BorderLayout());
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(panel,BorderLayout.EAST);
this.getContentPane().add(panel2,BorderLayout.CENTER);
this.setSize(850,750);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("人物拼圖游戲");
this.setVisible(true);
}
public static void main(String[] args) {
new GameClient();
}
}
GameClient類是游戲窗口類,裝載了游戲面板和輔助面板,用來開始游戲。
源碼已經粘貼完畢,最后再展示兩張游戲運行截圖:


到此這篇關于Java游戲開發(fā)拼圖游戲經典版的文章就介紹到這了,更多相關Java拼圖游戲內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解讀SpringBoot接收List<Bean>參數問題(POST請求方式)
這篇文章主要介紹了解讀SpringBoot接收List<Bean>參數問題(POST請求方式),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
如何應對spring框架的HTTP ERROR 400 Bad Request錯
這篇文章主要介紹了如何應對spring框架的HTTP ERROR 400 Bad Request錯誤返回問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
顯示IntelliJ IDEA工具的Run Dashboard功能圖文詳解
這篇文章主要介紹了顯示IntelliJ IDEA工具的Run Dashboard功能,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
Java Fluent Mybatis 項目工程化與常規(guī)操作詳解流程篇 下
Java中常用的ORM框架主要是mybatis, hibernate, JPA等框架。國內又以Mybatis用的多,基于mybatis上的增強框架,又有mybatis plus和TK mybatis等。今天我們介紹一個新的mybatis增強框架 fluent mybatis關于項目工程化與常規(guī)操作流程2021-10-10

