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