保卫萝卜项目(java端)

注:游戏开发样式借鉴原“保卫萝卜3”
运用技术
1:java 继承 封装 多肽 以及绘图工具 文件的输入流
开发工具 Eclipse ps。
界面效果
1:游戏启动窗口
在这里插入图片描述
2:冒险模式
在这里插入图片描述

3:关卡内效果
在这里插入图片描述
在这里插入图片描述

部分代码展示
1:角色工厂

package game;

import java.util.ArrayList;

import org.omg.CORBA.PUBLIC_MEMBER;

import game.Attack.Attacks;
import game.Attack.Attacks;
import game.Explod.Explod_T;
import game.FormArea.*;
import game.MaoxianWindow.*;
import game.MaoxianWindow.ChangJing1.*;
import game.MaoxianWindow.GuanKa.GuanKa;
import game.MaoxianWindow.GuanKa.GuanKa1;
import game.Monsters.*;
import game.Obstacles.*;
import game.Paota.*;
import game.StartWindow.*;
import game.Themes.*;

public class Factory {
	// 游戏中最开始被默认隐藏的角色
	// 窗口选择(初始都为不显示)
	// 游戏主窗口
	public static StartWindow startWindow = null;
	// 关卡窗口
	public static ThemesWindow ThemesWindow = null;
	// 冒险窗口
	public static MaoxianWindow maoxianWindow = null;
	// 选择关卡窗口
	public static ChangeGuanKaWindow changethemeswindow = null;
	// 金币
	public static FormArea formarer = new FormArea(198,30);
	// 菜单按钮
	public static Form form = new Form(760, 30);
	// 暂停
	public static Stop stop = new Stop(700, 32);
	public static GameStop gamestop = new GameStop(430, 34);
	// 初始游戏窗口选项按钮
	public static Maoxian maoxian = new Maoxian(100, 420);
	public static Boss boss = new Boss(410, 420);
	public static Guaiwu guaiwu = new Guaiwu(720, 420);
	// 关卡的选择
	public static Getback getback = new Getback(50, 33);
	public static Return ret = new Return(200, 415);
	public static ChangJing1 changjing1 = new ChangJing1(50, 100);
	public static ChangJing2 changjing2 = new ChangJing2(400, 100);
	public static ChangJing3 changjing3 = new ChangJing3(750, 100);
	public static ChangJing4 changjing4 = new ChangJing4(50, 300);
	public static ChangJing5 changjing5 = new ChangJing5(400, 300);
	public static More more = new More(750, 300);
	public static GuanKa guanka = null;
	//大关卡
	public static int DaGuanKa = 0;
	// 障碍物
	public static ArrayList<Obstacles> obstacle = new ArrayList<Obstacles>();
	// 菜单
	public static GameMenue gamemenue = new GameMenue(312, 126);
	// 萝卜
	public static Luobu luobu = new Luobu();
	// 游戏中怪物的行走路径
	public static RoadWay roadWay = new RoadWay();
	// 把场景创建进角色工厂
	public static Theme theme = null;
	// 炮塔动态数组
	public static ArrayList<Paota> paotas = new ArrayList<Paota>();
	//选地
	public static Location change =new Location();
	//建塔
	public static PaotaCard paotacards=new PaotaCard();
	//升级
	public static Upup up=new Upup();
	//加载中。。。
	public static boolean Loading = false;
	//倒数
	public static boolean Daoshu=false;
	// 测试monster
	public static ArrayList<Monster> monsters = new ArrayList<Monster>();
	// 测试爆炸效果
	public static ArrayList<Explod_T> e_t = new ArrayList<Explod_T>();
	// 测试子弹
	public static ArrayList<Attacks> T_A = new ArrayList<Attacks>();
	//游戏暂停
	public static boolean Stop =false;
	//重新开始
	public static void NewGame(){
		roadWay.TackNum();
		paotas = new ArrayList<Paota>();
		monsters = new ArrayList<Monster>();
		T_A = new ArrayList<Attacks>();
		e_t = new ArrayList<Explod_T>();
		Stop =false;
		up=new Upup();
		paotacards=new PaotaCard();
		change =new Location();
		luobu.hp=7;
		theme.monsterCount=7;
		Factory.formarer.money=1000;
		Loading=true;
		Daoshu=true;
	}
}

