Advertisement
Guest User

Bobb

a guest
May 20th, 2019
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.22 KB | None | 0 0
  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()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement