this is my version of the popular snake game. The snake is controlled by the mouse so be careful when you start :) it grows infinitely long...you should download the apple.jpg file for the game, or graw one of your own just name it apple.jpg and place it in the same directory as the code itself :) have fun. If there are any problems please post a comment :)
CONTROLS>> left MB increase speed; right MB decrease speed; middle MB pouse game and resume aswell

Edited 7 Years Ago by masterofpuppets: n/a

Attachments apple.JPG 0.79 KB
from Tkinter import *
from math import *
import time
import threading
from PIL import Image, ImageTk
from random import *
import winsound
import tkFont

root = Tk(); root.geometry( "600x400+350+150" ); root.title( "Snake III" )
c = Canvas( root, width = 600, height = 400, bg = 'white', cursor = "diamond_cross" ); c.pack()

xM, yM = 100, 100; xMin, xMax, yMin, yMax = 5, 595, 5, 395; game = True
c.create_rectangle( xMin, yMin, xMax, yMax, width = 3 )
coordinates = []; lives = 5; score = 0; speed = 0.06
body = [ c.create_line( 0, 0, 0, 0 ), c.create_line( 0, 0, 0, 0 ) ]

food = c.create_image( 0, 0 ); food2 = c.create_image( 0, 0 ); food3 = c.create_image( 0, 0 ); diskR, diskX, diskY = 0, 0, 0; diskR2, diskX2, diskY2 = 0, 0, 0; diskR3, diskX3, diskY3 = 0, 0, 0
f = Image.open( 'apple.jpg' )
f1 = ImageTk.PhotoImage( f ); f2 = ImageTk.PhotoImage( f ); f3 = ImageTk.PhotoImage( f )

c.create_text( 100, 30, text = "Apples >>", font = tkFont.Font( family = 'Papyrus', size = 12 ) ); ap = c.create_text( 0, 0 )
c.create_text( 300, 30, text = "Score >>", font = tkFont.Font( family = 'Papyrus', size = 12 ) ); sc = c.create_text( 0, 0 )
c.create_text( 500, 30, text = "Lives >>", font = tkFont.Font( family = 'Papyrus', size = 12 ) ); li = c.create_text( 0, 0 )
############################################################################################################################################################

def end_x( x, d, a ):
    return x + sin( radians( a ) ) * d

def end_y( y, d, a):
    return y - cos( radians( a ) ) * d

############################################################################################################################################################

def food_appearing():
    global diskR, diskX, diskY, food, f1, xMin, xMax, yMin, yMax

    c.delete ( food )
    
    diskX = randint( 10, 590 )
    diskY = randint( 48, 390 )
    if xMin + 10 <= diskX <= xMax - 10 and yMin + 10 <= diskY <= xMax - 10:
        food = c.create_image( diskX, diskY, image = f1 )
        return
    else:
        food_appearing()

def food2_appearing():
    global diskR2, diskX2, diskY2, food2, f2, xMin, xMax, yMin, yMax

    c.delete ( food2 )
    
    diskX2 = randint( 10, 590 )
    diskY2 = randint( 48, 390 )
    if xMin + 10 <= diskX2 <= xMax - 10 and yMin + 10 <= diskY2 <= xMax - 10:
        food2 = c.create_image( diskX2, diskY2, image = f2 )
        return
    else:
        food2_appearing()

def food3_appearing():
    global diskR3, diskX3, diskY3, food3, f3, xMin, xMax, yMin, yMax

    c.delete ( food3 )
    
    diskX3 = randint( 10, 590 )
    diskY3 = randint( 48, 390 )
    if xMin + 10 <= diskX3 <= xMax - 10 and yMin + 10 <= diskY3 <= xMax - 10:
        food3 = c.create_image( diskX3, diskY3, image = f3 )
        return
    else:
        food3_appearing()

