-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #350 from 17arindam/snake-game
gesture controlled snake game using opencv added
- Loading branch information
Showing
14 changed files
with
922 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
|
||
#PyInstaller | ||
*.manifest | ||
*.spec | ||
build/ | ||
dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 Mohit Singh | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
## Gesture Controlled Snake Game | ||
This program can be used to play a Snake Game (or like it) by detecting hand gestures to control movement of the snake on the screen. It has been implemented in Python using OpenCV library. Although, the demo shown here refers to playing a Snake Game, it can be used to play any game or control any application using hand gestures only. | ||
This program shall be used to play a Snake Game by detecting hand gestures to control movement of the snake on the screen. It has been implemented in Python using OpenCV library. Although, the demo shown here refers to playing a Snake Game, it can be used to play any game or control any application using hand gestures only. | ||
<p align="center"> | ||
<img src="http://img.youtube.com/vi/PE_rgc2K0sg/0.jpg?raw=true" alt="Gesture Controlled Snake Game Using OpenCV and Python"/> | ||
</p> | ||
Watch on Youtube | ||
|
||
[Gesture Controlled Snake Game Using OpenCV and Python](http://www.youtube.com/watch?v=PE_rgc2K0sg) | ||
|
||
## Getting Started | ||
### Prerequisites | ||
The program depends on the following libraries- | ||
|
||
numpy==1.15.2 | ||
imutils==0.5.1 | ||
PyAutoGUI==0.9.38 | ||
opencv_python==3.4.3.18 | ||
pygame==1.9.4 | ||
|
||
Install the libraries using `pip install -r requirements.txt` | ||
|
||
### Installing | ||
|
||
1. Clone the repository in your local computer. | ||
2. Use `python <filename.py>` to run specific files, which are described below. | ||
|
||
## Built With | ||
|
||
- [OpenCV](https://opencv.org/) - The Open Computer Vision Library | ||
- [PyAutoGUI](https://pypi.org/project/PyAutoGUI/) - Cross platform GUI Automation Python Module | ||
|
||
## Contributing | ||
Please feel free to contribute to the project and Pull Requests are open for everyone willing to improve upon the project. Feel free to provide any suggestions. | ||
|
||
## License | ||
This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/mohitwildbeast/Gesture-Controlled-Snake-Game/blob/master/LICENSE) file for details. | ||
## Acknowledgements | ||
|
||
- The inspiration for the project came through PyImageSearch blog's article- [OpenCV Tracking Object in Images](https://www.pyimagesearch.com/2015/09/21/opencv-track-object-movement/) blog post. | ||
- PyAutoGUI helped a lot for keyboard automation tasks. | ||
## File Contents | ||
The entire project has been made using a bottom up approach, and the project consists of the following files which are described below- | ||
|
||
## [Object Detection](https://github.com/mohitwildbeast/Gesture-Controlled-Snake-Game/blob/master/object-detection.py) | ||
|
||
> This script detects a object of specified object colour from the webcam video feed. Using OpenCV library for vision tasks and HSV color space for detecting object of given specific color. | ||
>See the demo on Youtube - [ Object Detection and Motion Tracking in OpenCV](https://www.youtube.com/watch?v=mtGBuMlusXQ) | ||
|
||
|
||
## [Object Tracking and Direction Detection](https://github.com/mohitwildbeast/Gesture-Controlled-Snake-Game/blob/master/object-tracking-direction-detection.py) | ||
|
||
> This script can detect objects specified by the HSV color and also sense | ||
direction of their movement. | ||
|
||
> See the demo on Youtube - [Object Tracking and Direction Detection using OpenCV](https://www.youtube.com/watch?v=zapq9QT9uwc) | ||
## [Game Control Using Object Tracking (Multithreaded Implementation)](https://github.com/mohitwildbeast/Gesture-Controlled-Snake-Game/blob/master/game-control-using-object-tracking-multithreaded.py) | ||
> This script can detect objects specified by the HSV color and also sense the | ||
direction of their movement.Using this script a Snake Game which has been loaded in the repo, can be played. Implemented using OpenCV. Uses seperate thread for reading frames through OpenCV. | ||
|
||
>See the demo on Youtube - [Gesture Controlled Snake Game Playing with OpenCV and Computer Vision](https://www.youtube.com/watch?v=PE_rgc2K0sg) | ||
## Snake Game | ||
>The Snake Game present in this video, has been taken from my previous repository [SnakeFun](https://github.com/mohitwildbeast/SnakeFun). The files from the game corrrespond to SnakeFun.py and settingsSnakeFun.py | ||
>Run the game using the code ```python SnakeFun.py``` | ||
|
182 changes: 182 additions & 0 deletions
182
Computer Vision/Gesture-Controlled-Snake-Game/SnakeGame.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
import random | ||
import pygame | ||
import sys | ||
from pygame.locals import * | ||
from settingsSnakeFun import * | ||
|
||
def main(): | ||
global CLOCK, SCREEN, FONT | ||
|
||
pygame.init() | ||
CLOCK = pygame.time.Clock() | ||
SCREEN = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) | ||
FONT = pygame.font.Font('freesansbold.ttf', 18) | ||
pygame.display.set_caption('Snake Game') | ||
|
||
showStartScreen() | ||
while True: | ||
pygame.mixer.music.play(-1,0.0) | ||
runGame() | ||
pygame.mixer.music.stop() | ||
showGameOverScreen() | ||
|
||
def runGame(): | ||
#Set a random starting point | ||
startx = random.randint(5, CELLWIDTH - 6) | ||
starty = random.randint(5, CELLHEIGHT - 6) | ||
global wormCoords | ||
wormCoords = [{'x' : startx, 'y' : starty}, {'x': startx - 1, 'y':starty}, {'x':startx - 2, 'y':starty}] | ||
direction = RIGHT | ||
|
||
apple = getRandomLocation() | ||
|
||
while True: | ||
for event in pygame.event.get(): | ||
if event.type == QUIT: | ||
terminate() | ||
elif event.type == KEYDOWN: | ||
if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT: | ||
direction = LEFT | ||
elif (event.key == K_RIGHT or event.key == K_d) and direction != LEFT: | ||
direction = RIGHT | ||
elif (event.key == K_UP or event.key == K_w) and direction != DOWN: | ||
direction = UP | ||
elif (event.key == K_DOWN or event.key == K_s) and direction != UP: | ||
direction = DOWN | ||
elif event.key == K_ESCAPE: | ||
terminate() | ||
#Collision Detection | ||
#Check Collision with edges | ||
if wormCoords[HEAD]['x'] == -1 or wormCoords[HEAD]['x'] == CELLWIDTH or wormCoords[HEAD]['y'] == -1 or wormCoords[HEAD]['y'] == CELLHEIGHT: | ||
return | ||
#Check Collision with snake's body | ||
for wormBody in wormCoords[1:]: | ||
if wormBody['x'] == wormCoords[HEAD]['x'] and wormBody['y'] == wormCoords[HEAD]['y']: | ||
return | ||
#Check Collision with Apple | ||
if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']: | ||
APPLEEATSOUND.play() | ||
apple = getRandomLocation() | ||
else: | ||
del wormCoords[-1] | ||
|
||
#Moving the Snake | ||
if direction == UP: | ||
newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] - 1} | ||
elif direction == DOWN: | ||
newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] + 1} | ||
elif direction == RIGHT: | ||
newHead = {'x': wormCoords[HEAD]['x'] + 1, 'y': wormCoords[HEAD]['y']} | ||
elif direction == LEFT: | ||
newHead = {'x': wormCoords[HEAD]['x'] - 1, 'y': wormCoords[HEAD]['y']} | ||
wormCoords.insert(0, newHead) | ||
|
||
#Drawing the Screen | ||
SCREEN.fill(BGCOLOR) | ||
drawGrid() | ||
drawWorm(wormCoords) | ||
drawApple(apple) | ||
drawScore((len(wormCoords) - 3) * 10) | ||
pygame.display.update() | ||
CLOCK.tick(FPS) | ||
|
||
def getTotalScore(): | ||
return ((len(wormCoords) - 3) * 10) | ||
|
||
def drawPressKeyMsg(): | ||
pressKeyText = FONT.render('Press A Key To Play', True, YELLOW) | ||
pressKeyRect = pressKeyText.get_rect() | ||
pressKeyRect.center = (WINDOWWIDTH - 200, WINDOWHEIGHT - 100) | ||
SCREEN.blit(pressKeyText, pressKeyRect) | ||
|
||
def drawSettingsMsg(): | ||
SCREEN.blit(SETTINGSBUTTON, (WINDOWWIDTH - SETTINGSBUTTON.get_width(), WINDOWHEIGHT - SETTINGSBUTTON.get_height())) | ||
|
||
def checkForKeyPress(): | ||
if len(pygame.event.get(QUIT)) > 0: | ||
terminate() | ||
|
||
keyUpEvents = pygame.event.get(KEYUP) | ||
if len(keyUpEvents) == 0: | ||
return None | ||
if keyUpEvents[0].key == K_ESCAPE: | ||
terminate() | ||
return keyUpEvents[0].key | ||
|
||
def showStartScreen(): | ||
titlefont = pygame.font.Font('freesansbold.ttf', 100) | ||
titleText = titlefont.render('SNAKE FUN', True, DARKGREEN) | ||
while True: | ||
SCREEN.fill(BGCOLOR) | ||
titleTextRect = titleText.get_rect() | ||
titleTextRect.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2) | ||
SCREEN.blit(titleText, titleTextRect) | ||
|
||
drawPressKeyMsg() | ||
if checkForKeyPress(): | ||
pygame.event.get() | ||
return | ||
pygame.display.update() | ||
CLOCK.tick(FPS) | ||
|
||
def terminate(): | ||
pygame.quit() | ||
sys.exit() | ||
|
||
def getRandomLocation(): | ||
return {'x': random.randint(0, CELLWIDTH - 1), 'y': random.randint(0, CELLHEIGHT - 1)} | ||
|
||
def showGameOverScreen(): | ||
gameOverFont = pygame.font.Font('freesansbold.ttf', 100) | ||
gameOverText = gameOverFont.render('Game Over', True, WHITE) | ||
gameOverRect = gameOverText.get_rect() | ||
totalscoreFont = pygame.font.Font('freesansbold.ttf', 40) | ||
totalscoreText = totalscoreFont.render('Total Score: %s' % (getTotalScore()), True, WHITE) | ||
totalscoreRect = totalscoreText.get_rect() | ||
totalscoreRect.midtop = (WINDOWWIDTH/2, 150) | ||
gameOverRect.midtop = (WINDOWWIDTH/2, 30) | ||
SCREEN.fill(BGCOLOR) | ||
SCREEN.blit(gameOverText, gameOverRect) | ||
SCREEN.blit(totalscoreText, totalscoreRect) | ||
drawPressKeyMsg() | ||
pygame.display.update() | ||
pygame.time.wait(1000) | ||
checkForKeyPress() | ||
|
||
while True: | ||
if checkForKeyPress(): | ||
pygame.event.get() | ||
return | ||
|
||
def drawScore(score): | ||
scoreText = FONT.render('Score: %s' % (score), True, WHITE) | ||
scoreRect = scoreText.get_rect() | ||
scoreRect.center = (WINDOWWIDTH - 100, 30) | ||
SCREEN.blit(scoreText, scoreRect) | ||
|
||
def drawWorm(wormCoords): | ||
x = wormCoords[HEAD]['x'] * CELLSIZE | ||
y = wormCoords[HEAD]['y'] * CELLSIZE | ||
wormHeadRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE) | ||
pygame.draw.rect(SCREEN, YELLOW, wormHeadRect) | ||
|
||
for coord in wormCoords[1:]: | ||
x = coord['x'] * CELLSIZE | ||
y = coord['y'] * CELLSIZE | ||
wormSegmentRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE) | ||
pygame.draw.rect(SCREEN, GREEN, wormSegmentRect) | ||
|
||
def drawApple(coord): | ||
x = coord['x'] * CELLSIZE | ||
y = coord['y'] * CELLSIZE | ||
appleRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE) | ||
pygame.draw.rect(SCREEN, RED, appleRect) | ||
|
||
def drawGrid(): | ||
for x in range(0, WINDOWWIDTH, CELLSIZE): | ||
pygame.draw.line(SCREEN, DARKGRAY, (x, 0), (x, WINDOWHEIGHT)) | ||
for y in range(0, WINDOWHEIGHT, CELLSIZE): | ||
pygame.draw.line(SCREEN, DARKGRAY, (0, y), (WINDOWWIDTH, y)) | ||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.