Reputation: 11
I am turning my board game into a simply animated python game and I was wondering how to create walls that will stop my player entity. It is a dungeon crawler style game. Perhaps it would be possible that, when the player comes in contact with the wall, it bounces the player back the same amount that it traveled. This being said, I'm not sure how to create a "threshold event," where, when an object comes in contact with another object, a specific event occurs.
This is the code so far. I am attempting to put solid/unbreachable walls into the canvas.
from tkinter import *
window = Tk()
window.title('Rook Map')
Width = 1200
Height = 800
c = Canvas(window, width=Width, height=Height, bg='midnight blue')
c.pack()
c_middle = [int(c['width']) / 2, int(c['height']) / 2]
window.resizable(False, False)
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
x_cordinate = int((screen_width/2) - (Width/2))
y_cordinate = int((screen_height/2) - (Height/2))
window.geometry("{}x{}+{}+{}".format(Width, Height, x_cordinate, y_cordinate))
player_width = 20
player_height = 20
player_id = c.create_rectangle(
c_middle[0] - (player_width / 2),
c_middle[1] - (player_height / 2),
c_middle[0] + (player_width / 2),
c_middle[1] + (player_height / 2),
fill='grey'
)
c.move(player_id, 0, 320)
player_move = 50
def player_movement(event):
if event.keysym == 'Up':
c.move(player_id, 0, -player_move)
elif event.keysym == 'Down':
c.move(player_id, 0, player_move)
elif event.keysym == 'Left':
c.move(player_id, -player_move, 0)
elif event.keysym == 'Right':
c.move(player_id, player_move, 0)
c.bind_all('<Key>', player_movement)
window.mainloop()
Upvotes: 0
Views: 89
Reputation: 5329
I have created a solution for you. It's a parametrizable frame (Wall) inside your canvas and the player object can move only inside this frame. I have written comments in the code. Perhaps there is much efficient solution but I hope my answer can help you.
Code:
from tkinter import *
window = Tk()
window.title("Rook Map")
Width = 1200
Height = 800
c = Canvas(window, width=Width, height=Height, bg="midnight blue")
c.pack()
c_middle = [int(c["width"]) / 2, int(c["height"]) / 2]
window.resizable(False, False)
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
x_cordinate = int((screen_width / 2) - (Width / 2))
y_cordinate = int((screen_height / 2) - (Height / 2))
window.geometry("{}x{}+{}+{}".format(Width, Height, x_cordinate, y_cordinate))
player_width = 20
player_height = 20
# Set the size of the wall (distance from frame)
wall_size = 100
player_id = c.create_rectangle(
c_middle[0] - (player_width / 2),
c_middle[1] - (player_height / 2),
c_middle[0] + (player_width / 2),
c_middle[1] + (player_height / 2),
fill="grey",
)
# Create the inside frame (Wall)
c.create_rectangle(wall_size, wall_size, Width - wall_size, Height - wall_size, outline="red")
# It's not really needed. Much efficient to start from the center of canvas.
# c.move(player_id, Height/2, Width/2)
player_move = 50
def player_movement(event):
"""
If the edge of player object plus the step size is greater/smaller, then the Wall position then the object
should step only for the edge of the Wall, and it's not possible to go forward.
"""
if event.keysym == "Up":
if c.coords(player_id)[1] - (player_height / 2) - wall_size - player_move < 0:
c.move(player_id, 0, -(c.coords(player_id)[1] - wall_size))
return
c.move(player_id, 0, -player_move)
elif event.keysym == "Down":
if c.coords(player_id)[1] + (player_height / 2) + wall_size + player_move > Height:
c.move(player_id, 0, Height - wall_size - (c.coords(player_id)[1] + player_height))
return
c.move(player_id, 0, player_move)
elif event.keysym == "Left":
if c.coords(player_id)[0] - (player_width / 2) - wall_size - player_move < 0:
c.move(player_id, -(c.coords(player_id)[0] - wall_size), 0)
return
c.move(player_id, -player_move, 0)
elif event.keysym == "Right":
if c.coords(player_id)[2] + (player_width / 2) + wall_size + player_move > Width:
c.move(player_id, Width - wall_size - (c.coords(player_id)[2]), 0)
return
c.move(player_id, player_move, 0)
c.bind_all("<Key>", player_movement)
window.mainloop()
GUI Window:
Upvotes: 0