用java开发小猪斗恶狼游戏

项目效果演示

java小猪斗恶狼

背景介绍

来自大学第一次实训的项目,整理下项目思路。其中有些代码有参考价值。游戏的主要内容是要防止恶狼到达小猪的城堡。游戏的主要玩法是通过键盘的上下方向键来控制小猪的上下移动,通过按下空格进行发射子弹击落恶狼。

界面设计

介绍部分关键的界面

1.主界面

可以进行不同界面的选择

2.游戏界面

3.充值界面(充值功能没实现,可以选择转换为三连发模式、转换子弹为火箭)

 选择后的效果

4.失败界面

项目思路及部分代码

 utill---工具类

1.GameImage--对图片进行封装

package util;


import javafx.scene.image.Image;
import javafx.scene.image.PixelReader;
import javafx.scene.image.WritableImage;

import java.net.URL;

/**
 * 封装图片的加载操作
 */
public class GameImage {
	public static Image BACK1;
	public static Image AGAIN;
	public static Image BAZOOKA;
	public static Image CHANGE;
	public static Image THREEBURSTS;

	/** 游戏背景图片 */
	public static Image BACKGROUND;
	/** 微信支付图片 */
	public static Image payMent;
	/** 充值进入图片 */
	public static Image payEnter;
	/** 子弹图片 */
	public static Image BULLET;
	/** 绳子图片 */
	public static Image CORD;
	/** 小猪死亡图片 */
	public static Image DEAD;
	/** 水果图片 */
	public static Image FRUIT;
	/** 帮助界面的背景图片 */
	public static Image HELP;
	/** 菜单界面的背景图片 */
	public static Image LOGIN;
	/** 选项设置界面的背景图片 */
	public static Image OPTIONS;

	/** 排行榜界面的背景图片 */
	public static Image PAIHANG;
	/** 降落伞图片 */
	public static Image UMBRELLA;
	/** 勇敢的猪文字图片 */
	public static Image [] PIG_TEXT;
	/** 气球爆炸动画图片 */
	public static Image [] BALL;
	/** 轮盘动画图片 */
	public static Image [] GEAR;
	/** 菜单标签图片 */
	public static Image [] MENU;
	/** 小猪角色图片 */
	public static Image [] PIG;
	/** 狼角色图片 */
	public static Image [][] WOLF;

	public static void loadImages(){
		BACKGROUND = loadImage("image/background.jpg");
		BULLET = loadImage("image/bullet.gif");
		CORD = loadImage("image/cord.gif");
		DEAD = loadImage("image/dead.gif");
		FRUIT = loadImage("image/fruit.gif");
		HELP = loadImage("image/help.jpg");
		LOGIN = loadImage("image/login.jpg");
		OPTIONS = loadImage("image/options.jpg");
		PAIHANG = loadImage("image/paihang.JPG");
		UMBRELLA = loadImage("image/umbrella.gif");
		payMent = loadImage("image/payMent.jpg");
		payEnter = loadImage("image/payEnter.jpg");
		AGAIN=	loadImage("image/again.jpg");

		BACK1 =loadImage("image/BACK1.jpg");
		BAZOOKA=loadImage("image/bazooka.jpg");
		CHANGE=loadImage("image/change.jpg");
		THREEBURSTS=loadImage("image/Threebursts.jpg");

		PIG_TEXT= loadImage(new String[]{"image/pig1.gif","image/pig2.gif","image/pig3.gif",
				"image/pig4.gif","image/pig5.gif"});
		BALL = cutImage("image/ball.gif",4,100,80,true);
		GEAR = cutImage("image/gear.gif",2,103,59,true);
		MENU = cutImage("image/menu.gif",8,200,100,false);
		PIG = cutImage("image/pig.gif",10,100,83,true);
		WOLF = cutImage("image/wolf.gif",2,7,125,125);
	}

	/**
	 * 根据路径加载对应的图片
	 * @param url - 图片路径
	 * @return 加载完成后的Image对象
	 */
	public static Image loadImage(String url){
		if(url != null) {
			try {
				url = url.replace("\\","/");
				String path = url;
				System.out.println("path:" + path);
				if (url.indexOf(":") == -1 && url.indexOf("/") != -1) {
					String packageDirName = url.substring(0, url.lastIndexOf("/"));
					URL pathUrl = Thread.currentThread().getContextClassLoader()
							.getResources(packageDirName).nextElement();
					path = pathUrl + url.substring(url.lastIndexOf("/"));
				}
				Image img = new Image(path);

				return img;
			}catch(Exception e){
				e.printStackTrace();
			}

		}
		return null;

	}

	/**
	 * 根据路径数组加载对应的图片
	 * @param imgPathes - 图片路径数组
	 * @return 加载完成后的Image对象数组
	 */
	public static Image [] loadImage(String [] imgPathes){
		Image [] imgs = new Image[imgPathes.length];
		for(int i = 0;i < imgs.length;i++){
			//产生image对象并放在数组中
			imgs[i] = loadImage(imgPathes[i]);
		}

		return imgs;
	}

	/**
	 * 加载给定路径的图片并按照指定大小裁剪成一维Image对象数组
	 * @param url 图片的路径
	 * @param length 裁剪图片数量
	 * @param width 每张图片的宽
	 * @param height 每张图片的高
	 * @param horizontal true表示水平裁剪,false表示垂直裁剪
	 * @return 裁剪完成后的一维Image对象数组
	 */
	public static Image [] cutImage(String url,int length,int width,int height,boolean horizontal){
		Image [] imgs = new Image[length];
		Image image = loadImage(url);
		//获取图片资源对象
		PixelReader reader = image.getPixelReader();
		for(int i = 0;i < length;i++){
			if(horizontal){
				imgs[i] = new WritableImage(reader,i*width, 0 , width, height);
			}else{
				imgs[i] = new WritableImage(reader,0, i*height , width, height);
			}


		}
		return imgs;
	}
	/**
	 * 加载给定路径的图片并按照指定大小裁剪成二维Image对象数组
	 * @param url 图片路径
	 * @param length1 行数
	 * @param length2 列数
	 * @param width 每张图片的宽
	 * @param height 每张图片的高
	 * @return 裁剪完成后的二维Image对象数组
	 */
	public static Image [][] cutImage(String url,int length1,int length2,int width,int height){
		Image [][] imgs = new Image[length1][length2];
		Image image = loadImage(url);
		//获取图片资源对象
		PixelReader reader = image.getPixelReader();
		for(int i = 0;i < length1;i++){
			for(int j = 0;j < length2;j++){
				imgs[i][j] = new WritableImage(reader,j*width, i*height , width, height);
			}

		}
		return imgs;
	}


}

PixelReader和PixelWriter,是像素读取和像素入写的类。须要注意的是,我们只能从JavaFX的Image中读取像素,而像素入写,必须要对Writablelmage行进作操作。cutImage函数能实现对图片(如图所示)的分割。

