Skip to content

Melee Enemies

samsmarttt edited this page Aug 30, 2022 · 50 revisions

Page Navigation

Jump to a specific section

Summary

The melee enemies of Atlantis Sinks are integral to the player experience as they present an immediate threat to the city.

Sprint 1

Within sprint 1, Team 9 created a Pirate Crab enemy to provide the player character with a close range combat challenge.

Challenges

During these two weeks, several issues were faced with putting the enemy into the game from rendering to spawning the entity into the game world.

Rendering in Pixels

One of the issues we ran into during development was with rendering in pixels. It didn't occur that rendering was being done in units described to be equivalent to metres. When pixmaps for the healthbar were rendered onto the screen, they appeared to be really big and so Google was used to investigate the issue. An article was stumbled upon that described the solution. The solution was to temporarily swap the projection to render in pixels and then swap it back to its original.

This obviously looked like a feature that was going to get used several times so a class called RenderUtil was created and placed in the util package. It allowed a easy way to make draw calls.

Unit Testing

While unit testing, mocking and spying methods were quite difficult, but a couple of rounds of Googling and searching stackoverflow for answers helped. The difficulty was that some methods couldn't be easily mocked or stub as they lived in a static class and Mockito does not interact well with static classes. So the solution was to convert RenderUtil to a singleton so that only one of it will always be available in the entire game. Once this had been implemented, mocking and stubbing was then possible. The existing tests also really helped in figuring out how to write tests for the engine.

Spawning within the terrain bound

-- Pranav how did we overcome

these were the challenges that were encountered... this is how we overcame them...

More information regarding the objectives and tasks associated with the development of the melee enemy: Enemies Task Ticket and Melee Character Design

Design Inspiration & Ideation

The design for the Pirate Crab melee enemy follows the design principles set out in the Base Enemy Entities page to keep enemies consistent across the design of the game.

More information on the design of melee enemies for Atlantis Sinks can be found here!

Testing & Validation

To test the effectiveness of the design of melee enemies, some form of testing has to be conducted to ensure it is recognisable and fits the theme of the game.

More information on the user testing for the Pirate Crab design can be found here.

Technical

Config

Like all enemies, the Pirate Crab is configured within the NPCs.json file with stats based off of the EnemyConfig class. As a standard enemy, the Pirate Crab has relatively low health and therefore drops a low amount of gold when defeated (as can be seen below), but these values can easily be balanced from within the json file.

"pirateCrab": {
    "health": 50,
    "baseAttack": 10,
    "gold": 10
}

Spawning

The Pirate Crab is spawned using the NPCFactory class with the createPirateCrab() method. This method takes a single argument for the target that the Pirate Crab should chase when in range of it. The method then returns a single Entity configured with the combat stats and textures for the Pirate Crab.

  public static Entity createPirateCrabEnemy(Entity target) {
    Entity pirateCrabEnemy = createBaseNPC(target);
    EnemyConfig config = configs.pirateCrab;
    TextureRenderComponent textureRenderComponent = new TextureRenderComponent("images/pirate_crab_SW.png");

    pirateCrabEnemy
            .addComponent(new CombatStatsComponent(config.health, config.baseAttack))
            .addComponent(new HealthBarComponent(100, 10))
            .addComponent(textureRenderComponent);

    pirateCrabEnemy.getComponent(TextureRenderComponent.class).scaleEntity();

    return pirateCrabEnemy;
  }

The current implementation passes through the Player entity as the enemies' target (with the intention of this being replaced with the Crystal entity in future sprints) inside the spawnPirateCrabEnemy() method from the ForestGameArea class.

  private void spawnPirateCrabEnemy(){
    Entity pirateCrabEnemy = NPCFactory.createPirateCrabEnemy(player);

    GridPoint2 minPos = new GridPoint2(0,0);
    GridPoint2 maxPos = terrain.getMapBounds(0);
    GridPoint2 randomPos = RandomUtils.random(minPos,maxPos);

    int counter = 0;

    while (this.entityMapping.wouldCollide(pirateCrabEnemy, randomPos.x, randomPos.y)
           ||entityMapping.isNearWater(randomPos.x, randomPos.y)){
      randomPos = RandomUtils.random(minPos,maxPos);
      if (counter > 1000){
        return;
      }
      counter++;
    }

    spawnEntityAt(pirateCrabEnemy,randomPos,true,true);
  }

This is then called within the create() method of the ForestGameArea class to actually spawn the enemy within the game world.

UML Diagram

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