隨筆 - 115  文章 - 481  trackbacks - 0
          <2006年10月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          常用鏈接

          留言簿(19)

          隨筆檔案(115)

          文章檔案(4)

          新聞檔案(1)

          成員連接

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

           由于Spring2的AOP部分作了比較大的調整,很多地方的使用引入了AspectJ中的內容,為了完成《深入Spring 2:輕量級J2EE開發框架原理與實踐》中Spring AOP應用一章的寫作,因此這兩天把AspectJ研究了一下,重讀了一次《AspectJ in action》,受益不少。這里是前幾天做的一個回合格斗戲示例:
            這個示例中有一個設計了一個戰士Soldier類,這個類具有一些隨機功能,包括發動攻擊、治療、躲避、移動等功能。另外有一個簡單的主程序MainTest,里面的功能就是讓兩個戰士回合制互相攻擊。另外有一個切面,是用來觀察并輸入戰斗的詳細過程,直到一個被打倒下:
          ?
          ?  先看戰士Soldier的代碼:

          package springroad.demo.chap5.aspectj;

          public class Soldier {
          private String name;
          private int health=100;
          private int damage=10;
          private int x=10;
          private int y=10;
          public boolean attack(Soldier target){
          ?boolean ret=false;
          ?if(!target.dodge())
          ?{
          ??target.setHealth(target.getHealth()-this.damage);
          ??ret=true;
          ?}
          ?move();
          ?treat();?
          ?return ret;
          }
          public void move()
          {
          ?this.x+=getRandom(5);
          ?this.y+=getRandom(5);
          }
          //躲避x及y隨機變動,成功率為50%
          public boolean dodge()
          {
          ?return getRandom(10)%2==0;
          }
          //治療,具有一定成功的機會,可以提高生命值0-20點
          public void treat()
          {
          ?if(canTreat())
          ??this.health+=getRandom(20);
          }
          public boolean canTreat()
          {
          ?return getRandom(10)/2==0;
          }

          private int getRandom(int seed)
          {
          ?return RandomUtil.getRandomValue(seed);
          }

          //getter及setter方法
          public int getHealth() {
          ?return health;
          }
          public void setHealth(int health) {
          ?this.health = health;
          }
          public String getName() {
          ?return name;
          }
          public void setName(String name) {
          ?this.name = name;
          }
          public int getX() {
          ?return x;
          }
          public void setX(int x) {
          ?this.x = x;
          }
          public int getY() {
          ?return y;
          }
          public void setY(int y) {
          ?this.y = y;
          }
          public int getDamage() {
          ?return damage;
          }
          public void setDamage(int damage) {
          ?this.damage = damage;
          }

          }

          ?
            
          ?
          再看看MainTest.java中戰場模擬的代碼(即主程序):
          package springroad.demo.chap5.aspectj;
          public class MainTest {?
          ?public static void main(String[] args) {
          ?Soldier p1=new Soldier();
          ?p1.setName("角色1");
          ?Soldier p2=new Soldier();
          ?p2.setName("角色2");
          ?int i=0;
          ?while(p1.getHealth()>0 && p2.getHealth()>0)
          ?{
          ??p2.attack(p1);
          ??p1.attack(p2);
          ??i+=2;
          ?}?
          ?System.out.println("戰斗次數:"+i);
          ?if(p1.getHealth()>0)System.out.println(p1.getName()+"戰勝!");
          ?else System.out.println(p2.getName()+"戰勝!");
          ?}
          }
          ?
          隨機數生成器(概率產生)
          package springroad.demo.chap5.aspectj;
          public class RandomUtil {
          private static java.util.Random random=new java.util.Random();
          public static int getRandomValue(int seed)
          {
          ?return random.nextInt(seed);
          }
          }
          ?
            這上面三個程序是完整的,可以直接用javac編譯,然后執行MainTest,我們可以看到經過一小段時間戰斗后分出勝負后,會顯示出戰斗的次數及勝負情況。
            為了要能觀察整個戰斗的詳細過程,這里在不改動上面的程序代碼的情況下,使用AspectJ做了一個切面,主要用來輸出攻擊的情況。
          ?
            切面RecordGame.aj的代碼如下 :
          ?
          package springroad.demo.chap5.aspectj;
          public aspect RecordGame {
          ?private static java.text.SimpleDateFormat df=new java.text.SimpleDateFormat("yyyy-MM-dd H:m:s");
          ?pointcut doRecord():execution(boolean Soldier.attack(Soldier));?
          ?pointcut? supperRole(Soldier s): target(s)&&execution(boolean Soldier.canTreat());?
          ?after() returning(boolean value) :doRecord()
          ?{
          ??Soldier s=(Soldier)thisJoinPoint.getTarget();?
          ??Soldier t=(Soldier)thisJoinPoint.getArgs()[0];
          ??System.out.println(df.format(new java.util.Date())+":"+s.getName()+" 向 "+t.getName()+" 發動了一次攻擊!--結果:"+(value?"成功":"失敗"));
          ??System.out.println(s.getName()+"生命值:"+s.getHealth()+";"+t.getName()+"生命值:"+t.getHealth());
          ?}
          ?after(Soldier s)returning(boolean value):target(s)&&call(boolean Soldier.canTreat())
          ?{
          ??if(value)System.out.println(s.getName()+"得到治療!");
          ?}
          ?boolean around(Soldier s): supperRole(s)
          ?{
          ??? if("super".equals(s.getName())) return true;
          ??? else return proceed(s);
          ?}
          ?}
          ?
          使用ajt編譯上面的四個文件,在命令行輸入如下所示命令(要求AspectJ正確安裝及配置):
          ajc springroad\demo\chap5\*.*j*
          ?
          然后再使用java 命令執行MainTest即可以看到非常有趣的結果(多執行幾次試試)。如下圖所示:
          ?


            另外,切面中還定義了一個超級角色,也即名稱為“super”的戰士,你把客戶端某個戰士的名稱改成super,然后再運行試試,90%的情況都是super勝。

           (本文作者:EasyJF開源團隊??大峽 轉載請保留作者聲明,謝謝!)
          posted on 2006-10-30 16:20 簡易java框架 閱讀(1449) 評論(1)  編輯  收藏

          FeedBack:
          # re: 用AspectJ做的一個回合格斗小游戲 2006-11-04 01:29 wln
          真的是太無聊了。。。。  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 土默特左旗| 安徽省| 延寿县| 鹿泉市| 鲜城| 南通市| 宝清县| 兴业县| 胶南市| 黔东| 荣昌县| 榕江县| 花垣县| 项城市| 宝应县| 霍山县| 甘泉县| 云梦县| 鄂尔多斯市| 成武县| 沙雅县| 浦城县| 镇原县| 铁岭市| 渝北区| 乌苏市| 淳安县| 六安市| 雷州市| 涟源市| 上思县| 常宁市| 泸州市| 从化市| 宜州市| 淄博市| 嘉兴市| 肃北| 泸州市| 竹溪县| 黑河市|