2:记分版

package game.FormArea;

import java.awt.Color;
import java.awt.Font;

import game.Factory;
import game.resources.Res;
import net.zj.game.Pen;

public class FormArea {
	public int x;
	public int y;
	public int money=1000;
	public FormArea(int x,int y){
		this.x=x;
		this.y=y;
	}
	/**
	 * 绘制
	 */
	public void draw(){
		Pen.drawImage(Res.Pic.formArea, x,y,null);//计分板
		Factory.roadWay.grid[0][2]='3';Factory.roadWay.grid[0][3]='3';Factory.roadWay.grid[0][4]='3';
		Factory.roadWay.grid[0][5]='3';Factory.roadWay.grid[0][6]='3';Factory.roadWay.grid[0][7]='3';
		Factory.roadWay.grid[0][8]='3';Factory.roadWay.grid[0][9]='3';
		Pen.setColor(Color.YELLOW);
		Pen.setFont(new Font("Tohoma",Font.BOLD,24));
		Pen.drawString(money+"", 250, 60);
	}
}

3:启动窗口

package game.StartWindow;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;

import game.Factory;
import game.resources.Res;
import net.zj.game.GameFrame;
import net.zj.game.Pen;

public class StartWindow extends GameFrame {
	public int x;
	public int y;
	public StartWindow(){
		setSize(1024,512);//窗口大小 (正常显示的窗口大小为1000)
		setTitle("保卫萝卜");//标题
		setVisible(false);//是否显示
		setCenter();//窗口居中
		setbackImage(Res.Pic.backImg);
		Res.Music.BGmusic.play();//添加游戏住背景音乐
		Res.Music.BGmusic.loop();//背景音乐循环播放
	}
	@Override
	public void mouseClicked(MouseEvent e) {
		Factory.maoxian.ByCklick(e.getX(), e.getY());
	}
	@Override
	public void animate() {
		Pen.drawImage(Res.Pic.name, 380, 130, null);
		Pen.drawGif(Res.Pic.a, 300, 100, null);
		Factory.maoxian.draw();
		Factory.boss.draw();
		Factory.guaiwu.draw();
	}
	/**
	 * 居中 让游戏窗口居中
	 */
	public void setCenter(){
		int width=Toolkit.getDefaultToolkit().getScreenSize().width;
		int height=Toolkit.getDefaultToolkit().getScreenSize().height;
		this.setLocation((width-1024)/2,(height-512)/2);
	}
}

4:怪物类(抽象)

package game.Monsters;

import java.awt.Color;

import game.Factory;
import game.Luobu;
import game.resources.Res;
import net.zj.game.Pen;
import net.zj.game.TimerTicker;
import net.zj.game.gifutil.GIF;

/**
 * 怪物抽象类
 * 
 */
public abstract class Monster {
	public int x, y;// x,y坐标
	public int dir;// 方向,(0为上,1为右,2为下,3为左)
	public int lbDir;// 萝卜在怪物的哪个方向,用以控制怪物吃掉萝卜(0为上,1为右,2为下,3为左)
	public boolean isBeAttack = false;// 是否被攻击,用以控制显示血条,默认为false(即没被攻击)
	public int hp;// 血量
	public int row, col;// 行,列
	public int speed;// 怪物速度
	public int control;// 控制,用以控制速度
	public GIF gif;// 用以加载怪物图片

	/**
	 * 构造器
	 * 
	 * @param x
	 *            初始化x
	 * @param y
	 *            初始化y
	 */
	Monster(int x, int y, int dir, int lbDir) {
		this.x = x;
		this.y = y;
		this.dir = dir;
		this.lbDir = lbDir;
	}