然后loadImage和cutImage函数对图片进行封装后,在其他代码中引用Gameimage就可以调用想用的图片,如下图所示

2.LovoImage---实现往画布中添加元素的效果

package util;

import javafx.event.EventHandler;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Paint;

import java.net.URL;

/**
 * 图片组件
 * @author lenovo
 *
 */
public class LovoImage extends ImageView{
	/**图片宽度*/
	private int width;
	/**图片高度*/
	private int height;
	private BorderPane p;
	/**
	 * 构造方法
	 * @param url 图片URL路径
	 * @param x 组件X坐标
	 * @param y 组件Y坐标
	 * @param width 组件宽度
	 * @param height 组件高度
	 * @param container 加入容器
	 */
	public LovoImage(String url,int x,int y,int width,int height,Pane container) {
		this(url,x,y,width,height,container,false);
	}
	public LovoImage(Image image,int x,int y,int width,int height,Pane container) {
		this.setImage(image);
		this.width = width;
		this.height = height;

		this.setLayoutX(x);
		this.setLayoutY(y);

		p = new BorderPane();

		p.setLayoutX(x);
		p.setLayoutY(y);
		p.setPrefSize(width, height);
		p.setCenter(this);

//		Rectangle rectangle = new Rectangle(width,height, Color.RED);
//		rectangle.setLayoutX(x);
//		rectangle.setLayoutY(y);
//		rectangle.setWidth(width);
//		rectangle.setHeight(height);
//		p.setCenter(rectangle);
		container.getChildren().add(p);
//		container.getChildren().add(rectangle);
	}

	
	/**
	 * 构造方法
	 * @param url 图片URL路径
	 * @param x 组件X坐标
	 * @param y 组件Y坐标
	 * @param width 组件宽度
	 * @param height 组件高度
	 * @param container 加入容器
	 */
	public LovoImage(String url,int x,int y,int width,int height,Pane container,boolean border) {
		this.width = width;
		this.height = height;
		
		this.flushImage(url);
		this.setLayoutX(x);
		this.setLayoutY(y);
		
		BorderPane p = new BorderPane();
		p.setLayoutX(x);
		p.setLayoutY(y);
		p.setPrefSize(width, height);
		p.setCenter(this);
		
		if(border) {
			p.setBorder(this.getViewBorder());
		}


		
		container.getChildren().add(p);
	}
	
	/**
	 * 更新图片
	 * @param url 图片URL
	 */
	public void flushImage(String url) {
		if(url != null) {
			try {
				url = url.replace("\\","/");
				String path = url;
				System.out.println("path:" + path);
				if (url.indexOf(":") == -1 && url.indexOf("/") != -1) {
						String packageDirName = url.substring(0, url.lastIndexOf("/"));
						URL pathUrl = Thread.currentThread().getContextClassLoader()
								.getResources(packageDirName).nextElement();
						path = pathUrl + url.substring(url.lastIndexOf("/"));
				}
				System.out.println("path:" + path);
				Image img = new Image(path, width, height, false, false);

				this.setImage(img);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	private Border getViewBorder() {
		return  new Border(new BorderStroke(Paint.valueOf("#000"), 
				BorderStrokeStyle.SOLID, new CornerRadii(5), new BorderWidths(1)));
	}
	public void onMouseEntered(EventHandler<? super MouseEvent> var1) {
		p.setOnMouseEntered(var1);
	}
	public void onMouseExited(EventHandler<? super MouseEvent> var1) {
		p.setOnMouseExited(var1);
	}
	public void onMouseClicked(EventHandler<? super MouseEvent> var1) {
		p.setOnMouseClicked(var1);
	}
	
}

使用方法如图所示,可以控制图片的位置:

3.LovoCanvas----可以实现在画布上清除图片、文字,绘制图片、文字的效果

package util;

import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;

/**
 * Canvas组件
 */
public class LovoCanvas extends Canvas {

    private GraphicsContext graphics;

    public LovoCanvas(double x, double y, double width, double height, Pane container){
        super(width,height);
        this.setLayoutX(x);
        this.setLayoutX(y);
        container.getChildren().add(this);
        graphics = this.getGraphicsContext2D();

    }
    public void clearRect(double x, double y, double width, double height){
        graphics.clearRect(x,y,width,height);
    }

    public void fillRect(double x, double y, double width, double height, Color color){
        graphics.setFill(color);
        graphics.fillRect(x,y,width,height);
    }
    public void drawImage(Image image,double x,double y){
        graphics.drawImage(image, x, y);
    }
    public void drawImage(Image image,double x,double y,double width,double height){
        graphics.drawImage(image, x, y,width,height);
    }
    public void drawImage(Image image,double sx, double sy, double sw,
                          double sh, double dx, double dy, double dw, double dh){
        graphics.drawImage(image, sx, sy,sw,sh,dx,dy,dw,dh);
    }

    public void fillText(String text, double x,double y){
           graphics.fillText(text,x,y);
    };



}

在这个项目里可以控制气球、狼、小猪在画布中移动。使用示例:

 使用示例如下图所示:

4.MusicUtill--用于音乐的播放控制,跟gameImage的封装一个道理

package util;


import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;

public class MuiscUtil {
    public static  String  MUSIC_BK="audio/bk.wav";
    public  static String  MUSIC_BK_LOG="audio/bkLog.wav";
    public static  String  MUSIC_BLAST="audio/blast.wav";
    public static  String  MUSIC_CUT="audio/cut.wav";
    public static  String  MUSIC_ENTER="audio/enter.wav";
    public static  String  MUSIC_HP="audio/hp.wav";
    public static  String  MUSIC_ITEM="audio/item.wav";
    public static  String  MUSIC_OP="audio/op.wav";
    public static  String  MUSIC_SHOT="audio/shot.wav";
    public static  String  MUSIC_START="audio/start.wav";
    public static  String  MUSIC_WOLF="audio/wolf.wav";
    public static  String  MUSIC_WOLF_DOWN="audio/wolfdown.wav";

      public static MediaPlayer getMediaPlayer(Class clazz,String musicPath){

          return new  MediaPlayer(new Media(clazz.getClassLoader().getResource(musicPath).toString()));
      }

}

bean---角色类(进行图片角色属性和事件设置)

1.RoleBean---最重要的基类

 我们这个游戏会有气球、狼、猪、子弹这些角色,他们共同点在于:

1)他们都会出现在画布中,因此都必须要有对应的在画布中的位置(设计roleX、roleY属性)。

2)他们都是图片,同时都有自己的大小。(设计imgWith、imgHeight,currentimg属性)。

3)气球有四张连续的图片,被子弹打中四次后,就会爆炸,可以理解为Hp(血量)为4。同时子弹碰到气球就会消失,可以理解为Hp为1.同时设计的是气球爆了以后狼就会坠落,可以理解为狼的HP为1,当满足气球爆了的条件后,清除为0.同时每有一只狼进入城堡中,小猪的HP就会减一。清空游戏结束(设计isLive、HP属性)

