Here we are, after Fall-ish break also known as Midterms Week:
Back to the Spelling Game
After a lot of planning, and not much sleep, I managed to achieve the general idea of my game, with a few bugs and missing elements. Although I would have loved to have it as I imagined, I think with the amount of time + midterms that I had, this is a cool result!
Additionally, if you still didn’t notice, I always try my best to avoid making games for our assignments and often opt for the artwork option. The thought of coding a game often scares me, especially when I think of moving between screens and checking for correct moves. So, this was a great challenge for me! And while I feel like I’m a bit more familiar with game states and other elements, I still think I can work on my game-making skills, and will probably end up looking at your codes for help 🙂

List of Classes:
- Animals: this is where I load and display the visual for my animal
- Buttons: where I create the start and replay buttons
- Letter: Where I create letter blocks for a keypad grid and check for player clicks.
Steps
- Make a start button, start screen, and then switch to the gameplay screen that is linked with an animal.
- Make a keypad for each possible animal. This keypad must contain the letters of the animal name in random order, and it must not repeat letters within the alphabet list:
For this bit, I created two functions
- WordCharsinKeypad(): fills the characters from the animal name into the keypad randomly (the letters won’t appear next to each other).
- fillRemainingKeys(): checks for remaining empty spots in the keypad and fills them with a random letter from the alphabet without repeating letters from that alphabet array.
- Display the game playing screen, make the keypad interactive, and give feedback to the user by printing on the screen the letters they get correctly:
I initially aimed to provide two types of feedback. One, which is evident in my program, is that the animal is gradually spelled out on the screen and a letter is added when the player picks the correct letter.
The other, however, I struggled with, which is showing a “try again” message when the player presses the wrong letter. For now, the program just doesn’t respond to a wrong letter.
When I tried to apply the second feedback this is what I got:
- Finally, I wanted to switch between screens, as you can see above, move from the start screen to the gameplay screen, to the replay screen:
For the start and replay, I relied on buttons from my button class, however, for moving from gameplay to replay screen, it only requires the player to guess the complete word. A small issue I have here is that the last letter does not display before moving to the replay screen. I tried to resolve it with delay() and altering the if condition in the code, but I still haven’t figured it out.
Some Design Choices
- I was truly excited to design my own animals, I thought it would be a great chance to work on my Adobe Illustrator skills. However, I placed that as my last priority and unfortunately did not have time for that. So I used free PNGs from open source websites.
- My game is missing sound, this is something that I will work on and practice as I still feel a bit unfamiliar with it
- I tried to use soft colors with great contrast to appeal to the child’s eye
- Keeping accessibility in mind, I made sure to use a font that is legible for most kids. This typeface is OpenDyslexic and it is specifically designed to make it easier for anyone with dyslexia to read a text.
Example of a Game Run
Future Developments
For a more developed version of this game, it would probably incorporate the sounds I mentioned in my progress post, my own designs, and levels rather than one run.
Here’s my code!
Main Function
// to load OpenDyslexic Font
PFont f;
//for final screen
PImage confetti;
boolean wrongLetter = false;
//startScreen
int screenNumber = 0;
//a string array to pick a random animal each time start is pressed:
String[] animalNames = {"CAT", "OWL", "FROG", "FISH", "PANDA", "MONKEY", "TURTLE", "CHAMELEON"};
// string where the random animal picked from array is stored:
String word;
//character array of all letters in the alphabet:
char alphabet[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
//initializing a letter object array for a keypad:
Letter[] keypad = new Letter[12];
//initializing the animal object for the animal displayed in the run:
Animals animal4Run;
//columns for keypad grid display
int cols = 3;
//rows for keypad grid display
int rows =4;
// a variable that checks the players progress of selecting the correct letters -- e.g. if they have "CA" out of "CAT" it will equal 1
int playerPosition = 0;
//initializing a button object for start button
Buttons startButton;
// initializing a button object for replay button
Buttons replayButton;
//an empty string variable. It will be used to reflect the player's progress in choosing the correct letter
String wordInProg;
void setup() {
size(960, 540);
confetti = loadImage("CONFETTI.png");
confetti.resize(960, 540);
//using OpenDyslexic so the font could be readable for most
f = createFont("OpenDyslexic-Bold.otf", 20);
textFont(f);
//creating the start button object
startButton = new Buttons(width/2, height/2+100, 100, 70, "Start"); //creating the start button object
//creating the replay button object
replayButton = new Buttons(width/2, height/2+200, 100, 70, "Replay");
//setup the word in progress as an empty string, it will fill gradually as the player picks the correct letters.
wordInProg = "";
//generates a random index to pick a random animal each time run is clicked
int indexForRun = (int)random(0, animalNames.length);
//sets the word variable using the generated random index
word = animalNames[indexForRun];
//creates an animal object using the word
animal4Run = new Animals(word);
//index variable to go through all objects in the keypad array
int index = 0;
for (int c = 0; c < cols; c++) {
for (int r = 0; r < rows; r++) {
//using columns and rows for a grid display
keypad[index] = new Letter('x', c, r);
index += 1;
}
}
//function that fills the characters from the animal name into the keypad in random positions
wordCharsInKeypad();
//function that fills the remaining empty keypad spaces
fillRemainingKeys();
}
void draw() {
background(227, 181, 164);
//switch function to move between game screens
switch(screenNumber) {
// case 0 is the start screen
case 0:
//calls setup to randomize a new animal everytime start is pressed
setup();
fill(232, 95, 92);
textSize(60);
text("Spell the Animal Name Game!", width/2, height/2 - 100);
//display function for start button
startButton.buttonDisplay();
//checks if player clicks the start button and moves on to the next game screen
if (mousePressed && mouseX >= startButton.xLoc - startButton.buttonW/2 && mouseX <= startButton.xLoc + startButton.buttonW/2 && mouseY >= startButton.yLoc - startButton.buttonH/2 && mouseY <= startButton.yLoc + startButton.buttonH/2) {
screenNumber = 1;
}
break;
// playing screen
case 1:
fill(156, 255, 250);
textSize(50);
text("What is this animal called?", width/2, height/2 - 200);
//displays the player's progress in choosing the correct letters on the screen
text(wordInProg, width/2-50, height/2 + 200);
for (int i = 0; i < keypad.length; i ++) {
//displays all letter objects in the keypad
keypad[i].display();
//displays the image of the animal in question
animal4Run.display();
//loops through all letters to check if 1. they are clicked , 2. if they are the correct letter
for (int j = 0; j < keypad.length; j++ ) {
textSize(20);
//calls a function that checks whether the letter is clicked
keypad[j].letterIsClicked();
if (keypad[j].letterClicked == true) {
keypad[j].letterClicked = false;
//println(">>>", keypad[j].letter, cat.animalName.charAt(playerPosition));
if (keypad[j].letter != animal4Run.animalName.charAt(playerPosition)) {
text("try again", width/2 - 300, height/2);} //?????
//checks if the character clicked in the keypad matches the character that is at the player's position in the animal name
if (keypad[j].letter == animal4Run.animalName.charAt(playerPosition)) {
//this condition ensures that it adds the correct letters only for as long as the word in progress is the same length as the animal name, otherwise you would get "CATTTTTTTTTT"
if (wordInProg.length() < animal4Run.animalName.length()) {
//keeps adding to reflect the player's progress
wordInProg = wordInProg + animal4Run.animalName.charAt(playerPosition);
//println(wordInProg);
//println(keypad[j].letter + " " + cat.animalName.charAt(playerPosition));
//condition: as long as the player position is still less than the length of the animal name, keep adding as the name is not complete yet
if (playerPosition < animal4Run.animalName.length() -1) {
playerPosition+= 1;
//checks if the word is complete to switch to end screen that reflects success and gives replay button
} else if (playerPosition == animal4Run.animalName.length()-1) {
screenNumber = 2;
break;
}
}
}
}
}
}
break;
//end screen
case 2:
//resets player position for next iteration of the game
playerPosition = 0;
for (int k = 0; k < keypad.length; k++ ) {
//resets any letters clicked
keypad[k].letterClicked = false;
}
background(227, 181, 164);
imageMode(CORNER);
//tint(255);
//loads confetti image for celebration :)
image(confetti, 0, 0);
fill(232, 95, 92);
textSize(60);
text("What a Spelling Champ!", width/2, height/2 - 100);
fill(156, 255, 250);
text("Press Replay to Spell Again!", width/2, height/2);
//displaying replay button
replayButton.buttonDisplay();
//checks if pressed to go back to start screen
if (mousePressed && mouseX >= replayButton.xLoc - replayButton.buttonW/2 && mouseX <= replayButton.xLoc + replayButton.buttonW/2 && mouseY >= replayButton.yLoc - replayButton.buttonH/2 && mouseY <= replayButton.yLoc + replayButton.buttonH/2) {
screenNumber = 0;
}
}
}
//function that inputs the characters of the animal name in the keypad
void wordCharsInKeypad() {
//a boolean to check if all the characters have been input
boolean complete = false;
//i variable to loop through all letters in the animal name
int i = 0;
while (complete == false) {
//generating a random index so letters don't appear in correct order in the keypad
int randomIndex = (int) random(keypad.length - 1);
// condition: if the key is empty, signified by 'x', fill it with this letter, and then move to the next character (to avoid overwriting keys)
if (keypad[randomIndex].letter == 'x') {
keypad[randomIndex].letter = animal4Run.animalName.charAt(i);
i += 1;
}
//if all the letters from the animal name are in the keypad, exit the while loop
if (i == animal4Run.animalName.length()) {
complete = true;
}
}
}
//function to fill the rest of the keypad
void fillRemainingKeys() {
//same boolean and variable concept as before
boolean complete = false;
int j = 0;
while (complete == false) {
//this boolean is to check if the chosen letter already exists in the keypad
boolean duplicated = false;
//generates a random index to input a random letter from the alphabet
int randomIndex = (int) random(alphabet.length -1);
// println(j, keypad[j].letter, alphabet[randomIndex], word.indexOf(alphabet[randomIndex]));
//if this position in the keypad is empty AND the chosen character is not in the animal name (as that wouldve been input in the prev function, fill it in the keypad)
if (keypad[j].letter == 'x' && animal4Run.animalName.indexOf(alphabet[randomIndex]) == -1) {
//for loop that checks if the letter that we are about to input already exists in the keypad to avoid repetition
for (int k = 0; k < keypad.length; k++) {
if (keypad[k].letter == alphabet[randomIndex] ) {
duplicated = true;
//if it is a duplicate it breaks out of this for loop and restarts to generate a new letter
break;
}
}
//to continue trying to generate
if (duplicated) {
continue;
}
// if it isn't a duplicate it inputs it into the keypad
keypad[j].letter = alphabet[randomIndex];
}
//if the letter is in the word, meaning it is already in the keypad, also continue to generate something else
if (word.indexOf(alphabet[randomIndex]) != -1) {
continue;
}
j+= 1;
//condition to exit the while loop when the keypad is fully formed
if (j == keypad.length) {
complete = true;
}
}
//for (int k = 0; k < keypad.length; k++) {
//println(k, keypad[k].letter);
// }
}
Animals Class
class Animals {
//two vars for animal name and to load the suitable image
String animalName;
PImage animalImage;
Animals(String tempAnimalName){
animalName = tempAnimalName;
//using animal name to load the image
animalImage = loadImage(animalName+".png");
animalImage.resize(300,300);
}
void display(){
fill(0,255,0);
imageMode(CENTER);
image(animalImage,width/2-50,height/2);
//rect(width/2,height/2,100,100);
//fill(0);
//textAlign(CENTER,CENTER);
//textSize(15);
//text("I am a" + " " + animalName, width/2,height/2);
}
}
Buttons Class:
class Buttons {
int xLoc, yLoc, buttonW, buttonH;
String buttonTitle;
//
Buttons(int xLocTemp, int yLocTemp, int buttonWTemp, int buttonHTemp, String buttonTitleTemp) {
xLoc = xLocTemp;
yLoc = yLocTemp;
buttonW = buttonWTemp;
buttonH = buttonHTemp;
buttonTitle = buttonTitleTemp;
}
void buttonDisplay() {
rectMode(CENTER);
noStroke();
fill(200);
rect(xLoc, yLoc, buttonW, buttonH);
fill(0);
textSize(25);
textAlign(CENTER,CENTER);
text(buttonTitle, xLoc, yLoc);
}
}
Letter Class:
class Letter {
char letter;
int xLoc, yLoc;
int blockW = 70;
int blockH = 70;
int colNo;
int rowNo;
//booleans to check during the game
boolean letterClicked;
boolean letterCorrect;
Letter(char letterTemp, int tempColNo, int tempRowNo) {
letter = letterTemp;
colNo = tempColNo;
rowNo = tempRowNo;
}
void display() {
//as it is a grid object, col and row number are used for x and y coordinates
rectMode(CORNER);
fill(0);
stroke(255);
rect(700+colNo*70, 150+rowNo*70, blockW, blockH);
fill(255);
textSize(20);
textAlign(CENTER, CENTER);
text(letter, 735+colNo*70, 185+rowNo*70);
}
//the function that checks if the letter is clicked
void letterIsClicked() {
if (mousePressed && mouseX >= 700+(colNo)*70 && mouseX <= 700+(colNo)*70 + blockW && mouseY >= 150+(rowNo)*70 && mouseY <= 150+(rowNo)*70+blockH) {
// println("mouseY: ", mouseY, " - 200+(rowNo-1)*70: ", 200+(rowNo-1)*70, " - 200+(rowNo-1)*70+blockH: ", 200+(rowNo-1)*70+blockH);
letterClicked = true;
//println(letter, " Clicked");
}
}
}
Zip: midtermm_Game