Java實現(xiàn)動物換位游戲完整?過程詳解
效果展示

一、效果展示
1.游戲界面
開始

成功

2.測試界面

二、項目介紹
1.總體需求
(1)在水平排列的7塊石頭上的左右各有3個類型相同的2種動物,中間的石頭上沒有動物。
(2)用鼠標單擊一個動物:
①若“該動物前方的石頭”上沒有動物,該動物就跳躍到該石頭上。
②若“該動物前方的石頭”上有動物,但隔位的石頭上無動物,該動物就越過自己前面的動物跳到隔位的石頭上。
③其他情形時,該動物不跳躍(跳躍時不能越過2塊石頭)。
(3)左面的動物只能向右方跳躍,右面的動物只能向左方跳躍。
(4)用戶可以通過單擊界面上提供的按鈕,隨時撤銷上一步的操作。
(5)用戶可以隨時單擊界面上的按鈕,重新開始游戲。
2.總體設(shè)計
項目結(jié)構(gòu)共四個package,分別是data,test,gui,view。具體實現(xiàn)封裝的12個類如圖所示:

三、代碼展示
1.圖形界面設(shè)計(gui包)
主類:AppWindows類
AppWindow類負責(zé)創(chuàng)建動物換位的主窗口,該類含有main方法,程序從該類開始執(zhí)行。
package ch1.gui;
import javax.swing.*;
import java.awt.*;
import ch1.view.GamePanel;
public class AppWindow extends JFrame {
GamePanel gamePanel;
public AppWindow(){
setTitle("動物換位游戲");
gamePanel = new GamePanel();
gamePanel.setAnimalCount(6);
gamePanel.setLeftAnimalImage("程序發(fā)布/image/cat.jpg");
gamePanel.setRightAnimalImage("程序發(fā)布/image/dog.jpg");
add(gamePanel,BorderLayout.CENTER);
gamePanel.setBackground(Color.white);
JPanel northP = new JPanel();
northP.add(gamePanel.buttonReStart);
northP.add(gamePanel.buttonRedo);
add(northP,BorderLayout.NORTH);
setBounds(60,60,9*gamePanel.width+9*gamePanel.gap,300);
validate();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String args[] ){
AppWindow win = new AppWindow();
}
}2.用戶操作設(shè)計(data包)
① Animal類
Animal類創(chuàng)建的對象是AppWindow類的重要成員之一,用來表示“動物”。
package ch1.data;
public abstract class Animal {
String name ;
Point [] allCanAtPoint; //全部點位置
Point point; //動物當前所在的點位置
ViewForAnimal animalView; //動物的外觀視圖
public void setAtPoint(Point p) {
if(p!=null){
point = p;
point.setIsHaveAnimal(true);
point.setAtPointAnimal(this);
}
}
public Point getAtPoint() {
return point;
}
public void setAllCanAtPoint(Point [] point){
allCanAtPoint = point;
}
public void setAnimalView(ViewForAnimal animalView) {
this.animalView = animalView;
animalView.setAnimal(this);
}
public ViewForAnimal getAnimalView() {
return animalView;
}
public void setName(String s) {
name = s;
}
public String getName() {
return name;
}
public abstract boolean move();
}② LeftAnimal類
LeftAnimal類是Animal的一個子類,創(chuàng)建的對象是AppWindow類的成員之一,表示“左動物”。
package ch1.data;
public class LeftAnimal extends Animal{
public boolean move(){
int k = -1;
boolean successMove = false;
Point p = getAtPoint();
for(int i=0;i<allCanAtPoint.length;i++){
if(allCanAtPoint[i].equals(p)){
k = i; //找到動物當前所處的位置:allCanAtPoint[k]
break;
}
}
if(k==allCanAtPoint.length-1){//已經(jīng)在最右面的點位置
return false;
}
if(allCanAtPoint[k+1].isHaveAnimal()==false) { //前面位置上沒有動物
this.setAtPoint(allCanAtPoint[k+1]);
successMove = true;
p.setAtPointAnimal(null);
return successMove ;
}
if((k+1)==allCanAtPoint.length-1){ //前面位置上是已經(jīng)到達終點的動物
return false;
}
if(allCanAtPoint[k+2].isHaveAnimal()==false) {//前方隔位上沒有動物
this.setAtPoint(allCanAtPoint[k+2]);
successMove = true;
p.setAtPointAnimal(null);
return successMove ;
}
return successMove ;
}
}③ RightAnimal類
RightAnimal類是Animal的一個子類,創(chuàng)建的對象是AppWindow類的成員之一,表示“右動物”。
package ch1.data;
public class RightAnimal extends Animal{
public boolean move(){
int k = -1;
boolean successMove = false;
Point p = getAtPoint();
for(int i=0;i<allCanAtPoint.length;i++){
if(allCanAtPoint[i].equals(p)){
k = i;
break;
}
}
if(k==0){ //已經(jīng)在最左面的點位置
return false;
}
if(allCanAtPoint[k-1].isHaveAnimal()==false) {//前面位置上沒有動物
this.setAtPoint(allCanAtPoint[k-1]);//動物到達allCanAtPoint[k-1]點
successMove = true;
p.setAtPointAnimal(null); //p點設(shè)置為無動物
return successMove ;
}
if((k-1)==0){ //前面位置上是已經(jīng)到達終點的動物
return false;
}
if(allCanAtPoint[k-2].isHaveAnimal()==false) {//前方隔位上沒有動物
this.setAtPoint(allCanAtPoint[k-2]); //動物到達allCanAtPoint[k-2]點
successMove = true;
p.setAtPointAnimal(null); //p點設(shè)置為無動物
return successMove ;
}
return successMove ;
}
}④ Point類
Point類負責(zé)創(chuàng)建確定位置的對象,使用Point對象,可以確定動物以及石頭對象在窗體中的位置。
package ch1.data;
public class Point{
int x,y;
boolean haveAnimal;
Animal animal=null; //在該點位置上的動物
public void setX(int x){
this.x=x;
}
public void setY(int y){
this.y=y;
}
public boolean isHaveAnimal(){
return haveAnimal;
}
public void setIsHaveAnimal(boolean boo){
haveAnimal=boo;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void setAtPointAnimal(Animal animal){
this.animal=animal;
if(animal!=null) {
haveAnimal = true;
}
else {
haveAnimal = false;
}
}
public Animal getAtPointAnimal(){
return animal;
}
}⑤ ViewForAnimal類
該類是JPanel類的一個子類,用于實現(xiàn)動物方法的定義。
package ch1.data;
import javax.swing.JPanel;
public abstract class ViewForAnimal extends JPanel {
public abstract void setAnimal(Animal animal);
public abstract void setImage(String name);
public abstract Animal getAnimal();
public abstract void setAnimalViewLocation(int x,int y);
public abstract void setAnimalViewSize(int w,int h);
}3.游戲視圖設(shè)計(view包)
① AnmialView類
AnimalView類是ViewForAnimal的一個子類,實現(xiàn)對動物操作的各種方法。
package ch1.view;
import java.awt.*;
import ch1.data.*;
public class AnimalView extends ViewForAnimal{
Animal animal;
Image image;
Toolkit tool;
public AnimalView() {
tool = getToolkit();
}
public void setAnimal(Animal animal){
this.animal = animal;
}
public void setImage(String name){
image = tool.getImage(name);
repaint();
}
public Animal getAnimal() {
return animal;
}
public void setAnimalViewLocation(int x,int y){
setLocation(x,y);
}
public void setAnimalViewSize(int w,int h){
setSize(w,h);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
int w=getBounds().width;
int h=getBounds().height;
g.drawImage(image,0,0,w,h,this);
}
}② GamePanel類
GamePanel類是JPanel的子類,用于游戲視圖的初始化。
package ch1.view;
import javax.swing.*;
import java.awt.*;
import ch1.data.Animal;
import ch1.data.Point;
import ch1.data.ViewForAnimal;
import ch1.data.LeftAnimal;
import ch1.data.RightAnimal;
import java.util.*;
import java.awt.geom.*;
public class GamePanel extends JPanel {
public int animalCount = -1;
public Point [] point ;
Animal [] leftAnimal,rightAnimal;
public ViewForAnimal [] leftAnimalView,rightAnimalView;//動物視圖
public int width =90,height=70; //動物視圖的大小
public int gap = 2; //動物之間的間隙
public JButton buttonRedo;//撤銷按鈕
public JButton buttonReStart;//重新開始游戲
public Stack<Point> saveAnimalStep; //存放動物走動的位置,以便恢復(fù)
HandleAnimalMove handleAnimalMove;//負責(zé)處理MouseEvent的監(jiān)視器
HandleRedo handleRedo; //負責(zé)ActionEvent的監(jiān)視器
HandleReStart handleReStart; //負責(zé)ActionEvent的監(jiān)視器
public GamePanel(){
setLayout(null);
buttonRedo = new JButton("撤銷");
buttonReStart = new JButton("重新開始");
saveAnimalStep = new Stack<Point>();
}
public void setAnimalCount(int n){
if(n%2 != 0 ||n<=1) {
System.out.println(n+"的個數(shù)不合理");
System.exit(0);
}
removeAll(); //首先移出曾添加到該容器中的全部組件
animalCount = n;
initPoitAndAnimal(); //初始化動物和位置對象
initLeftAnimalView(); //初始化左邊的動物視圖
initRightAnimalView();
registerListener(); //注冊監(jiān)視器
}
private void initPoitAndAnimal(){//初始化動物和位置對象
point = new Point[animalCount+1];
int posionX = width; //點的位置的x坐標
int posionY = height;
for(int i=0;i<point.length;i++) {
point[i] = new Point();
point[i].setX(posionX);
point[i].setY(posionY);
posionX = posionX+width+gap;
}
int m = animalCount/2;
leftAnimal = new LeftAnimal[m];
rightAnimal = new RightAnimal[m];
for(int i =0;i<leftAnimal.length;i++ ){
leftAnimal[i] = new LeftAnimal();
leftAnimal[i].setAtPoint(point[i]);
leftAnimal[i].setAllCanAtPoint(point);
}
for(int i =0;i<rightAnimal.length;i++ ){
rightAnimal[i] = new RightAnimal();
rightAnimal[i].setAtPoint(point[m+1+i]);
rightAnimal[i].setAllCanAtPoint(point);
}
}
private void initLeftAnimalView(){//初始化左邊的動物視圖
int m = animalCount/2;
leftAnimalView = new ViewForAnimal[m];
for(int i =0;i<leftAnimalView.length;i++ ){
leftAnimalView[i] = new AnimalView();
leftAnimal[i].setAnimalView(leftAnimalView[i]);
Point p = leftAnimal[i].getAtPoint();
int x = p.getX();
int y = p.getY();
add(leftAnimalView[i]);
//動物視圖所在位置和動物所在點相同:
leftAnimalView[i].setAnimalViewLocation(x,y);
leftAnimalView[i].setAnimalViewSize(width,height);
}
}
private void initRightAnimalView(){//初始化右邊的動物視圖
int m = animalCount/2;
rightAnimalView = new ViewForAnimal[m];
for(int i =0;i<rightAnimalView.length;i++ ){
rightAnimalView[i] = new AnimalView();
rightAnimal[i].setAnimalView(rightAnimalView[i]);
Point p = rightAnimal[i].getAtPoint();
int x = p.getX();
int y = p.getY();
add(rightAnimalView[i]);
rightAnimalView[i].setAnimalViewLocation(x,y);
rightAnimalView[i].setAnimalViewSize(width,height);
}
}
private void registerListener(){
handleAnimalMove = new HandleAnimalMove(this);
//監(jiān)視用戶在動物視圖上觸發(fā)的MouseEvent事件:
for(int i =0;i<rightAnimalView.length;i++ ){
rightAnimalView[i].addMouseListener(handleAnimalMove);
}
for(int i =0;i<leftAnimalView.length;i++ ){
leftAnimalView[i].addMouseListener(handleAnimalMove);
}
handleRedo = new HandleRedo(this);
handleReStart = new HandleReStart(this);
//監(jiān)視用戶在按鈕上觸發(fā)的ActionEvent事件:
buttonRedo.addActionListener(handleRedo);
buttonReStart.addActionListener(handleReStart);
}
public void setLeftAnimalImage(String pic){
if(animalCount==-1)
return;
for(int i =0;i<leftAnimalView.length;i++ ){
leftAnimalView[i].setImage(pic);
}
}
public void setRightAnimalImage(String pic){
if(animalCount==-1)
return;
for(int i =0;i<rightAnimalView.length;i++ ){
rightAnimalView[i].setImage(pic);
}
}
public void paintComponent(Graphics g){
int penHeight =12; //畫筆的高度
super.paintComponent(g);
int xStart =width+gap;
int yStart =2*height+penHeight/2;
int xEnd =(animalCount+2)*width+(animalCount+1)*2;
int yEnd =2*height+penHeight/2;
Line2D line=new Line2D.Double(xStart,yStart,xEnd,yEnd);
Graphics2D g_2d=(Graphics2D)g;
g_2d.setColor(Color.blue);
BasicStroke bs=
new BasicStroke(penHeight,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
g_2d.setStroke(bs);
g_2d.draw(line);
}
}③ HandleAnimalMove類
該類所創(chuàng)建的對象負責(zé)處理鼠標事件,實現(xiàn)動物位置的移動。
package ch1.view;
import java.awt.event.*;
import javax.swing.JOptionPane;
import ch1.data.Point;
import ch1.data.Animal;
import ch1.data.ViewForAnimal;
import ch1.data.LeftAnimal;
import ch1.data.RightAnimal;
public class HandleAnimalMove extends MouseAdapter {
GamePanel panel;
HandleAnimalMove(GamePanel panel){
this.panel = panel;
}
public void mousePressed(MouseEvent e){
ViewForAnimal animalView = (ViewForAnimal)e.getSource();
Animal animal = animalView.getAnimal();
Point pStart = animal.getAtPoint(); //得到動物移動前所在點
if(animal.move()) {
Point pEnd = animal.getAtPoint();//得到動物移動后所在點
int x = pEnd.getX();
int y = pEnd.getY();
animalView.setAnimalViewLocation(x,y);//讓動物視圖所在位置和動物所在點相同
panel.saveAnimalStep.push(pStart);
panel.saveAnimalStep.push(pEnd);
}
}
public void mouseReleased(MouseEvent e){
boolean success = true;
int n =panel.animalCount/2;
for(int i=0;i<n;i++){
Animal animal=panel.point[i].getAtPointAnimal();
success = success&&(animal instanceof RightAnimal);
animal=panel.point[n+1+i].getAtPointAnimal();
success = success&&(animal instanceof LeftAnimal);
if(success == false)
break;
}
if(success) {
JOptionPane.showMessageDialog(null,"您成功了","消息框",
JOptionPane.INFORMATION_MESSAGE);
}
}
}④ HandleRedo類
該類所創(chuàng)建的對象負責(zé)處理鼠標事件,實現(xiàn)鼠標操作的撤銷。
package ch1.view;
import ch1.data.Point;
import ch1.data.Animal;
import ch1.data.ViewForAnimal;
import java.awt.event.*;
public class HandleRedo implements ActionListener {
GamePanel panel;
HandleRedo(GamePanel panel){
this.panel = panel;
}
public void actionPerformed(ActionEvent e){ //撤銷移動動物的操作
if(panel.saveAnimalStep.empty())
return;
Point pEnd = panel.saveAnimalStep.pop();
Point pStart = panel.saveAnimalStep.pop();
Animal animal = pEnd.getAtPointAnimal();
pEnd.setIsHaveAnimal(false);
pEnd.setAtPointAnimal(null);
animal.setAtPoint(pStart);
ViewForAnimal animalView =animal.getAnimalView();
int x = pStart.getX();
int y = pStart.getY();
animalView.setAnimalViewLocation(x,y);//讓動物視圖所在位置和動物所在點相同
}
}⑤ HandleReStart類
該類所創(chuàng)建的對象負責(zé)處理鼠標事件,實現(xiàn)游戲的重開功能。
package ch1.view;
import ch1.data.ViewForAnimal;
import java.awt.event.*;
public class HandleReStart implements ActionListener {
GamePanel panel;
HandleReStart(GamePanel panel){
this.panel = panel;
}
public void actionPerformed(ActionEvent e){ //處理重新開始
panel.saveAnimalStep.clear();
for(int i=0;i<panel.point.length;i++) {
panel.point[i].setIsHaveAnimal(false);
}
for(int i =0;i<panel.leftAnimal.length;i++ ){
panel.leftAnimal[i].setAtPoint(panel.point[i]);
int x = panel.point[i].getX();
int y = panel.point[i].getY();
//讓動物視圖所在位置和動物所在點相同
ViewForAnimal animalView =panel.leftAnimal[i].getAnimalView();
animalView.setAnimalViewLocation(x,y);
}
for(int i =0;i<panel.rightAnimal.length;i++ ){
int m = panel.animalCount/2;
panel.rightAnimal[i].setAtPoint(panel.point[m+1+i]);
int x = panel.point[m+1+i].getX();
int y = panel.point[m+1+i].getY();
//讓動物視圖所在位置和動物所在點相同
ViewForAnimal animalView =panel.rightAnimal[i].getAnimalView();
animalView.setAnimalViewLocation(x,y);
}
}
}四、代碼測試
這里我們創(chuàng)建test包,實現(xiàn)AppTest類來進行代碼的測試,代碼如下:
package ch1.test;
import ch1.data.*;
public class AppTest {
public static void main(String [] args) {
Point [] point = new Point[7];
for(int i=0;i<point.length;i++) {
point[i] = new Point();
point[i].setX(i);
point[i].setY(10);
}
Animal [] left = new Animal[3];
Animal [] right = new Animal[3];
for(int i =0;i<left.length;i++ ){
left[i] = new LeftAnimal();
left[i].setName("貓"+i);
left[i].setAtPoint(point[i]);
left[i].setAllCanAtPoint(point);
}
for(int i =0;i<right.length;i++ ){
right[i] = new RightAnimal();
right[i].setName("狗"+i);
right[i].setAtPoint(point[4+i]);
right[i].setAllCanAtPoint(point);
}
input(point);
if(right[0].move())
input(point);
if(left[2].move())
input(point);
if(left[1].move())
input(point);
if(right[0].move())
input(point);
if(right[1].move())
input(point);
if(right[2].move())
input(point);
if(left[2].move())
input(point);
if(left[1].move())
input(point);
if(left[0].move())
input(point);
if(right[0].move())
input(point);
if(right[1].move())
input(point);
if(right[2].move())
input(point);
if(left[1].move())
input(point);
if(left[0].move())
input(point);
if(right[2].move())
input(point);
}
static void input(Point [] point){
for(int i=0;i<point.length;i++){
Animal animal=point[i].getAtPointAnimal();
if(animal!=null)
System.out.print(animal.getName());
else
System.out.print(" ");
}
System.out.println();
}
}五、所需圖像
預(yù)備名字分別為dog.jpg和cat.jpg的圖像文件,它們分別是左右動物所使用的圖像。

dog.jpg

cat.jpg
六、總結(jié)
本項目是很多大學(xué)課程設(shè)計中常見的題目之一,通過該項目的實現(xiàn),可以使開發(fā)者鞏固所學(xué)Java語言知識,增進Java語言編輯基本功,掌握JDK、IDEA等開發(fā)工具的運用,拓寬常用類庫的應(yīng)用。
通過該項目的實操,開發(fā)者可以把所學(xué)及相關(guān)知識加以融會貫通,全面掌握Java語言的編程思想及面向?qū)ο蟪绦蛟O(shè)計的方法,為今后從事實際工作打下堅實的基礎(chǔ)。
到此這篇關(guān)于Java實現(xiàn)動物換位游戲完整 過程詳解的文章就介紹到這了,更多相關(guān)Java動物換位內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決IDEA項目external libraries依賴包消失的問題
有時候電腦重啟后,再打開IDEA上的項目時會出現(xiàn)external libraries目錄下的依賴包都消失了的情況,只剩下了一個JDK的包,本文給大家介紹了解決IDEA項目external libraries依賴包消失的辦法,需要的朋友可以參考下2024-02-02
SpringMVC高級開發(fā)功能實現(xiàn)過程解析
這篇文章主要介紹了SpringMVC高級開發(fā)功能實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06
springboot?vue測試平臺接口定義前后端新增功能實現(xiàn)
這篇文章主要介紹了springboot?vue測試平臺接口定義前后端新增功能實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05
java使用common-httpclient包實現(xiàn)post請求方法示例
這篇文章主要給大家介紹了關(guān)于java使用common-httpclient包實現(xiàn)post請求的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
使用Springboot+poi上傳并處理百萬級數(shù)據(jù)EXCEL
這篇文章主要介紹了使用Springboot+poi上傳并處理百萬級數(shù)據(jù)EXCEL,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12
Spring security基于數(shù)據(jù)庫中賬戶密碼認證
這篇文章主要介紹了Spring security基于數(shù)據(jù)庫中賬戶密碼認證,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03