4)当时他们都会运动(设置speed属性、move函数)

所以我们建立了RoleBean的类文件,作为一个基类。

package bean;

import javafx.scene.image.Image;
import util.LovoCanvas;

public abstract class RoleBean {
    protected Image currentImg;
    protected double roleX;
    protected  double roleY;
    protected  int imgWidth;
    protected  int imgHeight;
    protected boolean isLive;
    protected int HP;
    protected  int speed;
    public abstract void move();
    public abstract void move1();
    public abstract void move2();

    public abstract void drawRole(LovoCanvas canvas);

    public Image getCurrentImg() {
        return currentImg;
    }

    public void setCurrentImg(Image currentImg) {
        this.currentImg = currentImg;
    }

    public double getRoleX() {
        return roleX;
    }

    public void setRoleX(double roleX) {
        this.roleX = roleX;
    }

    public double getRoleY() {
        return roleY;
    }

    public void setRoleY(double roleY) {
        this.roleY = roleY;
    }

    public int getImgWidth() {
        return imgWidth;
    }

    public void setImgWidth(int imgWidth) {
        this.imgWidth = imgWidth;
    }

    public int getImgHeight() {
        return imgHeight;
    }

    public void setImgHeight(int imgHeight) {
        this.imgHeight = imgHeight;
    }

    public boolean isLive() {
        return isLive;
    }

    public void setIsLive(boolean isLive) {
        this.isLive = isLive;
    }

    public int getHP() {
        return HP;
    }

    public void setHP(int HP) {
        this.HP = HP;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public RoleBean(Image currentImg, double roleX, double roleY, int imgWidth, int imgHeight, int HP, int speed) {
        super();
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return super.toString();
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
    }

    public RoleBean(Image currentImg, double roleX, double roleY, int imgWidth, int imgHeight, boolean isLive, int HP, int speed) {
        this.currentImg = currentImg;
        this.roleX = roleX;
        this.roleY = roleY;
        this.imgWidth = imgWidth;
        this.imgHeight = imgHeight;
        this.isLive =true;
        this.HP = HP;
        this.speed = speed;
    }
}

2..BallBean

控制的是如图所示的气球元素,在设定中气球是要跟着恶狼一起移动的,当气球被打爆时,恶狼就会坠落。

比基类会多一个分数和图片下标,因为游戏设计的是当打中气球后就会加分。同时要通过切换图片下标来显示动画效果和气球现在的状态。同时还需要一个下标来表明是哪只狼的气球,用于控制狼死亡判断的触发事件。

package bean;

import javafx.scene.image.Image;
import util.LovoCanvas;

public class BallBean extends RoleBean{
    //球的图片
    private Image[] ballImg;
    //当前图片的下标
    private  int currentIndex;
    //属于该气球的狼
    private WolfBean wolfBean;
    //球的分数
    private int Ballscore;

    public BallBean(Image currentImg, double roleX, double roleY, int imgWidth, int imgHeight, boolean isLive, int HP, int speed, Image[] ballImg, int currentIndex, WolfBean wolfBean, int ballscore) {
        super(currentImg, roleX, roleY, imgWidth, imgHeight, isLive, HP, speed);
        this.ballImg = ballImg;
        this.currentIndex = currentIndex;
        this.wolfBean = wolfBean;
        Ballscore = ballscore;
    }

    @Override
    public void move() {
        if(this.isLive){
            this.roleY-=this.speed;
            //判断边界
            if(this.roleY<=-90){
                this.isLive=false;
            }
        }
    }

    @Override
    public void move1() { }

    @Override
    public void move2() { }

    @Override
    public void drawRole(LovoCanvas canvas) {
        if(this.isLive=true){
            canvas.drawImage(this.currentImg,this.roleX,this.roleY);
        }

    }

    public Image[] getBallImg() {
        return ballImg;
    }

    public void setBallImg(Image[] ballImg) {
        this.ballImg = ballImg;
    }

    public int getCurrentIndex() {
        return currentIndex;
    }

    public void setCurrentIndex(int currentIndex) {
        this.currentIndex = currentIndex;
    }

    public WolfBean getWolfBean() {
        return wolfBean;
    }

    public void setWolfBean(WolfBean wolfBean) {
        this.wolfBean = wolfBean;
    }

    public int getBallscore() {
        return Ballscore;
    }

    public void setBallscore(int ballscore) {
        Ballscore = ballscore;
    }
}

代码中的move函数用于判断气球是否到达顶点,当气球到达顶点后,狼开始走向城堡,所以isLive为false。 同时通过drawRole来控制气球的运动。

注意,画面中的坐标是这样的,如下图所示:

因此控制气球上移的代码是这样的,if(this.isLive){this.roleY-=this.speed;}。

2.WolfBean--控制狼的行为

狼的图片如下:

  通过GameImage中的cutImage函数,如图:

把图片分为了【2】【7】的图片数组。其中【0】【0】到【0】【3】是狼向右走的图片,【0】【4】到【0】【6】是狼抓着气球的图片,【1】【0】到【1】【3】是狼坠毁的图片,【1】【4】到【1】【6】是狼初始化,吹气球起飞的图片,下面是完整的动画效果

(狼先吹气球向右走然后起飞,中途可能被击落,然后扔掉气球,向右走。)

代码如下:

package bean;

import javafx.scene.image.Image;
import javafx.scene.media.MediaPlayer;
import util.GameImage;
import util.LovoCanvas;
import util.MuiscUtil;
import view.GameView;

/**
 *
 */
public class WolfBean extends  RoleBean{
    //狼的图片
    private Image[][] WolfImg;
    //position 0 向右走 1准备起飞(吹气球)2飞起来 3坠落
    private int position;

    private int currentIndex;
    //选择上升的位置
    private  int upPosition;
    //主游戏界面
    private  GameView gameView;

    public WolfBean(Image currentImg, double roleX, double roleY, int imgWidth, int imgHeight, boolean isLive, int HP, int speed, Image[][] wolfImg, int position, int currentIndex, int upPosition,GameView gameView) {
        super(currentImg, roleX, roleY, imgWidth, imgHeight, isLive, HP, speed);
        this.WolfImg = wolfImg;
        this.position = position;
        this.currentIndex = currentIndex;
        this.upPosition = upPosition;
        this.gameView=gameView;
    }

