While we have a networked program, where two or more players can join a server, we don’t have much of a game. The next thing I’ve been working on is the player actions. Liam has implemented an input system which allows us to click on tiles on the map, meaning that I can start implementing the Move and Attack actions as well as allowing the player to actually place a unity they Buy.

First I setup functions for the movement and attack of units:

void GCNetClient::moveUnit(TileData* tile_clicked, TileData* previously_clicked)
{
  int range = getTroop(clientIndexNumber(), previously_clicked->troop_id)->getMovementRange();

  if (
    tile_clicked != nullptr &&
    map.tileInRange(previously_clicked->tile_id, tile_clicked->tile_id, range))
  {
    ASGE::Sprite* sprite =
      getTroop(clientIndexNumber(), previously_clicked->troop_id)->getSpriteComponent()->getSprite();
    sprite->xPos(
      tile_clicked->sprite->xPos() + tile_clicked->sprite->width() / 2 - sprite->width() / 2);
    sprite->yPos(
      tile_clicked->sprite->yPos() + tile_clicked->sprite->height() / 2 - sprite->height() / 2);

    tile_clicked->troop_id              = previously_clicked->troop_id;
    tile_clicked->troop_player_id       = clientIndexNumber();
    previously_clicked->troop_player_id = -1;
    previously_clicked->troop_id        = -1;

    Types type;
    type.move.unit_index      = tile_clicked->troop_id;
    type.move.current_tile_id = previously_clicked->tile_id;
    type.move.new_tile_id     = tile_clicked->tile_id;
    encodeAction(NetworkMessages::PLAYER_MOVE, type);
  }
}

void GCNetClient::attackUnit(TileData* tile_clicked, TileData* previously_clicked)
{
  Troop* owned_troop = getTroop(clientIndexNumber(), previously_clicked->troop_id);
  Troop* other_troop = getTroop(tile_clicked->troop_player_id, tile_clicked->troop_id);

  units_attacked_this_turn.emplace_back(owned_troop);
  owned_troop->setAttackedThisTurn(true);
  other_troop->takeDamage(owned_troop->getAttackDamage());

  if (other_troop->getHealth() <= 0)
  {
    auto it = std::find(
      troops[tile_clicked->troop_player_id].begin(),
      troops[tile_clicked->troop_player_id].end(),
      getTroop(tile_clicked->troop_player_id, tile_clicked->troop_id));
    troops[tile_clicked->troop_player_id].erase(it);

    tile_clicked->troop_id        = -1;
    tile_clicked->troop_player_id = -1;
  }

  Types type;
  type.attack.tile_id = tile_clicked->tile_id;
  type.attack.damage  = owned_troop->getAttackDamage();
  encodeAction(NetworkMessages::PLAYER_ATTACK, type);
}

I tested this out with Logging statements to make sure the units were being placed on the correct tiles and being damaged properly. I also added code to when the client recieves actions from the server, to correctly update the troops of the other players and map as needed. The next thing to do was to get players able to click on the map and move and attack units.

In order to do this I needed to make sure of several things for each action.

For attack:

  • The previously selected unit has to be owned by the player
  • The currently selected unit has to be owned by another player
  • The currently selected unit has to be in attack range of the previously selected unit


For movement:

  • The previously selected unit has to be owned by the player
  • The currently selected tile has to be empty of any units
  • The currently selected tile has to be in movement range of the previously selected unit


When the client recieves a “MAP_CLICK” message in Update() these two checks are run as well a check to see if the player is buying a unit. If none of the action checks run then the tile clicked will be selected. However, if any of them do return true then the corresponding function (BuyUnit(), AttackUnit(), MoveUnit()) will be run and the action handled.

Liam also added a Base Camp for each player where units are to be placed in range of when bought. As a final touch I also added ‘time units’ limiting the player to 3 actions per turn. I also limited units so that they couldn’t move or attack on the unit they’re bought and can only move once per turn.

Here is what the game looks like now: Selected tiles show up green when there is no unit on them and red when there is a unit.

unit actions