Home > OS >  I'm making a snake game using python. I cant seem to make the snake moves in any direction. Wha
I'm making a snake game using python. I cant seem to make the snake moves in any direction. Wha

Time:10-03

I have this code below where it will add a 1 or -1 unit whenever I press any of the arrow button. My question is how can I use that new value in velocity and add it to my snake to the snake moves? I believe my code is wrong in the def snake() function but I don't seem to find the solution.

additional: what else should I fix to my code here to make it cleaner and concise? thank you

import random
from tkinter import *

SCREEN_WIDTH = 500
SCREEN_HEIGHT = 500
SCORE = 0
BODY_SIZE = 10
SNAKE_COLOUR ="blue"
SNAKE_FOOD = "purple"

def food():
    x = random.randint(0,30-1)*BODY_SIZE
    y = random.randint(0,30-1)*BODY_SIZE
    canvas.create_rectangle (x,y,x BODY_SIZE,y BODY_SIZE,fill="GOLD")
    
def snake():
    SNAKE_VELOCITY_X = 0
    SNAKE_VELOCITY_Y = 0
    snakeX = 0
    snakeY = 0
    snakeX = snakeX   SNAKE_VELOCITY_X
    snakeY = snakeY   SNAKE_VELOCITY_Y
    canvas.create_rectangle (snakeX,snakeY,snakeX BODY_SIZE,snakeY BODY_SIZE,fill="blue")

def update():
    food()
    snake()
    
master =Tk()
master.geometry("%sx%s"%(SCREEN_WIDTH,SCREEN_HEIGHT))
labelName= Label(master, text="A python game!", font= ('Courier 10 underline'))
labelScore = Label(master, text="%s"%(SCORE), font=('Courier 10'))
labelName.pack()
labelScore.pack()
canvas = Canvas(master, bg="black",width=300,height=300)
canvas.pack()


update()

def right_direction(event):
    SNAKE_VELOCITY_X = 1
    SNAKE_VELOCITY_Y = 0
    print(SNAKE_VELOCITY_X)
def left_direction(event):
    SNAKE_VELOCITY_X = -1
    SNAKE_VELOCITY_Y = 0
    print(SNAKE_VELOCITY_X)
def up_direction(event):
    SNAKE_VELOCITY_X = 0
    SNAKE_VELOCITY_Y = 1
    print(SNAKE_VELOCITY_Y)
def down_direction(event):
    SNAKE_VELOCITY_X = 0
    SNAKE_VELOCITY_Y = -1
    print(SNAKE_VELOCITY_Y)

master.bind("<Right>", right_direction)
master.bind("<Left>", left_direction)
master.bind("<Up>", up_direction)
master.bind("<Down>", down_direction)

master.mainloop()

CodePudding user response:

This is not an exhaustive answer, but should get you moving in the right direction. First, the concept: you create objects with the create_...() functions, and those functions return "handles" to the created objects. you can then use the handles to move, etc. the objects. To actually redraw the screen, you need to call the Tk.update() function.

Roughly, you need to change number of things:

the function canvas.create_rectangle(...) returns a handle to the rectangle. Save it, this is your "snake"

snakeHandle=canvas.create_rectangle(...)

then, when you execute one of your functions ..._direction(event), inside that function, tell the snake to move somewhere like this:

canvas.move(snakeHandle,x_distance, y_distance)

then kick tkinter so it updates the screen:

master.update()

CodePudding user response:

i changed a couple off things and now it should move. but the only problem is that the the snake does not get removed after it moves. you can try canvas.delete().

i put a # after everything i changed.

import random
from tkinter import *

SCREEN_WIDTH = 500
SCREEN_HEIGHT = 500
SCORE = 0
BODY_SIZE = 10
SNAKE_COLOUR ="blue"
SNAKE_FOOD = "purple"
SNAKE_VELOCITY_X = 0 # making these variables avalable to the whole code
SNAKE_VELOCITY_Y = 0 #
snakeX = 0 #
snakeY = 0 #

def food():
    x = random.randint(0,30-1)*BODY_SIZE
    y = random.randint(0,30-1)*BODY_SIZE
    canvas.create_rectangle (x,y,x BODY_SIZE,y BODY_SIZE,fill="GOLD")
    
def snake():
    global snakeX, snakeY, SNAKE_VELOCITY_X, SNAKE_VELOCITY_Y # global makes it so that the change is not only for the function but for the entire code
    snakeX = snakeX   SNAKE_VELOCITY_X * BODY_SIZE # makes it so that the player moves on player size instead of one pixel
    snakeY = snakeY   SNAKE_VELOCITY_Y * BODY_SIZE #
    canvas.create_rectangle (snakeX,snakeY,snakeX BODY_SIZE,snakeY BODY_SIZE,fill="blue")

def update():
    #food() # otherwise spawns new food
    snake()
    