	/**
	 * 绘制怪物方法
	 * 
	 * @param pen
	 */
	public void draw() {
		Pen.drawGif(gif, x, y, null);
		if (isBeAttack == true) {
			Pen.setColor(Color.GREEN);
			Pen.fillRect(x, y, hp * 10, 3);
		}
	}

	/**
	 * 怪物移动方法
	 */
	public void move() {
		getRowCol(x, y);
		Luobu lb = Factory.luobu;
		if (this.row == lb.row && this.col == lb.col) {// 如果怪物所在行列与萝卜相同
			switch (lbDir) {// 根据萝卜方向和行列判断怪物是否吃掉萝卜
			case 0:// 如果萝卜最终在怪物上方
			case 2:
				if (this.y >= lb.y && this.y <= lb.y + 50) {// 如果y坐标位于萝卜图片位置以内
					lb.beAttack();// 调用萝卜被攻击方法
					Factory.monsters.remove(this);// 删除这只怪物
				}
				break;// 跳出switch
			case 1:// 如果萝卜最终在怪物右方或左方
			case 3:
				if (this.x >= lb.x || this.x <= lb.x + 50) {// 如果x坐标位于萝卜图片位置以内
					lb.beAttack();// 调用萝卜被攻击方法
					Factory.monsters.remove(this);// 删除这只怪物
				}
				break;// 跳出switch
			}
		}
		dir = getDir();// 获得方向
		switch (dir) {// 根据方向移动
		case 0:// 向上
			y -= speed * control;
			break;
		case 1:// 向右
			x += speed * control;
			break;
		case 2:// 向下
			y += speed * control;
			break;
		case 3:// 向左
			x -= speed * control;
			break;
		}
	}

	/**
	 * 计算行列
	 */
	public void getRowCol(int dx, int dy) {
		row = (dy - 15) / 78;
		col = (dx - 40) / 78;
	}

	/**
	 * 怪物被攻击方法
	 */
	public void beAttack() {
		isBeAttack = true;// 变更是否被攻击状态为“是被攻击”
		hp -= 2;
		if (this.hp <= 0) {// 如果怪物血量小于0
			Factory.formarer.money+=79;
			Factory.theme.xx=this.x+20;
			Factory.theme.yy=this.y-40;
			Factory.monsters.remove(this);// 删除怪物
			return;// 后续代码不执行
		}
		int oldHp = hp;// 获得目前血量
		if (new TimerTicker(3).tickOver() && oldHp == hp)// 如果3秒后血量未曾发生变化
			isBeAttack = false;// 变更是否被攻击状态为“未被攻击”
	}

	/**
	 * 方向探测器
	 * 
	 * @return
	 */
	public int getDir() {
		if (dir == 4)
			return dir;
		int dx = -1, dy = -1;
		switch (dir) {
		case 0:
			dx = x;
			dy = y - 20;
			break;
		case 1:
			dx = x + 50 + 15;
			dy = y;
			break;
		case 2:
			dx = x;
			dy = y + 50 + 22;
			break;
		case 3:
			dx = x - 22;
			dy = y;
			break;
		}
		getRowCol(dx, dy);
		if (row >= 0 && row < Factory.roadWay.grid.length && col >= 0 && col < Factory.roadWay.grid[0].length
				&& Factory.roadWay.grid[row][col] == '1') {
			return dir;
		} else {
			int d;
			for (d = 0; d < 4; d++) {
				if (dir - d == 2 || dir - d == -2)
					continue;
				dx = -1;
				dy = -1;
				switch (d) {
				case 0:
					dx = x;
					dy = y - 20;
					break;
				case 1:
					dx = x + 50 + 15;
					dy = y;
					break;
				case 2:
					dx = x;
					dy = y + 50 + 22;
					break;
				case 3:
					dx = x - 22;
					dy = y;
					break;
				}
				getRowCol(dx, dy);
				if (row >= 0 && row < Factory.roadWay.grid.length && col >= 0 && col < Factory.roadWay.grid[0].length
						&& Factory.roadWay.grid[row][col] == '1') {
					break;
				}
			}
			return d;
		}
	}
}

