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

          常用鏈接

          留言簿(19)

          隨筆檔案(115)

          文章檔案(4)

          新聞檔案(1)

          成員連接

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

           由于Spring2的AOP部分作了比較大的調(diào)整,很多地方的使用引入了AspectJ中的內(nèi)容,為了完成《深入Spring 2:輕量級(jí)J2EE開發(fā)框架原理與實(shí)踐》中Spring AOP應(yīng)用一章的寫作,因此這兩天把AspectJ研究了一下,重讀了一次《AspectJ in action》,受益不少。這里是前幾天做的一個(gè)回合格斗戲示例:
            這個(gè)示例中有一個(gè)設(shè)計(jì)了一個(gè)戰(zhàn)士Soldier類,這個(gè)類具有一些隨機(jī)功能,包括發(fā)動(dòng)攻擊、治療、躲避、移動(dòng)等功能。另外有一個(gè)簡(jiǎn)單的主程序MainTest,里面的功能就是讓兩個(gè)戰(zhàn)士回合制互相攻擊。另外有一個(gè)切面,是用來(lái)觀察并輸入戰(zhàn)斗的詳細(xì)過(guò)程,直到一個(gè)被打倒下:
          ?
          ?  先看戰(zhàn)士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隨機(jī)變動(dòng),成功率為50%
          public boolean dodge()
          {
          ?return getRandom(10)%2==0;
          }
          //治療,具有一定成功的機(jī)會(huì),可以提高生命值0-20點(diǎn)
          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中戰(zhàn)場(chǎng)模擬的代碼(即主程序):
          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("戰(zhàn)斗次數(shù):"+i);
          ?if(p1.getHealth()>0)System.out.println(p1.getName()+"戰(zhàn)勝!");
          ?else System.out.println(p2.getName()+"戰(zhàn)勝!");
          ?}
          }
          ?
          隨機(jī)數(shù)生成器(概率產(chǎn)生)
          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);
          }
          }
          ?
            這上面三個(gè)程序是完整的,可以直接用javac編譯,然后執(zhí)行MainTest,我們可以看到經(jīng)過(guò)一小段時(shí)間戰(zhàn)斗后分出勝負(fù)后,會(huì)顯示出戰(zhàn)斗的次數(shù)及勝負(fù)情況。
            為了要能觀察整個(gè)戰(zhàn)斗的詳細(xì)過(guò)程,這里在不改動(dòng)上面的程序代碼的情況下,使用AspectJ做了一個(gè)切面,主要用來(lái)輸出攻擊的情況。
          ?
            切面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()+" 發(fā)動(dòng)了一次攻擊!--結(jié)果:"+(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編譯上面的四個(gè)文件,在命令行輸入如下所示命令(要求AspectJ正確安裝及配置):
          ajc springroad\demo\chap5\*.*j*
          ?
          然后再使用java 命令執(zhí)行MainTest即可以看到非常有趣的結(jié)果(多執(zhí)行幾次試試)。如下圖所示:
          ?


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

           (本文作者:EasyJF開源團(tuán)隊(duì)??大峽 轉(zhuǎn)載請(qǐng)保留作者聲明,謝謝!)
          posted on 2006-10-30 16:20 簡(jiǎn)易java框架 閱讀(1455) 評(píng)論(1)  編輯  收藏

          FeedBack:
          # re: 用AspectJ做的一個(gè)回合格斗小游戲 2006-11-04 01:29 wln
          真的是太無(wú)聊了。。。。  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 阿拉善右旗| 曲周县| 舒城县| 双江| 马公市| 呼图壁县| 南投市| 台州市| 汕尾市| 根河市| 阳泉市| 太保市| 交口县| 七台河市| 独山县| 永昌县| 西乡县| 望都县| 漳州市| 沾化县| 察隅县| 哈尔滨市| 云林县| 奉节县| 兴安县| 萝北县| 江油市| 桂东县| 鸡西市| 喀什市| 盐津县| 武义县| 莎车县| 石棉县| 高唐县| 广灵县| 平遥县| 常熟市| 沙坪坝区| 偏关县| 手游|