这是我大二那时候写的一个程序,那时候刚上完老师说的java抽象类的课,老师打了个比方,具体的忘了,大概说英雄联盟里面的游戏人物,都是继承一个基类的模型,每个英雄都是拥有攻击、防御等相同的操作,但是每个攻击操作的技能效果又是不一样的,这就是抽象。每个英雄继承了基类的攻击防御方法,但是在具体的英雄实现类重写了原来的抽象方法。 听完老师的课,感触特别多,好像英雄联盟也是这么回事,只是动画效果多了一些,以及有一些人物位置碰撞检测。那时候感觉自己好像也能写一个出来。于是下课回去就开始写下这个程序
首先,先写一个抽象的英雄基类 BaseHero.java 1)包含了一些英雄的基础属性,比如姓名、描述、攻击力、防御力、敏捷力等 2)抽象出英雄的基本操作方法,比如每个英雄有4个技能方法、普通攻击、反击方法 3)基类代码 /*属性: * 名称name,ID,血HP,基础攻击力ATT,基础防御力DEF,敏捷DEX,头像head,形象body * 技能1名称sname1,技能2名称sname2,技能3名称sname3,技能4名称sname4, * 技能1描述describe_skill1,技能2描述describe_skill2,技能3描述describe_skill3,技能4描述describe_skill4 * 英雄描述describe_hero,运气值luck */ /** * 抽象方法: * skill1()技能1,skill2()技能2,skill3()技能3,Skill4()技能4 * 攻击attack(),反击defend(),isDodge()是否闪避 */ public abstract class BaseHero { String name; //名称 int ID; double HP; //血量 int ATT; //基础攻击力ATT double DEF; //基础防御力 int DEX; //敏捷 String myluck;//运气值描述,一般、良好、优秀 String headpath;//头像图片 String bodypath;//身体图片 String sname1;//技能1 String sname2;//技能2 String sname3;//技能3 String sname4;//技能4 String describe_skill1;//技能1描述 String describe_skill2;//技能2描述 String describe_skill3;//技能3描述 String describe_skill4;//技能4描述 String describe_hero;//英雄描述 public static int luck;//运气值 double lastHP; public String tip ;//提示伤害信息 int blue;//英雄蓝总量 boolean blood;//回血还是掉血标志 double maxHP;//最大血量 boolean noDodge=false; /* * get、set方法 */ public String getName() { return name; } public void setName(String name) { this.name = name; } ...... /* * 攻击防御方法 */ public abstract void attack(int skill,BaseHero enemy); // public abstract void defend(BaseHero enemy); public abstract void skill1(BaseHero enemy); public abstract void skill2(BaseHero enemy); public abstract void skill3(BaseHero enemy); public abstract void skill4(BaseHero enemy); public abstract boolean isDodge(BaseHero enemy); } 继承基类的英雄 在构造函数里面初始化基本属性,以及重写基类的抽象方法 public Xinlin() { this.name="新林" ; this.ID = 1364; this.HP = 850; this.maxHP=HP; this.ATT = 80; this.DEF = 18; this.DEX = 72; this.blue = 300; this.sname1 = "普通攻击"; this.sname2 = "窃魂剑"; this.sname3 = "凌波微步"; this.sname4 = "无敌连环斩"; this. describe_skill1 = "技能详解:普通攻击,造成一定的物理伤害"; this.describe_skill2 = "技能详解:耗蓝45,华丽的剑法,有效迷惑敌人造成一定物理伤害,并使敌人防御力降低2"; this.describe_skill3 = "技能详解:耗蓝25,主动释放敏捷永久提升5,敏捷最高提升到100,被动敌人闪避率格外降低10"; this.describe_skill4 = "技能详解:耗蓝160,大招,在高速状态下(敏捷必须达到90才可以使用),对敌人造成多段(3-6)连环斩,每段造成较大伤害伤害"; this.describe_hero = "人物介绍:时而话唠时而寡言,好静,追求平凡,英雄定位为高敏捷,刺客型英雄"; this.myluck="良好"; headpath="image\\"+"xlhead.png"; bodypath="image\\"+"xlbody.png"; } //技能1 public void skill1(BaseHero enemy) { // TODO Auto-generated method stub blood=true;//掉血 BaseHero.luck=(int)(Math.random()*10);//运气值随机数 enemy.setLastHP(enemy.getHP());//重置上一次血量 if((BaseHero.luck<2||isDodge(enemy))&&!noDodge){ tip="普通攻击,"+enemy.getName()+"运气太好了,闪开了这次攻击"; }else if(BaseHero.luck>7){ enemy.setHP(enemy.getHP()-(ATT*2+BaseHero.luck*5)*(1-enemy.getDEF()/100)); tip=name+"状态不错,使出了会心一击,造成"+enemy.getName()+(int)(enemy.getLastHP()-enemy.getHP())+"伤害"; }else { enemy.setHP(enemy.getHP()-(this.ATT+BaseHero.luck*4)*(1-enemy.getDEF()/100)); tip=name+"普通攻击,造成"+enemy.getName()+(int)(enemy.getLastHP()-enemy.getHP())+"伤害"; } } //技能2 public void skill2(BaseHero enemy) { // TODO Auto-generated method stub blood=true;//掉血 enemy.setLastHP(enemy.getHP());// 重置上一次血量 if ((blue - 45) >= 0) {// 是否够蓝 if (!noDodge && isDodge(enemy)) { // 闪避了 tip = "窃魂剑," + enemy.getName() + "太敏捷了,竟然闪开了这次攻击"; } else {// 没有闪避 enemy.setHP(enemy.getHP() - (50 + ATT * (1 - enemy.getDEF() / 100))); enemy.setDEX(enemy.getDEX() - 2); tip = name + "窃魂剑,造成" + enemy.getName() + (int) (enemy.getLastHP() - enemy.getHP()) + "点伤害,同时防御力降低2"; } blue -= 45; } else { skill1(enemy); } } //技能3 ...... 每次攻击后重新计算血量蓝量,使用TimerTask定时器,延时减去血量,造成缓慢掉血的动画效果 /* TODO * hero第一个为被攻击者 * myhero为发起攻击者 * progressbar为对方血条 * myprogressbar为己方血条 * bluebar为己方蓝条 */ public void reshowHP(BaseHero hero,BaseHero myhero,JProgressBar progressbar,JProgressBar myprogressbar,JProgressBar bluebar) { //己方英雄先减蓝 bluebar.setValue(myhero.getBlue()); bluebar.setString(String.valueOf(bluebar.getValue())); myprogressbar.setValue((int)myhero.getHP()); myprogressbar.setString(String.valueOf(myprogressbar.getValue())); //敌方英雄掉血 if(myhero.isBlood()){ timer.cancel(); timer=new Timer(); //设置定时器 timer.schedule(new delay_timer(hero,progressbar,timer,myhero.isBlood()), 0, 5);//每40毫秒启动一次 }else{ timer.cancel(); timer = new Timer(); // 设置定时器 timer.schedule(new delay_timer(myhero, myprogressbar, timer,myhero.isBlood()), 0, 5);// 每40毫秒启动一次 } 每次游戏开始前初始化相关英雄血量蓝量数据 //TODO 初始化血条函数 public void initprogressbar() { progressbar1 = new JProgressBar(); progressbar1.setBounds(45, 4, 180, 30); progressbar1.setOrientation(JProgressBar.HORIZONTAL);//进度条水平显示 progressbar1.setMinimum(0); progressbar1.setMaximum((int)hero.getHP()); progressbar1.setValue((int)hero.getHP()); progressbar1.setStringPainted(true);//显示进度条里的百分值 progressbar1.setString(String.valueOf(progressbar1.getValue())); //progressbar.setPreferredSize(new Dimension(150,30)); progressbar1.setBorderPainted(true); progressbar1.setBackground(Color.white);//改变进度条背景颜色 progressbar1.setForeground(Color.green); progressbar2 = new JProgressBar(); progressbar2.setBounds(297, 4, 180, 30); progressbar2.setOrientation(JProgressBar.HORIZONTAL);//进度条水平显示 progressbar2.setMinimum(0); progressbar2.setMaximum((int)hero2.getHP()); progressbar2.setValue((int)hero2.getHP()); progressbar2.setStringPainted(true);//显示进度条里的百分值 progressbar2.setString(String.valueOf(progressbar2.getValue())); //progressbar.setPreferredSize(new Dimension(150,30)); progressbar2.setBorderPainted(true); progressbar2.setBackground(Color.white);//改变进度条背景颜色 progressbar2.setForeground(Color.green); //蓝 bluebar1 = new JProgressBar(); bluebar1.setBounds(45, 30, 180, 22); bluebar1.setOrientation(JProgressBar.HORIZONTAL);//进度条水平显示 bluebar1.setMinimum(0); bluebar1.setMaximum(hero.getBlue()); bluebar1.setValue(hero.getBlue()); bluebar1.setStringPainted(true);//显示进度条里的百分值 bluebar1.setString(String.valueOf(bluebar1.getValue())); bluebar1.setBorderPainted(true); bluebar1.setBackground(Color.white);//改变进度条背景颜色 bluebar1.setForeground(Color.blue); bluebar2 = new JProgressBar(); bluebar2.setBounds(297, 30, 180, 22); bluebar2.setOrientation(JProgressBar.HORIZONTAL);//进度条水平显示 bluebar2.setMinimum(0); bluebar2.setMaximum(hero2.getBlue()); bluebar2.setValue(hero2.getBlue()); bluebar2.setStringPainted(true);//显示进度条里的百分值 bluebar2.setString(String.valueOf(bluebar2.getValue())); bluebar2.setBorderPainted(true); bluebar2.setBackground(Color.white);//改变进度条背景颜色 bluebar2.setForeground(Color.blue); } 界面设计 界面流程:StartFrame -> SelectFrame -> MainFrame 一共有设计有4个界面 运行src/dao/Frame/StartFrame文件里面的main方法即可 主菜单界面选择英雄界面 格斗界面 帮助界面项目源码: https://gitee.com/zhangxinlin/HeroGame2