5:场景障碍物

package game.Obstacles;

import java.awt.image.BufferedImage;

import game.Factory;
import net.zj.game.Pen;

/**
 * 场景障碍物的父类
 * @author 
 *  后续在写子类的时候 给images赋值 赋值根据障碍物图片的颜色不同来进行分类 
 */
public abstract class Obstacles {
	public int x,y;
	public int hp;
	public int addMoney;
	public int col,row;
	//变量控制 数组中的第几章图片 (赋值改变选择图片)
	public int state = 0;
	//创建游戏障碍物图片数组 图片后续再子类中给予值 不在父类中写
	public BufferedImage[] images;
	//构造器
	Obstacles(int row,int col,int state){
		this.row = row;
		this.col = col;
		this.state = state;//初始化障碍物种类
	}
	/**
	 * 绘制方法
	 */
	public void draw(){
		Pen.drawImage(images[state],x,y,null);//绘制方法 根据state改变绘制的图片 图片后续再子类中给予值 不在父类中写

	}
	/**
	 * 被攻击方法 (未调用)
	 */
	public void beAttack(){
		hp--;
	}
	/**
	 * 获取行列  (后续子类如果需要占用多个格子的重写方法来改变 根据情况来定)
	 */
	public void getColRow(){
		this.x=Factory.roadWay.getX(col)+10;//获取列
		this.y=Factory.roadWay.getY(row);//获取行
	//	System.out.println(x+"   "+y);
	}
	/**
	 * 种植进小院抽象方法需要后续子类进行修改
	 */
	public abstract void takeObstacles();
}

6:资源文件的处理

package game.resources;

import java.applet.AudioClip;
import java.awt.image.BufferedImage;

import net.zj.game.ImageUtil;
import net.zj.game.MusicUtil;
import net.zj.game.gifutil.GIF;

/**
 * 资源加载
 * @autho
 * 2017.11.28
 */
public class Res {

	//加载图片
	public static class Pic{
		//背景图片
		public static BufferedImage backImg=ImageUtil.load("/images/main/main.png");
		public static BufferedImage name=ImageUtil.load("/images/main/name.png");
		public static BufferedImage maoxian=ImageUtil.load("/images/main/maoxian.png");
		public static BufferedImage boss=ImageUtil.load("/images/main/boss.png");
		public static BufferedImage guaiwu=ImageUtil.load("/images/main/guaiwu.png");
		public static BufferedImage formArea=ImageUtil.load("/images/continue/formArea.png");
		public static BufferedImage form=ImageUtil.load("/images/continue/form.png");
		public static BufferedImage Stopgame=ImageUtil.load("/images/continue/stopgame.png");
		//冒险关卡
		public static BufferedImage back=ImageUtil.load("/images/Guanka/back.png");
		public static BufferedImage getback=ImageUtil.load("/images/Guanka/getback.png");
		public static BufferedImage ret=ImageUtil.load("/images/Guanka/return.png");
		public static BufferedImage change=ImageUtil.load("/images/Guanka/change.png");
		public static BufferedImage Guanka1=ImageUtil.load("/images/Guanka/Guanka-1.png");
		public static BufferedImage Guanka2=ImageUtil.load("/images/Guanka/Guanka-2.png");
		public static BufferedImage Guanka3=ImageUtil.load("/images/Guanka/Guanka-3.png");
		public static BufferedImage Guanka4=ImageUtil.load("/images/Guanka/Guanka-4.png");
		public static BufferedImage Guanka5=ImageUtil.load("/images/Guanka/Guanka-5.png");
		public static BufferedImage more=ImageUtil.load("/images/Guanka/more.png");
		public static BufferedImage monsterout=ImageUtil.load("/images/Monsters/Monster-out.png");
		public static GIF a=ImageUtil.loadGif("/images/main/2.gif");
		//游戏中菜单
		public static BufferedImage gamemenue=ImageUtil.load("/images/continue/GameMenue.png");
		public static BufferedImage cont=ImageUtil.load("/images/continue/continue.png");
		public static BufferedImage xuanzhe=ImageUtil.load("/images/continue/change.png");
		public static BufferedImage remove=ImageUtil.load("/images/continue/remove.png");	
		//游戏结束
		public static BufferedImage GameOver=ImageUtil.load("/images/continue/GameOver.png");
		public static BufferedImage Ko=ImageUtil.load("/images/continue/Ko.png");
		//怪物时空门
		public static BufferedImage monsterSpace = ImageUtil.load("/images/Change/out.png");
		//游戏倒数
		public static GIF Daoso = ImageUtil.loadGif("/images/Change/Daoshu.gif");
		//增加金币
		public static BufferedImage Money4 = ImageUtil.load("/images/Change/Money+4.png");
	}
	//加载音乐
	public static class Music{
		public static AudioClip BGmusic=MusicUtil.getMusic("/Music/BGmusic.wav");
		public static AudioClip Accomplish=MusicUtil.getMusic("/Music/Accomplish.wav");
	}
}

