How do I make the square move when pressing the "d" button (for example) on the keyboard?
from tkinter import *
root = Tk()
root.title('Snake')
root["width"] = 400
root["height"] = 400
field = Canvas(root)
x = 0
y = 0
def snake(x, y):
field.create_rectangle(10, 20, 30, 40)
field.grid(row=x, column=y)
x = 1
y = 1
return(x, y)
root.bind("<KeyPress>", snake(x=x, y=y))
root.mainloop()
CodePudding user response:
An easy way is to use event.char
. It returns the character of the button pressed. Then check which button it was and move it if it is w,a,s,d
-
from tkinter import *
root = Tk()
root.title('Snake')
root["width"] = 400
root["height"] = 400
field = Canvas(root)
rect = field.create_rectangle(10, 20, 30, 40)
field.grid(row=0, column=0)
def snake(event):
x = 0 # Default
y = 0
if event.char == 'w':
y = -10
if event.char == 'a':
x = -10
if event.char == 's':
y = 10
if event.char == 'd':
x = 10
field.move(rect,x,y)
root.bind("<Key>", snake)
root.mainloop()
CodePudding user response:
This is one way you can do it:
import tkinter as tk
from tkinter import Canvas
root = tk.Tk()
root.title('Snake')
root.geometry("450x450")
w = 400
h = 400
x = w//2
y = h//2
field = Canvas(root, width=w, heigh=h, bg="white")
field.pack(pady=5)
my_rectangle = field.create_rectangle(10, 20, 30, 40)
def left(event):
x = -10
y = 0
field.move(my_rectangle, x, y)
def right(event):
x = 10
y = 0
field.move(my_rectangle, x, y)
def up(event):
x = 0
y = -10
field.move(my_rectangle, x, y)
def down(event):
x = 0
y = 10
field.move(my_rectangle, x, y)
root.bind("<Left>", left)
root.bind("<Right>", right)
root.bind("<Up>", up)
root.bind("<Down>", down)
root.mainloop()
First create root
, and give geometry
to it, in this case it is 450x450
.
After that create variables that will store height
and width
, and coordinates x and y
. Then, create canvas
(field
) and in canvas
specify where canvas
will be located and geometry
of canvas
(and background color
). When canvas
is created, we create rectangle
. Functions left, right, up and down
will cover movement of rectangle
on canvas. field.move(my_rectangle, x, y)
- this line of code will move my_rectangle on canvas by x and y, or by left, right up or down, depends what is passed. root.bind("<Left>", left)
- bind left arrow key to left function
. Thats why event
is parameter
of fucntion
.
CodePudding user response:
An alternative method
from tkinter import *
root = Tk()
root.title('Snake')
root["width"] = 400
root["height"] = 400
field = Canvas(root)
SIZE = 50
class Snake:
def __init__(self,x,y,canvas):
self.x = x
self.y = y
self.canvas = canvas
self.direction = (SIZE,0)
def keypress(self,event):
if event.keysym == 'Right':
self.direction = (SIZE,0)
if event.keysym == 'Left':
self.direction = (-SIZE,0)
if event.keysym == 'Up':
self.direction = (0,-SIZE)
if event.keysym == 'Down':
self.direction = (0,SIZE)
def move(self):
self.x = self.direction[0]
self.y = self.direction[1]
def redraw(self):
self.canvas.delete('snake')
self.move()
self.canvas.create_rectangle(self.x,self.y,self.x SIZE,self.y SIZE,fill="green",tag="snake")
def update_screen():
snake.redraw()
root.after(1000,update_screen)
snake = Snake(0,0,field)
root.bind("<KeyPress>", lambda event: snake.keypress(event))
root.after_idle(update_screen)
field.grid()
root.mainloop()
This uses an object for the snake with methods to react to key presses and redraw the snake. This deletes the existing rectangles and draws new ones rather than moving (might prove more useful for showing the different snake segments).
Advantage of this method, is that the snake can be made to move regardless of whether the user has pressed a button or not. If no button has been pressed the snake will continue in the same direction.
Once you have a more complex game, I'd expect your Snake class to contain a list of the different snake segments that get drawn each time. When the snake moves over a fruit, a new segment is added. See below for a moving snake with multiple segments
from tkinter import *
root = Tk()
root.title('Snake')
root["width"] = 400
root["height"] = 400
field = Canvas(root)
SIZE = 10
class Snake:
def __init__(self,x,y,canvas):
self.x = x
self.y = y
self.canvas = canvas
self.direction = (SIZE,0)
self.segments = [(self.x,self.y)]
self.length = 5
def keypress(self,event):
if event.keysym == 'Right':
self.direction = (SIZE,0)
if event.keysym == 'Left':
self.direction = (-SIZE,0)
if event.keysym == 'Up':
self.direction = (0,-SIZE)
if event.keysym == 'Down':
self.direction = (0,SIZE)
def move(self):
self.x = self.direction[0]
self.y = self.direction[1]
new_segment = (self.segments[-1][0] self.direction[0],self.segments[-1][1] self.direction[1])
self.segments.append(new_segment)
if len(self.segments) > self.length:
self.segments.pop(0)
def redraw(self):
self.canvas.delete('snake')
self.move()
for seg in self.segments:
self.canvas.create_rectangle(seg[0],seg[1],seg[0] SIZE,seg[1] SIZE,fill="green",tag="snake")
#self.canvas.create_rectangle(self.x,self.y,self.x SIZE,self.y SIZE,fill="green",tag="snake")
def update_screen():
snake.redraw()
root.after(1000,update_screen)
snake = Snake(0,0,field)
root.bind("<KeyPress>", lambda event: snake.keypress(event))
root.after_idle(update_screen)
field.grid()
root.mainloop()