Name: Kshitij Chandrakar
Course: B.Tech CSE (Hons)
Semester: 2
SAP: 500124827
Enrollment Number: 2142231661
Topic: Video Game Using Computer Vision
As the name suggest, its a platform based runner game, however the controls are based on the movement of the user as captured by the camera.
it utilizes various technologies like:
- Movenet
- Tensorflow
- Computer Vision
in the game You can jump, dodge obstacles and the character follows your actual body movements as captured from the camera
- Create The Base Game
- Its a game where you have to dodge obstacles
- Create the Sprites
- Create the body models
- Train an AI model to recognise body movement
- Preferably use Google's teachable machine otherwise we could do tensorflow from scratch (Although that would create a problem with the dataset but whatever)
- used movenet
- Track average body postion relative to previous position to check if it jumped
- if it did jump then jump the main character
- Added Controls for the character
- If possible, add body models to the game along with animations that follow the body movement
Explanation For the Main GameLoop System:
from MyColors import *
from MyFunctions import *
import random, os
from ObjectClass import *
from buttons import *
from scene import *
from Attributes import *
- These lines import various modules needed for the game:
MyColors
: Likely contains predefined color constants.MyFunctions
: Probably contains custom functions for the game.random
: Python's built-in module for generating random numbers.os
: Python's built-in module for interacting with the operating system.ObjectClass
: Contains the definition of theBox
class for game objects.buttons
: Provides functionality for creating buttons in the game interface.scene
: Handles scene management in the game.Attributes
: Holds attributes and configurations for the game.
print("RAAAAAAAAAAAAAH IM STARTING UP RAWr")
clock = pygame.time.Clock()
movenetUsed = 0
- The program prints a startup message.
pygame.time.Clock()
creates a clock object to control the game's frame rate.movenetUsed
is set to 0, indicating that a motion control system (possibly for player movement) is not being used.
def setHighScore():
with open(highScoreFile, 'w') as file:
file.write(str(environmentAttributes["highScore"]))
- This function writes the current high score to a file.
font = pygame.font.Font(r"Gotham-Bold.otf", 32)
# Additional font objects with different sizes
- Fonts are loaded for rendering text with different sizes.
def resetEnv():
# Code to reset the game environment, including player and obstacles.
pass
- This function resets the game environment, initializing player and obstacle objects.
script_dir = os.path.dirname(os.path.abspath(__file__))
highScoreFile = os.path.join(script_dir, 'highScore.txt')
# Read from the input file
with open(highScoreFile, 'r') as file:
environmentAttributes["highScore"] = int(float(file.read()))
- It reads the high score from a file and initializes it in the game environment attributes.
def updateEnv():
# Function to update the game environment based on the current score.
pass
- This function updates the game environment based on the current score, possibly adjusting difficulty.
def checkEvent(event):
# Function to handle user input events such as keyboard input.
pass
- It handles user input events such as keyboard presses, controlling player actions.
def centerText(centerTextStr, x_offset = 0, y_offset=0, color=white, font=font):
# Function to render centered text on the screen.
pass
- This function renders text centered on the screen with optional offsets, color, and font.
def StartScreen():
# Function to render the start screen.
pass
- It renders the start screen of the game.
def GameLoop():
# Main game loop function, responsible for running the game logic.
pass
- This function represents the main game loop, executing game logic and rendering frames.
currentScene = "StartScreen"
scenes = {}
currentScene
stores the current scene name.scenes
is a dictionary that maps scene names to their respective functions and attributes.
def changeScene(a):
# Function to change the current scene.
pass
- This function changes the current scene to the one specified.
while True:
# Main game loop where events are processed, scenes are rendered, and game logic is executed.
pass
- The program enters a perpetual loop where events are handled, scenes are rendered, and game logic is executed continuously.
The ObjectClass code defines a class Box
which seems to represent a game object or entity.
- Attributes and Initialization:
from MyFunctions import *
import pygame, random, sys, os
from Filenames import *
vector = pygame.math.Vector2
coll = checkCollisionVector
- The class has various attributes like position, velocity, acceleration, etc., which are initialized in the
__init__
method. - Attributes are accessed using a dictionary (
self.Attributes
), where keys are strings representing attribute names.
- Rendering:
def render(self):
try:
if self.Attributes["Sprites"]:
try:
try:
CurrentFrameNumber = int((self.environmentAttributes['score']//self.Attributes["changeFrameCount"][self.Attributes["CurrentSprite"]])%len(self.sprites[self.Attributes["CurrentSprite"]]))
except KeyError:
CurrentFrameNumber = int((self.environmentAttributes['score']//self.Attributes["changeFrameCount"])%self.spritesheet[0].cols)
except ZeroDivisionError:
CurrentFrameNumber = 0
# self.environmentAttributes["screen"].blit(self.sprites[CurrentFrameNumber], self.Attributes["pos"])
try:
if self.Attributes["SwitchSprites"]:
self.environmentAttributes["screen"].blit(pygame.transform.scale(self.sprites[self.Attributes["CurrentSprite"]][CurrentFrameNumber].convert_alpha(), self.Attributes["Dimensions"]), self.Attributes["pos"])
else:
self.environmentAttributes["screen"].blit(pygame.transform.scale(self.sprites[CurrentFrameNumber].convert_alpha(), self.Attributes["Dimensions"]), self.Attributes["pos"])
except KeyError:
self.environmentAttributes["screen"].blit(pygame.transform.scale(self.sprites[CurrentFrameNumber].convert_alpha(), self.Attributes["Dimensions"]), self.Attributes["pos"])
except (KeyError, IndexError):
try:
if self.Attributes["Image"]:
image = []
for i in self.Attributes['Image']:
image.append(pygame.transform.scale(pygame.image.load(i).convert_alpha(), self.Attributes["Dimensions"]))
# self.environmentAttributes["score"]
NumOfImages = len(image)
try:
CurrentFrameNumber = int((self.environmentAttributes['score']//self.Attributes["changeFrameCount"])%NumOfImages)
except ZeroDivisionError:
CurrentFrameNumber = 0
self.environmentAttributes["screen"].blit(image[CurrentFrameNumber], self.Attributes["pos"])
except (KeyError, IndexError):
pygame.draw.rect(self.environmentAttributes["screen"], self.Attributes["color"], (self.Attributes["pos"].x, self.Attributes["pos"].y, self.Attributes["Dimensions"].x, self.Attributes["Dimensions"].y))
pass
# self.environmentAttributes["screen"].fill((255,0,0))
pass
- The
render
method seems to handle rendering of the object on the screen. It supports rendering with sprites, images, or simple rectangles.- It utilizes Pygame for rendering and scaling images/sprites.
- Updating:
def update(self):
self.Attributes["Velocity"] += self.Attributes["Acceleration"]
self.Attributes["pos"] += self.Attributes["Velocity"]
self.Attributes["Acceleration"] = vector(0,0)
- The
update
method updates the position of the object based on its velocity and acceleration. - Acceleration is applied to velocity, and velocity is applied to position.
- Collision Detection:
def checkCollision(self, ObjList):
try:
if self.Attributes["Collider"]:
for object in ObjList:
if object != None:
if coll(self.Attributes["pos"],self.Attributes["Dimensions"], object.Attributes["pos"], object.Attributes["Dimensions"]):
return True
return False
else:
return False
except KeyError:
return False
pass
- The
checkCollision
method seems to check for collisions between this object and others passed as a list. - It uses a function
checkCollisionVector
imported fromMyFunctions
.
-
Forces and Constraints:
- There are methods like
Force
andForce1
for applying forces to the object. - Constraints are applied to restrict the object's movement within specified bounds.
- There are methods like
-
Other Functionalities:
- There are methods for handling randomization of position and vectors (
randomScalar
,randomVector
,randomise
). - Debugging functionality (
debug
) is available to print debug information if enabled.
- There are methods for handling randomization of position and vectors (
-
Main Loop:
- The
run
method seems to orchestrate the main operations of the object, including update, render, collision detection, and constraint enforcement.
- The
Certainly! Let's break down each method and provide detailed explanations along with the corresponding code snippets:
from MyFunctions import EmptyFunction
'''
Scene is a subset of Environment
'''
class Scene:
def handleExp(self, E):
# Method to handle exceptions raised by the scene
try:
self.excep[E][0](self.excep[E][1])
except (KeyError, TypeError):
pass
def initialise(self):
# Method to initialize the scene
try:
for i in self.initialise1:
i()
except TypeError:
pass
def uninitialise(self):
# Method to uninitialize the scene
try:
for i in self.uninitialise1:
i()
except TypeError:
pass
def __init__(self, renderFunction, event=None, excep=None, eventFunction=None, initialise=None, uninitialise=None):
# Constructor method to initialize the Scene object
self.initialise1 = initialise
self.Initialised = 0
self.uninitialise1 = uninitialise
self.renderFunction = renderFunction
self.events = event # Events = {eventType: what To do in case of event}
self.excep = excep # Exceptions that scenes raise
self.eventFunction = eventFunction # A function to call with event as the parameter
def render(self):
# Method to render the scene
self.renderFunction()
def handleEvent(self, event):
# Method to handle events
try:
self.events[event][0](self.events[event][1])
except IndexError:
self.events[event][0]()
except KeyError:
pass
Explanation For the Scene System:
-
handleExp(self, E):
- This method handles exceptions raised by the scene.
- It attempts to execute the exception handling function corresponding to the provided exception
E
.
-
initialise(self):
- This method initializes the scene.
- It iterates over a list of initialization functions (
initialise1
) and executes each function.
-
uninitialise(self):
- This method uninitializes the scene.
- It iterates over a list of uninitialization functions (
uninitialise1
) and executes each function.
-
init(self, renderFunction, event=None, excep=None, eventFunction=None, initialise=None, uninitialise=None):
- This is the constructor method for the
Scene
class. - It initializes the scene with the provided parameters:
renderFunction
: Function to render the scene.event
: Dictionary containing event types and corresponding actions.excep
: Dictionary containing exception types and corresponding exception handling functions.eventFunction
: Function to handle events.initialise
: List of functions to initialize the scene.uninitialise
: List of functions to uninitialize the scene.
- This is the constructor method for the
-
render(self):
- This method renders the scene by calling the provided render function (
renderFunction
).
- This method renders the scene by calling the provided render function (
-
handleEvent(self, event):
- This method handles events received by the scene.
- It attempts to execute the corresponding event handling function based on the event type.
Explanation For the SpriteSheet System:
from pygameInit import *
from pygame.math import Vector2 as vector
from MyColors import *
from MyFunctions import *
import os
- Imports:
- The code imports necessary modules including custom ones (
pygameInit
,MyColors
,MyFunctions
) and standard ones (os
,pygame.math
). - It initializes Pygame with
pygameInit
.
- The code imports necessary modules including custom ones (
width, height = startPygame(hypo = 1000, ratioa = 21, ratiob = 10, caption = "AAAAAAAAA")
screen = pygame.display.set_mode((width, height), pygame.SRCALPHA)
- Pygame Initialization:
- It initializes Pygame with specific parameters such as window size (
width
,height
) and window caption.
- It initializes Pygame with specific parameters such as window size (
class SpriteSheet:
def __init__(self, filename):
"""Load the sheet."""
try:
self.sheet = pygame.image.load(filename).convert_alpha()
except pygame.error as e:
print(f"Unable to load spritesheet image: {filename}")
raise SystemExit(e)
- SpriteSheet Class Initialization:
- It defines a class
SpriteSheet
to handle sprite sheets. - The
__init__
method loads the sprite sheet image from the provided filename.
- It defines a class
def image_at(self, rectangle, colorkey = None):
"""Load a specific image from a specific rectangle."""
rect = pygame.Rect(rectangle)
image = pygame.Surface(rect.size, pygame.SRCALPHA) # Create surface with per-pixel alpha
image.blit(self.sheet, (0, 0), rect)
if colorkey is not None:
if colorkey == -1:
colorkey = image.get_at((0, 0))
image.set_colorkey(colorkey, pygame.RLEACCEL)
return image
- image_at Method:
- It extracts a specific image from a rectangle within the sprite sheet.
- Optionally, it sets a colorkey for transparency if provided.
def images_at(self, rects, colorkey = None):
"""Load a whole bunch of images and return them as a list."""
return [self.image_at(rect, colorkey) for rect in rects]
- images_at Method:
- It loads a list of images from a list of rectangles and returns them as a list.
def load_strip(self, rect, image_count, colorkey = None):
"""Load a whole strip of images, and return them as a list."""
tups = [(rect[0]+rect[2]*x, rect[1], rect[2], rect[3])
for x in range(image_count)]
return self.images_at(tups, colorkey)
- load_strip Method:
- It loads a strip of images (e.g., animation frames) from a single rectangle and returns them as a list.
def load_grid_images(self, num_rows, num_cols, x_margin=0, x_padding=0,
y_margin=0, y_padding=0):
"""Load a grid of images."""
# Code snippet explaining the load_grid_images method
- load_grid_images Method:
- It loads a grid of images from the sprite sheet, arranging them in rows and columns.
- Parameters
x_margin
,x_padding
,y_margin
,y_padding
control spacing between sprites.
Explanation For the Movenet System:
- tensorflow and tensorflow_hub: Importing TensorFlow and TensorFlow Hub for loading and running the MoveNet model.
- tensorflow_docs.vis.embed: Importing the
embed
function fromtensorflow_docs.vis
module for embedding visualizations. - numpy: Importing NumPy for numerical computations.
- cv2: Importing OpenCV for image processing.
- MovenetAttributes: Importing custom attributes (
KEYPOINT_DICT
,KEYPOINT_EDGE_INDS_TO_COLOR
) related to the MoveNet model. - matplotlib.pyplot: Importing Matplotlib's pyplot module for visualization.
- matplotlib.collections: Importing LineCollection from matplotlib.collections for drawing lines.
- matplotlib.patches: Importing patches module from matplotlib for drawing shapes.
- imageio and IPython.display: Importing imageio for working with image sequences and IPython.display for displaying HTML content.
extract_keypoint_coordinates
: Extracts xy coordinates of keypoints from keypoints with scores array.keypoints_and_edges_for_display
: Returns high confidence keypoints and edges for visualization.draw_prediction_on_image
: Draws keypoint predictions on the image.to_gif
: Converts an image sequence (4D numpy array) to a GIF.progress
: Displays a progress bar as HTML.movenet1
: Runs detection on an input image using the MoveNet model.init_crop_region
: Defines the default crop region.torso_visible
: Checks whether there are enough torso keypoints for determining the crop region.determine_torso_and_body_range
: Calculates the maximum distance from each keypoint to the center location.determine_crop_region
: Determines the region to crop the image for the model to run inference on.crop_and_resize
: Crops and resizes the image to prepare for the model input.run_inference
: Runs model inference on the cropped region.Outliers
: Detects outliers in the given data using the z-score method.
the Above Code Summary Outlined how the game works.