    @Override
    public void move() {
        if(isLive==true){
            if(this.position==0){
                this.roleX+=this.speed;
                if(this.roleX<=650){
                    //向右走
                    //修改x的坐标

                    this.currentImg= GameImage.WOLF[0][this.currentIndex++];
                    //移动效果———实时切换图片
                    if(currentIndex==4){
                        currentIndex=0;
                    }

                    //准备进入下一个状态
                    if(this.roleX>=this.upPosition&&this.roleY>=130){
                        //切换方位
                        this.position=1;
                        this.currentIndex=4;
                    }

                }else {
                    //获得播放器
                   MediaPlayer player = MuiscUtil.getMediaPlayer(WolfBean.class,MuiscUtil.MUSIC_CUT);
                    player.play();
                    //判断狼是否走到650的位置,割绳子
                    PigBean pigBean = gameView.getPigBean();
                    pigBean.setHP((pigBean.getHP()-1));
                    this.isLive=false;
                    if(pigBean.getHP()<=0){
                        //切换小猪的状态
                        pigBean.setIsLive(false);

                    }
                }
            }else if(this.position==1){
                //准备起飞
                this.currentImg=GameImage.WOLF[1][currentIndex++];
                if(currentIndex==7){
                    //切换方位
                    position=2;
                    currentIndex=4;
                    //创建气球
                    BallBean ballBean=new BallBean(GameImage.BALL[0],this.roleX+10,this.roleY-50,(int)(GameImage.BALL[0].getWidth()),(int)(GameImage.BALL[0].getHeight()),
                            true,3,this.speed,GameImage.BALL,0,this,1);
                    this.gameView.getBallBeanList().add(ballBean);
                }
                //把气球添加到气球的集合中




            } else if(this.position==2){
                //起飞(修改y的坐标)
                this.roleY-=this.speed;

                this.currentImg= GameImage.WOLF[0][this.currentIndex++];
                if(currentIndex==7){
                    currentIndex=4;
                }
                //切换方位
                if(this.roleY<=5){
                    position=0;
                    this.currentIndex=0;
                }

            }else if(position==3){
                //坠落,当气球无了
                this.roleY+=this.speed;
                this.currentImg=GameImage.WOLF[1][this.currentIndex++];
                if(this.currentIndex==4){
                    this.currentIndex=3;
                }
                //当狼落在地上的时候狼就死亡了
                if(this.roleY>=550){
                    this.isLive=false;
                    //获得播放器
                    MediaPlayer player =MuiscUtil.getMediaPlayer(WolfBean.class,MuiscUtil.MUSIC_WOLF_DOWN);
                    player.play();

                }

            }

        }
    }

    @Override
    public void move1() {
        }

    @Override
    public void move2() {

    }

    @Override
    public void drawRole(LovoCanvas canvas) {
        if(this.isLive==true){
        canvas.drawImage(this.currentImg,this.roleX,this.roleY);}

    }

    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }

    public Image[][] getWolfImg() {
        return WolfImg;
    }

    public void setWolfImg(Image[][] wolfImg) {
        WolfImg = wolfImg;
    }

    public int getCurrentIndex() {
        return currentIndex;
    }

    public void setCurrentIndex(int currentIndex) {
        this.currentIndex = currentIndex;
    }

    public int getUpPosition() {
        return upPosition;
    }

    public void setUpPosition(int upPosition) {
        this.upPosition = upPosition;
    }

    public GameView getGameView() {
        return gameView;
    }

    public void setGameView(GameView gameView) {
        this.gameView = gameView;
    }
}

 代码中用position来表示狼的状态---- 0 向右走 1准备起飞(吹气球)2飞起来 3坠落

在move函数中通过判断狼坐标、气球HP等控制狼的运动。在准备起飞的时候生成气球(位置稍高于狼的坐标)

同时也有判断是否进入城堡,扣除小猪血量的检测

在界面中,是通过GameImage的cutimage函数对狼、猪、气球的图片进行分割,然后根据发生的事件通过Rolebean等角色类的处理,更换图片。

其中狼有一个UpPosition属性,这是一个狼选择上升的位置,在界面中初始化这个值为随机的数,如图所示,增加游戏趣味性。

整体逻辑:

当狼向右走(position为1)时,可以是在底部的向右走,也可以是在顶部的向右走,两者的共同点在于都需要进行图片的切换,来实现对应的动画效果,两者的区别在于坐标是否超过了upPosition,如果没超过,需要实时检测是否大于upPosition,这时候就需要切换position为1(准备吹气球起飞)。如果已经超过了,就正常走,当x坐标大于650时,就相当于进入了城堡,就需要减少小猪的hp。
当狼准备吹气球起飞时,也需要切换图片实现动画效果,与此同时,生成一个与狼相对应的气球,当图片切换到第7张时,就进入起飞状态(设置position为2)
当狼在起飞的过程中,需要实时修改狼的y坐标,当到达顶点时(检测roleY是否小于5),狼又向右走(设置position为0)。同时当气球没了,就坠落(position为3),播放坠落的动画和声音。

设置坠落的逻辑是在界面中实现的,如下图所示:

3.BulletBean----控制子弹运动和事件

package bean;

import javafx.scene.image.Image;
import util.LovoCanvas;

public class BulletBean extends RoleBean {
    //子弹的图片
    private Image bulletImg;

    public BulletBean(Image currentImg, double roleX, double roleY, int imgWidth, int imgHeight, boolean isLive, int HP, int speed, Image bulletImg) {
        super(currentImg, roleX, roleY, imgWidth, imgHeight, isLive, HP, speed);
        this.bulletImg = bulletImg;
    }

    @Override
    public void move() {
        if(this.isLive){
            this.roleX-=this.speed;
        }
        if(this.roleX<=20){
            this.isLive=false;
        }
    }
    public void move1() {
        if(this.isLive){
            this.roleX-=this.speed;
            this.roleY+=this.speed-40;
        }
        if(this.roleX<=20){
            this.isLive=false;
        }
    }
    public void move2() {
        if(this.isLive){
            this.roleX-=this.speed;
            this.roleY-=this.speed-40;
        }
        if(this.roleX<=20){
            this.isLive=false;
        }
    }

    @Override
    public void drawRole(LovoCanvas canvas) {
        //绘制图片
        if(this.isLive){
        canvas.drawImage(bulletImg,this.roleX,this.roleY);}

    }
    //绘制图片

}

这里子弹有move、move1、move2三种运动方式,因为支付界面中有转化为三连发的操作,需要不同方向的子弹的移动。

4.PigBean----控制小猪运动和事件

package bean;

import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import util.GameImage;
import util.LovoCanvas;
import view.DeadView;
import view.GameView;
import view.WinView;

import java.util.TimerTask;


public class PigBean extends RoleBean {
private Image[] pigImg;
private  int currentImgIndex;
private Image  cordImg;
private  int cordLength;
private  boolean ok=true;


//主游戏面板
    private GameView gameView;

