重溫了黑馬的這個小程序
首先介紹一下:相當于一個小游戲,你打我一下,我打你一下;中間經歷一些來回,最終根據血量的大小來判斷誰輸誰贏,實話講黑馬整個課在這個之前的題目沒有什么難度,這個不難,但有很多小知識點忘記,以此文總結一下。
知識點梳理
1、拿到這個題目的時候需要先思考,和前面的都寫在單獨一個類中的有什么區別?如果全部寫在一個類,所有功能(角色屬性、攻擊邏輯、游戲流程)可能集中在一個類中,導致代碼冗長,難以實現復雜的游戲系統(如繼承、多態),如不同角色的特殊技能。
2、所以要分離主類(GameTest)和業務類(Role),繼續思考如何界定里面?
3、大方向是:先寫業務類(里面的多個角色實例(如喬峰、摩智)均可復用)
- 首先先帶著數據類型和公私有去定義角色的屬性(名字、血量、性別、狀態...)
- 然后就是利用快捷鍵(Fn+Alt+insert去調出無參和全參的構造函數<初始化對象>及getset方法)
- 最基本的處理完成后,就要思考自定義方法了(attack)和(showRoleInfo)。
4、對于set和get方法
set 方法:用于修改成員變量的值,需要參數,因為 set 方法的目的是設置成員變量的值,所以它需要一個參數來接收新的值。
- 比較特殊的是face,這個對象得隨機生成,構造函數中也不同于其他屬性那樣直接賦值 this.某=某,它需要在set里面修改。
- 具體操作也是利用隨機索引,調用提前在類中定義的描述男女兩長相數組的索引,注意不要忘記寫 this.某 = 數組名 [ 隨機產生的索引 ] 。
public void setFace(char gender) {Random r = new Random();//長相是隨機的if(gender=='男'){int index = r.nextInt(boyfaces.length);this.face = boyfaces[index];}else if(gender=='女'){int index = r.nextInt(girlfaces.length);this.face = girlfaces[index];}else {this.face = "非男非女";}}
get 方法:用于讀取成員變量的值。?
5、第一個自定義方法attack,目的是實現一個角色對另一個角色的攻擊行為,需要一個 role 類型的參數來表示被攻擊的角色。
- role.getName():獲取被攻擊角色的名字
- this.getName():獲取當前攻擊角色的名字,this是方法的調用者(在gametest中調用)
public void attack(Role role){//隨機攻擊效果Random r1 = new Random();int index = r1.nextInt(attack_esc.length);String kongfu = attack_esc[index];//輸出一個攻擊的效果System.out.printf(kongfu,this.getName(),role.getName());System.out.println("");//造成的隨機傷害Random r = new Random();int hurt = r.nextInt(20)+1;//修改一下挨揍人的血量int remainBlood = role.getBlood()-hurt;//剩余血量remainBlood = remainBlood<0?0:remainBlood; //驗證剩余的血量role.setBlood(remainBlood);if(remainBlood>90){System.out.printf(injureds_esc[0],role.getName());}else if(remainBlood>60){System.out.printf(injureds_esc[1],role.getName());}else {System.out.printf(injureds_esc[2],role.getName());}System.out.println("");// //this是方法的調用者
// System.out.println(this.getName()+"打了"+role.getName()
// +"一下,造成了"+hurt+"傷害,"+"\n"+
// role.getName()+"還剩"+remainBlood+"血量");}
- 想要實現隨機攻擊效果,首先需要在方法之前寫一個字符串數組,想要生動形象的調用名詞就需要使用到 printf(允許你按照指定的格式輸出文本),在方法中使用隨機索引來調用一個攻擊效果。System.out.printf (隨機攻擊的數組名,第一個% this.getName(),第二個% role.getName());
- 同樣的想要輸出一個受傷描述,這個是根據剩余血量的大小(在方法中定義的變量)來決定的,輸出是也是使用 printf。System.out.printf ( 被攻擊狀態名?[數組中第幾個值根據血量大小],role.getName());
格式說明符 | 作用 | 示例 |
---|---|---|
%d | 格式化整數 | int num = 10; |
%s | 格式化字符串 | String str = "hello"; |
%f | 格式化浮點數 | double d = 3.14159; |
%c | 格式化字符 | char c = 'A'; |
%b | 格式化布爾值 | boolean b = true; |
6、第二個方法showRoleInfo,不需要參數,因為它只操作當前對象自身的屬性,不需要外部輸入,調用的時候只需要寫出對應的get返回值即可。
7、寫完業務類的屬性、并對屬性的構造函數和對應方法寫完之后,就要寫一個test類,這個類的目的是作為程序入口,負責創建角色、控制游戲流程,不涉及角色內部實現。兩個類的兩者職責分離,修改其中一個不會影響另一個。
8、在test類中,首先主要對應上一個類中的構造函數創建角色 上一個類名?r1 = new 上一個類名(逗號隔開分別傳入構造函數中的參數);
9、在該類中可以利用上面構造的角色名調另一個類中的方法 調用者對象.方法名(方法參數),如果在調用方法中有對應的限制比如是否小于了0。
全部代碼
Role類:
import java.util.Random;public class Role {private String name;private int blood;private char gender;private String face;String[] boyfaces = {"風流倜儻","氣宇軒昂","相貌英俊"};String[] girlfaces = {"風華正茂","清秀","身材較好"};//攻擊描述String[] attack_esc = {"%s用牛角尖刺中%s","%s用小刀砍中%s","%s用小棒打中%s"};//受傷描述String[] injureds_esc = {"結果%s被攻擊,","結果%s被打倒","結果%s被打中"};public Role(String name, int blood, char gender) {this.name = name;this.blood = blood;this.gender = gender;//隨機長相setFace(gender);}public Role() { }public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}//get 方法:用于讀取成員變量的值。public String getFace() {return face;}//set 方法:用于修改成員變量的值。//set 方法需要參數:因為 set 方法的目的是設置成員變量的值,所以它需要一個參數來接收新的值。public void setFace(char gender) {Random r = new Random();//長相是隨機的if(gender=='男'){int index = r.nextInt(boyfaces.length);this.face = boyfaces[index];}else if(gender=='女'){int index = r.nextInt(girlfaces.length);this.face = girlfaces[index];}else {this.face = "非男非女";}}public String[] getBoyfaces() {return boyfaces;}public void setBoyfaces(String[] boyfaces) {this.boyfaces = boyfaces;}public String[] getGirlfaces() {return girlfaces;}public void setGirlfaces(String[] girlfaces) {this.girlfaces = girlfaces;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getBlood() {return blood;}public void setBlood(int blood) {this.blood = blood;}//定義一個方法用于攻擊別人,方法需要一個Role參數:因為需要指定攻擊的目標角色。//role.getName():獲取被攻擊角色的名字。//this.getName():獲取當前攻擊角色的名字。// this是方法的調用者即 this.getName// role也就是參數,是挨揍的人即 role.getNamepublic void attack(Role role){//隨機攻擊效果Random r1 = new Random();int index = r1.nextInt(attack_esc.length);String kongfu = attack_esc[index];//輸出一個攻擊的效果System.out.printf(kongfu,this.getName(),role.getName());System.out.println("");//造成的隨機傷害Random r = new Random();int hurt = r.nextInt(20)+1;//修改一下挨揍人的血量int remainBlood = role.getBlood()-hurt;//剩余血量//驗證剩余的血量remainBlood = remainBlood<0?0:remainBlood;//修改挨揍人的血量role.setBlood(remainBlood);if(remainBlood>90){System.out.printf(injureds_esc[0],role.getName());}else if(remainBlood>60){System.out.printf(injureds_esc[1],role.getName());}else {System.out.printf(injureds_esc[2],role.getName());}System.out.println("");// //this是方法的調用者
// System.out.println(this.getName()+"打了"+role.getName()
// +"一下,造成了"+hurt+"傷害,"+"\n"+
// role.getName()+"還剩"+remainBlood+"血量");}
//showRoleInfo 方法不需要參數:因為它只操作當前對象自身的屬性,不需要外部輸入。public void showRoleInfo(){System.out.println("姓名為:"+getName());System.out.println("血量為:"+getBlood());System.out.println("性別為:"+getGender());System.out.println("長相為:"+getFace());}
}
GameTest類:
public class GameTest {public static void main(String[] args) {Role r1 = new Role("喬峰",100,'男');Role r2 = new Role("摩智",100,'男');//展示角色信息r1.showRoleInfo();r2.showRoleInfo();//不知道要打擊多少輪,所有要用whilewhile (true){r1.attack(r2);//判斷一下剩余血量if (r2.getBlood()==0){System.out.println(r1.getName()+" ko "+r2.getName());break;}r2.attack(r1);if(r1.getBlood()==0){System.out.println(r2.getName()+" ko "+r1.getName());break;}}}
}
?