Reputation: 57
I wrote Dino game with Arcade in Python. To move the dinosaur, I use mediapipe hand detection with a webcam. The problem is that I can not open both the webcam and the game window together.
To solve this problem I wanted to use the threading library. But the Game class had to inherit from this library, which I could not do because it should be inherit from arcade library.
please guide me. Thank you
class Game(arcade.Window):
def __init__(self):
self.w = 900
self.h = 400
self.msec = 0
self.gravity = 0.5
super().__init__(self.w , self.h ,"Dino")
arcade.set_background_color(arcade.color.WHITE)
self.dino = Dino()
self.grounds = arcade.SpriteList()
self.cap = cv2.VideoCapture(0) # Use the webcam to detect hand movements
self.mpHands = mp.solutions.hands
self.hands = self.mpHands.Hands()
self.mpDraw = mp.solutions.drawing_utils
for i in range(0, self.w + 132, 132):
ground = Ground(i, 50)
self.grounds.append(ground)
self.physics_engine = arcade.PhysicsEnginePlatformer(self.dino, self.grounds, self.gravity)
def on_draw(self):
arcade.start_render()
for ground in self.grounds:
ground.draw()
self.dino.draw()
def on_update(self, delta_time: float):
self.physics_engine.update()
self.dino.update_animation()
self.dino.center_x = 200
self.msec += 0.5
self.dino.show_walking(self.msec)
# ___ start Recognize hand postures ___
success,img = self.cap.read()
imgRGB = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
results = self.hands.process(imgRGB)
lmList = []
if results.multi_hand_landmarks:
for handlandmark in results.multi_hand_landmarks:
for id,lm in enumerate(handlandmark.landmark):
h,w,_ = img.shape
cx,cy = int(lm.x*w),int(lm.y*h)
lmList.append([id,cx,cy])
self.mpDraw.draw_landmarks(img,handlandmark,self.mpHands.HAND_CONNECTIONS)
# Detect fisted hand
if lmList != []:
x1,y1 = lmList[4][1], lmList[4][2]
x2,y2 = lmList[8][1], lmList[8][2]
x3,y3 = lmList[12][1], lmList[12][2]
x4,y4 = lmList[16][1], lmList[16][2]
x5,y5 = lmList[20][1], lmList[20][2]
length54 = hypot(x5-x4 , y5-y4)
length43 = hypot(x4-x3 , y4-y3)
length32 = hypot(x3-x2 , y3-y2)
length21 = hypot(x2-x1 , y2-y1)
# ___ end Recognize hand postures ___
# Moving the dinosaur
if length21 < 50 and length32 < 50 and length43 < 50 and length54 < 50:
if self.physics_engine.can_jump():
self.dino.change_y = 15
cv2.imshow('Image',img)
for ground in self.grounds:
if ground.center_x < 0:
self.grounds.remove(ground)
self.grounds.append(Ground(self.w + 132 ,50))
class Ground(arcade.Sprite):
def __init__(self, width, height):
super().__init__()
self.picture = random.choice(['img/ground-0.png','img/ground-1.png', 'img/ground-2.png', 'img/ground-3.png', 'img/ground-4.png', 'img/ground-5.png', 'img/ground-6.png'])
self.texture = arcade.load_texture(self.picture)
self.center_x = width
self.center_y = height
self.change_x = -6
self.change_y = 0
self.width = 132
self.height = 56
class Dino(arcade.AnimatedWalkingSprite):
def __init__(self):
super().__init__()
self.walk_right_textures = [arcade.load_texture('img/dino-walk-0.png'), arcade.load_texture('img/dino-walk-1.png')]
self.walk_down_textures = [arcade.load_texture('img/dino-down-0.png'), arcade.load_texture('img/dino-down-1.png')]
self.walk_up_textures = [arcade.load_texture('img/dino-walk-1.png')]
self.walk_down_textures = [arcade.load_texture('img/dino-walk-0.png')]
self.center_x = 200
self.center_y = 233
self.change_x = 1
self.change_y = 0
self.scale = 0.3
self.bent = 0
def show_walking(self, s):
if s % 2 == 0:
self.texture = arcade.load_texture('img/dino-walk-0.png')
elif s % 3 == 0:
self.texture = arcade.load_texture('img/dino-walk-1.png')
if __name__ == '__main__':
game = Game()
arcade.run()
Upvotes: 0
Views: 439
Reputation: 8260
You can inherit your class from arcade.Window
and add mediapipe
code within. Simple example:
import cv2
import arcade
import mediapipe as mp
class Game(arcade.Window):
def __init__(self):
super().__init__(400, 300)
self.x = 20
self.cap = cv2.VideoCapture(0)
self.hands = mp.solutions.hands.Hands(model_complexity=0, min_detection_confidence=0.5, min_tracking_confidence=0.5)
def on_draw(self):
arcade.start_render()
arcade.draw_circle_filled(center_x=self.x, center_y=150, radius=20, color=arcade.color.RED)
arcade.draw_text(text='Move circle with a hand!', start_x=200, start_y=250, color=arcade.color.GREEN, font_size=24, anchor_x='center')
def on_update(self, delta_time):
_, image = self.cap.read()
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.resize(image, (400, 300))
results = self.hands.process(image)
cv2.imshow('Game', cv2.flip(image, 1))
if results.multi_hand_landmarks:
self.x += 5
Game()
arcade.run()
Output:
Upvotes: 2