    public PigBean(Image currentImg, double roleX, double roleY, int imgWidth, int imgHeight, boolean isLive, int HP, int speed, Image[] pigImg, int currentImgIndex, Image cordImg, int cordLength,GameView gameView) {
        super(currentImg, roleX, roleY, imgWidth, imgHeight, isLive, HP, speed);
        this.pigImg = pigImg;
        this.currentImgIndex = currentImgIndex;
        this.cordImg = cordImg;
        this.cordLength = cordLength;
        this.gameView=gameView;

    }

    @Override
    public void move() {
    }

    @Override
    public void move1() {

    }

    @Override
    public void move2() {

    }

    @Override
    public void drawRole(LovoCanvas canvas) {
        if(this.isLive==true){
            //游戏胜利

            canvas.drawImage(this.currentImg,this.roleX,this.roleY);
            //画左边的绳子
            canvas.drawImage(cordImg,700,130,3,cordLength);
            //画右边的
            canvas.drawImage(cordImg,740,130,3,cordLength);
        }else{

            if(this.roleY<=480){
                this.roleY+=this.speed;

            }else{
                currentImgIndex=9;
                ok=false;
                //小猪死亡(在狼那里写了代码),这里是小猪死亡下坠的过程
                this.gameView.setPlay(false);
                Platform.runLater(()->{//游戏结束
                    Alert alert =new Alert(Alert.AlertType.INFORMATION);
                    alert.setTitle("");
                    alert.setContentText("your score:"+this.gameView.getScore());
                    alert.show();
                });
            }
            canvas.drawImage(GameImage.PIG[currentImgIndex++],this.roleX,this.roleY);
            if(currentImgIndex==9){
                currentImgIndex=0;
            }
        }


    }

    public int getCurrentImgIndex() {
        return currentImgIndex;
    }

    public void setCurrentImgIndex(int currentImgIndex) {
        this.currentImgIndex = currentImgIndex;
    }

    public Image getCordImg() {
        return cordImg;
    }

    public void setCordImg(Image cordImg) {
        this.cordImg = cordImg;
    }

    public int getCordLength() {
        return cordLength;
    }

    public void setCordLength(int cordLength) {
        this.cordLength = cordLength;
    }

    public boolean isOk() {
        return ok;
    }

    public void setOk(boolean ok) {
        this.ok = ok;
    }

}

 小猪有一根绳索,在控制小猪移动的时候需要控制绳索的长度变化。同时如同一个气球对应一只狼的逻辑一样,一只小猪对应一个游戏界面GameView,因为涉及到重新开始游戏,需要重新初始化小猪。

view——界面类(只介绍关键的)

每个界面中都有一个hanle函数,通过匿名内部类实现了对按钮事件的监听,来实现对应的效果。代码示例如下:

1.Main和MyAppView界面--实现舞台初始化和pig主角按键初始化

package view;

import javafx.application.Application;

public class Main {
    public static void main(String[] args) {

        Application.launch(MyAppView.class);
    }
}
package view;

import bean.BulletBean;
import bean.PigBean;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import util.GameImage;
import util.MuiscUtil;

public class MyAppView extends Application {
    private  Scene scene;
   private BorderPane root;

    @Override
    public void start(Stage stage ) throws Exception {
        GameImage.loadImages();

         root=new BorderPane();
        root.setCenter(new LoginView(root));
         scene=new Scene(root,800,600);
        stage.setScene(scene);
        stage.setResizable(false);
        this.pigMove();
        stage.setTitle("the rich pig");
        stage.show();
    }

    public Scene getScene() {
        return scene;
    }

    protected   void pigMove(){

    scene.setOnKeyPressed((e)->{
        GameView gameView=(GameView) root.getChildren().get(0);
        PigBean pigBean = gameView.getPigBean();
        if(pigBean.isLive()){
        if(e.getCode().getCode()== KeyCode.UP.getCode()){

            if(pigBean.getRoleY()>=130){
                pigBean.setRoleY(pigBean.getRoleY()-pigBean.getSpeed());
                //修改绳子的长度
                pigBean.setCordLength((int)(pigBean.getRoleY())-92);
            }
        }else if(e.getCode().getCode()==KeyCode.DOWN.getCode()){

            //修改小猪y坐标
            if(pigBean.getRoleY()<=500){
                pigBean.setRoleY(pigBean.getRoleY()+pigBean.getSpeed());
                pigBean.setCordLength((int)(pigBean.getRoleY())-92);
            }
        }else if(e.getCode().getCode()==KeyCode.LEFT.getCode()){

            //修改小猪y坐标
            if(pigBean.getRoleX()>=50){
                pigBean.setRoleX(pigBean.getRoleX()-pigBean.getSpeed());}
        }else if(e.getCode().getCode()==KeyCode.RIGHT.getCode()){

            //修改小猪y坐标
            if(pigBean.getRoleX()<=680){
                pigBean.setRoleX(pigBean.getRoleX()+pigBean.getSpeed());}
        }else if(e.getCode().getCode()==KeyCode.SPACE.getCode()){
            //创建子弹
            if(PayView.isChange==true){
                BulletBean bulletBean=new BulletBean(GameImage.BAZOOKA, pigBean.getRoleX(), pigBean.getRoleY(), (int)(GameImage.BAZOOKA.getWidth()),(int)(GameImage.BAZOOKA.getHeight()),true,0,50,GameImage.BAZOOKA);
                gameView.getBulletBeanList().add(bulletBean);
                //获得播放音乐的播放器
               MediaPlayer  player= MuiscUtil.getMediaPlayer(MyAppView.class,MuiscUtil.MUSIC_SHOT);
                //播放
                player.play();
            }else{BulletBean bulletBean=new BulletBean(GameImage.BULLET, pigBean.getRoleX(), pigBean.getRoleY()+15, (int)(GameImage.BULLET.getWidth()),(int)(GameImage.BULLET.getHeight()),true,0,50,GameImage.BULLET);
            gameView.getBulletBeanList().add(bulletBean);
                //获得播放音乐的播放器
                MediaPlayer  player= MuiscUtil.getMediaPlayer(MyAppView.class,MuiscUtil.MUSIC_SHOT);
                //播放
                player.play();}
            if(PayView.isPay==true){
                if(PayView.isChange==true){
                    BulletBean bulletBean1=new BulletBean(GameImage.BAZOOKA, pigBean.getRoleX(), pigBean.getRoleY(), (int)(GameImage.BAZOOKA.getWidth()),(int)(GameImage.BAZOOKA.getHeight()),true,0,50,GameImage.BAZOOKA);
                    gameView.getBulletBeanList1().add(bulletBean1);
                    BulletBean bulletBean2=new BulletBean(GameImage.BAZOOKA, pigBean.getRoleX(), pigBean.getRoleY(), (int)(GameImage.BAZOOKA.getWidth()),(int)(GameImage.BAZOOKA.getHeight()),true,0,50,GameImage.BAZOOKA);
                    gameView.getBulletBeanList2().add(bulletBean2);
                    //获得播放音乐的播放器
                    MediaPlayer  player= MuiscUtil.getMediaPlayer(MyAppView.class,MuiscUtil.MUSIC_SHOT);
                    //播放
                    player.play();
                }else{
                    BulletBean bulletBean1=new BulletBean(GameImage.BULLET, pigBean.getRoleX(), pigBean.getRoleY()+20, (int)(GameImage.BULLET.getWidth()),(int)(GameImage.BULLET.getHeight()),true,0,50,GameImage.BULLET);
                    gameView.getBulletBeanList1().add(bulletBean1);
                    BulletBean bulletBean2=new BulletBean(GameImage.BULLET, pigBean.getRoleX(), pigBean.getRoleY()+20, (int)(GameImage.BULLET.getWidth()),(int)(GameImage.BULLET.getHeight()),true,0,50,GameImage.BULLET);
                    gameView.getBulletBeanList2().add(bulletBean2);
                    //获得播放音乐的播放器
                    MediaPlayer  player= MuiscUtil.getMediaPlayer(MyAppView.class,MuiscUtil.MUSIC_SHOT);
                    //播放
                    player.play();
                }
            }

        }}else{
            new DeadView(root);
            System.out.println("1");
        }

        });


}


}

 小猪的具体逻辑有:上下方向键控制上下移动,同时要跟着绘制绳索。同时要判断是否使用了“外挂”,根据isChange和isPay会控制子弹的样式和数量。