7:炮台

package game.Paota;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import game.Factory;
import game.Attack.Attacks;
import game.Attack.TArrowAttack;
import game.Attack.TRocktAttack;
import game.Monsters.*;
import game.Obstacles.Obstacles;
import net.zj.game.ImageUtil;
import net.zj.game.Pen;
import net.zj.game.TimerTicker;

public class TArrow extends Paota{
	public TimerTicker ticker = new TimerTicker(2);
	int degree = 0;
	public Monster Monster[];
	public boolean state1=true;
	public boolean isRotate = false;// 是否可以旋转
	BufferedImage img_rotate;
	BufferedImage img_rotate_2;
	BufferedImage img_rotate_3;
	public Monster m;
	public Obstacles o;
	//public BufferedImage imgs[] = new BufferedImage[2];

	public TArrow(int row, int col) {
		super(row, col);
		//底座
		imgs[0]=ImageUtil.load("/images/Paota/TArrow/botton.png");
		//炮塔小 中 大
		imgs[1]=ImageUtil.load("/images/Paota/TArrow/TArrow-b.png");
		imgs[2]=ImageUtil.load("/images/Paota/TArrow/TArrow-m.png");
		imgs[3]=ImageUtil.load("/images/Paota/TArrow/TArrow-s.png");
	}

	public void draw() {
		img_rotate = ImageUtil.rotateImage(imgs[3], degree);
		img_rotate_2 = ImageUtil.rotateImage(imgs[2], degree);
		img_rotate_3 = ImageUtil.rotateImage(imgs[1], degree);
		Pen.drawImage(imgs[0], x, y, null);
		//Pen.drawImage(imgs[1], x, y, null);Pen.drawImage(imgs[0], x, y, null);
		switch (state) {
		case 0:
			Pen.drawImage(img_rotate, x, y-3, null);
			break;
		case 1:
			Pen.drawImage(img_rotate_2, x, y-3, null);
			break;
		case 2:
			Pen.drawImage(img_rotate_3, x, y-5, null);
			break;
		default:
			break;
		}	
		//Pen.drawImage(img_rotate, x, y - 5, null);
		// if(degree<360)degree+=1;
		// else degree=0;
	}

	public void Attack() {// 攻击方法
		if (state1 == true) {// 判断状态是否为空闲状态,是则攻击
			for (int i = 0; i < Factory.monsters.size(); i++) {
				if (Factory.monsters.get(i) == null)
					return;// 判断monster是有没有怪物
				if (Factory.monsters.get(i).hp <= 0)
					return;// 判断monster是否是活的
				m = Factory.monsters.get(i);
				// 判断自己的攻击范围
				move(m);// 调用自己的转动方法
				// 如果在则攻击
				if (ticker.tickOver()) {
//					System.out.println(22222);
					if(Math.abs(this.y - m.y) < 200 && Math.abs(this.x - m.x) < 200) {
						Attacks T = new TArrowAttack(x + 5, y + 5, degree);
						Factory.T_A.add(T);
						T.Attack(m);// 子弹攻击
						ticker.reset();
						state1 = false;
					}
				}
			}
		}
		if (state1 == false) {
			if (ticker.tickOver()) {
				if(Math.abs(this.y - m.y) < 200 && Math.abs(this.x - m.x) < 200) {
					Attacks T = new TArrowAttack(x + 5, y + 5, degree);
					Factory.T_A.add(T);
					T.Attack(m);// 子弹攻击
					ticker.reset();
				}
			}
			if (m.hp <= 0) {
				state1 = true;
			}
		}
	}
	
	
	
	
	
