效果展示

一、效果展示
1.游戏界面
开始

成功

2.测试界面

二、项目介绍
1.总体需求
(1)在水平排列的7块石头上的左右各有3个类型相同的2种动物,中间的石头上没有动物。
(2)用鼠标单击一个动物:
①若“该动物前方的石头”上没有动物,该动物就跳跃到该石头上。
②若“该动物前方的石头”上有动物,但隔位的石头上无动物,该动物就越过自己前面的动物跳到隔位的石头上。
③其他情形时,该动物不跳跃(跳跃时不能越过2块石头)。
(3)左面的动物只能向右方跳跃,右面的动物只能向左方跳跃。
(4)用户可以通过单击界面上提供的按钮,随时撤销上一步的操作。
(5)用户可以随时单击界面上的按钮,重新开始游戏。
2.总体设计
项目结构共四个package,分别是data,test,gui,view。具体实现封装的12个类如图所示:

三、代码展示
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③ 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④ 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 saveAnimalStep; //存放动物走动的位置,以便恢复
HandleAnimalMove handleAnimalMove;//负责处理MouseEvent的监视器
HandleRedo handleRedo; //负责ActionEvent的监视器
HandleReStart handleReStart; //负责ActionEvent的监视器
public GamePanel(){
setLayout(null);
buttonRedo = new JButton("撤销");
buttonReStart = new JButton("重新开始");
saveAnimalStep = new Stack();
}
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③ 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④ 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四、代码测试
这里我们创建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