代码改变世界

小球互动(附带AS3抽象类写法)

2008-11-27 16:35  宝宝合凤凰  阅读(781)  评论(0)    收藏  举报
最近群里面老是在说什么,三个球,一个球被控制,一个球针对主球逃跑,一个球针对主球追赶。。
其实这种东西嘛。算法上的东西并不多的,如果结构清晰,这种东西是非常容易写的
 
先请看例子:

 
简单说说这个结构,写了一个抽象类Ball,然后再写三种球都继承该抽象类
逃亡的球:侦听被控制球的位置,在快接近的时候,即时做出反应
追赶的球:侦听被控制球的位置,在快靠近的时候,立即去追主球
控制的球:侦听键盘操作,做出移动动作
然后在设置逃亡/追赶对象的时候,使用抽象类的数据类型,这样不但可以让逃亡/追赶的球对象是控制的球,如果需要扩展,逃亡/追赶的球设置的逃亡/追赶对象也可以是其他的球,这样按正常的理解,任何一个小球都是可以成为被追赶,被逃亡的对象,符合实情,只要创建的小球是继承抽象类Ball来实现,那么他就可以被设置为追赶和逃亡的对象
另外我们也可以很快的创建很多个追赶,逃亡的小球比如下面这个例子不过是for循环创建了10个逃亡和追赶小球罢了,很快就可以实现,这也是oop非常不错的一面,你只要把东西封装好了,每次使用都非常方便

 
这个简单结构的缺点:一个小球只能设置一个追赶或者逃亡的对象,但其实是有办法做到的,大家可以来想想办法,将这个小例子给完善
 
另外请大家注意Ball类的写法,其中含有AS3如何写抽象类的办法,但不是真正的抽象类,只是利用了一些属性等来达到抽象类的目的
知识点:抽象类通俗的说,就是类的本身不能被实例化,只有继承该类才能实例化,但ADOBE给出的是抽象基类,就算继承了也不能用,只有去继承Sprite才行。。
 
源代码结构比较清晰,没啥好说好解释的,请看源代码:
该源代码中使用了:Random类 Direction类
文档类:
package{
  
  import flash.display.Sprite;
  
  import index.base.func.Random;
  
  public class Index extends Sprite{
    
    private var cueBall:CueBall;
    
    public function Index(){
      init();
    }
    
    //初始化
    private function init():void{
      createCueBall();
      createFleeBall(50);
      createChaseBall(50);
    }
    
    //创建主球
    private function createCueBall():void{
      cueBall = new CueBall;
      addChild(cueBall);
      cueBall.setControl();
      cueBall.x = stage.stageWidth / 2;
      cueBall.y = stage.stageHeight / 2;
    }
    
    //创建逃亡小球
    private function createFleeBall(_scope:Number):void{
      var fleeBall:FleeBall = new FleeBall;
      addChild(fleeBall);
      fleeBall.x = Random.number(stage.stageWidth);
      fleeBall.y = Random.number(stage.stageHeight);
      fleeBall.scope = _scope;
      
      fleeBall.setFlee(cueBall);
      fleeBall = null;
    }
    
    //创建追赶小球
    private function createChaseBall(_scope:Number):void{
      var chaseBall:ChaseBall = new ChaseBall;
      addChild(chaseBall);
      chaseBall.x = Random.number(stage.stageWidth);
      chaseBall.y = Random.number(stage.stageHeight);
      chaseBall.scope = _scope;
      
      chaseBall.setChase(cueBall);
      chaseBall = null;
    }
    
  }
  
}
 
抽象类Ball 请注意构造函数中的抽象类写法
package{
  
  import flash.display.Sprite;
  import flash.events.Event;
  
  public class Ball extends Sprite{
    
    public function Ball(){
      //抽象类
      if(this["constructor"] == "[class Ball]"){
        throw new Error("抽象类无法实例化!");
      }
      init();
    }
    
    //初始化
    private function init():void{
      
    }
    
  }
  
}
 
逃亡的小球,FleeBall类
package{
  
  import flash.events.Event;
  
  public class FleeBall extends Ball{
    
    private var _ball:Ball;
    private var targetX:Number;
    private var targetY:Number;
    
    public var scope:Number = 0;
    
    public function FleeBall(){
      init();
    }
    
    //初始化
    private function init():void{
      graphics.lineStyle(0);
      graphics.beginFill(0x00000);
      graphics.drawCircle(0,0,5);
    }
    
    //设定躲避的对象
    public function setFlee(_flee:Ball):void{
      _ball = _flee;
      targetX = x;
      targetY = y;
      
      addEventListener(Event.ENTER_FRAME,onBallFleeEnterFrame);
    }
    
    //追赶对象
    private function onBallFleeEnterFrame(e:Event):void{
      x += (targetX - x) / 10;
      y += (targetY - y) / 10;
      
      if(Math.sqrt(Math.pow(Math.abs(_ball.x - x),2) + Math.pow(Math.abs(_ball.y - y),2)) < scope){
        targetX += _ball.x > targetX ? -3 : 3;
        targetY += _ball.y > targetY ? -3 : 3;
      }
    }
    
  }
  
}
 
追赶的球。ChaseBall类
package{
  
  import flash.events.Event;
  
  public class ChaseBall extends Ball{
    
    private var _ball:Ball;
    
    public var scope:Number = 0;
    
    public function ChaseBall(){
      init();
    }
    
    //初始化
    private function init():void{
      graphics.lineStyle(0);
      graphics.beginFill(0x336699);
      graphics.drawCircle(0,0,5);
    }
    
    //设定追赶的对象
    public function setChase(_chase:Ball):void{
      _ball = _chase;
      
      addEventListener(Event.ENTER_FRAME,onBallChaseEnterFrame);
    }
    
    //追赶对象
    private function onBallChaseEnterFrame(e:Event):void{
      if(Math.sqrt(Math.pow(Math.abs(_ball.x - x),2) + Math.pow(Math.abs(_ball.y - y),2)) < scope){
        x += (_ball.x - x) / 20;
        y += (_ball.y - y) / 20;
      }
    }
    
  }
  
}
 
被控制的主球,CueBall类
package{
  
  import flash.events.KeyboardEvent;
  
  import index.base.game.Direction;
  import index.base.events.DirectionEvent;
  
  public class CueBall extends Ball{
    
    private var operate:Direction;
    
    public function CueBall(){
      init();
    }
    
    //初始化
    public function setControl():void{
      graphics.lineStyle(0);
      graphics.beginFill(0xff0000);
      graphics.drawCircle(0,0,5);
      
      //给小球加上控制
      operate = new Direction(stage);
      operate.addEventListener(DirectionEvent.DO,onBallDo);
    }
    
    //球的行动
    private function onBallDo(e:DirectionEvent):void{
      if(e.left) x -= 3;
      if(e.right) x += 3;
      if(e.up) y -= 3;
      if(e.down) y += 3;
    }
    
  }
  
}