2.GameView---多线程实现游戏进程控制

package view;

import bean.BallBean;
import bean.BulletBean;

import bean.PigBean;
import bean.WolfBean;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import util.GameImage;
import util.LovoCanvas;
import util.LovoImage;
import util.MuiscUtil;

import java.util.ArrayList;
import java.util.List;


public class GameView extends Pane implements Runnable{
    private BorderPane root;
    private Image gameImg;
    private LovoCanvas canvas;
    private PigBean pigBean;
  private List<BulletBean> bulletBeanList=new ArrayList<>();
  //加强版子弹
    private List<BulletBean> bulletBeanList1=new ArrayList<>();
    private List<BulletBean> bulletBeanList2=new ArrayList<>();
    //狼
    private List<WolfBean> wolfBeanList=new ArrayList<>();
    //产生狼的计时器
    private int createWolfTime=0;
    //充值进入界面
    protected LovoImage payEnterImg;
    LovoImage BACK1Img;
    //气球的集合
    private List<BallBean> ballBeanList=new ArrayList<>();
    private  int score;
    private boolean isPlay=true;

    private MediaPlayer player;
    public GameView(BorderPane root){
        player= MuiscUtil.getMediaPlayer(GameView.class,MuiscUtil.MUSIC_START);
        player.play();
        this.root=root;
        canvas=new LovoCanvas(0,0,800,600,this);
        pigBean=new PigBean(GameImage.PIG[0],680,130,(int)(GameImage.PIG[0].getWidth()),(int)(GameImage.PIG[0].getHeight()),true,3,30,GameImage.PIG,0,GameImage.CORD,0,this);
        payEnterImg = new LovoImage(GameImage.payEnter,0,300,10,10,this);
        BACK1Img=new LovoImage(GameImage.BACK1,700,20,10,10,this);
        this.handle();
        root.setCenter(this);
        //启动线程

        new Thread(this).start();

    }
    private  void handle(){

        root.setOnMouseClicked((e)->{
            if(pigBean.isOk()==false){
                this.setPlay(false);
                new DeadView(root);
            }
        });

        BACK1Img.setOnMouseClicked((e)->{
            this.setPlay(false);
            new LoginView(root);

        });
        payEnterImg.setOnMouseClicked((e)->{
            this.setPlay(false);
            new PayView(root);
        });
    }



