J'ai fait une carte hexadécimale avec Python

Je fais un jeu avec la bibliothèque python "pygame" dans le cadre de mes études à l'école. Puisqu'il s'agit d'un jeu de simulation, j'ai essayé de créer une carte hexadécimale commune, mais le code qui peut être utilisé ne frappe pas facilement. Après tout, j'ai décidé de le créer à partir de zéro. C'était ... mais j'ai demandé à l'utilisateur de Qiita shiracamus de réécrire le code enfantin! Merci beaucoup.

Site référencé http://www.redblobgames.com/grids/hexagons/ http://qiita.com/kapipara-games/items/7978a7b51a47df8ace38

environnement

code

my_hexmap.py


#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import pygame
from pygame.locals import *

# colors (Red, Green, Blue)
BLACK = (0, 0, 0)
ORANGE = (255, 120, 0)
YELLOW = (255, 255, 0)
CYAN = (0, 255, 255)


class Hexagon:
    """
    Hexagon index/pixel coordinate converter
    There is no limit to the number of hexagon.

       x: 0/4 1/4 3/4 4/4
      y:    |  |   |  |
    0/2--   v0 _____ v1
              /     \
    1/2--    /       \
          v5 \       / v2
    2/2--     \_____/
             v4       v3
    """

    VERTEXES = (1, 0), (3, 0), (4, 1), (3, 2), (1, 2), (0, 1)

    def __init__(self, size):
        self.SIZE = size
        self.HALF = size * 1 // 2
        self.QUARTER = size * 1 // 4
        self.WIDTH = size * 3 // 4
        self.HEIGHT = size

    def index_at(self, pixel_x, pixel_y):
        """get the index coordinae at the pixel coordinate"""
        x = pixel_x // self.WIDTH
        x0 = pixel_x % self.WIDTH
        if x0 < self.QUARTER:  # overlap area
            y0 = (pixel_y - (x % 2) * self.HALF) % self.HEIGHT
            if y0 >= self.HALF:  # lower half
                y0 = self.SIZE - y0
            is_leftarea = x0 < self.QUARTER - y0 * self.QUARTER // self.HALF
            if is_leftarea:
                x -= 1
        y = (pixel_y - (x % 2) * self.HALF) // self.HEIGHT
        return x, y

    def origin_of(self, x, y):
        return x * self.WIDTH, y * self.HEIGHT + (x % 2) * self.HALF

    def vertexes_of(self, x, y):
        """get vertex coodinates of the index coordinate"""
        origin_x, origin_y = self.origin_of(x, y)
        return [(origin_x + vx * self.QUARTER, origin_y + vy * self.HALF)
                for vx, vy in self.VERTEXES]


class HexMap:
    """
    Hexagon map
     ___ x,y ___
    /0,0\___/2,0\
    \___/1,0\___/
    /0,1\___/2,1\
    \___/1,1\___/
    /0,2\___/2,2\
    \___/   \___/
    """

    def __init__(self, columns, rows, hexagon_size):
        self.COLUMNS = columns
        self.ROWS = rows
        self.hexagon = Hexagon(hexagon_size)
        width, height = self.hexagon.origin_of(self.COLUMNS, self.ROWS)
        width += self.hexagon.QUARTER
        self.size = width + 1, height + 1
        self.clear_clicked()

    def clear_clicked(self):
        self.clicked = [[False] * self.ROWS for x in range(self.COLUMNS)]

    def click_at(self, pixel_x, pixel_y):
        x, y = self.hexagon.index_at(pixel_x, pixel_y)
        if 0 <= x < self.COLUMNS and 0 <= y < self.ROWS:
            self.clicked[x][y] = not self.clicked[x][y]

    def is_clicked_on(self, x, y):
        return (0 <= x < self.COLUMNS and 0 <= y < self.ROWS and
                self.clicked[x][y])

    def hexagons(self):
        for x in range(self.COLUMNS):
            for y in range(self.ROWS - (x % 2)):
                yield self.hexagon, x, y


class HexCanvas:
    LINE_WIDTH = 1
    CURSOR_SIZE = 5

    def __init__(self, hexmap):
        self.hexmap = hexmap
        self.canvas = pygame.display.set_mode(hexmap.size)
        self.font = pygame.font.SysFont(None, 17)
        self.cursor = None

    def cursor_at(self, pixel_x, pixel_y):
        self.cursor = pixel_x, pixel_y

    def draw(self):
        canvas = self.canvas
        canvas.fill(BLACK)
        hexmap = self.hexmap
        for hexagon, x, y in hexmap.hexagons():
            vertexes = hexagon.vertexes_of(x, y)
            #Remplissage hexagonal
            color = ORANGE if hexmap.is_clicked_on(x, y) else YELLOW
            pygame.draw.polygon(canvas, color, vertexes)
            #Dessin de bordure hexagonale
            for v1, v2 in zip(vertexes, vertexes[1:] + vertexes[:1]):
                pygame.draw.line(canvas, BLACK, v1, v2, self.LINE_WIDTH)
            #Dessin d'étiquette de coordonnées
            tag = "{0}, {1}".format(x, y)
            text = self.font.render(tag, True, CYAN)
            origin_x, origin_y = hexagon.origin_of(x, y)
            text_area = text.get_rect(center=(origin_x + hexagon.HALF,
                                                  origin_y + hexagon.HALF))
            canvas.blit(text, text_area)
        #Dessin du curseur
        if self.cursor:
            pygame.draw.circle(canvas, BLACK, self.cursor, self.CURSOR_SIZE, 0)


