Element
010 Project
Final Project
SID:2008483
[MOD002691]
SID:200848
Abstract
The project report contains the introduction into the reports structure starting with
the research done into the creation of the project using video tutorials as examples in the
creation of a personal aim trainer code. After which a straightforward design concept was
created to match the desire and created using python coding applications and various
corresponding files for the correct functionality of the program. After all the code has been
shown and briefly described images are shown on the various sections of the game when
loaded proving its functionality.
Additional files were present in the creation of the program such as a drawn target,
game audio and text files containing the difficulty presets, which shortens the coding process.
Once that has been done a conclusion is present and outlining the various improvements that
could be made in making it more viable for consumer use if more time were given. Separate
files were attached containing the interim report and poster oppose to being included within
this
document allowing for easier differentiation of the project’s sections.
1| P a g e
SID:200848
Table of Contents
Abstract..................................................................................................................................................1
Introduction..........................................................................................................................................3
Methodology..........................................................................................................................................4
Tools Used.................................................................................................................................. 4
Design..................................................................................................................................................5
Implementation....................................................................................................................................6
Project Code......................................................................................................................................6
Additional Files................................................................................................................................11
Results.......................................................................................................................................... 12
Conclusion................................................................................................................................... 13
References..........................................................................................................................................14
2| P a g e
SID:200848
Introduction
This project involves the creation of a simple game, which helps improve a person’s
reaction time with a computer mouse. It is aimed at individuals who play first person shooter
games and want to improve their accuracy within them, as well as how quickly they can spot
all the targets presented before them. It would function as a standalone app to the currently
played game which can be used to practice before after and during down times in the game;
helping them improve whenever possible. It aims to do It by setting targets onto a screen and
giving a certain time to click them. The game would record accuracy by percentage; it is
tracked by subtracting the amount of clicks not on target from the total clicks during the play
time. When the user is no longer able to press all the targets within the time the game stops
and records the data gathered (accuracy and targets hit) to display which then lets the user
improve upon them by restarting.
3| P a g e
SID:200848
Methodology
Tools Used
Visual Studio was used in the programming of the application due to its vast amount of
coding language downloads, as well as the option to add various extension such as
the necessary pygame import to make the code work as intended in the form of a
game. This program allows the simple addition of audio, text and image files within the
coding
folder unlike default python idle. This aids in creating a library of files for the project
and the execution of their contents without any errors or missing file directories. This
can also aid in the conversion of the pygame file into an .exe which will allow for its
launch without the python coding application.
YouTube Tutorials were viable in the research of various games like the created
project. This allowed for the various commands to be learnt so programming can be
easier although the source code differs from the researched material on the tutorials.
The most useful was the Coding an aim trainer in python! (2023) which finalised the
decision on the use of visual studio due to the impression given by the video creator.
Git Hub was a necessary area to visit as it allowed for the audio files to be procured
and used within the code for target hits and misses, oppose to researching matching
audio which required purchase or did not fit the game concept.
Paint.Net was used to create the target image due to the application being simple,
free and quick to operate. The concept was created and uploaded to the coding tool
allowing for testing of the program to be done quickly and if it were not sufficient
could be quickly corrected and reuploaded instead of creating and changing code for a
target.
4| P a g e
SID:200848
Design
The first concept was to create a trainer that shows multiple targets at random
intervals, which proved to be more time consuming and more like existing aim games such as
the bestest free-to-win rhythm game (no date) osu! that is the inspiration of the project. The
program was changed to run only hit targets oppose to drag as they are less linked to a quick
snapshot which is the desire for the user within an FPS Game. The music concept was scrapped
due to the
complications that could occur with copyrights and linking the spawn speed to the beat,
which if it were able to link to an external app such as Spotify would make it easier to control
as the music function would run separately to the python game code.
After creating the various game screens and elements the accuracy equation was
placed to help show the user the hit percentage during game time - hitshots/totalShots * 100.
With this in place an infinite loop of targets was created with only a timer being a stopper
which makes it more effective in game lobbies as it doesn’t possess levels like competitors or
a preset amount of time, making it usable for as long as necessary then letting it run out of
time when desired to see progress.
During the design stage the game was meant to convert into an ‘.exe’ which would
allow players to use it via a downloadable zip without possession of programming
applications, like a real live game. This would allow for it to be tested by others such as
friends or family to help
improve upon it and get formative feedback. The various attempts to exe conversion didn’t
work at first but once it was done another error occurred. The file would launch but not
display the game window, meaning it opened and closed instantly causing the program to be
unplayable without visual studio present on a device. As a result, feedback and improvements
were no
longer made, and the game was simplified but could be further developed into a more
appealing and effective application into hand eye coordination with better time and research
on coding.
With the further development being stopped testing was made to see if the various
difficulties worked, which proved effective but too simple, so the configuration text files were
tweaked to display smaller and more targets with less time to press them making even the easy
mode difficult for beginners. This was done to stop the game from being boring and the easy
and medium modes being obsolete since only the hard proved challenging although slightly.
With these changes in place the project was completed and satisfactory for the user purpose
although only by a basic amount.
5| P a g e
SID:200848
Implementation
Project Code
The project is coded through python and uses pygame to allow its launch and use in
real time. Each code section shows the varied screens that can be present in the game from
the title screen, active round and end game. Using simple code and free image imports the
game can function as intended with the addition of sounds to hear a hit or a miss during play
time, although not a necessity for the game to function.
Title Screen
The first coding segment involves the various extension imports necessary for the
game’s functionality, followed by the game window creation which is set at 750 by 750. With
the window created colours were implemented to be used for font, background and cursor
within the game. The next step was adding the options to quit the game when the window is
closed, as well as display the various difficulty options on the screen. With the draw text
command three different difficulties were shown (easy, medium and hard). Then when one is
clicked, the user is diverted to the active game screen matching the difficulty.
import pygame, random, sys, os
from pygame.locals import *
pygame.init()
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
BLUE = (0,0,255)
WINDOWHEIGHT = 750
WINDOWWIDTH = 750
FONT = pygame.font.SysFont(None, 48)
def terminate():
pygame.quit()
sys.exit()
def Menu():
timer = 0
color = BLUE
switch = False
while True:
windowSurface.fill(BLACK)
difficultyRects = []
difficultyRects.append(pygame.Rect(5, 450, 240, 100))
difficultyRects.append(pygame.Rect(255, 450, 240, 100))
6| P a g e
SID:200848
difficultyRects.append(pygame.Rect(505, 450, 240, 100))
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
terminate()
if event.type == MOUSEBUTTONDOWN:
if difficultyRects[0].collidepoint(pygame.mouse.get_pos()):
game("easy")
if difficultyRects[1].collidepoint(pygame.mouse.get_pos()):
game("medium")
if difficultyRects[2].collidepoint(pygame.mouse.get_pos()):
game("hard")
for rect in difficultyRects:
pygame.draw.rect(windowSurface, RED, rect)
drawText("Pick a difficulty", windowSurface, 90, 150,
pygame.font.SysFont(None, 112), color)
drawText("Easy", windowSurface, 83, 485, FONT , BLACK)
drawText("Medium", windowSurface, 312, 485,FONT , BLACK)
drawText("Hard", windowSurface, 580, 485,FONT , BLACK)
mainClock.tick(50)
timer += 1
if timer % 100 == 0:
color = BLUE
elif timer % 50 == 0:
color = RED
pygame.display.update()
Score Counter
This code displays the current game modes score, time and calculates the accuracy of hits.
Within the first part the font and colour of the rendered text is determined after which the
accuracy equation is inputted ‘ hitshots/totalShots * 100’. After this the screen displays game
over and the score and accuracy after the game ends (once time runs out). It also tells the
user they can click anywhere to restart; with the mouse press being the restart to home
screen
indicator.
def drawText(text, surface, x, y, font = FONT, color = RED):
textObject = font.render(text, 1, color)
textRect = textObject.get_rect()
textRect.topleft = (x,y)
surface.blit(textObject, textRect)
def gameOver(totalShots, hitShots, difficulty,
score): pygame.mouse.set_visible(True)
if totalShots != 0 and hitShots != 0:
accuracy = round(hitShots/totalShots * 100)
else:
accuracy = 0
7| P a g e
SID:200848
windowSurface.fill(BLACK)
drawText("GAME OVER", windowSurface, 200, 325, pygame.font.SysFont(None,
72, True))
drawText("Click anywhere to restart", windowSurface, 170, 380)
drawText("Accuracy: " + str(accuracy) + "%", windowSurface, 269, 414)
drawText("Score: " + str(score), windowSurface, 308, 450)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == MOUSEBUTTONDOWN:
windowSurface.fill(BLACK)
Menu()
if event.type == KEYDOWN:
terminate()
Difficulty
Here the code determines if the difficulty is easy, medium or hard through the press of the
corresponding box on the home screen. Each section is to open the corresponding file which
determines the number of targets and time given to press them. It also states to load the
target image within the game and multiply it to match the difficulties preset amount. It also
scales the image pixels by what type of difficulty making it smaller the harder it gets allowing
for a smaller margin of error during game time. It also determines the volume and matching
sound for hitting and missing the targets with a miss being subtle but a hit having a greater
volume. Finally, it determines the mouse to be invisible so it can be replaced with a plus
which matches a crosshair from the games it is aimed at.
def populateConfig(difficulty):
global targetImage
targetImage = pygame.image.load("target.png")
config = {}
if(difficulty == "easy"):
difficultyFile = open("easy.txt", "r")
elif(difficulty == "medium"):
difficultyFile = open("medium.txt", "r")
elif(difficulty == "hard"):
difficultyFile = open("hard.txt", "r")
for line in difficultyFile:
splitLine = line.split(":")
splitLine[1] = splitLine[1].strip("\n")
config[splitLine[0]] = int(splitLine[1])
targetImage = pygame.transform.scale(targetImage,
(config["enemySize"],config["enemySize"]))
difficultyFile.close()
return config
mainClock = pygame.time.Clock()
8| P a g e
SID:200848
windowSurface = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT))
pygame.display.set_caption("Aim Reaction Time Tester")
shootSound =
pygame.mixer.Sound("audio_shot.mp3") hitSound =
pygame.mixer.Sound("audio_Hit.mp3")
shootSound.set_volume(0.25)
hitSound.set_volume(1)
enemies = []
def game(difficulty):
config = populateConfig(difficulty)
pygame.mouse.set_visible(False)
mouseY = (round(WINDOWHEIGHT / 2))
mouseX = (round(WINDOWWIDTH / 2))
tickCounter = 0
enemies = []
amountOfEnemies = 0
score = 0
FPS = 75
hitShots = 0
totalShots = 0
STARTINGTIME = config.get("time")
CIRCLERADIUS = 150
while True:
if(config.get("time") <= 0):
gameOver(totalShots, hitShots, difficulty, score)
tickCounter += 1
if(tickCounter % FPS == 0):
config["time"] -= 1
windowSurface.fill(BLACK)
if (amountOfEnemies == 0):
config["time"] = STARTINGTIME
while(amountOfEnemies != config.get("maxAmountOfEnemies")):
enemies.append(pygame.Rect((random.randint(0,WINDOWWIDTH -
config.get("enemySize"))),
(random.randint(0,WINDOWHEIGHT -
config.get("enemySize"))),
config.get("enemySize"),
config.get("enemySize")))
if enemies[amountOfEnemies].topleft[0] < 135 and
enemies[amountOfEnemies].topleft[1] < 65:
enemies.pop(amountOfEnemies)
9| P a g e
SID:200848
else:
10| P a g
SID:200848
amountOfEnemies += 1
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
pass
if event.type == KEYUP:
if event.key == K_ESCAPE:
terminate()
if event.type == MOUSEMOTION:
mouseX = event.pos[0]
mouseY = event.pos[1]
if event.type == MOUSEBUTTONDOWN:
pygame.mixer.Channel(0).play(shootSound)
totalShots += 1
for enemy in enemies[:]:
if mouseX > enemy.topleft[0] and mouseX <
enemy.bottomright[0]\
and mouseY > enemy.topleft[1] and mouseY <
enemy.bottomright[1]:
pygame.mixer.Channel(1).play(hitSound)
enemies.remove(enemy)
amountOfEnemies -= 1
score += 1
hitShots += 1
Crosshair
The final segment draws the crosshair which originally was a circle with a plus inside which
resembles a rifle scope, but the background was made black so it’s easier on the eyes oppose
to the white screen which could be too bright in the dark or after extended periods of screen
time. Because of this the circle was left as black and only the cross lines remained which
proved to be an improvement, covering less area in unnecessary areas.
pygame.draw.circle(windowSurface, BLACK, (mouseX,mouseY),
CIRCLERADIUS,0)
for enemy in enemies:
windowSurface.blit(targetImage, enemy)
pygame.draw.circle(windowSurface, BLACK, (mouseX,mouseY),
CIRCLERADIUS + 1, 1)
pygame.draw.line(windowSurface, WHITE, (mouseX, mouseY + 50),
(mouseX, mouseY - 50), 2)
pygame.draw.line(windowSurface, WHITE, (mouseX + 50, mouseY),
(mouseX - 50, mouseY), 2)
drawText("Time: " + str(config.get("time")), windowSurface, 8,8)
drawText("Score: " + str(score), windowSurface, 8,38)
pygame.display.update()
mainClock.tick(FPS)
Menu()
11| P a g
SID:200848
Additional Files
Difficulty:
The three difficulty files provide a set number of targets to hit on the screen
within a pre-determined time; after which the timer resets and another random set is
given on the game screen. This runs in a constant loop until the user’s time runs out or
they allow it to.
The file also states the desired pixel size of the target image which gets smaller with the
difficulty increase making it harder to hit the target without great precision and quick
mouse movement.
Hit Icon:
The icon was created within ‘Paint.Net’ by creating
three varied sized circles within each other. The central circle
was filled first then the matching colour was used in between
the second and third, after which the background as removed
as well as the interior of the middle circle leaving a dot with a
ring. Finally, four parts were selected and cut from the ring
making it resemble a simple crosshair that can be seen within
shooter games. The vibrant green colour (76,255,0) was used as
it is easy to spot on the black background and usually a colour
the human eye can distinguish quickly on a surface.
Sounds:
The two sounds within the game were for a ‘hit’ or ‘miss’ of the shown targets.
This helped the player identify with certainty if they got the target if they are quickly
trying to click on them or are tunnel visioned and do not see they missed causing the
game to abruptly end. Using the Programming AIMBOT with python! (2023) video the
idea of sound implementation was given, and the same audio was used within the
project. The files were procured from notaSWE (no date) Aimtrainer-aimbot/audio due
to the connected tutorial video being like the current project, as it included an aim
trainer but with a different tweak and code to the one used.
12| P a g
SID:200848
Results
The images display the different sections working as intended with a title screen that
allows for the selection of difficulty once pressed being the first thing present once the game
is loaded. It clearly states what the user is meant to do to start the game which then diverts
to the game screen. This screen is looped back to after the user clicks on the end game
screen.
Shown on the middle image is the score and time is accurately shown depending on the
difficulty which it corresponds to, with the desired targets being shown alongside the plus sign
crosshair which replaces the cursor allowing for a more accurate click on the target due to its
shape. When the game was assessed, it produced the assigned audio to a hit or a miss with
accuracy although quite loudly making it difficult to focus from the constant audio repeat as
the screen is clicked. Having no audio allows less distractions but can be resolved by using
different audio that is lower on pitch or even quieter to make it more appealing to keep on.
The final image on the right displays the game over screen which occurs only when
the time runs out, this shows the games score which is the number of targets hit during the
round, as well as the accuracy of clicks on the screen which is determined by the number of
times the player missed the target compared to the amount of hits they made. It also states
what the player must do to return to the main screen to start again on the home screen,
which works as intended.
13| P a g
SID:200848
Conclusion
To conclude the project has provided a simple game which performs as intended having
all the aspects of an aim game and keeping the necessary score for the user to review and
improve upon. It accurately calculates accuracy which is displayed post-game only which helps
reduce distractions and make the user anxious to see their results once they are done. The
simplicity of the background helps in seeing the target and crosshair but could modified to
what the user prefers which either helps or impedes them depending on the choice, allowing
for a greater difficulty to be present.
The program could be improved by adding more difficulty through the randomisation of
targets present, as well as a set time to finish it within making it more necessary to think
quicker and react quicker. Having the targets vary in size and colour would also help
randomise what is seen on the screen and make it more realistic to the assorted colours and
shapes shown in the FPS shooter played by the target audience. Another improvement would
be to implement
different audio such as songs which would play accordingly to the targets hit making it seem
more pleasurable to the ear; causing the user to want to reach as far as possible to hear the
song play out fully not just cut off once they fail.
14| P a g
SID:200848
References
notaSWE (no date) Aimtrainer-aimbot/audio at main · NOTASWE/Aimtrainer-aimbot,
GitHub. Available at: https://github.com/notaSWE/aimtrainer-aimbot/tree/main/audio
(Accessed: 16 March 2024).
Programming AIMBOT with python! (2023) YouTube. Available at:
https://www.youtube.com/watch?v=Fw7w8U0CBVM&t=344s (Accessed: 16
March 2024).
Coding an aim trainer in python! (2023) YouTube. Available at:
https://www.youtube.com/watch?v=bwuosv2m70g&t=108s (Accessed: 17 March
2024).
The bestest free-to-win rhythm game (no date) osu! Available at: https://osu.ppy.sh/
(Accessed: 15 March 2024).
15| P a g