    @Override
    //运行游戏的线程
    public void run() {

        while (isPlay) {
            if(this.getScore()==50){
            this.setPlay(false);
            Platform.runLater(()->{
                        Alert alert =new Alert(Alert.AlertType.INFORMATION);
                        alert.setTitle("");
                        alert.setContentText("you win");
                        alert.show();
                        new WinView(root);
                    }
            );
        }



            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //清理画布
            canvas.clearRect(0, 0, 800, 600);
            //重绘游戏界面
            canvas.drawImage(GameImage.BACKGROUND, 0, 0);
            canvas.drawImage(GameImage.FRUIT, 0, 50);
            canvas.getGraphicsContext2D().setFill(Color.RED);
            canvas.getGraphicsContext2D().setFont(new Font("黑体", 40));
            //画生命值
            canvas.fillText("X1", 75, 100);


            //重绘小猪
            pigBean.drawRole(canvas);
            //画分数
            canvas.fillText(score+"",135,45);

            //修改计时器
            createWolfTime++;
            //每一秒创建一个狼
            if(createWolfTime%5==0){
                createWolfTime=0;
                //新建狼
                WolfBean wolfBean =new WolfBean(GameImage.WOLF[0][0],-125,475,
                        (int)(GameImage.WOLF[0][0].getWidth()),(int)(GameImage.WOLF[0][0].getHeight()),
                        true,1,20,GameImage.WOLF,0,0, (int) (60+Math.floor(Math.random()*440)),this);
                wolfBeanList.add(wolfBean);
                //获得播放器
                player =MuiscUtil.getMediaPlayer(GameView.class,MuiscUtil.MUSIC_WOLF);
                player.play();
            }

            //加入狼的集合和绘制狼
            for (int i = 0; i < wolfBeanList.size(); i++) {
                WolfBean wolfBean1=wolfBeanList.get(i);
                if(wolfBean1.isLive()==true){
                    wolfBean1.drawRole(canvas);
                }else{
                    wolfBeanList.remove(wolfBean1);
                }
            }
            //狼移动
            for (int i = 0; i < wolfBeanList.size(); i++) {
                WolfBean wolfBean1=wolfBeanList.get(i);
                if(wolfBean1.isLive()==true){
                    wolfBean1.move();
                }else{
                    wolfBeanList.remove(wolfBean1);
                }
            }


            //绘制气球
            for (int i = 0; i < ballBeanList.size(); i++) {
                BallBean ballBean =ballBeanList.get(i);
                if(ballBean.isLive()){
                    ballBean.drawRole(canvas);
                }
            }
            //移动气球
            for (int i = 0; i < ballBeanList.size(); i++) {
                BallBean ballBean =ballBeanList.get(i);
                if(ballBean.isLive() == true){
                    ballBean.move();
                }else{
                    ballBeanList.remove(ballBean);
                    i--;
                }
            }
            //判断子弹是否与气球发生碰撞
            for (int i = 0; i < bulletBeanList.size(); i++) {
                BulletBean bulletBean =bulletBeanList.get(i);
                //遍历每一个气球
                for (int i1 = 0; i1 < ballBeanList.size(); i1++) {
                    //取出每一个气球
                    BallBean ballBean =ballBeanList.get(i1);
                    //判断子弹是否击中气球
                    if(
                            (ballBean.getRoleX()+ballBean.getImgWidth()>=bulletBean.getRoleX())&&
                            (bulletBean.getRoleX()+bulletBean.getImgWidth()>=ballBean.getRoleX())&&
                            (bulletBean.getImgHeight()+bulletBean.getRoleY()>=ballBean.getRoleY())&&
                            (ballBean.getRoleY()+ballBean.getImgHeight()>=bulletBean.getRoleY())
                    ){
                        //获得播放器
                        player =MuiscUtil.getMediaPlayer(GameView.class,MuiscUtil.MUSIC_BLAST);
                        player.play();
                        //System.out.println("ok");
                        bulletBean.setIsLive(false);
                        //改变气球的HP,更换被击中的图片
                        ballBean.setHP(ballBean.getHP()-1);
                        //判断气球是否死亡
                        if(ballBean.getHP()>0){
                            //修改图片的下标
                            int currentIndex =ballBean.getCurrentIndex();
                            ballBean.setCurrentImg(GameImage.BALL[++currentIndex]);

                        }else{
                            ballBean.setIsLive(false);
                            //加分数
                            this.score+=ballBean.getBallscore();
                            //设置狼的方向为坠落
                            ballBean.getWolfBean().setPosition(3);
                            //设置图片的下标
                            ballBean.getWolfBean().setCurrentIndex(0);
                        }

                    }
                }
            }
            for (int i = 0; i < bulletBeanList1.size(); i++) {
                BulletBean bulletBean =bulletBeanList1.get(i);
                //遍历每一个气球
                for (int i1 = 0; i1 < ballBeanList.size(); i1++) {
                    //取出每一个气球
                    BallBean ballBean =ballBeanList.get(i1);
                    //判断子弹是否击中气球
                    if(
                            (ballBean.getRoleX()+ballBean.getImgWidth()>=bulletBean.getRoleX())&&
                                    (bulletBean.getRoleX()+bulletBean.getImgWidth()>=ballBean.getRoleX())&&
                                    (bulletBean.getImgHeight()+bulletBean.getRoleY()>=ballBean.getRoleY())&&
                                    (ballBean.getRoleY()+ballBean.getImgHeight()>=bulletBean.getRoleY())
                    ){
                        //获得播放器
                        player =MuiscUtil.getMediaPlayer(GameView.class,MuiscUtil.MUSIC_BLAST);
                        player.play();
                        //System.out.println("ok");
                        bulletBean.setIsLive(false);
                        //改变气球的HP,更换被击中的图片
                        ballBean.setHP(ballBean.getHP()-1);
                        //判断气球是否死亡
                        if(ballBean.getHP()>0){
                            //修改图片的下标
                            int currentIndex =ballBean.getCurrentIndex();
                            ballBean.setCurrentImg(GameImage.BALL[++currentIndex]);

                        }else{
                            ballBean.setIsLive(false);
                            //加分数
                            this.score+=ballBean.getBallscore();
                            //设置狼的方向为坠落
                            ballBean.getWolfBean().setPosition(3);
                            //设置图片的下标
                            ballBean.getWolfBean().setCurrentIndex(0);
                        }

                    }
                }
            }
            for (int i = 0; i < bulletBeanList2.size(); i++) {
                BulletBean bulletBean =bulletBeanList2.get(i);
                //遍历每一个气球
                for (int i1 = 0; i1 < ballBeanList.size(); i1++) {
                    //取出每一个气球
                    BallBean ballBean =ballBeanList.get(i1);
                    //判断子弹是否击中气球
                    if(
                            (ballBean.getRoleX()+ballBean.getImgWidth()>=bulletBean.getRoleX())&&
                                    (bulletBean.getRoleX()+bulletBean.getImgWidth()>=ballBean.getRoleX())&&
                                    (bulletBean.getImgHeight()+bulletBean.getRoleY()>=ballBean.getRoleY())&&
                                    (ballBean.getRoleY()+ballBean.getImgHeight()>=bulletBean.getRoleY())
                    ){
                        //获得播放器
                        player =MuiscUtil.getMediaPlayer(GameView.class,MuiscUtil.MUSIC_BLAST);
                        player.play();
                        //System.out.println("ok");
                        bulletBean.setIsLive(false);
                        //改变气球的HP,更换被击中的图片
                        ballBean.setHP(ballBean.getHP()-1);
                        //判断气球是否死亡
                        if(ballBean.getHP()>0){
                            //修改图片的下标
                            int currentIndex =ballBean.getCurrentIndex();
                            ballBean.setCurrentImg(GameImage.BALL[++currentIndex]);

                        }else{
                            ballBean.setIsLive(false);
                            //加分数
                            this.score+=ballBean.getBallscore();
                            //设置狼的方向为坠落
                            ballBean.getWolfBean().setPosition(3);
                            //设置图片的下标
                            ballBean.getWolfBean().setCurrentIndex(0);
                        }

                    }
                }
            }


            //绘制子弹
            for (int i = 0; i < bulletBeanList.size(); i++) {
                //取出每颗子弹
                BulletBean bulletBean = bulletBeanList.get(i);
                if (bulletBean.isLive() == true) {
                    bulletBean.drawRole(canvas);
                } else {
                    bulletBeanList.remove(bulletBean);
                    i--;
                }

            }
            for (int i = 0; i < bulletBeanList.size(); i++) {
                //取出每颗子弹
                BulletBean bulletBean = bulletBeanList.get(i);
                if (bulletBean.isLive() == true) {
                    bulletBean.move();
                } else {
                    bulletBeanList.remove(bulletBean);
                    i--;
                }
            }
            for (int i = 0; i < bulletBeanList1.size(); i++) {
                //取出每颗子弹
                BulletBean bulletBean = bulletBeanList1.get(i);
                if (bulletBean.isLive() == true) {
                    bulletBean.drawRole(canvas);
                } else {
                    bulletBeanList1.remove(bulletBean);
                    i--;
                }

            }
            for (int i = 0; i < bulletBeanList1.size(); i++) {
                //取出每颗子弹,让他运动
                BulletBean bulletBean = bulletBeanList1.get(i);
                if (bulletBean.isLive() == true) {
                    bulletBean.move1();
                } else {
                    bulletBeanList1.remove(bulletBean);
                    i--;
                }
            }
            for (int i = 0; i < bulletBeanList2.size(); i++) {
                //取出每颗子弹
                BulletBean bulletBean = bulletBeanList2.get(i);
                if (bulletBean.isLive() == true) {
                    bulletBean.drawRole(canvas);
                } else {
                    bulletBeanList2.remove(bulletBean);
                    i--;
                }

            }
            for (int i = 0; i < bulletBeanList2.size(); i++) {
                //取出每颗子弹
                BulletBean bulletBean = bulletBeanList2.get(i);
                if (bulletBean.isLive() == true) {
                    bulletBean.move2();
                } else {
                    bulletBeanList2.remove(bulletBean);
                    i--;
                }
            }

            }
        }

