手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏17敌人自动追踪(自动寻路)

这节比较有趣,我们来实现Enemy自动追踪Player的算法,无论player走到哪里,enemy都如影随形。
这里我们主要用到了向量加减的几何意义。

向量类

Vector2d.java

package utils;
public class Vector2d {

   public double dX;
   public double dY;

   // Constructor methods ....
   public Vector2d(double dXp, double dYp ) {
          this.dX = dXp;
          this.dY = dYp;
   }
   
   public Vector2d() {
      dX = dY = 0.0;
   }



   // Convert Vector2d to a string ...
    
   public String toString() {
      return "Vector2d(" + dX + ", " + dY + ")";
   }

   // Compute magnitude of Vector2d ....
 
   public double length() {
      return Math.sqrt ( dX*dX + dY*dY );
   }

   // Sum of two Vector2ds ....

   public void add( Vector2d v1 ) {
       this.dX += v1.dX;
       this.dY += v1.dY;
   }

   // Subtract Vector2d v1 from v .....

   public void sub( Vector2d v1 ) {
       this.dX -= v1.dX;
       this.dY -= v1.dY;
   }

   // Scale Vector2d by a constant ...

   public void scale( double scaleFactor ) {
       this.dX *=scaleFactor;
       this.dY *=scaleFactor;
   }

   // Normalize a Vector2ds length....

   public Vector2d normalize() {
      Vector2d v2 = new Vector2d();

      double length = Math.sqrt( this.dX*this.dX + this.dY*this.dY );
      if (length != 0) {
        v2.dX = this.dX/length;
        v2.dY = this.dY/length;
      }

      return v2;
   }   

   // Dot product of two Vector2ds .....

   public double dotProduct ( Vector2d v1 ) {
        return this.dX*v1.dX + this.dY*v1.dY;
   }
 
}

修改Enemy类,添加Player类型的成员;因为我们要追踪Player,所以必须维护一个Player类型的对象,作为追踪的目标。
_isInRange()方法主要用来判断Enemy是否已经距离Player足够近了,主要是检测两者x坐标和y坐标之间的差值是否足够小。
每帧对update方法的调用中,我们都调用followPath()方法来计算新的enemy位置。

public class Enemy extends AttackAbleObject{
    private Animator _animator;
    private Player _player;
    private double _speed = 1.5;


    public Enemy(Player players, Animator animator, int hurtx, int hurty, int hurtscale_x, int hurtscale_y
            , int hitoffset_x1, int hitoffset_y1, int hitoffset_x2, int hitoffset_y2){
        super(animator,hurtx,hurty,hurtscale_x,hurtscale_y
                ,hitoffset_x1,hitoffset_y1,hitoffset_x2,hitoffset_y2);
        _animator = animator;
        _player= players;
        _animator.setAnimation("idle");
    }


    @Override
    public void update(Graphics2D g){
        _animator.show(g);
        followPath();
    }

    public Transform getTransform(){
        return _animator;
    }

    private boolean _isInRange(){
        boolean bRet = Math.abs(getX() - _player.getX()) < 60
                && Math.abs(getZ() - _player.getZ()) < Config.Z_FIGHT_DIST;

        return bRet;
    }


    public void followPath(){
        if(!_isInRange()){

            Vector2d towards = new Vector2d(_player.getX()-getX(),
                    _player.getZ()-getZ());

            Vector2d normalizedTowards = towards.normalize();

            Vector2d posVector = new Vector2d(normalizedTowards.dX,normalizedTowards.dY);


            posVector.scale(_speed);

            posVector.add(new Vector2d(getX(),getZ()));


            setPosition(posVector.dX,posVector.dY);

            if((getX()-_player.getX())<0 && !getTransform().isFlippedRight()){
                getTransform().flip();
            }

            if((getX()-_player.getX())>=0 && getTransform().isFlippedRight()){
                getTransform().flip();
            }

        }
    }
}

followPath()方法是自动追踪的核心算法,原理如下图所示:

31aaa47bd98c24184a056865d2256e1.png

如果您迷路了,请参考完整源码:

项目源码

项目源码

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容