Hire a web Developer and Designer to upgrade and boost your online presence with cutting edge Technologies

Monday, 18 January 2021

Chrome Dinosaur Game using Python – Free Code Available

 When there is no internet connection available on Chrome, we can see the offline Dinosaur Game on Chome Browser. Today we are going to build a model to play ” Chrome Dinosaur Game using Python “.

Characters:

  • 1. Dinosaur
  • 2. Cactus
  • 3. Bird

When the internet connection suddenly breaks down, during each surfing browser redirects you to the offline gaming page. You need to jump to skip the flying birds and cactus to play this game and should save it from colliding with them. You can have 2 modes: Night mode & Day mode which changes suddenly. The more you survive, the more you will get the score. You can play the online version of the game here: 

It’s great to play the game and exercise a bit after spending a long time coding. The IDE should enforce us to do some extra physical movement from time to time, maybe integrating with the Fitbit!

REQUIRED LIBRARIES

Here comes the important step. Since the codes are in ipynb, you need to have Jupyter Notebook installed on your setup. You also need to have OpenCV, Numpy, PyGame installed on your computer.

In this project, we are using our physical movement (jump) to play the game. So, we are using Support Vector Machine (SVM) to develop the model to integrate the game and our physical movements.

GETTING HANDS ON

Now just copy  you will extract the files there is a file called DINO_GAME.ipynb, JUMPING_IMAGES_CAPTURE.ipynb, & MACHINE_LEARNING.ipynb. After everything been done Let’s quickly configure the source file so that it will be able to run on your computer. 

---DINO_GAME.ipynb----

import cv2
import numpy as np
import joblib
import pygame
from sys import exit
from random import randrange, choice
import os

jump_model = joblib.load('jump_model.pkl')
msg = ''

def convert_frame_to_model(Canny_image):
    '''
    1° step = resize the image to (height=96, width=128) 
    2° step = reshape the image to (-1, img.size)
    3° step = give the image to the model
    '''
    #1° Step
    width = 128
    height = 96
    dim = (width, height)
    resized = cv2.resize(Canny_image, dim, interpolation = cv2.INTER_AREA)
    
    #2° Step
    reshaped_image = resized.reshape(-1, resized.size)
    
    #3° Step
    return jump_model.predict(reshaped_image)
    
cap = cv2.VideoCapture(0)


x = 800 #500
y = 700 #400

os.environ['SDL_VIDEO_WINDOW_POS'] = f'{(x, y)}'

#os.environ['SDL_VIDEO_CENTERED'] = '0'

THIS_FOLDER = os.getcwd()

pygame.init()

SCREEN_WIDTH = 840
SCREEN_HEIGHT = 680

WHITE = (255,255,255)
BLACK = (0,0,0)

FPS = 30
GAME_SPEED = 10
FLOOR_SPEED = 10
GAME_OVER = False

points = 0
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

song = 0

font = pygame.font.SysFont('comicsansms', 40, True, True)
score_sound = pygame.mixer.Sound(os.path.join(THIS_FOLDER,'score_sound.wav'))
score_sound.set_volume(0.2)