    public PigBean getPigBean() {
        return pigBean;
    }

    public LovoCanvas getCanvas() {
        return canvas;
    }
    public List<BulletBean> getBulletBeanList() {
        return bulletBeanList;
    }

    public BorderPane getRoot() {
        return root;
    }

    public Image getGameImg() {
        return gameImg;
    }

    public List<BulletBean> getBulletBeanList1() {
        return bulletBeanList1;
    }

    public List<BulletBean> getBulletBeanList2() {
        return bulletBeanList2;
    }

    public List<BallBean> getBallBeanList() {
        return ballBeanList;
    }

    public int getScore() {
        return score;
    }

    public boolean isPlay() {
        return isPlay;
    }

    public void setPlay(boolean play) {
        isPlay = play;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

GameView继承Runnable 通过run函数开始游戏进程,在我的理解中,多进程,相当于增加了一个实时监听。相当于unity游戏引擎中的update函数(每一帧运行一次)。

因此,能在其中创建一个计时器,在run函数中sleep的时间是200ms,每次运行createWolfTime++;当%5=0时就新生成一只恶狼,这样就实现了每一秒生成一只恶狼,代码如下图所示:

同时建立了存储狼、气球、子弹的arraylist(可变大小数组)---bulletBeanList、wolfBeanList、ballBeanList,在线程中通过遍历数组进行类似于绘制、移动的操作,代码示例如下:

同时需要检测子弹是否撞击到了气球

java控制坐标是从左上角(0,0)开始,图片的坐标也是基于左上角进行移动,判断的逻辑如下图:

 判断的代码如下图:

 

3.PayView---进行子弹的升级

package view;

import bean.PigBean;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import util.GameImage;
import util.LovoCanvas;
import util.LovoImage;

public class PayView extends Pane {
    protected static boolean isPay;
    protected static boolean isChange;


    private BorderPane root;
    private LovoImage payMentImg;
    private LovoImage BACK1Img;
    private LovoImage changeImg;
    private LovoImage threeBurstsImg;


    public PayView(BorderPane root) {
        this.root = root;

        payMentImg = new LovoImage(GameImage.payMent, 0, -100, 824, 846, this);
        BACK1Img=new LovoImage(GameImage.BACK1,600,550,10,10,this);
        changeImg=new LovoImage(GameImage.CHANGE,380,120,157,28,this);
        threeBurstsImg=new LovoImage(GameImage.THREEBURSTS,350,450,110,222,this);
        this.handle();

        root.setCenter(this);


    }
    public void handle(){

        BACK1Img.setOnMouseClicked((e)->{

            new GameView(root);

        });
        changeImg.setOnMouseClicked((e)->{
            isChange=true;
        });
        threeBurstsImg.setOnMouseClicked((e)->{
            isPay=true;
        });

    }

    public BorderPane getRoot() {
        return root;
    }

    public void setRoot(BorderPane root) {
        this.root = root;
    }

    public LovoImage getPayMentImg() {
        return payMentImg;
    }

    public void setPayMentImg(LovoImage payMentImg) {
        this.payMentImg = payMentImg;
    }

    public LovoImage getBACK1Img() {
        return BACK1Img;
    }

    public void setBACK1Img(LovoImage BACK1Img) {
        this.BACK1Img = BACK1Img;
    }

    public static boolean isIsPay() {
        return isPay;
    }

    public static void setIsPay(boolean isPay) {
        PayView.isPay = isPay;
    }

    public static boolean isIsChange() {
        return isChange;
    }

    public static void setIsChange(boolean isChange) {
        PayView.isChange = isChange;
    }

}

 主要就是检测两个按钮是否按下,然后传递isPay和isChange两个全局参数,在MyAppview中的pigmove函数中判断是否更新子弹

4.DeadView--失败界面

package view;

import bean.PigBean;
import javafx.scene.Node;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import util.GameImage;
import util.LovoImage;

public class DeadView extends Pane {
    private BorderPane root;
    private LovoImage BACK1Img;
    private  LovoImage deadImg;
    private  LovoImage againImg;

    public  DeadView(BorderPane root){
        this.root =root;

        deadImg=new LovoImage(GameImage.DEAD,0,0,800,600,this);
        BACK1Img=new LovoImage(GameImage.BACK1,600,550,10,10,this);
        againImg=new LovoImage(GameImage.AGAIN,600,250,10,10,this);
        this.handle();
        root.setCenter(this);


    }
    public void handle(){


        BACK1Img.setOnMouseClicked((e)->{
            new LoginView(root);

        });
        againImg.setOnMouseClicked((e)->{
            new GameView(root);

        });
    }

    public DeadView() {
    }

    public DeadView(Node... nodes) {
        super(nodes);
    }
}


在MyAppView中的pigmove函数中会检测是否小猪死亡,然后会进入DeadView界面,代码如下图所示:

5.WinView --成功界面

package view;

import javafx.scene.Node;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import util.GameImage;
import util.LovoImage;

public class WinView extends Pane {
private BorderPane root;
private LovoImage winImg;
 private    LovoImage BACK1Img;


public   WinView(BorderPane root){
    this.root =root;

    winImg=new LovoImage(GameImage.PAIHANG,-180,0,800,600,this);
    BACK1Img=new LovoImage(GameImage.BACK1,600,550,10,10,this);
    this.handle();
    root.setCenter(this);
}
    public void handle(){

        BACK1Img.setOnMouseClicked((e)->{
            new LoginView(root);

        });}

    public BorderPane getRoot() {
        return root;
    }

    public void setRoot(BorderPane root) {
        this.root = root;
    }

    public LovoImage getWinImg() {
        return winImg;
    }

    public void setWinImg(LovoImage winImg) {
        this.winImg = winImg;
    }

    public LovoImage getBACK1Img() {
        return BACK1Img;
    }

    public void setBACK1Img(LovoImage BACK1Img) {
        this.BACK1Img = BACK1Img;
    }

    public WinView(Node... nodes) {
        super(nodes);
    }

}

 在GameView中触发这个条件的时候,就会进入WinView,如下图所示:

补: javaFX画面设置(容器大小---从大到小)    舞台->场景->面板->面板元素,代码就是根据这个控制画面元素的。

资源分享

源码和运行文件

链接:https://pan.baidu.com/s/1-RAaRcc_PYJ2jMoSzvVTew?pwd=alsw
提取码:alsw

同类型文章:

用java开发一个整活餐厅-CSDN博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值