diff --git a/Open CV Game/bird_sprite.png b/Open CV Game/bird_sprite.png
new file mode 100644
index 000000000..f8d23d25e
Binary files /dev/null and b/Open CV Game/bird_sprite.png differ
diff --git a/Open CV Game/canonical_face_model_uv_visualization.png b/Open CV Game/canonical_face_model_uv_visualization.png
new file mode 100644
index 000000000..2acd991eb
Binary files /dev/null and b/Open CV Game/canonical_face_model_uv_visualization.png differ
diff --git a/Open CV Game/gitignore b/Open CV Game/gitignore
new file mode 100644
index 000000000..e43b0f988
--- /dev/null
+++ b/Open CV Game/gitignore
@@ -0,0 +1 @@
+.DS_Store
diff --git a/Open CV Game/idea/FlappyBirdCV.iml b/Open CV Game/idea/FlappyBirdCV.iml
new file mode 100644
index 000000000..d0876a78d
--- /dev/null
+++ b/Open CV Game/idea/FlappyBirdCV.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Open CV Game/idea/IncpectionProfiles/profiles_settings.xml b/Open CV Game/idea/IncpectionProfiles/profiles_settings.xml
new file mode 100644
index 000000000..105ce2da2
--- /dev/null
+++ b/Open CV Game/idea/IncpectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Open CV Game/idea/misc.xml b/Open CV Game/idea/misc.xml
new file mode 100644
index 000000000..d56657add
--- /dev/null
+++ b/Open CV Game/idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/Open CV Game/idea/modules.xml b/Open CV Game/idea/modules.xml
new file mode 100644
index 000000000..471b0ea46
--- /dev/null
+++ b/Open CV Game/idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Open CV Game/idea/vcs.xml b/Open CV Game/idea/vcs.xml
new file mode 100644
index 000000000..288b36b1e
--- /dev/null
+++ b/Open CV Game/idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Open CV Game/main.py b/Open CV Game/main.py
new file mode 100644
index 000000000..4cf44fe2e
--- /dev/null
+++ b/Open CV Game/main.py
@@ -0,0 +1,149 @@
+import sys, time, random, pygame
+from collections import deque
+import cv2 as cv, mediapipe as mp
+mp_drawing = mp.solutions.drawing_utils
+mp_drawing_styles = mp.solutions.drawing_styles
+mp_face_mesh = mp.solutions.face_mesh
+drawing_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1)
+pygame.init()
+
+# Initialize required elements/environment
+VID_CAP = cv.VideoCapture(3)
+window_size = (VID_CAP.get(cv.CAP_PROP_FRAME_WIDTH), VID_CAP.get(cv.CAP_PROP_FRAME_HEIGHT)) # width by height
+screen = pygame.display.set_mode(window_size)
+
+# Bird and pipe init
+bird_img = pygame.image.load("bird_sprite.png")
+bird_img = pygame.transform.scale(bird_img, (bird_img.get_width() / 6, bird_img.get_height() / 6))
+bird_frame = bird_img.get_rect()
+bird_frame.center = (window_size[0] // 6, window_size[1] // 2)
+pipe_frames = deque()
+pipe_img = pygame.image.load("pipe_sprite_single.png")
+
+pipe_starting_template = pipe_img.get_rect()
+space_between_pipes = 250
+
+# Game loop
+game_clock = time.time()
+stage = 1
+pipeSpawnTimer = 0
+time_between_pipe_spawn = 40
+dist_between_pipes = 500
+pipe_velocity = lambda: dist_between_pipes / time_between_pipe_spawn
+level = 0
+score = 0
+didUpdateScore = False
+game_is_running = True
+
+with mp_face_mesh.FaceMesh(
+ max_num_faces=1,
+ refine_landmarks=True,
+ min_detection_confidence=0.5,
+ min_tracking_confidence=0.5) as face_mesh:
+ while True:
+ # Check if game is running
+ if not game_is_running:
+ text = pygame.font.SysFont("Helvetica Bold.ttf", 64).render('Game over!', True, (99, 245, 255))
+ tr = text.get_rect()
+ tr.center = (window_size[0]/2, window_size[1]/2)
+ screen.blit(text, tr)
+ pygame.display.update()
+ pygame.time.wait(2000)
+ VID_CAP.release()
+ cv.destroyAllWindows()
+ pygame.quit()
+ sys.exit()
+
+ # Check if user quit window
+ for event in pygame.event.get():
+ if event.type == pygame.QUIT:
+ VID_CAP.release()
+ cv.destroyAllWindows()
+ pygame.quit()
+ sys.exit()
+
+ # Get frame
+ ret, frame = VID_CAP.read()
+ if not ret:
+ print("Empty frame, continuing...")
+ continue
+
+ # Clear screen
+ screen.fill((125, 220, 232))
+
+ # Face mesh
+ frame.flags.writeable = False
+ frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
+ results = face_mesh.process(frame)
+ frame.flags.writeable = True
+
+ # Draw mesh
+ if results.multi_face_landmarks and len(results.multi_face_landmarks) > 0:
+ # 94 = Tip of nose
+ marker = results.multi_face_landmarks[0].landmark[94].y
+ bird_frame.centery = (marker - 0.5) * 1.5 * window_size[1] + window_size[1]/2
+ if bird_frame.top < 0: bird_frame.y = 0
+ if bird_frame.bottom > window_size[1]: bird_frame.y = window_size[1] - bird_frame.height
+
+ # Mirror frame, swap axes because opencv != pygame
+ frame = cv.flip(frame, 1).swapaxes(0, 1)
+
+ # Update pipe positions
+ for pf in pipe_frames:
+ pf[0].x -= pipe_velocity()
+ pf[1].x -= pipe_velocity()
+
+ if len(pipe_frames) > 0 and pipe_frames[0][0].right < 0:
+ pipe_frames.popleft()
+
+ # Update screen
+ pygame.surfarray.blit_array(screen, frame)
+ screen.blit(bird_img, bird_frame)
+ checker = True
+ for pf in pipe_frames:
+ # Check if bird went through to update score
+ if pf[0].left <= bird_frame.x <= pf[0].right:
+ checker = False
+ if not didUpdateScore:
+ score += 1
+ didUpdateScore = True
+ # Update screen
+ screen.blit(pipe_img, pf[1])
+ screen.blit(pygame.transform.flip(pipe_img, 0, 1), pf[0])
+ if checker: didUpdateScore = False
+
+ # Stage, score text
+ text = pygame.font.SysFont("Helvetica Bold.ttf", 50).render(f'Stage {stage}', True, (99, 245, 255))
+ tr = text.get_rect()
+ tr.center = (100, 50)
+ screen.blit(text, tr)
+ text = pygame.font.SysFont("Helvetica Bold.ttf", 50).render(f'Score: {score}', True, (99, 245, 255))
+ tr = text.get_rect()
+ tr.center = (100, 100)
+ screen.blit(text, tr)
+
+ # Update screen
+ pygame.display.flip()
+
+ # Check if bird is touching a pipe
+ if any([bird_frame.colliderect(pf[0]) or bird_frame.colliderect(pf[1]) for pf in pipe_frames]):
+ game_is_running = False
+
+ # Time to add new pipes
+ if pipeSpawnTimer == 0:
+ top = pipe_starting_template.copy()
+ top.x, top.y = window_size[0], random.randint(120 - 1000, window_size[1] - 120 - space_between_pipes - 1000)
+ bottom = pipe_starting_template.copy()
+ bottom.x, bottom.y = window_size[0], top.y + 1000 + space_between_pipes
+ pipe_frames.append([top, bottom])
+
+ # Update pipe spawn timer - make it cyclical
+ pipeSpawnTimer += 1
+ if pipeSpawnTimer >= time_between_pipe_spawn: pipeSpawnTimer = 0
+
+ # Update stage
+ if time.time() - game_clock >= 10:
+ time_between_pipe_spawn *= 5 / 6
+ stage += 1
+ game_clock = time.time()
+
diff --git a/Open CV Game/pipe_sprite_single.png b/Open CV Game/pipe_sprite_single.png
new file mode 100644
index 000000000..8d24d25de
Binary files /dev/null and b/Open CV Game/pipe_sprite_single.png differ