class Dino(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.jump_sound = pygame.mixer.Sound(os.path.join(THIS_FOLDER,'jump_sound.wav'))
        self.death_sound = pygame.mixer.Sound(os.path.join(THIS_FOLDER, 'death_sound.wav'))
        
        self.up = False
        self.stop = False
        self.xpos = 50
        self.ypos = (SCREEN_HEIGHT // 2) + 140
        self.dino_imgs = [os.path.join(THIS_FOLDER,f'dinossaur{i}.png') for i in range(3)]

        self.index = 0
        self.image = pygame.image.load(self.dino_imgs[self.index]).convert_alpha()
        self.mask = pygame.mask.from_surface(self.image)

        self.image = pygame.transform.scale(self.image, (84, 84))
        self.rect = self.image.get_rect()
        self.rect[0], self.rect[1] = self.xpos, self.ypos
    
    def collision(self):
        global GAME_SPEED, FLOOR_SPEED
        if pygame.sprite.spritecollide(dino, obstacle_group, False, pygame.sprite.collide_mask) or pygame.sprite.spritecollide(dino, flying_dino_group, False, pygame.sprite.collide_mask):
            GAME_SPEED = 0
            FLOOR_SPEED = 0
            self.stop = True
            flying_dino.stop = True
            
    def jump(self):
        self.jump_sound.play()
        self.up = True
        
    def update(self):
        #JUMP CONDITION
        if self.stop == False:
            if self.up == False:
                if self.rect[1] < self.ypos:
                    self.rect[1] += 20
                else:
                    self.rect[1] = self.ypos
            if self.up == True:
                if self.rect[1] <= self.ypos - 200:
                    self.up = False
                else:
                    self.rect[1] -= 30
        
            #SPRITES
            if self.index >= len(self.dino_imgs) - 1:
                self.index = 0
            self.index += 0.25

            self.image = pygame.image.load(self.dino_imgs[int(self.index)]).convert_alpha()
            self.image = pygame.transform.scale(self.image, (128, 128))
            self.mask = pygame.mask.from_surface(self.image)

        else:
            pass

class Flying_dino(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()        
        self.flying_dino_imgs = [os.path.join(THIS_FOLDER, f'fly_dino{i}.png') for i in range(2)]
        self.stop = False
        self.index = 0
        self.image = pygame.image.load(self.flying_dino_imgs[self.index]).convert_alpha()
        self.mask = pygame.mask.from_surface(self.image)
        
        self.image = pygame.transform.scale(self.image, (84, 84))
        self.rect = self.image.get_rect()
        self.rect[0], self.rect[1] = SCREEN_WIDTH, (SCREEN_HEIGHT // 2) 

    def update(self):
        #SPRITES
        if self.stop == False:
            if self.index >= len(self.flying_dino_imgs) - 1:
                self.index = 0

            self.index += 0.25
            self.image = pygame.image.load(self.flying_dino_imgs[int(self.index)]).convert_alpha()
            self.image = pygame.transform.scale(self.image, (128, 128))
            self.mask = pygame.mask.from_surface(self.image)
        else:
            pass

class Obstacle(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.obstacle_imgs = [os.path.join(THIS_FOLDER,'obstacle0.png')]

        self.image = pygame.image.load(self.obstacle_imgs[0]).convert_alpha()
        self.mask = pygame.mask.from_surface(self.image)
        self.image = pygame.transform.scale(self.image, (84, 84))
        self.rect = self.image.get_rect()
        self.rect[0], self.rect[1] = SCREEN_WIDTH, (SCREEN_HEIGHT // 2) + 162
        self.mask = pygame.mask.from_surface(self.image)

class Clouds(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.cloud_imgs = [os.path.join(THIS_FOLDER,'clouds0.png')]

        self.image = pygame.image.load(self.cloud_imgs[0]).convert_alpha()
        self.image = pygame.transform.scale(self.image, (148, 148))
        self.rect = self.image.get_rect()
        self.rect[0], self.rect[1] = (SCREEN_WIDTH // 2) + randrange(-400, 400, 100) , (SCREEN_HEIGHT // 2) - randrange(200, 400, 100)
    
    def update(self):
        if self.rect.topright[0] < 0:
            self.rect[0] = SCREEN_WIDTH
            self.rect[1] = (SCREEN_HEIGHT // 2) - randrange(200, 400, 100)
        self.rect[0] -= GAME_SPEED

class Floor(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.floor_imgs = [os.path.join(THIS_FOLDER,'floor0.png')]

        self.image = pygame.image.load(self.floor_imgs[0]).convert_alpha()
        self.image = pygame.transform.scale(self.image, (64, 64))
        self.rect = self.image.get_rect()
        self.rect[0], self.rect[1] = 0 , SCREEN_HEIGHT // 2  + 200
    def update(self):
        if self.rect.topright[0] < 0:
            self.rect[0] = SCREEN_WIDTH
        self.rect[0] -= FLOOR_SPEED

dino = Dino()
dino_group = pygame.sprite.Group()
dino_group.add(dino)

flying_dino = Flying_dino()
flying_dino_group = pygame.sprite.Group()
flying_dino_group.add(flying_dino)

obstacle = Obstacle()
obstacle_group = pygame.sprite.Group()
obstacle_group.add(obstacle)

numb_of_clouds = 5
clouds_group = pygame.sprite.Group()
for c in range(numb_of_clouds):
    clouds = Clouds()
    clouds_group.add(clouds)

floor_group = pygame.sprite.Group()
for c in range(-64, SCREEN_WIDTH, 60):
    floor = Floor()
    floor.rect[0] = c
    floor_group.add(floor)

clock = pygame.time.Clock()

obstacle_choice = choice([obstacle, flying_dino])

while True:
    sucess, img = cap.read()
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    imgCanny = cv2.Canny(gray, 155, 105)
        
    model_prediction = convert_frame_to_model(imgCanny)
        
    if model_prediction == 0:
        msg = 'Not jumping'
    else:
        msg = 'Jumping'
            
    cv2.putText(imgCanny, f'{msg}', (480//2, 50), cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),3) #msg, origin, font, scale_font, color, thickness
    cv2.imshow('Canny', imgCanny)
                
    if cv2.waitKey(1) & 0xff == ord('q'):
        break
    
    clock.tick(FPS)
    screen.fill(WHITE)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                cap.release()
                cv2.destroyAllWindows()
                pygame.quit()
                exit()
                '''
                if event.key == pygame.K_SPACE:
                    if dino.rect[1] < dino.ypos:
                        pass
                    else:
                        dino.jump()
                '''
            if event.key == pygame.K_r and GAME_OVER == True:
                GAME_SPEED = 10
                FLOOR_SPEED = 10
                points = 0
                song = 0
                obstacle.rect[0] = SCREEN_WIDTH
                flying_dino.rect[0] = SCREEN_WIDTH
                dino.stop = False
                dino.rect[1] = dino.ypos
                flying_dino.stop = False

    dino_group.draw(screen)
    dino_group.update()
    dino.collision()

    flying_dino_group.draw(screen)
    flying_dino_group.update()

    obstacle_group.draw(screen)
    obstacle_group.update()

    clouds_group.draw(screen)
    clouds_group.update()

    floor_group.draw(screen)
    floor_group.update()

    text = font.render(f'{points}', True, BLACK)
    screen.blit(text, (700, 40))
    
    if model_prediction == 1:
        if dino.rect[1] < dino.ypos:
            pass
        else:
            dino.jump()

    if obstacle_choice.rect.topright[0] < 0:
        flying_dino.rect[0] = SCREEN_WIDTH
        obstacle.rect[0] = SCREEN_WIDTH
        obstacle_choice = choice([obstacle, flying_dino])
    else:
        obstacle_choice.rect[0] -= GAME_SPEED

    if GAME_SPEED != 0:
        points += 1
        if (points % 100) == 0:
            score_sound.play()
            if GAME_SPEED == 46:
                pass
            else:
                GAME_SPEED += 2
    else:
        points += 0
        if song > 1:
            song = 2
        else:
            song += 1
        dino.jump_sound.stop()
        txt = ['GAME OVER', 'Press R to play again']
        line1 = font.render(txt[0], True, BLACK)
        line2 = font.render(txt[1], True, BLACK)
        screen.blit(line1, ((SCREEN_WIDTH // 2) - (line1.get_width()//2), (SCREEN_HEIGHT // 2) - 100))
        screen.blit(line2, ((SCREEN_WIDTH // 2) - (line2.get_width()//2), (SCREEN_HEIGHT // 2) - 50))
        GAME_OVER = True

    if song == 1:
        dino.death_sound.play()

    pygame.display.flip()

#Release everything if job is finished
cap.release()
cv2.destroyAllWindows()

-----JUMPING_IMAGES_CAPTURE.ipynb-----
import cv2
import numpy as np
from time import sleep

i = 0
   
cap = cv2.VideoCapture(0)
directory = 'C:/Users/joaovitor/Desktop/Frames'

while True:
    sucess, img = cap.read()
    
    if sucess:
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        imgCanny = cv2.Canny(gray, 155, 105)
        
        cv2.imwrite(f'{directory}/image_{i}.png', imgCanny)
        
        i += 1
        
        cv2.imshow('Canny', imgCanny)
        
        sleep(0.25)
        
        if cv2.waitKey(1) & 0xff == ord('q'):
            break
    else:
        break
        

#Release everything if job is finished
cap.release()
cv2.destroyAllWindows()
-----MACHINE_LEARNING.ipynb----

 

Importing the images into this script

In [1]:
import os
import numpy as np

directory = 'C:/Users/joaovitor/Desktop/Meu_Canal/DINO/'
jump_img = os.listdir(os.path.join(directory, 'jump'))
nojump_img = os.listdir(os.path.join(directory, 'no_jump'))

#checking if the number of images in both directories are equals
print(len(jump_img) == len(nojump_img))
print(len(jump_img))
False
81

Storing the images array into lists

In [2]:
import cv2

imgs_list_jump = []
imgs_list_nojump = []

for img in jump_img:
    images = cv2.imread(os.path.join(directory, 'jump', img), 0) #0 to convert the image to grayscale
    imgs_list_jump.append(images)
    
for img in nojump_img:
    images = cv2.imread(os.path.join(directory, 'no_jump', img), 0) #0 to convert the image to grayscale
    imgs_list_nojump.append(images) 

#Taking a look at the first img of array_imgs_jump list
print(imgs_list_jump[0])
print(50*'=')
print('Images Dimensions:', imgs_list_jump[0].shape)
[[0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]]
==================================================
Images Dimensions: (480, 640)

Let's display the first image

In [3]:
import matplotlib.pyplot as plt

img = cv2.cvtColor(imgs_list_jump[0], cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()

The images have 480 pixels height and 640 pixels width

In [4]:
print(imgs_list_jump[0].shape)
(480, 640)

The images sizes still very big, so we are going to resize all images in order to make them smaller

In [5]:
print('Original size:', imgs_list_jump[0].size) #original size
Original size: 307200

We will apply the code bellow to all images

In [6]:
scale_percent = 20 #20 percent of original size

width = int(imgs_list_jump[0].shape[1] * scale_percent / 100)
height = int(imgs_list_jump[0].shape[0] * scale_percent / 100)

dim = (width, height)

#resize image
resized = cv2.resize(imgs_list_jump[0], dim, interpolation = cv2.INTER_AREA)

print('Original Dimensions:', imgs_list_jump[0].shape)
print('Resized Dimensions:', resized.shape)

img = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()
Original Dimensions: (480, 640)
Resized Dimensions: (96, 128)

Applying to all images

In [7]:
scale_percent = 20 # 20 percent of original size
resized_jump_list = []
resized_nojump_list = []

for img in imgs_list_jump:
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)

    dim = (width, height)

    #resize image
    resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
    resized_jump_list.append(resized)

for img in imgs_list_nojump:
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)
    
    dim = (width, height)
    
    #resize image
    resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
    resized_nojump_list.append(resized)

#Checking if it worked:
print(resized_jump_list[0].shape)
print(resized_nojump_list[0].shape)

img = cv2.cvtColor(resized_nojump_list[10], cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()

cv2.imwrite('imagem_resized.png', resized_nojump_list[10])
(96, 128)
(96, 128)

Out[7]:
True

Creating my X dataset

In [9]:
nojump_list_reshaped = []
jump_list_reshaped = []

for img in resized_nojump_list:
    nojump_list_reshaped.append(img.reshape(-1, img.size))

for img in resized_jump_list:
    jump_list_reshaped.append(img.reshape(-1, img.size))

X_nojump = np.array(nojump_list_reshaped).reshape(len(nojump_list_reshaped), nojump_list_reshaped[0].size)
X_jump = np.array(jump_list_reshaped).reshape(len(jump_list_reshaped), jump_list_reshaped[0].size)

print(X_nojump.shape)
print(X_jump.shape)
(386, 12288)
(81, 12288)

Joining both X's

In [10]:
X = np.vstack([X_nojump, X_jump])
print(X.shape)
(467, 12288)

Creating my Y dataset

In [11]:
y_nojump = np.array([0 for i in range(len(nojump_list_reshaped))]).reshape(len(nojump_list_reshaped),-1)
y_jump = np.array([1 for i in range(len(jump_list_reshaped))]).reshape(len(jump_list_reshaped),-1)

Joining both Y's

In [12]:
y = np.vstack([y_nojump, y_jump])
print(y.shape)
(467, 1)

Shuffling both datasets

In [13]:
shuffle_index = np.random.permutation(y.shape[0])
#print(shuffle_index)
X, y = X[shuffle_index], y[shuffle_index]

Creating a X_train and y_train dataset

In [14]:
X_train = X
y_train = y

Choosing SVM (Support Vector Machine) as our Machine Learning model

In [15]:
from sklearn.svm import SVC
svm_clf = SVC(kernel='linear')
svm_clf.fit(X_train, y_train.ravel())
Out[15]:
SVC(kernel='linear')

Creating a confusion matrix to evaluate the model performance

In [16]:
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import confusion_matrix

y_train_pred = cross_val_predict(svm_clf, X_train, y_train.ravel(), cv=3) #sgd_clf no primeiro parametro
confusion_matrix(y_train.ravel(), y_train_pred)
Out[16]:
array([[381,   5],
       [ 16,  65]], dtype=int64)

Saving the model

In [17]:
import joblib

joblib.dump(svm_clf, 'jump_model.pkl') #sgd_clf no primeiro parametro
Out[17]:
['jump_model.pkl']

No comments:

Post a Comment

Connect broadband

A Gentle Introduction To Method Of Lagrange Multipliers

The method of Lagrange multipliers is a simple and elegant method of finding the local minima or local maxima of a function subject to equal...