SHARE
TWEET

Bobb

a guest May 20th, 2019 102 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import math
  2. import random
  3. import pygame
  4. import tkinter as tk
  5. from tkinter import messagebox
  6. pygame.init()
  7.  
  8. #dimensions of the screen
  9. n_units = 20 #Numbers of blocks in one line/column of the grid
  10. dim = 500 #Dimension of the screen (lenght of a side of the square window)
  11. unit_lenght = dim/n_units
  12. counter = 0
  13. boom = False
  14.  
  15.  
  16.  
  17. # Defines a block in the game (snake is composed of block and fruit/other objects are blocks)
  18. # Has a move method and draw methods which are called in the update_screen function
  19. class block():
  20.     counter = 0
  21.     def __init__(self,start,dir_x=1,dir_y=0,color=(255,228,196)):
  22.         self.pos = start #initial position given when an object is created
  23.         self.dir_x = 1
  24.         self.dir_y = 0
  25.         self.color = color #Default color = color of the snake
  26.  
  27.     #moves the block in (dirx,diry) direction
  28.     def move(self, dir_x, dir_y):
  29.         self.dir_x = dir_x
  30.         self.dir_y = dir_y
  31.         self.pos = (self.pos[0] + self.dir_x, self.pos[1] + self.dir_y) #New position
  32.  
  33.     #draws the block on the screen
  34.     def draw(self, screen, head=False):
  35.        
  36.         i = self.pos[0]
  37.         j = self.pos[1]
  38.        
  39.         #Drawing function
  40.         pygame.draw.rect(screen, self.color, (i*unit_lenght+1,j*unit_lenght+1, unit_lenght-2, unit_lenght-2))
  41.        
  42.         #Draws eyes of the snake
  43.         if head:
  44.             centre = unit_lenght/2
  45.             radius = 3
  46.             circleMiddle = (int(i*unit_lenght+centre-radius),int(j*unit_lenght+8))
  47.             circleMiddle2 = (int(i*unit_lenght + unit_lenght -radius*2),int(j*unit_lenght+8))
  48.             pygame.draw.circle(screen, (0,0,0), circleMiddle, radius)
  49.             pygame.draw.circle(screen, (0,0,0), circleMiddle2, radius)
  50.            
  51.            
  52.                        
  53.    
  54.  
  55.  
  56. #Class snakes:
  57. #Attributes: body (list of blocks),
  58.  
  59. class snake():
  60.     body = [] # contains blocks
  61.     # Dictionnary with two keys CoordX, CoordY with corresponding values dir_x, dir_Y
  62.     turns = {}  #Contains the values of the last block move
  63.     last_key = [0,0,0,0] #Left,  right, up, down
  64.     def __init__(self, color, pos):
  65.         self.color = color
  66.         self.head = block(pos)
  67.         self.body.append(self.head) #add a block for the head in body
  68.         self.dir_x = 0 #initial direction
  69.         self.dir_y = 0 #initial direction
  70.  
  71.     #Moves all the blocks in body
  72.     def move(self):
  73.         #Loop through each frame
  74.         for event in pygame.event.get():
  75.             if event.type == pygame.QUIT: #If the user leaves the window
  76.                 pygame.quit() #Quit the game
  77.  
  78.             keys = pygame.key.get_pressed() #Get the state of all keyboard buttons (if pushed = True)
  79.  
  80.             for key in keys:
  81.                 #Test the 4 buttons UP,Down,Left,Right and fill turns with the associates values
  82.                 #that indicate in which direction the snake moves
  83.    
  84.                 if keys[pygame.K_LEFT]: # Players hit left arrow
  85.                     #Forbid the snake to turn in the opposite direction it is in
  86.                     if self.last_key == [0,1,0,0]: # Is moves to the right
  87.                         self.dir_x = 1
  88.                         self.dir_y = 0
  89.                         self.turns[self.head.pos[:]] = [self.dir_x, self.dir_y] # Continues to the right
  90.                         self.last_key = [0,1,0,0]
  91.                     else: # Else goes left
  92.                         self.dir_x = -1 # Indicates that the snake will move left
  93.                         self.dir_y = 0
  94.                         self.turns[self.head.pos[:]] = [self.dir_x, self.dir_y] #Stores in turns the values and keys
  95.                         self.last_key = [1,0,0,0]
  96.  
  97.                 elif keys[pygame.K_RIGHT]: #Right arrow
  98.                     if self.last_key == [1,0,0,0]:
  99.                         self.dir_x = -1 # Indicates that the snake will move left
  100.                         self.dir_y = 0
  101.                         self.turns[self.head.pos[:]] = [self.dir_x, self.dir_y] #Stores in turns the values and keys
  102.                         self.last_key = [1,0,0,0]
  103.                     else:    
  104.                         self.dir_x = 1
  105.                         self.dir_y = 0
  106.                         self.turns[self.head.pos[:]] = [self.dir_x, self.dir_y]
  107.                         self.last_key = [0,1,0,0]
  108.  
  109.                 elif keys[pygame.K_UP]: # Up arrow
  110.                     if self.last_key == [0,0,0,1]:
  111.                         self.dir_x = 0
  112.                         self.dir_y = 1
  113.                         self.turns[self.head.pos[:]] = [self.dir_x, self.dir_y]
  114.                         self.last_key = [0,0,0,1]
  115.                     else:
  116.                         self.dir_x = 0
  117.                         self.dir_y = -1
  118.                         self.turns[self.head.pos[:]] = [self.dir_x, self.dir_y]
  119.                         self.last_key = [0,0,1,0]
  120.  
  121.                 elif keys[pygame.K_DOWN]: #Down arrow
  122.                     if self.last_key == [0,0,1,0]:
  123.                         self.dir_x = 0
  124.                         self.dir_y = -1
  125.                         self.turns[self.head.pos[:]] = [self.dir_x, self.dir_y]
  126.                         self.last_key = [0,0,1,0]
  127.                     else:
  128.                         self.dir_x = 0
  129.                         self.dir_y = 1
  130.                         self.turns[self.head.pos[:]] = [self.dir_x, self.dir_y]
  131.                         self.last_key = [0,0,0,1]
  132.                    
  133.         #Loop through all the blocks in body to move them one by one
  134.         #by calling the block.move() method
  135.         for i, block in enumerate(self.body):
  136.             position = block.pos[:] #Get the position of the block on the screen
  137.            
  138.             #If the player pressed a key, call block.move with the values associated to the block's coordinates in turns
  139.             if position in self.turns:  
  140.                 turn = self.turns[position]
  141.                 block.move(turn[0],turn[1])
  142.                 if i == len(self.body)-1: # If this is the last block, clear turns
  143.                     self.turns.pop(position)
  144.                    
  145.             #Will move the snake if the player didn't hit a button
  146.             else:
  147.                 #Deals with the snake hitting a border of the screen
  148.                 if block.dir_x == -1 and block.pos[0] <= 0: block.pos = (n_units-1, block.pos[1])
  149.                 elif block.dir_x == 1 and block.pos[0] >= n_units-1: block.pos = (0,block.pos[1])
  150.                 elif block.dir_y == 1 and block.pos[1] >= n_units-1: block.pos = (block.pos[0], 0)
  151.                 elif block.dir_y == -1 and block.pos[1] <= 0: block.pos = (block.pos[0], n_units-1)
  152.                 # No border case
  153.                 else: block.move(block.dir_x,block.dir_y)
  154.        
  155.  
  156.     #Reset to the initial parameters (to restart the game)
  157.     def reset(self, pos):
  158.         self.head = block(pos)
  159.         self.body = []
  160.         self.body.append(self.head)
  161.         self.turns = {}
  162.         self.dir_x = 0
  163.         self.dir_y = 1
  164.  
  165.  
  166.     #Add a block at the back of the snake
  167.     def add_block(self):
  168.         tail = self.body[-1] #Last block of the body
  169.         dx, dy = tail.dir_x, tail.dir_y
  170.        
  171.         #Detects the direction in wich the snake is to fill the body with a block in the right position
  172.         if dx == 1 and dy == 0:
  173.             self.body.append(block((tail.pos[0]-1,tail.pos[1])))
  174.         elif dx == -1 and dy == 0:
  175.             self.body.append(block((tail.pos[0]+1,tail.pos[1])))
  176.         elif dx == 0 and dy == 1:
  177.             self.body.append(block((tail.pos[0],tail.pos[1]-1)))
  178.         elif dx == 0 and dy == -1:
  179.             self.body.append(block((tail.pos[0],tail.pos[1]+1)))
  180.        
  181.         #Gives the direction to the block
  182.         self.body[-1].dir_x = dx
  183.         self.body[-1].dir_y = dy
  184.        
  185.     #Calls the draw function from block
  186.     def draw(self, screen):
  187.         for i, c in enumerate(self.body):
  188.             if i ==0:
  189.                 c.draw(screen, True)
  190.             else:
  191.                 c.draw(screen)
  192.  
  193.  
  194.        
  195.    
  196. #Function called each loop to draw the elements and the screen
  197. def draw_frame(screen, Snake, Fruit, Mine, Animation1, Animation2):
  198.     global counter, boom
  199.     screen.fill((250, 250,250)) #Color of the screen
  200.     Snake.draw(screen) #Draw the snake
  201.     screen.blit(Animation2[len(Snake.body)%9], (Fruit.pos[0]*unit_lenght, Fruit.pos[1]*unit_lenght)) #Draw the fruit
  202.     if boom == True:
  203.         screen.blit(Animation1[counter//3], (Mine.pos[0]*unit_lenght, Mine.pos[1]*unit_lenght))
  204.         counter += 1
  205.        
  206.         if counter >= 27:
  207.             counter = 0
  208.             boom = False
  209.            
  210.     else:
  211.         screen.blit(Animation1[counter//3],(Mine.pos[0]*unit_lenght, Mine.pos[1]*unit_lenght))
  212.    
  213.     pygame.display.update()
  214.  
  215.  
  216.  
  217. #Function that creates a fruit
  218. #(it only returns 2 randoms numbers as coordinates and check that they are not on the snake)
  219. def randomSnack(snake): # give the snake to get its position
  220.    
  221.     positions = snake.body #snake position
  222.     while True:
  223.         x = random.randrange(n_units)
  224.         y = random.randrange(n_units)
  225.         if len(list(filter(lambda z:z.pos == (x,y), positions))) > 0: #check if the fruit is not on a block of the snake
  226.             continue
  227.         else:
  228.             break
  229.        
  230.     return (x,y)
  231.  
  232. def mine(snake, randomsnack):
  233.     position_S = snake.body
  234.     position_snack = randomsnack.pos
  235.     while True:
  236.         x = random.randrange(n_units)
  237.         y = random.randrange(n_units)
  238.         if len(list(filter(lambda z:z.pos == (x,y), position_S))) > 0 or position_snack == (x,y): #check if the fruit is not on a block of the snake
  239.             continue
  240.    
  241.         else:
  242.             break
  243.        
  244.     return (x,y)
  245.    
  246.  
  247.  
  248.  
  249. def message_box(subject, content):
  250.     root = tk.Tk()
  251.     root.attributes("-topmost", True)
  252.     root.withdraw()
  253.     messagebox.showinfo(subject, content)
  254.     try:
  255.         root.destroy()
  256.     except:
  257.         pass
  258.  
  259.  
  260. def main():
  261.     global boom
  262.     win = pygame.display.set_mode((dim, dim))
  263.     s = snake((255,0,0), (10,10))
  264.     fruit = block(randomSnack(s), color=(255,0,0))
  265.     bomb = block(mine(s, fruit), color = (0,0,255))
  266.     #myfont = pygame.font.SysFont("monospace", 16)
  267.     flag = True
  268.  
  269.     clock = pygame.time.Clock()
  270.     mine_animation = [pygame.image.load('mine1.png'), pygame.image.load('mine2.png'), pygame.image.load('Mine3.png'),
  271.                       pygame.image.load('Mine4.png'), pygame.image.load('Mine5.png'), pygame.image.load('Mine6.png'),
  272.                       pygame.image.load('Mine7.png'), pygame.image.load('Mine8.png'), pygame.image.load('Mine9.png')]
  273.    
  274.     fruit_animation = [pygame.image.load('Fruit1.png'), pygame.image.load('Fruit2.png'), pygame.image.load('Fruit3.png'),
  275.                       pygame.image.load('Fruit4.png'), pygame.image.load('Fruit5.png'), pygame.image.load('Fruit6.png'),
  276.                       pygame.image.load('Fruit7.png'), pygame.image.load('Fruit8.png'), pygame.image.load('Fruit9.png')]
  277.    
  278.     Boom_sound = pygame.mixer.Sound('Bomb+1.wav')
  279.     eat_sound = pygame.mixer.Sound('Slurp+6.wav')
  280.    
  281.     music = pygame.mixer.Sound('music.wav')
  282.     music.play(-1)
  283.  
  284.    
  285.     while flag:
  286.         pygame.time.delay(50)
  287.         clock.tick(10)
  288.         s.move()
  289.         if s.body[0].pos == fruit.pos:
  290.             s.add_block()
  291.             eat_sound.play(0)
  292.             fruit = block(randomSnack(s), color=(255,0,0))
  293.  
  294.         for x in range(len(s.body)):
  295.             if s.body[x].pos in list(map(lambda z:z.pos,s.body[x+1:])):
  296.                 print('Score: ', len(s.body))
  297.                 message_box('Score', len(s.body))
  298.                 s.reset((10,10))
  299.                 break
  300.             elif s.body[0].pos == bomb.pos:
  301.                 if len(s.body) < 4:
  302.                     message_box('Score', len(s.body))
  303.                     s.reset((10,10))
  304.                     break
  305.                 Boom_sound.play(0)
  306.                 s.body.pop(-1)
  307.                 s.body.pop(-1)
  308.                 s.body.pop(-1)
  309.                 boom = True
  310.                 break
  311.         print(counter)
  312.         if counter == 26:
  313.             bomb = block(mine(s, fruit), color = (0,0,255))
  314.         draw_frame(win, s, fruit, bomb, mine_animation, fruit_animation)
  315.                
  316.  
  317. main()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top