Back

Activity 4.5 Turn-Based Battle with GameCharacter

divider

Introduction

Activity 4.5

Turn-Based Battle Simulation

Topics

  • Objects interacting with other objects
  • Instance methods that modify and return state
  • Using loops and conditionals to control game flow
  • Maintaining invariants during gameplay
  • Designing a simple system of classes

What Are We Building?

In this activity, you will design a class that models a character in a game and write a simple turn-based battle.

  • Characters can attack and heal
  • Health must stay between 0 and maxHealth
  • Battle continues until one character is defeated

Key Ideas

  • Objects can call methods on other objects.
  • Instance methods enforce class invariants.
  • Logic in main drives the simulation.
  • Encapsulation ensures predictable behavior.

'F' → Fullscreen

Objectives

  • icon Write instance methods that perform actions and update state
  • icon Enforce invariants in methods (health cannot go below 0)
  • icon Use objects inside other objects and methods
  • icon Create a simple text-based game using OOP
divider

Activity Tasks

  • icon Create a new project named 4-5-GameCharacter-Battle.
  • icon Complete each task individually.

Task 1: Implement GameCharacter

Create the GameCharacter class by following the example shown above.

GameCharacter.java
class GameCharacter
{
private String name;
private int maxHealth;
private int currentHealth;
private int attackPower;
public GameCharacter(String name, int maxHealth, int attackPower)
{
this.name = name;
this.maxHealth = maxHealth;
this.currentHealth = maxHealth; // start full health
this.attackPower = attackPower;
}
public String getName()
{
return name;
}
public int getCurrentHealth()
{
return currentHealth;
}
public int getAttackPower()
{
return attackPower;
}
// Reduce health but never below 0
public void takeDamage(int amount)
{
if (amount > 0)
{
currentHealth -= amount;
if (currentHealth < 0)
{
currentHealth = 0;
}
}
}
// Heal but never above maxHealth
public void heal(int amount)
{
if (amount > 0)
{
currentHealth += amount;
if (currentHealth > maxHealth)
{
currentHealth = maxHealth;
}
}
}
// Deal attack damage equal to attackPower
public void attack(GameCharacter target)
{
target.takeDamage(attackPower);
}
public boolean isDefeated()
{
return currentHealth == 0;
}
}

Task 2: Build the Battle Loop

Write the main game loop where the player chooses actions and the enemy responds automatically.

Main.java
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
GameCharacter player = new GameCharacter("Hero", 100, 15);
GameCharacter enemy = new GameCharacter("Goblin", 75, 10);
System.out.println("-- Turn-Based Battle --");
while (!player.isDefeated() && !enemy.isDefeated())
{
System.out.println("\n" + player.getName() + " HP: " + player.getCurrentHealth());
System.out.println(enemy.getName() + " HP: " + enemy.getCurrentHealth());
System.out.println("\nChoose an action:");
System.out.println("1) Attack");
System.out.println("2) Heal");
System.out.print("> ");
String choice = input.nextLine();
if (choice.equals("1"))
{
player.attack(enemy);
System.out.println("\nYou dealt " + player.getAttackPower() + " damage!");
}
else if (choice.equals("2")) {
player.heal(10);
System.out.println("\nYou healed 10 HP.");
}
else
{
System.out.println("Invalid choice. You lose your turn!");
}
if (enemy.isDefeated())
{
break;
}
enemy.attack(player);
System.out.println("The " + enemy.getName() + " attacks for " + enemy.getAttackPower() + " damage!");
}
if (player.isDefeated())
{
System.out.println("\nYou were defeated...");
}
else
{
System.out.println("\nYou defeated the enemy!");
}
}
}
divider

Sample Output

Sample Output
-- Turn-Based Battle --
Hero HP: 100
Goblin HP: 75
Choose an action:
1) Attack
2) Heal
> 1
You dealt 15 damage!
The Goblin attacks for 10 damage!
Hero HP: 90
Goblin HP: 60
...
You defeated the enemy!
divider

Reflection Questions

  1. Why should health never go below 0 or above maxHealth?
  2. How does encapsulation protect the internal state of a character?
  3. Why is a loop used to control the flow of the battle?
  4. What advantages do instance methods provide over writing logic in main?
  5. How could you expand this system in the future (e.g., items, spells, multiple enemies)?
divider

Submission

Submit your project and reflection answers to the appropriate dropbox.

Activity Complete