master =Tk()
master.geometry("%sx%s"%(SCREEN_WIDTH,SCREEN_HEIGHT))
labelName= Label(master, text="A python game!", font= ('Courier 10 underline'))
labelScore = Label(master, text="%s"%(SCORE), font=('Courier 10'))
labelName.pack()
labelScore.pack()
canvas = Canvas(master, bg="black",width=300,height=300)
canvas.pack()


update()

def right_direction(event):
    global SNAKE_VELOCITY_X, SNAKE_VELOCITY_Y #
    SNAKE_VELOCITY_X = 1
    SNAKE_VELOCITY_Y = 0
    print(SNAKE_VELOCITY_X)
    update() # calling the update function
def left_direction(event):
    global SNAKE_VELOCITY_X, SNAKE_VELOCITY_Y #
    SNAKE_VELOCITY_X = -1
    SNAKE_VELOCITY_Y = 0
    print(SNAKE_VELOCITY_X)
    update() #
def up_direction(event):
    global SNAKE_VELOCITY_X, SNAKE_VELOCITY_Y #
    SNAKE_VELOCITY_X = 0
    SNAKE_VELOCITY_Y = -1
    print(SNAKE_VELOCITY_Y)
    update() #
def down_direction(event):
    global SNAKE_VELOCITY_X, SNAKE_VELOCITY_Y #
    SNAKE_VELOCITY_X = 0
    SNAKE_VELOCITY_Y = 1
    print(SNAKE_VELOCITY_Y)
    update() #

master.bind("<Right>", right_direction)
master.bind("<Left>", left_direction)
master.bind("<Up>", up_direction)
master.bind("<Down>", down_direction)

master.mainloop()

hope this helps

EDIT

i change your code to be in a class and cleaned some things up

import random
from tkinter import *


class game(Tk):
    def __init__(self):
        super().__init__()
        self.createVariables()
        self.createWindow()
        self.bindControls()
        self.snake()
        self.food()


    def createVariables(self):
        self.SCREEN_WIDTH = 500
        self.SCREEN_HEIGHT = 500
        self.SCORE = 0
        self.BODY_SIZE = 10
        self.SNAKE_COLOUR ="blue"
        self.SNAKE_FOOD = "purple"
        self.SNAKE_VELOCITY_X = 0
        self.SNAKE_VELOCITY_Y = 0
        self.snakeX = 0
        self.snakeY = 0
        self._snake = None


    def createWindow(self):
        self.geometry("%sx%s"%(self.SCREEN_WIDTH,self.SCREEN_HEIGHT))
        self.labelName= Label(self, text="A python game!", font= ('Courier 10 underline'))
        self.labelScore = Label(self, text="%s"%(self.SCORE), font=('Courier 10'))
        self.labelName.pack()
        self.labelScore.pack()
        self.canvas = Canvas(self, bg="black",width=300,height=300)
        self.canvas.pack()


    def bindControls(self):
        self.bind("<Right>", self.right_direction)
        self.bind("<Left>", self.left_direction)
        self.bind("<Up>", self.up_direction)
        self.bind("<Down>", self.down_direction)


    def food(self):
        x = random.randint(0,30-1)*self.BODY_SIZE
        y = random.randint(0,30-1)*self.BODY_SIZE
        self._food = self.canvas.create_rectangle (x,y,x self.BODY_SIZE,y self.BODY_SIZE,fill="GOLD")
        
    def snake(self):
        if self._snake != None:
            self.canvas.delete(self._snake)
        self.snakeX = self.snakeX   self.SNAKE_VELOCITY_X * self.BODY_SIZE
        self.snakeY = self.snakeY   self.SNAKE_VELOCITY_Y * self.BODY_SIZE
        self._snake = self.canvas.create_rectangle (self.snakeX,self.snakeY,self.snakeX self.BODY_SIZE,self.snakeY self.BODY_SIZE,fill="blue")

    def update(self):
        self.snake()
        

    def right_direction(self, event):
        self.SNAKE_VELOCITY_X = 1
        self.SNAKE_VELOCITY_Y = 0
        print(self.SNAKE_VELOCITY_X)
        self.update()
    def left_direction(self, event):
        self.SNAKE_VELOCITY_X = -1
        self.SNAKE_VELOCITY_Y = 0
        print(self.SNAKE_VELOCITY_X)
        self.update()
    def up_direction(self, event):
        self.SNAKE_VELOCITY_X = 0
        self.SNAKE_VELOCITY_Y = -1
        print(self.SNAKE_VELOCITY_Y)
        self.update()
    def down_direction(self, event):
        self.SNAKE_VELOCITY_X = 0
        self.SNAKE_VELOCITY_Y = 1
        print(self.SNAKE_VELOCITY_Y)
        self.update()


if __name__ == "__main__":
    run = game()
    run.mainloop()

hope it helps

  • Related