Good morning I have a project where I must code a game that looks like this: http://www.apppicker.com/apps/1055267582/1010-hex-fit--block-puzzle-mania-archanoid-pixduel-plus-saga-free-game? And I must code the game without classes ("class"), because my school doesn't want me to :(.
Now, I have already drawn the grid perfectly, but unfortunatly I can't seem to make my pawns go on the exact hexagonal "squares"n because it's not a traditional grid. Can someone help me on that? And how can I assign an array with values to it?
And if you can't do anything with this issue can you at least guide me on something else?
(I changed my program a bit from the last version of my post to make it clearer)
Thank in advance for your time.
from tkinter import *
from random import choice #for colors
beige = (255,228,196)
def dessus(evt): #mouse on hexagonal pawn
forme = "arrow"
if x_pion - 50 < evt.x < x_pion + 50 and y_pion - 100 < evt.y < y_pion + 100:
forme = "fleur"
# print(x_pion , y_pion)
can.config(cursor = forme)
def glisser(evt): #mouse dragging the hexagonal pawn
global x, y
if x == -1 :
if x_pion - 50 < evt.x < x_pion + 50 and y_pion - 100 < evt.y < y_pion + 100:
x, y = evt.x, evt.y
else :
delta_x, delta_y = evt.x - x, evt.y - y
can.coords(pion, x_pion + delta_x, y_pion + delta_y)
def coord_case(x_pos,y_pos):
# return hexagonal coordinates spot from the game board
coord_x = x_pos//c
coord_y = y_pos//c
print(x_pos, y_pos)
return coord_x, coord_y
def coord_image(x_pos,y_pos):
# return the coordinates of the image
x = c * x_pos + dc
y = c * y_pos + dc
return x, y
def deposer(evt): #put/release the image (hexagonal pawn) on the screen
global x_pion, y_pion, x
if x != -1:
x_pion, y_pion = x_pion + evt.x - x, y_pion + evt.y - y
x =- 1
def hexagone(origine, c): #draws the hexagones
seg = c / 4
x, y = origine[0], origine[1]
# hexagone
can.create_polygon(x,y+seg, x+2*seg,y, x+c,y+seg, x+c,y+3*seg ,x+2*seg,y+c ,x,y+3*seg, x,y+seg,
outline='black', width=1, fill="beige")
def ligne_d_hexagones(x, y, c, n): #draws the hexagonal lines
i = 0
seg = c / 4
while i < n:
hexagone((x + 2, y + 2), c) # +2 :
i += 1
x += 4.25 * seg
def damier(c, nl, nc):
#finally draws everything (the hexagonal game board)
x = 2.08 # commencera la ligne
y = 0.02
i = 1
for i in range(nc-1):
ligne_d_hexagones(x * c, y * c, c, nc // 2)
i+=1
y = y + 0.79
if i < 5:
nc = nc + 2
x = x - 0.52
if i == 5:
nc = nc - 2
x = x + 0.52
if i > 5:
nc = nc - 2
x = x + 0.52
c = 70 # size of the hexagones from the board
nl = 10 # number of lines
nc = 10 # number of columns (this valuer will change)
dc = c//2
fen = Tk()
fen.title("HEX1010")
can = Canvas(fen, width=1000, height=700)
can.pack(side=TOP)
damier(c, nl, nc)
can.grid()
x, y = -1, -1
f_pion = PhotoImage(file="HEX.png")
x_pion, y_pion = 600, 600
pion = can.create_image(x_pion, y_pion,image=f_pion)
x, y, num = -1, -1, -1
can.bind('<B1-Motion>',glisser)
can.bind('<ButtonRelease-1>',deposer)
can.bind('<Motion>',dessus)
fen.mainloop()
I eventually found a bit of time to look at your code...
1- you need to read a little bit about canvas items and how they can be accessed, identified, and made to reveal their state and position, that will help you decide how to structure your app. At this moment, you were mostly trying to account for each item, instead of using the canvas methods.
2- I added a dictionary to hold a mapping of the grid hexagons to their center positions; the key is the canvas item number of each hexagon.
3- I identify the hexagon the mouse is over using canvas.find_overlapping
, and use this return value to look up into the centers dictionary of tile centers, to snap the 'pion' to the correct position.
Mostly it does what you wanted, but it is probably a bit brittle: for instance, 2 pions can be placed on top of each other. It may break on some special cases. My suggestion is to rewrite the entire code using a class for the Cases
, a class for the Damier
, a class for the Pion
, and a class for the Pions
, and equip them with the methods you need to let them behave the way you want.
from tkinter import *
beige = (255,228,196)
def selectioner(evt):
global x, y, num
x, y = evt.x, evt.y
x0, y0, x1, y1 = x - 3, y - 3, x + 3, y + 3
for item in can.find_overlapping(x0, y0, x1, y1):
if item in pion:
num = item
x, y = can.coords(num)
break
def glisser(evt): #mouse dragging the hexagonal pawn
global x, y, num
if num == -1 :
pass
else :
delta_x, delta_y = evt.x - x, evt.y - y
can.coords(num, x + delta_x, y + delta_y)
def deposer(evt): #put/release the image (hexagonal pawn) on the screen
global num
if num == -1:
return
x0, y0, x1, y1 = evt.x - 3, evt.y - 3, evt.x + 3, evt.y + 3
snap = None
for item in can.find_overlapping(x0, y0, x1, y1):
try:
snap = centers[item]
break
except KeyError:
pass
if num != -1 and snap is not None:
xs, ys = snap
can.coords(num, xs, ys)
num = -1
def hexagone(origine, c): #draws the hexagones
seg = c / 4
x, y = origine[0], origine[1]
center = center_x, center_y = (x + x+c) / 2, (y+seg + y+3*seg) / 2
p = can.create_polygon(x, y+seg, x+2*seg, y, x+c, y+seg, x+c, y+3*seg , x+2*seg, y+c , x,y+3*seg, x,y+seg,
outline='black', width=1, fill="beige")
# can.create_oval(center_x-2, center_y-2, center_x+2, center_y+2)
centers[p] = center
def ligne_d_hexagones(x, y, c, n): #draws the hexagonal lines
i = 0
seg = c / 4
while i < n:
hexagone((x + 2, y + 2), c) # +2 :
i += 1
x += 4.25 * seg
def damier(c, nl, nc):
# finally draws everything (the hexagonal game board)
x = 2.08 # commencera la ligne
y = 0.02
i = 1
for i in range(nc-1):
ligne_d_hexagones(x * c, y * c, c, nc // 2)
i+=1
y = y + 0.79
if i < 5:
nc = nc + 2
x = x - 0.52
if i == 5:
nc = nc - 2
x = x + 0.52
if i > 5:
nc = nc - 2
x = x + 0.52
centers = {}
c = 70 # size of the hexagones from the board
nl = 10 # number of lines
nc = 10 # number of columns (this valuer will change)
dc = c//2
fen = Tk()
fen.title("HEX1010")
can = Canvas(fen, width=1000, height=700)
can.pack(side=TOP)
damier(c, nl, nc)
can.grid()
pion, x_pion, y_pion = [], [], []
f_pion = PhotoImage(file="HEX.png")
for i in range(3):
idx, idy = 300*(i+1), 300
x_pion.append(idx)
y_pion.append(idy)
pion.append(can.create_image(idx,idy,image=f_pion))
x, y, num = -1, -1, -1
can.bind('<Button-1>', selectioner)
can.bind('<B1-Motion>', glisser)
can.bind('<ButtonRelease-1>', deposer)
fen.mainloop()