	public void attack_obstacle(int x, int y) {
		if (state1 == true) {// 判断状态是否为空闲状态,是则攻击
			for (int i = 0; i < Factory.obstacle.size(); i++) {
				if (Factory.obstacle.get(i) == null)
					return;// 判断obstacle
				if (Factory.obstacle.get(i).hp <= 0)
					return;
				o = Factory.obstacle.get(i);
				// 判断自己的攻击范围
				move_obstacles(o);// 调用自己的转动方法
				// 如果在则攻击
				if (ticker.tickOver()) {
//					System.out.println(22222);
					if (Math.abs(this.y - y) < 200 && Math.abs(this.x - x) < 200) {
						Attacks T = new TArrowAttack(x + 5, y + 5, degree);
						Factory.T_A.add(T);
//						T_a=T;
						T.Attack_obstacle(x,y);// 子弹攻击
						ticker.reset();
						state1 = false;
					}
				}
			}
		}
		if (state1 == false) {
			if (ticker.tickOver()) {
				if (Math.abs(this.y - y) < 200 && Math.abs(this.x - x) < 200) {
					Attacks T = new TArrowAttack(x + 5, y + 5, degree);
					Factory.T_A.add(T);
					T.Attack_obstacle(x,y);// 子弹攻击
					ticker.reset();
				}
			}
			if (m.hp <= 0) {
				state1 = true;
			}
		}
	}

	public void move(Monster enemy) {// 自己的转动方法
		if (Math.abs(this.y - enemy.y) < 200 && Math.abs(this.x - enemy.x) < 200) {
			// isRotate=true;
			// double a=(double)(enemy.y-this.y)/(double)(enemy.x-this.x);
			// double d=Math.atan(a);
			// degree=(int)(d*180/Math.PI)+90;
			if (this.x > enemy.x) {
				double a = (double) (enemy.y - this.y) / (double) (enemy.x - this.x);
				double d = Math.atan(a);
				degree = (int) (d * 180 / Math.PI) - 90;
			}

			if (this.x < enemy.x) {
				double a = (double) (enemy.y - this.y) / (double) (enemy.x - this.x);
				double d = Math.atan(a);
				degree = (int) (d * 180 / Math.PI) + 90;
			}

		}
	}

	@Override
	public void adjustment() {
		x+=78/4;
		y+=78/4;
		
	}
	public void move_obstacles (Obstacles o){
		if (Math.abs(this.y - o.y) < 50 && Math.abs(this.x - o.x) < 50) {
			// isRotate=true;
			// double a=(double)(enemy.y-this.y)/(double)(enemy.x-this.x);
			// double d=Math.atan(a);
			// degree=(int)(d*180/Math.PI)+90;
			if (this.x > o.x) {
				double a = (double) (o.y - this.y) / (double) (o.x - this.x);
				double d = Math.atan(a);
				degree = (int) (d * 180 / Math.PI) - 90;
			}

			if (this.x < o.x) {
				double a = (double) (o.y - this.y) / (double) (o.x - this.x);
				double d = Math.atan(a);
				degree = (int) (d * 180 / Math.PI) + 90;
			}

		}
		}
}

项目描述
1:本项目只针对于学习 提升对java语言基础知识的认识
项目下载地址
https://download.csdn.net/download/qq_41193701/11190924

猜你喜欢

转载自blog.csdn.net/qq_41193701/article/details/90402304
今日推荐