def main():
    pygame.init()
    FPSCLOCK = pygame.time.Clock()

    hexmap = HexMap(columns=20, rows=15, hexagon_size=50)
    canvas = HexCanvas(hexmap)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT or event.type == KEYDOWN and event.key == K_q:
                pygame.quit()
                return
            if event.type == MOUSEMOTION:
                x, y = pygame.mouse.get_pos()
                canvas.cursor_at(x, y)
            elif event.type == MOUSEBUTTONDOWN:
                x, y = pygame.mouse.get_pos()
                hexmap.click_at(x, y)

        canvas.draw()
        pygame.display.update()
        FPSCLOCK.tick(30)

if __name__ == '__main__':
    main()

Commentaire

Image de l'exécution de ce qui suit dans ubuntu hexview.png

Recommended Posts

J'ai fait une carte hexadécimale avec Python
J'ai fait une loterie avec Python.
J'ai créé un démon avec Python
J'ai fait un compteur de caractères avec Python
J'ai fait un jeu rogue-like avec Python
J'ai fait un simple blackjack avec Python
J'ai créé un fichier de configuration avec Python
J'ai fait un simulateur de neurones avec Python
J'ai fait une prévision météo de type bot avec Python.
J'ai fait un blackjack avec du python!
J'ai fait un texte Python
J'ai fait un blackjack avec Python.
J'ai créé wordcloud avec Python.
J'ai fait un jeu de cueillette avec Python
Made Mattermost Bot avec Python (+ Flask)
J'ai fait un Twitter BOT avec GAE (python) (avec une référence)
J'ai fait un jeu d'éclairage de sapin de Noël avec Python
J'ai créé un environnement Python3 sur Ubuntu avec direnv.
J'ai essayé de faire LINE BOT avec Python et Heroku
J'ai fait un jeu de frappe simple avec tkinter de Python
J'ai fait un jeu de puzzle (comme) avec Tkinter of Python
J'ai fait un programme de gestion de la paie en Python!
J'ai dessiné une carte thermique avec Seaborn [Python]
Carte des informations de location sur une carte avec python
J'ai essayé un langage fonctionnel avec Python
Ce que j'ai fait avec les tableaux Python
J'ai fait un jeu de vie avec Numpy
J'ai fait un générateur Hanko avec GAN
Essayez de dessiner une carte avec python + cartopy 0.18.0
Après avoir étudié Python3, j'ai créé un Slackbot
J'ai fait une application WEB avec Django
J'ai fait un circuit simple avec Python (AND, OR, NOR, etc.)
J'ai fait un package qui peut comparer des analyseurs morphologiques avec Python
J'ai créé un formulaire de tweet Nyanko avec Python, Flask et Heroku
J'ai créé beaucoup de fichiers pour la connexion RDP avec Python
[Python] J'ai créé une visionneuse d'images avec une fonction de tri simple.
J'ai fait un shuffle qui peut être réinitialisé (inversé) avec Python
J'ai créé un chat-holdem de serveur de jeu de poker en utilisant websocket avec python
〇✕ J'ai fait un jeu
J'ai fait un robot de remplacement de tampon avec une ligne
J'ai créé un fichier de dictionnaire python pour Neocomplete
Je veux faire un jeu avec Python
Procédure de création d'un LineBot réalisé avec Python
Folium: Visualisez les données sur une carte avec Python
J'ai fait un simple portefeuille de Bitcoin avec pycoin
J'ai fait un graphique de nombres aléatoires avec Numpy
Je veux écrire dans un fichier avec Python
Visualiser grib2 sur une carte avec python (matplotlib)
J'ai créé un programme cryptographique César en Python.
Création du wrapper d'API Qiita Python "qiipy"
J'ai créé un outil pour parcourir automatiquement plusieurs sites avec Selenium (Python)
J'ai créé un plug-in "EZPrinter" qui génère facilement des PDF cartographiques avec QGIS.
J'ai créé un outil qui facilite un peu la décompression avec CLI (Python3)
J'ai fait un module PyNanaco qui peut charger des crédits nanaco avec python
[AWS] J'ai créé un BOT de rappel avec LINE WORKS
J'ai essayé fp-growth avec python