def remove_snake( coord_list, head_of_snake, l, bod ):
    global score, sc
    
    c.delete( head_of_snake ); c.update()
    for part in coord_list:
        try:
            time.sleep( 0.09 )
            score -= 2; c.delete( sc ); sc = c.create_text( 370, 30, text = score, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
            c.delete( part ); c.update()
        except:
            return
    if l <= 0:
        fin = c.create_text( 310, 170, text = "Score >> " + str( score ), font = tkFont.Font( family = 'Papyrus', size = 15 ) ); c.update()
        time.sleep( 3 ); c.delete( fin )
        root.destroy()
    else:
        rest = c.create_text( 310, 170, text = "Restarting...", font = tkFont.Font( family = 'Papyrus', size = 15 ) ); c.update()
        time.sleep( 2 )
        c.delete( rest ); c.update()
        moveSnake()
        
############################################################################################################################################################

def moveSnake():
    global xM, yM, coordinates, body, game, diskX, diskY, xMin, xMax, yMin, yMax, score, lives, ap, li, sc, speed

    c.delete( ap, li, sc )
    head = c.create_oval( 0, 0, 0, 0 ); 
    xS = 10; yS = 200; xM, yM = 100, 100
    count = 0; speed = 0.06
    food_appearing(); food2_appearing(); food3_appearing();
    apples = 0
    ap = c.create_text( 170, 30, text = apples, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
    sc = c.create_text( 370, 30, text = score, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
    li = c.create_text( 545, 30, text = lives, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
    xM, yM = 100, 100
    coordinates = []
    body = [ c.create_line( 0, 0, 0, 0 ), c.create_line( 0, 0, 0, 0 ) ]
    p = c.create_text( 0, 0 )
    while True:
        try:
            if game:
                c.delete( p )
                time.sleep( speed )
                # find the distance between the point xS = 10 and yS = 200 and the coordinates of the mouse using d = sqrt( ( x1 - x2 ) ** 2 + ( y1 - y2 ) ** 2 )
                # and then using end_x = x + sin( a ) * d we have -sin( a ) = ( x - end_x ) / d we find that a = -sin( ( x - end_x ) / d )
                # and then multiply by 100 to get the actual angle
                dist = sqrt( ( ( xS - xM ) ** 2 ) + ( ( yS - yM ) ** 2 ) )
                a = -sin( ( ( xS - xM ) / dist ) ); angle = a * 100
                if yM > yS:
                    angle = -angle + 180 # invert angle and add 180 to invert the direction

                try:
                    c.delete( head ); head = c.create_oval( xS, yS, xS + 10, yS + 10, fill = "brown" )
                except:
                    return
                coordinates += [ ( xS, yS, end_x( xS, 10, angle ), end_y( yS, 10, angle ) ) ]

                if len( coordinates ) > 1:
                    del coordinates[ : -len( body ) - 1 ]
                    tmp = 0
                    for part in body:
                        c.delete( part ); body.remove( part )
                        part = c.create_oval( coordinates[ tmp ][ 0 ], coordinates[ tmp ][ 1 ], coordinates[ tmp ][ 0 ] + 10, coordinates[ tmp ][ 1 ] + 10, fill = "green" )
                        body.insert( 0, part )
                        tmp += 1

                if diskX - 13 <= xS <= diskX + 8 and diskY - 13 <= yS <= diskY + 5:           
                    winsound.PlaySound( 'notify', winsound.SND_ASYNC )
                    apples += 1; score += 25; c.delete( ap, sc )
                    ap = c.create_text( 170, 30, text = apples, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                    sc = c.create_text( 370, 30, text = score, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                    w = c.create_image( 0, 0 )
                    body += [ w ]
                    food_appearing()
                if diskX2 - 13 <= xS <= diskX2 + 8 and diskY2 - 13 <= yS <= diskY2 + 5:           
                    winsound.PlaySound( 'notify', winsound.SND_ASYNC )
                    apples += 1; score += 25; c.delete( ap, sc )
                    ap = c.create_text( 170, 30, text = apples, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                    sc = c.create_text( 370, 30, text = score, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                    w = c.create_image( 0, 0 )
                    body += [ w ]
                    food2_appearing()
                if diskX3 - 13 <= xS <= diskX3 + 8 and diskY3 - 13 <= yS <= diskY3 + 5:           
                    winsound.PlaySound( 'notify', winsound.SND_ASYNC )
                    apples += 1; score += 25; c.delete( ap, sc )
                    ap = c.create_text( 170, 30, text = apples, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                    sc = c.create_text( 370, 30, text = score, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                    w = c.create_image( 0, 0 )
                    body += [ w ]
                    food3_appearing()

                for i in coordinates[ 1: len( body ) - 1 ]:
                    if int( i[ 0 ] ) - 5 <= int( xS ) <= int( i[ 0 ] ) + 5 and int( i[ 1 ] ) - 5 <= int( yS ) <= int( i[ 1 ] ) + 5:
                        apples = 0; lives -= 1; c.delete( ap, li )
                        ap = c.create_text( 170, 30, text = apples, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                        li = c.create_text( 545, 30, text = lives, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                        remove_snake( body, head, lives, body )
                        return

                if xS <= xMin or xS >= xMax - 10 or yS <= yMin or yS >= yMax - 8:
                    apples = 0; lives -= 1; c.delete( ap, li )
                    ap = c.create_text( 170, 30, text = apples, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                    li = c.create_text( 545, 30, text = lives, font = tkFont.Font( family = 'Papyrus', size = 15 ) )
                    remove_snake( body, head, lives, body )
                    return

                # Here I use the angle to find the next point according to the mouse coordinates, and this repeats as long as the mouse is in the Canvas window
                xS = end_x( xS, 10, angle )
                yS = end_y( yS, 10, angle )
                count += 1
                c.update()
            else:
                c.delete( p )
                p = c.create_text( 310, 170, text = "...Paused...", font = tkFont.Font( family = 'Papyrus', size = 15 ) ); c.update()
        except:
            return
        
def movement( event ):
    global xM, yM
    xM = event.x; yM = event.y
    
def increaseSpeed( event ):
    global speed
    speed -= 0.01

def decreaseSpeed( event ):
    global speed
    speed += 0.01

def pause( event ):
    global game
    if game == True: game = False
    else: game = True

c.bind( "<Button-1>", increaseSpeed )
c.bind( "<Button-2>", pause )
c.bind( "<Button-3>", decreaseSpeed )
c.bind( "<Motion>", movement )

moveSnake()

try:
    mainloop()
except:
    pass
The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.