Cat Toy Simulator

Oct 29 2024
Arduino/Processing/ESP32 (C++/Processing)


Github: https://github.com/davidjihwan/Cat_Toy_Simulator/tree/main

Media


The hardware side:


Joystick Movement:


Button movement (”jumps” or “impulses”):


Cats are able to catch the player, who then has to shake themselves loose:


More gameplay:


Ideation & Design Process

This project was completed for my Creative Embedded Systems class, where we were were required to use a joystick and a button/potentiometer to interface to the computer.

After brainstorming for a while with these constraints, I landed on the idea of a cat toy simulator, where the user would control a cat toy and try their best not to get caught by a number of cats. First of all, I greatly enjoy playing with my cats, so I knew that some version of the implementation would be fun to play with. Secondly, the motions that one has to carry out when playing with a cat can be broken up into two general categories: 1. You move the cat toy in a general direction, and 2. You jerk your hand to pull the cat toy back when the cat is about to grab it. As I had only a few input methods to work with, the small number of types of movements was perfect, as it meant I could assign a type of movement to each input.

I visualized my game as a WarioWare type minigame, where even with relatively simple controls (often just one or two at most) and visuals, the hectic and fast-paced nature of the games made them engaging and fun.

After testing the potentiometer that we were given, I opted to leave it out of the design. While I could have found a use for it, such as in allowing the user more control over their movement, I realized that turning the potentiometer was a little bit difficult due to its size and resistance. While this clunkier, finer type of control may have been more fitting for a different type of simulation, my cat toy simulation would have to be fast-paced and rapid, which would make it inefficient for the potentiometer to be a method of input.

I also initially pictured the cat toy as a toy connected to a stick by a string. However, I quickly resigned this idea after doing some research on string simulations (and even methods to fake doing so) as it would have taken far longer than the time constraints I had to work with. I still wanted to implement the general scenario I had planned, so I instead made the player control the cat toy directly. In this new plan, the player acts as the cat toy itself and not the hand controlling the stick, which I still thought would still be a fun scenario and preserved the general idea of the simulation.

I decided to implement the cat’s behavior through tasks, where the cat would either walk in a certain direction, stay still, or pounce at the cat toy. I wasn’t too worried about being accurate or realistic; the decision behind implementing many types of behaviors was to keep the simulation visually interesting or engaging.

As I continued to develop the simulation, I started to realize that I didn’t want to gamify the simulation more by adding something like a score or a timer, or freeze the game once the player was caught. I didn’t want the players to focus too much on maximizing score, as this may might lead to scenarios where the players just stay near the top of the screen where it would be more difficult for the cats to catch the player. Instead, I added more “soft” game elements, like making the cats increase in their likelihood to pounce at the cat toy the longer it went without any of them catching it. I also liked the idea of the game not “ending” when one of the cats caught you. Instead, just like in real life, you would have to shake the cat toy loose from the cat’s paws in order to play again (see Media section below). These design decisions allowed for what felt like a much softer gameplay loop that encouraged the player not to take themselves or the gameplay too seriously.

After I made sure the simulation was running as expected, I created an enclosure for the joystick as it was a little uncomfortable to hurt without one due to the pins sticking out of the bottom. I took my Professor Tiffany Tseng’s design and extruded cat faces into two of the sides to fit the theme of the game.




Technical Challenges

I had an interesting hardware problem where if I just tried to use the [0, analogMax] range to map to the joystick inputs, the player would drift slightly even if the joystick wasn’t moved at all. After printing some of the values out, I realized that there was a slight mechanical error in the output of the joysticks, where the values would vary slightly even if the joystick was not touched. To fix this, I added a small buffer wherein if the joystick values lay within the buffer’s range, the player would not move at all.

On the software side, I had some issues with what I’m assuming is how Arduino decides how to handle division and rounding. In my code, I had to keep track of the difference in time between the current frame and the last one (which I decided was better for stability instead of using a hard-coded value based on fps) to use in my calculations for movement. I was struggling with getting the cats to move properly until I realized that at times, by calculated time step, dt, was negative. Let’s say that millisLast was the value of millis() at the last time step. In my testing, the values given by millis()/1000 - millisLast/1000 is wildly different from (millis() - millisLast)/1000, and even sometimes becomes negative, which shouldn’t be possible. If floats were used to carry out these operations, the difference between the two methods should be negligible, which is why I believe it has to do with something the Arduino compiler is doing behind the scenes.

A cat not behaving as it should: