将六角棋子定位并捕捉到六角形网格
Position and snap hex pawns to a hexagonal grid
早上好
我有一个项目,我必须编写一个如下所示的游戏:
http://www.apppicker.com/apps/1055267582/1010-hex-fit--block-puzzle-mania-archanoid-pixduel-plus-saga-free-game?
而且我必须在没有 类 ("class") 的情况下编写游戏代码,因为我的学校不希望我:(.
现在,我已经完美地绘制了网格,但不幸的是,我似乎无法让我的棋子走上精确的六角形 "squares"n,因为它不是传统的网格。
有人可以帮我吗?
以及如何为数组分配值?
如果你对这个问题无能为力,你至少可以指导我解决其他问题吗?
(我对我的 post 的最后一个版本稍微修改了我的程序以使其更清晰)
提前感谢您的宝贵时间。
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()
我终于抽出时间看了你的代码...
1- 您需要阅读一些关于 canvas 项目的内容,以及如何访问、识别它们以及如何显示它们的状态和位置,这将帮助您决定如何构建您的应用程序。此时此刻,您主要是在尝试计算每个项目,而不是使用 canvas 方法。
2- 我添加了一个字典来保存网格六边形到它们中心位置的映射;关键是每个六边形的 canvas 项目编号。
3- 我使用 canvas.find_overlapping
识别鼠标悬停的六边形,并使用此 return 值查找瓷砖中心的中心字典,捕捉 'pion'到正确的位置。
大部分情况下它都能满足您的要求,但它可能有点脆弱:例如,2 个π介子可以相互叠加。它可能会在某些特殊情况下中断。我的建议是重写整个代码,对 Cases
使用 class,对 Damier
使用 class,对 Pion
使用 class ,以及 Pions
的 class,并为他们配备你需要的方法,让他们按照你想要的方式行事。
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()
早上好 我有一个项目,我必须编写一个如下所示的游戏: http://www.apppicker.com/apps/1055267582/1010-hex-fit--block-puzzle-mania-archanoid-pixduel-plus-saga-free-game? 而且我必须在没有 类 ("class") 的情况下编写游戏代码,因为我的学校不希望我:(.
现在,我已经完美地绘制了网格,但不幸的是,我似乎无法让我的棋子走上精确的六角形 "squares"n,因为它不是传统的网格。 有人可以帮我吗? 以及如何为数组分配值?
如果你对这个问题无能为力,你至少可以指导我解决其他问题吗?
(我对我的 post 的最后一个版本稍微修改了我的程序以使其更清晰)
提前感谢您的宝贵时间。
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()
我终于抽出时间看了你的代码...
1- 您需要阅读一些关于 canvas 项目的内容,以及如何访问、识别它们以及如何显示它们的状态和位置,这将帮助您决定如何构建您的应用程序。此时此刻,您主要是在尝试计算每个项目,而不是使用 canvas 方法。
2- 我添加了一个字典来保存网格六边形到它们中心位置的映射;关键是每个六边形的 canvas 项目编号。
3- 我使用 canvas.find_overlapping
识别鼠标悬停的六边形,并使用此 return 值查找瓷砖中心的中心字典,捕捉 'pion'到正确的位置。
大部分情况下它都能满足您的要求,但它可能有点脆弱:例如,2 个π介子可以相互叠加。它可能会在某些特殊情况下中断。我的建议是重写整个代码,对 Cases
使用 class,对 Damier
使用 class,对 Pion
使用 class ,以及 Pions
的 class,并为他们配备你需要的方法,让他们按照你想要的方式行事。
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()