手把手一步一步教你使用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


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


项目源码


项目源码


目录
相关文章
|
10天前
|
Java API Maven
如何使用Java开发抖音API接口?
在数字化时代,社交媒体平台如抖音成为生活的重要部分。本文详细介绍了如何用Java开发抖音API接口,从创建开发者账号、申请API权限、准备开发环境,到编写代码、测试运行及注意事项,全面覆盖了整个开发流程。
53 10
|
4天前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
|
16天前
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
34 4
|
13天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
17天前
|
缓存 监控 Java
如何运用JAVA开发API接口?
本文详细介绍了如何使用Java开发API接口,涵盖创建、实现、测试和部署接口的关键步骤。同时,讨论了接口的安全性设计和设计原则,帮助开发者构建高效、安全、易于维护的API接口。
46 4
|
18天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
64 4
|
17天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
31 0
|
8天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
15天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
|
7天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
下一篇
无影云桌面