【问题标题】:Position and snap hex pawns to a hexagonal grid将六角棋子定位并捕捉到六角形网格
【发布时间】:2019-02-08 19:41:17
【问题描述】:

早上好 我有一个项目,我必须编写一个看起来像这样的游戏: http://www.apppicker.com/apps/1055267582/1010-hex-fit--block-puzzle-mania-archanoid-pixduel-plus-saga-free-game? 而且我必须编写没有课程(“课程”)的游戏,因为我的学校不希望我这样做:(。

现在,我已经完美地绘制了网格,但不幸的是,我似乎无法让我的棋子走在精确的六边形“正方形”上,因为它不是传统的网格。 有人可以帮我吗? 以及如何为数组分配值?

如果您对此问题无能为力,至少可以指导我做其他事情吗?

(我在帖子的最后一个版本中稍微更改了我的程序以使其更清晰)

提前感谢您的宝贵时间。

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()

【问题讨论】:

  • 您应该提供指向HEX.png的链接
  • @ReblochonMasque 您好,很抱歉给您带来不便。在这里,现在可以访问 HEX.png。非常感谢您的回复。
  • @ReblochonMasque 我也稍微改变了我的程序,只有一个棋子而不是 3 个......它更简单

标签: grid-layout hexagonal-tiles


【解决方案1】:

我终于找到了一些时间来查看您的代码...

1- 您需要阅读一些有关画布项目以及如何访问、识别和制作它们以显示它们的状态和位置的信息,这将帮助您决定如何构建您的应用程序。此时,您主要是在尝试计算每个项目,而不是使用画布方法。

2- 我添加了一个字典来保存网格六边形到它们的中心位置的映射;关键是每个六边形的画布项目编号。

3- 我使用canvas.find_overlapping 识别鼠标所在的六边形,并使用此返回值查找图块中心的中心字典,以将“pion”捕捉到正确的位置。

大多数情况下它会做你想做的事,但它可能有点脆弱:例如,可以将 2 个π介子放在彼此的顶部。它可能会在某些特殊情况下中断。我的建议是使用Cases 的类、Damier 的类、Pion 的类和Pions 的类来重写整个代码,并为它们配备您需要的方法让他们按照你想要的方式行事。

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()

【讨论】:

  • 非常感谢您,您的工作非常出色!对于课程,我会稍微看一下,但总的来说,谢谢,我会尽快仔细看看代码! (如果我还有更多问题,可以问你吗?如果这不打扰你?)
  • 但是数组呢?链接到瓷砖?没有π介子时为0,有π时为1?它可以防止介子共享同一个地方....
  • 是的,这是可能的;您还可以使用centers 字典来存储单元格是否被占用。
  • 我拒绝了您的修改,这不是本网站的运作方式。
  • 正确的作业方式是引用和参考您使用的外部资源,以及您获得的帮助;这也是这些东西在“现实生活”中的运作方式;它向您的老师表明,您知道给予学分是游戏的玩法,并且会将手电筒照亮那些可能使用相同代码但没有引用的人。此外,您的老师不是傻瓜,他们知道该站点,并且知道如何进行搜索。大多数大学还使用抄袭检测算法来判断一段代码是否受到另一段代码的“启发”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多