Java如何实现动物换位游戏

蜗牛 互联网技术资讯 2022-08-19 119 0

本篇内容介绍了“Java如何实现动物换位游戏”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    效果展示

    Java如何实现动物换位游戏  java 第1张

    一、效果展示

    1.游戏界面

    开始

    Java如何实现动物换位游戏  java 第2张

    成功

    Java如何实现动物换位游戏  java 第3张

    2.测试界面

    Java如何实现动物换位游戏  java 第4张

    二、项目介绍

    1.总体需求

    (1)在水平排列的7块石头上的左右各有3个类型相同的2种动物,中间的石头上没有动物。

    (2)用鼠标单击一个动物:

    ①若“该动物前方的石头”上没有动物,该动物就跳跃到该石头上。

    ②若“该动物前方的石头”上有动物,但隔位的石头上无动物,该动物就越过自己前面的动物跳到隔位的石头上。

    ③其他情形时,该动物不跳跃(跳跃时不能越过2块石头)。

    (3)左面的动物只能向右方跳跃,右面的动物只能向左方跳跃。

    (4)用户可以通过单击界面上提供的按钮,随时撤销上一步的操作。

    (5)用户可以随时单击界面上的按钮,重新开始游戏。

    2.总体设计

    项目结构共四个package,分别是data,test,gui,view。具体实现封装的12个类如图所示:

    Java如何实现动物换位游戏  java 第5张

    三、代码展示

    1.图形界面设计(gui包)

    主类:AppWindows类

    AppWindow类负责创建动物换位的主窗口,该类含有main方法,程序从该类开始执行。

    package ch2.gui;
    import javax.swing.*;
    import java.awt.*;
    import ch2.view.GamePanel;
    public class AppWindow extends JFrame {
        GamePanel gamePanel;
        public AppWindow(){
           setTitle("动物换位游戏");
           gamePanel = new GamePanel();
           gamePanel.setAnimalCount(6);
           gamePanel.setLeftAnimalImage("程序发布/image/cat.jpg");
           gamePanel.setRightAnimalImage("程序发布/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.用户操作设计(data包)

    ① Animal类

    Animal类创建的对象是AppWindow类的重要成员之一,用来表示“动物”。

    package ch2.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的一个子类,创建的对象是AppWindow类的成员之一,表示“左动物”。

    package ch2.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){//已经在最右面的点位置
              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){ //前面位置上是已经到达终点的动物
              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的一个子类,创建的对象是AppWindow类的成员之一,表示“右动物”。

    package ch2.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){  //已经在最左面的点位置
              return false;
          }
          if(allCanAtPoint[k-1].isHaveAnimal()==false) {//前面位置上没有动物
             this.setAtPoint(allCanAtPoint[k-1]);//动物到达allCanAtPoint[k-1]点
             successMove = true;
             p.setAtPointAnimal(null);           //p点设置为无动物
             return successMove ;
          }
          if((k-1)==0){   //前面位置上是已经到达终点的动物
              return false;
          }  
          if(allCanAtPoint[k-2].isHaveAnimal()==false) {//前方隔位上没有动物
             this.setAtPoint(allCanAtPoint[k-2]); //动物到达allCanAtPoint[k-2]点
             successMove = true;
             p.setAtPointAnimal(null);           //p点设置为无动物
             return successMove ;
          }
          return successMove ;  
       }  
    }
    ④ Point类

    Point类负责创建确定位置的对象,使用Point对象,可以确定动物以及石头对象在窗体中的位置。

    package ch2.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类的一个子类,用于实现动物方法的定义。

    package ch2.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.游戏视图设计(view包)

    ① AnmialView类

    AnimalView类是ViewForAnimal的一个子类,实现对动物操作的各种方法。

    package ch2.view;
    import java.awt.*;
    import ch2.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 ch2.view;
    import javax.swing.*;
    import java.awt.*;
    import ch2.data.Animal;
    import ch2.data.Point;
    import ch2.data.ViewForAnimal;
    import ch2.data.LeftAnimal;
    import ch2.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; //存放动物走动的位置,以便恢复
        HandleAnimalMove handleAnimalMove;//负责处理MouseEvent的监视器
        HandleRedo handleRedo;           //负责ActionEvent的监视器 
        HandleReStart handleReStart;    //负责ActionEvent的监视器
        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+"的个数不合理");
              System.exit(0);
           } 
           removeAll();  //首先移出曾添加到该容器中的全部组件
           animalCount = n;
           initPoitAndAnimal();  //初始化动物和位置对象
           initLeftAnimalView(); //初始化左边的动物视图
           initRightAnimalView();
           registerListener();   //注册监视器
        }
        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);
            //监视用户在动物视图上触发的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);
            //监视用户在按钮上触发的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类

    该类所创建的对象负责处理鼠标事件,实现动物位置的移动。

    package ch2.view;
    import java.awt.event.*;
    import javax.swing.JOptionPane;
    import ch2.data.Point;
    import ch2.data.Animal;
    import ch2.data.ViewForAnimal;
    import ch2.data.LeftAnimal;
    import ch2.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类

    该类所创建的对象负责处理鼠标事件,实现鼠标操作的撤销。

    package ch2.view;
    import ch2.data.Point;
    import ch2.data.Animal;
    import ch2.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类

    该类所创建的对象负责处理鼠标事件,实现游戏的重开功能。

    package ch2.view;
    import ch2.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);
           }  
         } 
    }

    四、代码测试

    这里我们创建test包,实现AppTest类来进行代码的测试,代码如下:

    package ch2.test;
    import ch2.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();
        }
    }

    “Java如何实现动物换位游戏”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注蜗牛博客网站,小编将为大家输出更多高质量的实用文章!

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    评论

    有免费节点资源,我们会通知你!加入纸飞机订阅群

    ×
    天气预报查看日历分享网页手机扫码留言评论Telegram