Skip to content

Ranged Enemy Projectiles

Josephjmet edited this page Oct 4, 2022 · 6 revisions

Link back to main page

Spawning of Projectile

The current implementation to spawn a ranged enemy projectile can be found in the shoottask.java and the projectileFactory.java classes. Firstly the creation of a ranged enemy has been changed to include a new AI task, shooting. This is similar to previous tasks but has additional implementation.

private static Enemy createBaseRangeNPC(Entity target, Entity crystal) {
    //Vector2 RangeHitbox = new Vector2(2f, 1f);
    AITaskComponent aiComponent =
            new AITaskComponent()
                    .addTask(new WanderTask(new Vector2(3f, 3f), 2f))
                    .addTask(new RangedMovementTask(crystal, 10, 2f, 50f, 60f))
                    .addTask(new RangedMovementTask(target, 20, 2f, 50f, 60f))
                    .addTask(new MeleeAvoidObstacleTask(target))
                    .addTask(new ShootTask(target, 30, 50f, 60f))
                    .addTask(new ShootTask(crystal, 30, 50f, 60f));
    Enemy enemy =
            (Enemy) new Enemy()
                    .addComponent(new PhysicsComponent())
                    .addComponent(new PhysicsMovementComponent())
                    .addComponent(new ColliderComponent())
                    .addComponent(new HitboxComponent().setLayer(PhysicsLayer.RangeNPC))
                    .addComponent(new TouchAttackComponent(PhysicsLayer.RangeNPC))
                    .addComponent(aiComponent);

    PhysicsUtils.setScaledCollider(enemy, 0.9f, 0.4f);
    return enemy;
  }

The Shoot task includes a time check to periodically check if it is time to create a new projecitle entity, This task has a range similar to the movement tasks to ensure that the enemy does not constantly spawn projectiles.

Shoot Task

public ShootTask(Entity target, int priority, float viewDistance, float maxChaseDistance) {
        this.target = target;
        this.priority = priority;
        this.maxChaseDistance = maxChaseDistance;
        this.GameTime = ServiceLocator.getTimeSource();
        this.viewDistance = viewDistance;
        physics = ServiceLocator.getPhysicsService().getPhysics();
        debugRenderer = ServiceLocator.getRenderService().getDebug();
    }

    @Override
    public void start() {
        super.start();
        System.out.println("start shooting");
        taskEnd = GameTime.getTime() + (int)(1 * SECOND);
        System.out.println(taskEnd);
    }

    @Override
    public void update() {
        Entity entity = this.owner.getEntity();
        System.out.println(taskEnd);
        System.out.println(GameTime.getTime());
        if (GameTime.getTime() >= taskEnd) {
            System.out.println("shoots");
            ProjectileFactory.createProjectile(entity, target);
            taskEnd = GameTime.getTime() + (int)(SECOND);
        }
        System.out.println(entity.getPosition());
        System.out.println("1");
        System.out.println(target.getPosition());
        System.out.println("2");
    }

The below code is the projectileFactory code. Every time the shooting task updates and the current time has passed the update threshold, a new projectile is made. This involves calculating the target of the projectile and creating an entity that will act as the projectile and setting movement characteristics to the entity.

public static Entity createProjectile(Entity shooter, Entity target) {
        Vector2 targetNew = target.getPosition();
        return makeProjectile(targetNew, shooter);
    }

    private static Entity makeProjectile(Vector2 destination, Entity source) {
        Entity projectile = new Entity()
                .addComponent(new TextureRenderComponent("images/Eel_Bright_SW.png"))
                .addComponent(new PhysicsComponent())
                .addComponent(new PhysicsMovementComponent())
                .addComponent(new ColliderComponent())
                .addComponent(new HitboxComponent().setLayer(PhysicsLayer.NPC))
                .addComponent(new CombatStatsComponent(1,5))
                .addComponent(new EntityClassification(EntityClassification.NPCClassification.ENEMY))
                .addComponent(new TouchAttackComponent(PhysicsLayer.PLAYER, 0.2f));

        projectile.getComponent(PhysicsMovementComponent.class).setTarget(destination);
        projectile.getComponent(PhysicsMovementComponent.class).setMoving(true);
        projectile.getComponent(ColliderComponent.class).setSensor(true);

        projectile.setPosition(source.getPosition());
        PhysicsUtils.setScaledCollider(projectile, 2f, 2f);

        ServiceLocator.getEntityService().registerNamed("Enemy@" + projectile.getId(), projectile);
        return projectile;
    }

Table of Contents

Home

How to Play

Introduction

Game Features

Main Character

Enemies
The Final Boss

Landscape Objects

Shop
Inventory
Achievements
Camera

Crystal

Infrastructure

Audio

User Interfaces Across All Pages
Juicy UI
User Interfaces Buildings
Guidebook
[Resource Management](Resource-Management)
Map
Day and Night Cycle
Unified Grid System (UGS)
Polishing

Game Engine

Getting Started

Entities and Components

Service Locator

Loading Resources

Logging

Unit Testing

Debug Terminal

Input Handling

UI

Animations

Audio

AI

Physics

Game Screens and Areas

Terrain

Concurrency & Threading

Settings

Troubleshooting

MacOS Setup Guide

Clone this wiki locally