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

简介: 手把手一步一步教你使用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()方法是自动追踪的核心算法,原理如下图所示:


image.png


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


项目源码


项目源码


目录
相关文章
|
8天前
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
21 4
|
6天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
10天前
|
缓存 监控 Java
如何运用JAVA开发API接口?
本文详细介绍了如何使用Java开发API接口,涵盖创建、实现、测试和部署接口的关键步骤。同时,讨论了接口的安全性设计和设计原则,帮助开发者构建高效、安全、易于维护的API接口。
32 4
|
10天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
49 4
|
11天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
26 2
|
9天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
21 0
|
10天前
|
Java API Android开发
kotlin和java开发优缺点
kotlin和java开发优缺点
24 0
|
IDE 小程序 前端开发
详细解读java的俄罗斯方块游戏的源代码--【课程设计】
详细解读java的俄罗斯方块游戏的源代码--【课程设计】
|
Java 定位技术 开发者
基于Java的俄罗斯方块游戏
基于Java的俄罗斯方块游戏
基于Java的俄罗斯方块游戏