Ich mache ein Spiel mit der Python-Bibliothek "Pygame" als Teil meines Studiums in der Schule. Da es sich um ein Simulationsspiel handelt, habe ich versucht, eine gemeinsame Hex-Karte zu erstellen, aber der Code, der verwendet werden kann, ist nicht leicht zu treffen. Immerhin habe ich beschlossen, es von Grund auf neu zu machen. Es war ... aber ich bat den Qiita-Benutzer shiracamus, den kindischen Code neu zu schreiben! Vielen Dank.
Referenzierte Site http://www.redblobgames.com/grids/hexagons/ http://qiita.com/kapipara-games/items/7978a7b51a47df8ace38
Umgebung
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)
#Sechseckfüllung
color = ORANGE if hexmap.is_clicked_on(x, y) else YELLOW
pygame.draw.polygon(canvas, color, vertexes)
#Sechseckige Randzeichnung
for v1, v2 in zip(vertexes, vertexes[1:] + vertexes[:1]):
pygame.draw.line(canvas, BLACK, v1, v2, self.LINE_WIDTH)
#Koordinaten-Tag-Zeichnung
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)
#Cursorzeichnung
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()
Bild des Ausführens der folgenden in Ubuntu
Recommended Posts