TRY THE FINAL PRODUCT HERE: https://replit.com/@ChrisChen42/Story-of-Star-Boy?v=1
JUNE 10: Basic Setup
The first step was importing Pygame, the library we will be using to code our game. I also imported sys because later we might use it to allow the user to press a button to exit the game. Pygame was then initialized, and the width and height of the window were declared. Using the pygame.display.set_mode method, the window's dimensions were set. Next, a clock was created using pygame.time.Clock(), which can be used later to control the frame rate. Finally, a standard font was declared, which will be used to create any text appearing in the game.
A simple start screen was created with a galaxy background, displaying the title of the game "Story of Star Boy" and the instructions "Press Any Key to Start". A while loop was used to wait for the user to press any button to begin the game.
A main function was created to run the sub-functions in chronological order. This was my easy way to keep everything organized.
Utility functions are incredibly useful as they make coding more organized, efficient, and less repetitive. There will be many utility functions for this game. The ones that I have created include the "clearScreen()" function, which clears the screen; the "setBackground()" function, which sets the background using the image name in the "images" folder; and the "continuationHandler()" function, which will be used to wait for the user to press Enter to continue the story or progress in the game.
Since we are making an RPG (Role-Playing Game), there will be a lot of captions and storylines. Therefore, the "createCaption" function is very useful in reducing repetitive code related to creating and rendering captions. This function has parameters for the caption text, the background color of the caption box, and the text color. All of these will be used to create a caption in a box. Additionally, there is a text-wrapping feature in this function, which is valuable when dealing with lengthy text that may overflow, making it extremely useful for handling paragraphs of text.
DEMO: Starting screen
JUNE 11: Beginning Scene
A new parameter, "position", was added to the "createCaption()" function. This allows the caption box to be positioned either at the top or bottom of the screen, which is extremely useful for managing what the caption covers in the background.
The "createClickBox()" function is designed to wait for the user to click on the created box before continuing the program.
The "s_beginning()" function was created to handle the opening scenes of how Star Boy got his powers and his decision to leave Earth to fight Dark Nebula. This function uses a list of scene pictures stored in "scenesPictures" and a list of captions stored in "scenesText". A for loop iterates through all the scenes, using the "setBackground()" function to set the background of each scene and the "createCaption()" function to create the accompanying caption. Finally, the "continuationHandler()" function waits for the user to press any key to continue the storyline.
DEMO: Scene with background and caption
JUNE 12: Level 1 and Cut Scene 1
A set of variables was created for basic game level management. These include the size of the energy and Star Boy, the y-level at which Star Boy will stay, the fuel depletion and gain rate, the frequency of dropping energy, the speed at which the energy will drop, and finally the trail that follows Star Boy as he flies.
Fuel is managed here using a "fuelDepletion_counter" to deplete fuel at a controlled interval based on the number of elapsed frames. The fuel percentage is recalculated, which will be used for altitude control.
Altitude can increase by a maximum of 10 per frame, but the actual increase is a fraction of this maximum, determined by the fuel percentage.
The first part sets the level cover, displaying the current level, game instructions, and conditions for winning or losing. The background is then set, Star Boy is rendered and scaled, and a hitbox is created to manage Star Boy's position. Energy and the trail are also rendered, with the trail positioned under Star Boy. A while loop running on a "running" variable is created to continuously run while the game is in progress. Additionally, a quick event handler is set up to allow the user to quit the program.
Star Boy's movement is handled here. His position will follow the x-coordinate of the center of the cursor. The trail is positioned directly under Star Boy by using his x-coordinate and adding a constant offset. The height of the trail is calculated according to the fuel percentage, creating a visual effect where more fuel results in a longer trail and less fuel results in a shorter trail. A line is also drawn under Star Boy to indicate if a game element passes the zone. Anything that passes this line can no longer be collected by Star Boy.
Two essential statistics are rendered and displayed to the user: the fuel and the altitude, along with the altitude goal to beat the level.
First a counter "energyDrop_counter" is increased to control the energy drop to certain intervals controlled by frame rate. Using the width of the game window and the size of the energy, we can randomize an x-coordinate where the energy can be dropped. They are stored into the "energy_boxes" list and then a for loop is used to loop through every single box to change the y-coordinate to be higher for the energy to be dropped down from the top of the screen. When the energy reaches the bottom of the screen, they are removed from the list of energies as new ones are created every interval of frames. Finally using the ".colliderext()" method we handle if Star Boy collects the energy. The energy will then be removed and fuel will be added. A restriction is also placed on how muhc fuel is added with a maximum amount of fuel and there is an if statement to handle this.
This handler manages the scenario when fuel is 0 or below. A game over screen is displayed, and a retry button is created using the "createClickBox()" function. Clicking this button will restart the level.
This handles the scenario when the user reaches the altitude goal of the level. A quick animation of Star Boy and his trail moving up and off the screen is triggered by decreasing the y-coordinates. This transitions smoothly into the cut scene following the level.
Variables are created to control the cutscene animation, which includes Star Boy and his trail as he travels past Earth's atmosphere and into space. The background is also set to a scene showing Earth from space.
An animation is created using a while loop and the "running" variable. A maximum size for Star Boy is set, and he will continue to increase in size until he reaches that size. Star Boy will also continue to move up the screen until he moves out of view, after which the animation will transition to scenes with captions.
The scenes (part 1 and 2) are displayed by setting the background with the "setBackground()" function, and the captions are shown with the "createCaption()" function. The "continuationHandler()" function waits for the user to press any key to continue the storyline. Play the game to see the animation!
DEMO: Gameplay of level 1
DEMO: Screen when you lose a level
DEMO: Star Boy flying up and out after winning a level
JUNE 13: Level 2 and Cut Scene 2
New variables were declared locally in the "level_2()" function to control the explosive bananas dropped by the space monkey.
Additionally, enemy variables such as health, movement speed, and y-level were also created; these will be used to move the enemies side to side during the level.
Handle if the fuel or Star Boy's health is less than or equal to 0. It will show the game over screen and allow the user to try the level again.
For levels 2 and beyond, an enemy will move along the top of the screen. The movement is controlled such that if the enemy hits the side of the screen, its direction reverses by multiplying its movement vector by "-1". In a manner similar to the energy drops, explosive bananas are also dropped using different variables.
These bananas have an additional feature: there's a 50% chance they will drop from the enemy or randomly from elsewhere, increasing the difficulty.
Collision detection has been implemented to handle scenarios where a banana touches Star Boy, resulting in Star Boy losing 1 HP.
A new function called "cut_scene2()" has been created, which progresses through three parts, each with its own background and caption. This functionality is achieved using the "setBackground()" and "createCaption()" functions. The program waits for a user response using "continuationHandler()", prompting them to press any key to continue the storyline.
DEMO: Cover screen for level 2
DEMO: Level 2 with dropping explosive bananas
JUNE 14: Level 3, Ending Scene
Having different level functions can make the code repetitive, especially when the subsequent levels are just extensions of the previous ones. Therefore, a combined function called "levelGenerator()" is created. It has five parameters: level, bg (for background), altitudeGoal, outlineColor, and enemyImage (set to "None" if there is no enemy).
A new feature for level 3 is implemented by first checking if the level is 3 and if the key pressed is the space bar. If so, the variable lightPulse_launch is set to true, and this will be handled later in the loop.
The "lightPulse_launch" variable is used to check if the user launched any light pulses. When a light pulse is launched, it is added to the list of light pulses, the amount of light pulses in storage is decremented, and the "lightPulse_launch" variable is reset to false.
A for loop then iterates through all launched light pulses, decreasing their y-position so they move up the screen. If a light pulse reaches the top of the screen, it is removed from the list to save memory.
The light pulse is intended to hit the enemy, so a collision handler is created to manage the collision detection. If a light pulse hits the enemy, the enemy's health decreases.
To add a competitive feature for multiple players, a total score calculator will return the final score of each player based on their performance. The more fuel and HP left at the end of each level, the higher the final score will be.
A final function "final_scene()" is used for the concluding scene. Variables are used to hold the position of the Dark Nebula explosion, the size the explosion will reach, and the timing of the explosion. Using these variables, a while loop is created to make the Dark Nebula expand and then explode. Finally, the "createCaption()" function is used to display the caption of what happened. The "continuationHandler()" function is then used to wait for the user to press any key to proceed to the last display of the game.
The last display shows the final score calculated with the "calculateTotalScore()" function and stored in the "final_score" variable.
All of the scenes and levels are organized in chronological order within the "main()" function for better structure. Finally, the game is complete!