分析设计:
本题目要求首先用户输入角色姓名,然后由用户选择角色性别,然后由用户选择种族,然后选择职业,然后自动分配力量、敏捷、体力、智力和智慧属性,并计算生命值和魔法值。最后向用户显示该角色的所有信息,然后询问用户是否满意,如用户不满意则重新创建,若用户满意则程序结束,并将用户创建角色的相关信息写入文件保存。
一、角色限制
名字 | 小于50个字符。 |
---|---|
性别 | 男 、女 |
种族 | 人类、精灵、兽人、矮人和元素。 |
职业 | 狂战士、圣骑士、刺客、猎手、祭司和巫师。 |
属性 | 力量 、敏捷 、体力 、智力 、智慧 |
生命值 | 生命值=体力*20 |
魔法值 | 魔法值=(智力+智慧)*10 |
二、职业限制
很多职业会限制某些种族选择,例如兽人不能就职圣骑士等等,种族和职业的限制表如下:
种族/职业 | 狂战士 | 圣骑士 | 刺客 | 猎手 | 祭司 | 巫师 |
---|---|---|---|---|---|---|
人类 | 允许 | 允许 | 允许 | 允许 | 允许 | 允许 |
精灵 | 不允许 | 不允许 | 允许 | 允许 | 允许 | 允许 |
兽人 | 允许 | 不允许 | 不允许 | 允许 | 允许 | 不允许 |
矮人 | 允许 | 允许 | 不允许 | 不允许 | 允许 | 不允许 |
元素 | 不允许 | 不允许 | 不允许 | 不允许 | 允许 | 允许 |
三、初始属性:
本题目要求力量、敏捷、体力、智力和智慧要求是随机值(利用随机数函数来取得随机数),但是五项属性的总和应该是100,并且应该和职业相关。例如狂战士的体力和力量就要比较高,而巫师需要较高的智力,而祭司则需要较高的智慧。各职业初始属性的大致比例应遵从下表:
职业/属性 | 力量 | 敏捷 | 体力 | 智力 | 智慧 |
---|---|---|---|---|---|
狂战士 | 40 | 20 | 30 | 5 | 5 |
圣骑士 | 25 | 15 | 30 | 20 | 10 |
刺客 | 20 | 35 | 20 | 15 | 10 |
猎手 | 15 | 40 | 15 | 10 | 20 |
祭司 | 15 | 20 | 15 | 35 | 15 |
巫师 | 10 | 20 | 10 | 20 | 40 |
例如,前面示意图中的祭司的初始属性,大致满足该比例,但是应该是随机的。
然后利用属性值计算生命值和魔法值。
分析设计:
实现阶段:
最终效果图1:创建窗口
最终效果图2:不同的种族有不同的职业限制
最终效果图3:不同的职业有不同的初始属性
最终效果图4:每一次的属性都是随机的
面板代码(View):
package charactercreate;
import java.util.HashMap;
/**
* 功能:ChaaracterView类用于接收用户需求
* @author nazi
*/
public class CharacterView extends javax.swing.JFrame {
private Character c;
/*
getProperties():从控件中获取数据然后赋值给Model对象
*/
public void getProperties() {
String name = this.name.getText();
String sex;
if (man.isSelected()) {
sex = man.getText();
} else {
sex = female.getText();
}
String race = this.Race.getSelectedValue();
String stages = this.Propertiy.getSelectedValue();
c.update(name, sex, race, stages);
}
/*
@param model 获的CharacterCreateController中单例的引用
*/
public void bindModel(Character m) {
c = m;
System.out.println("从控制器到view传递成功");
}
/**
* Creates new form CharacterView
*/
public CharacterView() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
buttonGroup1 = new javax.swing.ButtonGroup();
buttonGroup2 = new javax.swing.ButtonGroup();
name = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
man = new javax.swing.JRadioButton();
female = new javax.swing.JRadioButton();
jLabel3 = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane();
Propertiy = new javax.swing.JList<>();
jLabel4 = new javax.swing.JLabel();
jScrollPane2 = new javax.swing.JScrollPane();
Race = new javax.swing.JList<>();
createC = new javax.swing.JButton();
jScrollPane3 = new javax.swing.JScrollPane();
showArea = new javax.swing.JTextArea();
jLabel5 = new javax.swing.JLabel();
saveBtn = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
name.setText("一拳打手");
name.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nameActionPerformed(evt);
}
});
jLabel1.setText("角色名:");
jLabel2.setText("性别:");
buttonGroup1.add(man);
man.setText("男");
man.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
manActionPerformed(evt);
}
});
buttonGroup1.add(female);
female.setText("女");
female.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
femaleActionPerformed(evt);
}
});
jLabel3.setText("职业:");
Propertiy.setModel(new javax.swing.AbstractListModel<String>() {
String[] strings = { "狂战士", "圣骑士", "刺客", "猎手", "祭司", "巫师" };
public int getSize() { return strings.length; }
public String getElementAt(int i) { return strings[i]; }
});
jScrollPane1.setViewportView(Propertiy);
jLabel4.setText("种族:");
Race.setModel(new javax.swing.AbstractListModel<String>() {
String[] strings = { "人类", "精灵", "兽人", "矮人", "元素" };
public int getSize() { return strings.length; }
public String getElementAt(int i) { return strings[i]; }
});
Race.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
RaceMouseClicked(evt);
}
});
jScrollPane2.setViewportView(Race);
createC.setText("创建角色");
createC.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
createCActionPerformed(evt);
}
});
showArea.setColumns(20);
showArea.setRows(5);
jScrollPane3.setViewportView(showArea);
jLabel5.setText("属性展示:");
saveBtn.setText("保存角色");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(name, javax.swing.GroupLayout.PREFERRED_SIZE, 201, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel4)
.addGap(136, 136, 136)
.addComponent(jLabel3))
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel2)
.addGap(164, 164, 164)
.addComponent(man))))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 299, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jLabel5, javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addGap(32, 32, 32)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(female)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(52, 52, 52)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(createC, javax.swing.GroupLayout.DEFAULT_SIZE, 73, Short.MAX_VALUE)
.addComponent(saveBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addGap(22, 22, 22))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(name, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(man, javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(female)))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel4)
.addComponent(jLabel3))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 9, Short.MAX_VALUE)
.addComponent(jLabel5)
.addGap(5, 5, 5)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(createC, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(48, 48, 48)
.addComponent(saveBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
);
pack();
}// </editor-fold>
private void nameActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
/*
@param evt
@return
*/
private void createCActionPerformed(java.awt.event.ActionEvent evt) {
//临时基本角色信息
getProperties();
//根据信息初始化属性
c.setProperties();
//在文本框中展示角色信息
String s = c.getAll();
showArea.setText(s);
}
private void manActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
private void femaleActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
/*
@param evt
@return 职业选择框中数据随着种族动态的变化
*/
private void RaceMouseClicked(java.awt.event.MouseEvent evt) {
HashMap<String , String[]> hashMap = new HashMap<String , String[] >();
hashMap.put("人类", new String[] { "狂战士","圣骑士", "刺客","猎手"," 祭司"," 巫师"});
hashMap.put("精灵", new String[] { "刺客","猎手","祭司","巫师" });
hashMap.put("兽人", new String[] { "狂战士","猎手","祭司" });
hashMap.put("矮人",new String[] { "狂战士","圣骑士"," 祭司" } );
hashMap.put("元素", new String[] { "祭司","巫师" });
String race = this.Race.getSelectedValue();
String[] property = hashMap.get(race);
Propertiy.setListData(property);
}
// Variables declaration - do not modify
private javax.swing.JList<String> Propertiy;
private javax.swing.JList<String> Race;
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JButton createC;
private javax.swing.JRadioButton female;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JRadioButton man;
private javax.swing.JTextField name;
private javax.swing.JButton saveBtn;
private javax.swing.JTextArea showArea;
// End of variables declaration
}
控制器类:
package charactercreate;
/**
* 创建单例 创建窗口 传递引用
* @author nazi
*/
public class CharacterCreateController {
//单例模式
private static Character sModel = new Character();
public static void main(String[] args) {
CharacterView v = new CharacterView();
v.setVisible(true);
v.bindModel(model);
}
}
角色类Model:
/*
* 角色类
*/
package charactercreate;
import java.util.Arrays;
import java.util.Random;
/**
* 名字 小于50个字符。
* 性别 男 、女
* 种族 人类、精灵、兽人、矮人和元素。
* 职业 狂战士、圣骑士、刺客、猎手、祭司和巫师。
* 属性 力量 、敏捷 、体力 、智力 、智慧
* 生命值 生命值=体力*20
* 魔法值 魔法值=(智力+智慧)*10
* @author nazi
*/
public class Character {
//属性
private String name;
private String sex;
private String race;
private String stage;
private int[] p = {0,0,0,0,0};
private int HP;
private int MP;
public String getAll(){
String s = "角色名:"+name +"\n"+"性别:"+ sex +"\n"+"种族:"+ race+"\n" +"职业:"+ stage+"\n" +"属性:"+ Arrays.toString(p) +"\n"+"HP:"+ HP +"\n"+ "MP:"+MP;
return s;
}
//get 方法
public String getName() {
return name;
}
public String getSex() {
return sex;
}
public String getRace() {
System.out.println(race);
return race;
}
public String getStage() {
return stage;
}
public int[] getP() {
return p;
}
public int getHP() {
return HP;
}
public int getMP() {
return MP;
}
/*
根据所选职业随机生成初始属性
狂战士、圣骑士、刺客、猎手、祭司和巫师
*/
public void setProperties(){
if(stage.equals("狂战士")){
p[0] = getProperWithMin(40);
p[1] = getProperWithMin(15);
p[2] = getProperWithMin(25);
p[3] = getProperWithMin(1);
p[4] = getProperWithMin(0);
HP = p[2]*20;
MP =(p[3]+p[4])*10;
}else if(stage.equals("圣骑士")){
p[0] = getProperWithMin(25);
p[1] = getProperWithMin(12);
p[2] = getProperWithMin(25);
p[3] = getProperWithMin(17);
p[4] = getProperWithMin(5);
HP = p[2]*20;
MP =(p[3]+p[4])*10;
}else if(stage.equals("刺客")){
p[0] = getProperWithMin(15);
p[1] = getProperWithMin(31);
p[2] = getProperWithMin(16);
p[3] = getProperWithMin(15);
p[4] = getProperWithMin(5);
HP = p[2]*20;
MP =(p[3]+p[4])*10;
}else if(stage.equals("巫师")){
p[0] = getProperWithMin(5);
p[1] = getProperWithMin(15);
p[2] = getProperWithMin(5);
p[3] = getProperWithMin(5);
p[4] = getProperWithMin(37);
HP = p[2]*20;
MP =(p[3]+p[4])*10;
}else if(stage.equals("猎手")){
p[0] = getProperWithMin(11);
p[1] = getProperWithMin(37);
p[2] = getProperWithMin(10);
p[3] = getProperWithMin(11);
p[4] = getProperWithMin(15);
HP = p[2]*20;
MP =(p[3]+p[4])*10;
}else if(stage.equals("祭司"))
p[0] = getProperWithMin(10);
p[1] = getProperWithMin(15);
p[2] = getProperWithMin(5);
p[3] = getProperWithMin(15);
p[4] = getProperWithMin(35);
HP = p[2]*20;
MP =(p[3]+p[4])*10;
}
/*
@param min 随机下限
return 随机数
*/
public int getProperWithMin(int min){
int max = min +5;
Random r = new Random();
int s = r.nextInt(max)%(max-min+1) + min;
return s;
}
/*
@param Character c
@retun null
*/
public void update(String n ,String s , String r ,String stage){
name = n;
sex = s;
race = r;
this.stage = stage;
}
}