2021.03.17 pokémon小游戏开发记录与周总结
此篇仅包含部分项目代码,只是个人的学习总结。
文章目录
前言
昨天结束了老师布置的小游戏项目,今天又听了老师自己开发这类项目的流程与思路,使我受益良多。
在本次项目中,我们小组以《pokémon》为原型,模拟实现了这个经典游戏的新手章节。虽然实现了最基础的几个功能,但还是有很多功能没有能实现,也对面向对象的编程思想不够了解。今天在老师与同学的帮助下对这类语言的了解又多了一些,大致也理解了一部分继承、封装、多态的功能与用法。学到了就应该记下来,趁热打铁,万一我哪天又忘了,这不白瞎了嘛。
声明:这篇文章中包含我们组的小游戏——《pokémon》项目,也包含老师教学讲解的小游戏框架——《伏魔录》项目。
一、前期准备
当接到一个新项目的时候,首先要在团队中落实每个人的工作任务,选定项目负责人,个人处理好个人的事情,在有余力的情况下帮助其他人更快的完成。其次要做好需求分析与调研(我们这种就是查查背景资料),做好前期的策划方案,可以明确项目的大致方向。接着做好流程设计,明确细节,有助于理清思绪,更便于分工合作。一定不能在接到项目后就急于动手编写代码,欲速则不达!
二、开发总结
这里我主要只阐述我在这次项目中所学到的一些知识和一些改进我代码编写方式的小技巧,我已经搞懂的、熟悉的、在使用的就没有写在里面。
1.分类建包
在开始编写类之前,先把大致的包分好类,做好文件管理。这里不需要考虑的特别全面,在编写代码的过程中有想到建立新的包,或者之前分包方式有不方便的地方可以再适当添加修改。在我们这个《pokémon》项目里新建的包有:
1)存放地图类的 map包
2)存放NPC、商店的 npc包
3)存放玩家数据与战斗方法的 player包
4)存放宝可梦与宝可梦技能的 pokemon包
5)存放流程逻辑主函数的 pokemonmain包
2.定义与调用属性
这方面我们组内的小游戏项目还有着很大的问题,没有充分利用JAVA语言面向对象的优势,大都还在使用面向过程的编写逻辑,导致组内的分工合作经常无法开展下去。这里使用老师建立的教学项目《伏魔录》来描述;
老师在新建类时先建立的玩家类Player,在其中定义各种玩家属性,代码如下:
public class Player {
//名字
private String name="张三";
//攻击力
private int attack = 10;
//当前血量
private int health = 50;
//最大血量
private int maxHealth = 50;
//当前蓝量
private int mana = 100;
//最大蓝量
private int maxMana = 100;
//当前经验值
private int exp = 0;
//最大经验值
private int maxExp = 10;
//最大经验值的增长
private int maxExpGrowth = 10;
//防御力
private int defense = 10;
//当前金钱
private int gold = 100;
//等级
private int level = 1;
//物品栏
private Item[] items = new Item[10];
//技能栏
private Skill[] skills = new Skill[5];
//职业
private Profession profession;
}
这里玩家的属性都将访问修饰符设置为私有private,并使用getter&setter方法来读取或者写入这些属性。这里主要说一下getter&setter方法的快速建立方法:
Getter&Setter方法快速建立
在创建好私有属性后可以通过右键找到并打开Generate选项,或者通过Alt+Insert来实现同样的功能:
打开后可以在Generate选项中找到getter and setter
选择getter and setter后,在裂变中选择需要使用getter&setter方法的属性,在点击OK按钮即可完成建立
3.类的建立与整合
完成类中属性与方法的定义后,就要开始按照流程设置一些类了。我们这个《pokémon》项目中,“御三家”以及后续 宝可梦 都是通过继承的方式来进行一些属性及方法的定义,这样便于整合同一类代码,减少了代码的冗余,有利于拓展功能
其中父类pokemon的代码如下:
//父类
public class Pokemon {
public String pokemonName;
// 生命值
public int pokemonHp;
public int pokemonhp;
// 攻击值
public int pokemonAttack;
// 防御
public int pokemonDefend;
//状态
public boolean pokemonStatus=true;
// 每个精灵均有4个技能,但是每个技能不一样
// 攻击技能1 ,攻击技能所对应的技能值
public String attackSkill1;
public int attackSkill1Value;
public int proficiency1;
// 攻击技能2 ,攻击技能所对应的技能值
public String attackSkill2;
public int attackSkill2Value;
public int proficiency2;
// 攻击技能2 ,攻击技能所对应的技能值
public String attackSkill3;
public int attackSkill3Value;
public int proficiency3;
// 特殊技能 ,特殊技能技能所对应的技能值
public String specSkill;
public int specSkillValue;
public int proficiency4;
// 初始化各项属性,第一级
public Pokemon() {
// 生命值 开始初始化的值随机数(50,70)
this.pokemonHp= (int) (Math.random()*20)+70;
this.pokemonhp=this.pokemonHp;
// 攻击值 随机数(10,30)
this.pokemonAttack=(int) (Math.random()*20)+10;
// 防御值 随机数(10,30)
this.pokemonDefend=(int) (Math.random()*20)+10;
}
public void elfSkills(){ }
public void upgrade(){ }
public void upgradeattribute(){ }//
public void show() {
System.out.println("@@@@@@@@@^@^@@@@@@@@@@");
System.out.println("+===" + this.pokemonName + "===+");
System.out.println("@|生命值:" + this.pokemonHp);
System.out.println("@|\t技能\t技能值");
System.out.println("@|\t"+this.attackSkill1+this.attackSkill1Value);
System.out.println("@|\t"+this.attackSkill2+this.attackSkill2Value);
System.out.println("@|\t"+this.attackSkill3+this.attackSkill3Value);
System.out.println("@|\t"+this.specSkill+this.specSkillValue);
System.out.println("@|防御力:" + this.pokemonDefend);
System.out.println("@@@@@@@@@^@^@@@@@@@@@@");
}
其中之一的子类Hitokage的代码如下:
//小火龙
public class Hitokage extends Pokemon {
// 宝可梦的名称
public Hitokage(){
this.pokemonName="小火龙";
this.attackSkill1="撞击";
this.attackSkill1Value=40;
this.proficiency1=0;
this.attackSkill2="火花";
this.attackSkill2Value=45;
this.proficiency2=0;
this.attackSkill3="火焰牙";
this.attackSkill3Value=65;
this.proficiency3=0;
this.specSkill="龙息";
this.specSkillValue=70;
this.proficiency4=0;
}
//升级
public void upgrade(){
if (this.proficiency1>=10){
//熟练度清零
this.proficiency1-=10;
//伤害值提升
this.attackSkill1Value+=5;
upgradeattribute();
}else if (this.proficiency2>=10){
//熟练度清零
this.proficiency2-=10;
//伤害值提升
this.attackSkill1Value+=5;
}else if (this.proficiency3>=10){
//熟练度清零
this.proficiency3-=10;
//伤害值提升
this.attackSkill1Value+=5;
}else if (this.proficiency4>=10){
//熟练度清零
this.proficiency4-=10;
//伤害值提升
this.specSkillValue+=5;
}
upgradeattribute();
}
//属性面板升级
public void upgradeattribute(){
this.pokemonHp+=20;
this.pokemonAttack+=4;
this.pokemonDefend+=1;
}
而在老师建立的教学项目《伏魔录》中,老师更是大量使用了继承的方式,在职业技能、物品设定、地图设定、NPC设定及野怪设定中都有很多的运用。
4.多态的适当使用会事半功倍
老师在地图的设定中,使用了多态性这个概念,将地图传入的选择放到共同父类里面,在后续的方法中选择使用可以减少很多没必要的语句
//玩家类中
public boolean wander(Field nowhere, Scanner scanner) {
int i = (int)Math.floor(Math.random()*9);
System.out.println("遇到怪物 " + nowhere.enemies[i].enemyName);
boolean flag = this.attack(nowhere.enemies[i],scanner);
if(flag){
System.out.println("胜利");
this.addExp(nowhere.enemies[i].exp);
this.addGold(nowhere.enemies[i].gold);
return true;
}else {
System.out.println("失败");
return false;
}
}
…………
//游戏运行流程类,主方法
if (choice > 0 && choice < 3) {
if (choice == 1) {
Nowhere nowhere = new Nowhere();
boolean state = player.wander(nowhere, scanner);
if(!state){
System.out.println("英雄十八年后又是一条好汉");
return;
}
} else if (choice == 2) {
Mountain mountain = new Mountain();
boolean state = player.wander(mountain, scanner);
if(!state){
System.out.println("英雄十八年后又是一条好汉");
return;
}
} else if (choice == 3){
continue;
}
}
三、项目中的小收获
注释!注释!注释!!! 重要的事情讲三遍!写代码一定要加注释!这句话是我对自己的要求!但我饿希望各位也这样做!真的,写注释的好处太多太多了,我也就不哔哔了,缺点可能就是有点麻烦,但我真的看没有注释的代码看到头秃,可太难为我这种小白了,夺笋啊!
写代码的时候一定要按照一定的一思路,有序的写,可别东一句,西一句,整到后面自己都忘了哪儿写了哪儿没写,最后还要找好久,报几次错,才找得到问题在哪里。
最后就是在合作项目时,一定要经常沟通,在保证自己进度的前提下多帮助其他人,这是一个小组的项目,不是某个人自己的项目,与其一个人累死累活的弄,不如齐心协力,携手并进。
总结
在本次项目中,由于组内大多数成员是JAVA语言的初学者,对面向对象的语言十分陌生,所以开发进度十分缓慢,还有很多功能由于能力与时间的原因无法实现。并且我们现在也只是第二次开展合作性质的项目,不论是组员间的分工合作还是代码的统一整合都挺陌生的,急需改进。对我来说,本次项目是一堂非常好的课,只有在实践中才能真正找到自己所欠缺的地方,找到基础的问题才能更快的学习上层知识。目前,我需要的是尽快梳理清晰基础知识要点,尽快熟悉这种面向对象编程的方式。
在本周所学的知识点中,包装类与单例模式的学习还有所欠缺,在同学的讲解下对概念有了了解。但让我在实际中运用,我可能根本就不会用,可能还是以一种面向过程的方式去编写。现在要继续改进,尽快复习搞懂这些不扎实的基础。