Crafting “Garden Guardian”: The Journey of My Midterm Project

When coming up with the idea for “Garden Guardian,” I wanted to make a charming, aesthetic game that had a challenging twist. A basic garden planting game didn’t seem very exciting on its own. I needed to add something to it.

However, this wasn’t always the case. In the very beginning, this project was pretty basic and boring. My first draft was just a game where you could plant flowers in a field, and that’s all it did. I didn’t focus much on how it looked during this early phase. It was pretty simple and not very attractive. This is what it looked like at first.

With the core functionality in place, I could now turn my attention to the aesthetics. To enhance the visuals, I utilized a combination of images generated by Dall-E and icons sourced from Google images. This allowed me to give the project a more polished and appealing look while retaining the foundational code I had already developed.

The game was pretty, but I wasn’t satisfied. That’s when I decided to throw in some pests causing trouble for the player’s garden. These pest invasions make the simple act of growing flowers into more of a defensive mission. Cultivating a colourful garden is still the main goal, but now you have to protect it as well.

Imagine this: you start with a blank canvas, ready to transform it into a breathtaking field of blooms. With a simple click, you can choose between flowers to add splashes of colour. 

But just when you think you’ve mastered the game, the real fun begins! Pesky pests appear out of nowhere, trying their best to kill your floral babies. That’s when your skills as a true Garden Guardian will be put to the test.

With this project, I really wanted to challenge my coding skills. One of the first challenges I faced was designing a game state management system. I wanted smooth transitions between the introduction screen, gameplay, and instructions. Through trial and error, I eventually settled on a streamlined approach, with the draw() function acting as the game’s heartbeat, constantly updating and rendering all the visuals used in the game (icons, buttons and backgrounds) based on the current state.

The drawGame() function became the centrepiece of my code, responsible for orchestrating the entire garden experience. I spent SO MANY hours refining this function, ensuring that the rendering of the garden background, the placement of icons, and the display of planted flowers all worked seamlessly together. I’m particularly proud of the highlighting technique I implemented, which draws attention to the currently selected icon, enhancing the overall user experience.

// Highlight the selected icon
noFill();
stroke(255, 204, 0); 
strokeWeight(2); 
let selectedIconIndex = selectedFlowerType - 1;
if (selectedIconIndex >= 0 && selectedIconIndex < iconPositions.length) {
  let pos = iconPositions[selectedIconIndex];
  rect(pos.x, pos.y, 50, 50, 10);

One of the most rewarding aspects of this project was creating the Flower class. Building a system to manage the lifecycle of each flower, from planting to potential infestation and treatment, was a true test of my object-oriented programming skills. The introducePest() method, which simulates the arrival of a pest and sets a timer for the flower’s demise if left untreated, was a particularly satisfying challenge to overcome. This took way too much time but as my mother would say, it felt like eating a ladoo (a delicious Indian dessert) when I could finally get it to work!

class Flower {
  constructor(x, y, type) {
    this.x = x;
    this.y = y;
    this.type = type;
    this.size = 50;
    this.hasPest = false;
    this.pestTimer = null;
  }

  display() {
    let img = [flowerImg1, flowerImg2, flowerImg3][this.type - 1];
    image(img, this.x - this.size / 2, this.y - this.size / 2, this.size, this.size);
    if (this.hasPest) {
      image(pestImg, this.x - this.size / 2, this.y - this.size / 2, this.size, this.size);
    }
  }

  introducePest() {
    if (!this.hasPest) {
      this.hasPest = true;
      this.pestTimer = setTimeout(() => this.die(), map(targetFlowers.planted, 0, targetFlowers.total, 4000, 3000));
    }
  }

  treatWithPesticide() {
    if (this.hasPest) {
      clearTimeout(this.pestTimer);
      this.hasPest = false;
      gameTime += 3;
    }
  }

  die() {
    let index = flowers.indexOf(this);
    if (index !== -1) {
      flowers.splice(index, 1);
      targetFlowers.planted = max(0, targetFlowers.planted - 1);
    }
  }
}

The Flower class encapsulates all the properties and behaviours of each flower in the garden. From managing the flower’s position, type, and size to handling pest infestations and treatment, this class is the backbone of the game’s core mechanics.

The introducePest() method is a prime example of the thought process behind crafting engaging gameplay. When a pest is introduced, a timer is set to simulate the potential demise of the flower if left untreated. The duration of this timer is dynamically adjusted based on the number of flowers already planted, increasing the difficulty as the game progresses. I had to do a lot of research (and some help from ChatGPT) to get this section working.  

Conversely, the treatWithPesticide() method allows players to counter the pest threat by using the pesticide icon. When a flower is treated, the pest timer is cleared, the hasPest flag is reset, and the player is rewarded with a few extra seconds on the game timer, encouraging strategic decision-making.

The die() method handles the removal of a flower from the game when it succumbs to a pest infestation. By splicing the flower from the flowers array and adjusting the targetFlowers.planted count, the game state is seamlessly updated, reflecting the player’s progress towards the target.

Throughout the development process, I encountered numerous roadblocks and debugging nightmares. However, each obstacle was an opportunity to learn and grow. I quickly realised the importance of modular code, which led me to create separate functions and classes for specific tasks, improving the overall readability and maintainability of my code.

Looking back on this journey, I’m filled with a sense of accomplishment and gratitude. “Garden Guardian” not only allowed me to create an entertaining game but also served as a valuable learning experience. I gained a deeper understanding of game mechanics, object-oriented programming, and the intricacies of creative coding with p5.js. Most importantly, I discovered the joy of problem-solving and the satisfaction of seeing my code come to life in the form of an engaging interactive experience.

However, there are still so many areas where I can improve and expand “Garden Guardian”: The scoring system needs work. Right now, you just win by planting enough flowers before time runs out. But I want a better system that scores you based on things like how many pests you treated, the variety of flowers planted, and maybe even keeping your garden completely pest-free. 

The difficulty progression could be better too. I think having the difficulty adapt based on the player’s performance would make it more engaging. If someone is struggling, the game could spawn fewer pests or give more time.

Visually, while the current look is charming, adding more detailed graphics, animations and effects could really enhance the overall aesthetic appeal. And new gameplay elements like power-ups, special abilities or different game modes could add lots of replay value.

During development, I ran into some tough challenges. Managing all the different timers and making sure the countdown was accurate when players gained extra time was really tricky. Weird edge cases, like planting flowers outside the garden area still need some work. 

Working through the issues I faced was a huge learning experience for me. It really emphasised the importance of thorough testing, keeping my code organised, and anticipating potential problems. Moving forward, I’ll apply those lessons to make my games even more polished.

“Garden Guardian” may be a small project, but it represents a big milestone in my coding journey. I had so much fun tackling challenges and adding and improving features and I cannot wait to experiment with game dev more!

Leave a Reply