Anda di halaman 1dari 9

# HEX METRICS:

# -
# / \ | +-------+

# / hex \ | / \

# / dir \ _ | / \
# | 4 5 | | | / \
# | \ / | |s | b \ /
# | 3-----0 | | | \ /
# | / \ | _ | \ /
# \ 2 1 / | | +-------+
# \ / |h |
# \ / _ |
# -
# |------|
# r
# |-----------|
# a
import pygame
from pygame.locals import *
from sys import exit
from math import *
from random import randint
RELATIVE_SIZE = 15
MAP_WIDTH = 40
MAP_HEIGHT = 30
POST_PROCESS_PASSES = 4
button_zoom_in_filename = 'hex_zoom_in_v2.png'
button_zoom_out_filename = 'hex_zoom_out_v2.png'
button_randomize_map_filename = 'generateWorld.png'
button_area = (52, 52)
icon_size = (48, 48)
control_panel_offset = (8, 8)
button_offset = 10
map_panel_size = (1212, 835)
map_panel_loc = (0, 0)
info_panel_size = (1280, 125)
info_panel_loc = (0,835)
control_panel_size = (68, 835)
control_panel_loc = (1212, 0)
scroll_x = 0
scroll_y = 0
SCROLL_AMOUNT = 5
HEX_S = 2.0 / 3.0 # length of a side of a hex; s==0.6666667
HEX_S *= RELATIVE_SIZE
HEX_H = sin(radians(30.0)) * HEX_S # h==0.33333334
HEX_R = cos(radians(30.0)) * HEX_S # r==0.57735026
HEX_B = HEX_S + 2 * HEX_H # height of the entire hex; b==1.3333334
HEX_B2 = HEX_B / 2.0 # half the height of the entire hex
HEX_A = 2 * HEX_R # width of the entire hex; a==1.1547005
HEX_WIDTH = HEX_A
HEX_HEIGHT = HEX_S + HEX_H # This is equal to RELATIVE_SIZE
HEX_SLOPE = HEX_H / HEX_R
HEX_EAST = 0
HEX_SOUTHEAST = 1
HEX_SOUTHWEST = 2
HEX_WEST = 3
HEX_NORTHWEST = 4
HEX_NORTHEAST = 5
pygame.init()
pygame.display.list_modes()
screen = pygame.display.set_mode((1280, 960), 0, 32)
map_panel = screen.subsurface(map_panel_loc, map_panel_size)
info_panel = screen.subsurface(info_panel_loc, info_panel_size)
control_panel = screen.subsurface(control_panel_loc, control_panel_size)
button_zoom_in = pygame.image.load(button_zoom_in_filename)
button_zoom_out = pygame.image.load(button_zoom_out_filename)
button_randomize_map = pygame.image.load(button_randomize_map_filename)
new_dim = 3*RELATIVE_SIZE/4
color_blue = (0,0,255)
color_green = (0,127,0)
color_white = (245,245,245)
color_black = (0,0,0)
color_red = (255, 0, 0)
color_cyan = (0, 255, 255)
color_steel_blue = (70, 130, 180)
color_orange = (255, 127, 80)
color_dodger_blue = (16, 78, 139)
color_dim_gray = (105, 105, 105)
color_gray_77 = (77, 77, 77)
color_gray_196 = (196, 196, 196)
color_yellow_4 = (139, 139, 0)
color_dark_goldenrod = (139, 101, 8)
color_navajo_white4 = (139, 121, 94)
color_burly_wood4 = (139, 115, 85)
color_chocolate_brown = (139, 69, 19)
color_sienna = (139, 71, 38)
color_bisque3 = (205, 183, 158)
color_bisque4 = (139, 125, 107)
color_cornsilk4 = (139, 136, 120)
color_dark_orchid = (104, 34, 139)
color_indigo = (75, 0, 130)
font = pygame.font.SysFont("accidental presidency", 18)
font_height = font.get_linesize()
small_font = pygame.font.SysFont("accidental presidency", 10)
small_font_height = small_font.get_linesize()
large_font = pygame.font.SysFont("accidental presidency", 24)
large_font_height = large_font.get_linesize()
event_text = "MOUSE COORDS:"
hex_coord_text = "HEX COORDS:"
show_debug_text = False
show_hex_coords = False
fullscreen = False
show_hex_lines = False
#terrain_types
GRASS = 0
WATER = 1
def getNeighborHexes(x, y):
neighboringHexes = []
neighboringHexes.append((x-1, y))
neighboringHexes.append((x, y-1))
neighboringHexes.append((x, y+1))
neighboringHexes.append((x+1, y-1))
neighboringHexes.append((x+1, y))
neighboringHexes.append((x+1, y+1))
return neighboringHexes
# -- getNeighborHexes --
def create_random_map(width, height):
random_map = [ ]
#initialize map with water hexes
for h in xrange(height):
random_row = [ ]
for w in xrange(width):
random_row.append(WATER)
random_map.append(random_row)
#add random seeds
#num_seeds = randint(15, 25)
num_seeds = trunc(width * height * 0.004)
for s in xrange(num_seeds):
rand_x = randint(8, width - 8)
rand_y = randint(8, height - 8)
random_map[rand_y][rand_x] = GRASS
building = True
cur_x = rand_x
cur_y = rand_y
limit = 100
while building:
dir = randint(0, 3)
if dir == 0: #N
if cur_y > 1:
cur_y -= 1
elif dir == 1: #S
if cur_y < height - 2:
cur_y += 1
elif dir == 2: #W
if cur_x > 1:
cur_x -= 1
elif dir == 3: #E
if cur_x < width - 2:
cur_x += 1
#print("cur: " + str(cur_x) + "," + str(cur_y))
random_map[cur_y][cur_x] = GRASS

roll = randint(1, 100)
if roll > 65:
limit = limit - 1
if limit == 0:
building = False
return random_map
# -- end create_random_map --
game_map = create_random_map(MAP_WIDTH, MAP_HEIGHT)
def post_process_map(random_map):
# postprocess random map
# fill in some small lakes
for h in xrange(len(random_map)-1):
if h > 0:
row = random_map[h]
for w in xrange(len(row)-1):
if w > 0:
if random_map[h][w] == WATER:
# check if neighbors are land
neighbors = getNeighborHexes(w, h)
check = 0
for i in xrange(len(neighbors)):
#check if valid coords
coord = neighbors.pop()
if coord[0] >= 0 and coord[0] < MAP_WIDTH and coord[
1] >= 0 and coord[1] < MAP_HEIGHT:
if random_map[coord[1]][coord[0]] == GRASS:
check += 1
p = randint(1, 100)
if check == 6 and p <= 95:
random_map[h][w] = GRASS
elif check == 5 and p <= 75:
random_map[h][w] = GRASS
elif check == 4 and p <= 55:
random_map[h][w] = GRASS
elif check == 3 and p <= 35:
random_map[h][w] = GRASS
elif check == 2 and p <= 15:
random_map[h][w] = GRASS
elif check == 1 and p <= 5:
random_map[h][w] = GRASS
return random_map
# -- end post_process_map --
for i in xrange(POST_PROCESS_PASSES):
game_map = post_process_map(game_map)
def draw_map_image(game_map):
width = ceil(len(game_map[0]) * HEX_WIDTH + HEX_R) + 1
height = ceil(len(game_map) * HEX_HEIGHT + HEX_H) + 1
map_surface = pygame.Surface((width, height))
map_surface.fill(color_dodger_blue)
for y in xrange(len(game_map)):
yf = y*RELATIVE_SIZE
if (y % 2 > 0):
is_row_odd = True
else:
is_row_odd = False

for x in xrange(len(game_map[0])):
xa = x*HEX_A
if is_row_odd:
xa += HEX_R

p1 = (xa+HEX_R, yf)
p2 = (xa, yf+HEX_H)
p3 = (xa, yf+1*RELATIVE_SIZE)
p4 = (xa+HEX_R, yf+HEX_B)
p5 = (xa+HEX_A, yf+1*RELATIVE_SIZE)
p6 = (xa+HEX_A, yf+HEX_H)
if game_map[y][x] == WATER:
color = color_steel_blue
elif game_map[y][x] == GRASS:
color = color_green
else: # dirt
color = color_chocolate_brown
pygame.draw.polygon(map_surface, color, (p1, p2, p3, p4, p5, p6))
if show_hex_lines:
pygame.draw.polygon(map_surface, color_gray_77, (p1, p2, p3, p4,
p5, p6), 1)
if show_hex_coords:
hex_coords_text = str(x) + "," + str(y)
hex_center = (xa+HEX_R, yf+HEX_S)
size = small_font.size(hex_coords_text)
map_surface.blit(small_font.render(hex_coords_text, True, color_
gray_196), (hex_center[0] - size[0]/2, hex_center[1] - size[1]/2))
return map_surface
# -- end draw_map_image --
map_image = draw_map_image(game_map)
def calculate_hex_sizes(new_size):
global RELATIVE_SIZE
global HEX_S
global HEX_H
global HEX_R
global HEX_B
global HEX_B2
global HEX_A
global HEX_WIDTH
global HEX_HEIGHT
global HEX_SLOPE
global new_dim

RELATIVE_SIZE = new_size
HEX_S = 2.0 / 3.0 # length of a side of a hex; s==0.6666667
HEX_S *= RELATIVE_SIZE
HEX_H = sin(radians(30.0)) * HEX_S # h==0.33333334
HEX_R = cos(radians(30.0)) * HEX_S # r==0.57735026
HEX_B = HEX_S + 2 * HEX_H # height of the entire hex; b==1.3333334
HEX_B2 = HEX_B / 2.0 # half the height of the entire hex
HEX_A = 2 * HEX_R # width of the entire hex; a==1.1547005
HEX_WIDTH = HEX_A
HEX_HEIGHT = HEX_S + HEX_H # This is equal to RELATIVE_SIZE
HEX_SLOPE = HEX_H / HEX_R
new_dim = 3*RELATIVE_SIZE/4
# -- end calculate_hex_sizes --
# draw the GUI elements
control_panel.fill(color_dim_gray)
info_panel.fill(color_dim_gray)
pygame.draw.line(screen, color_gray_77, (map_panel_size[0], 0), (map_panel_size[
0], map_panel_size[1]), 3)
pygame.draw.line(screen, color_gray_77, (0, map_panel_size[1]), (map_panel_size[
0], map_panel_size[1]), 3)
pygame.draw.rect(control_panel, color_gray_196, Rect(control_panel_offset, butto
n_area), 1)
pygame.draw.rect(control_panel, color_gray_196, Rect((control_panel_offset[0], c
ontrol_panel_offset[1] + button_area[1] + button_offset), button_area), 1)
pygame.draw.rect(control_panel, color_gray_196, Rect((control_panel_offset[0], (
control_panel_offset[1] + button_area[1])*2 + button_offset), button_area), 1)
control_panel.blit(button_zoom_in, (button_offset, button_offset))
control_panel.blit(button_zoom_out, (button_offset, button_offset*2 + button_are
a[1]))
control_panel.blit(button_randomize_map, (button_offset, button_offset*3 + butto
n_area[1]*2))
running = True
while running:
map_panel.fill(color_white)
# control_panel.fill(color_dim_gray)
# info_panel.fill(color_dim_gray)
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
if event.key == K_F1:
show_debug_text = not show_debug_text
if event.key == K_F2:
show_hex_coords = not show_hex_coords
map_image = draw_map_image(game_map)
if event.key == K_F3:
show_hex_lines = not show_hex_lines
map_image = draw_map_image(game_map)
if event.key == K_F4:
fullscreen = not fullscreen
if fullscreen:
screen = pygame.display.set_mode((1440, 900), FULLSCREEN, 32
)
else:
screen = pygame.display.set_mode((1280, 960), RESIZABLE, 32)
if event.type == MOUSEMOTION:
event_text = "MOUSE COORDS:" + str(event.pos)
if event.type == MOUSEBUTTONDOWN:
#print event.button
x, y = pygame.mouse.get_pos()
if (y >= info_panel_loc[1]): # mouse clicked in info panel at botto
m of screen
print "info panel:", x, y
elif (x >= control_panel_loc[0]): # mouse clicked in control panel o
n right of screen
x -= control_panel_loc[0]
# check if mouse clicked in a button
if (x > button_offset) & (x < button_offset + button_area[0]):
# figure out which button clicked
if (y > button_offset) & (y < button_offset + button_area[1]
):
# first button clicked
if (RELATIVE_SIZE < 100):
calculate_hex_sizes(RELATIVE_SIZE+5)
map_image = draw_map_image(game_map)
elif (y > control_panel_offset[1] + button_area[1] + button_
offset) & (y < control_panel_offset[1] + button_area[1]*2 + button_offset):
if (RELATIVE_SIZE > 5):
calculate_hex_sizes(RELATIVE_SIZE-5)
map_image = draw_map_image(game_map)
elif (y > (control_panel_offset[1] + button_area[1])*2 + but
ton_offset) & (y < control_panel_offset[1] + button_area[1]*3 + button_offset*2)
:
# randomize map button pressed
game_map = create_random_map(MAP_WIDTH, MAP_HEIGHT)
for i in xrange(POST_PROCESS_PASSES):
game_map = post_process_map(game_map)
map_image = draw_map_image(game_map)
else: # mouse clicked in main map panel
if event.button == 4: # scroll wheel up
if (RELATIVE_SIZE < 100):
calculate_hex_sizes(RELATIVE_SIZE+5)
map_image = draw_map_image(game_map)
elif event.button == 5: # scroll wheel down
if (RELATIVE_SIZE > 5):
calculate_hex_sizes(RELATIVE_SIZE-5)
map_image = draw_map_image(game_map)

elif event.button == 1: # left click
guess_x = trunc((x + scroll_x) / HEX_WIDTH) # same as secti
on_x
guess_y = trunc((y + scroll_y) / HEX_HEIGHT) # same as secti
on_y
section_pixel_x = trunc((x + scroll_x) % HEX_WIDTH)
section_pixel_y = trunc((y + scroll_y) % HEX_HEIGHT)
real_hex_x = guess_x
real_hex_y = guess_y

if (guess_y % 2 > 0):
#section_type = "b"
if (section_pixel_x >= HEX_R): # right half of a B sect
ion
if (section_pixel_y < (2* HEX_H - section_pixel_x *
HEX_SLOPE)): # upper triangle of right half B section
real_hex_y -= 1
elif (section_pixel_x < HEX_R): # left half of a B secti
on
if (section_pixel_y < (section_pixel_x * HEX_SLOPE))
: # upper triangle portion of left half B section
real_hex_y -= 1
else: # bottom part of left half of B section
real_hex_x -= 1
else:
#section_type = "a"
if (section_pixel_y < HEX_H - (section_pixel_x * HEX_SLO
PE)): # upper left triangle of A section
real_hex_x -= 1
real_hex_y -= 1
elif (section_pixel_y < (-1 * (HEX_H - (section_pixel_x
* HEX_SLOPE)))): # upper right triangle of A section
real_hex_y -= 1
hex_coord_text = "HEX COORDS: (" + str(real_hex_x) + ", " +
str(real_hex_y) + ")"
key_pressed = pygame.key.get_pressed()
if key_pressed[K_w]:
scroll_y -= SCROLL_AMOUNT
if scroll_y < 0:
scroll_y = 0
if key_pressed[K_a]:
scroll_x -= SCROLL_AMOUNT
if scroll_x < 0:
scroll_x = 0
if key_pressed[K_s]:
scroll_y += SCROLL_AMOUNT
if scroll_y + map_panel_size[1] > (map_image.get_size())[1]:
scroll_y = (map_image.get_size())[1] - map_panel_size[1]
if key_pressed[K_d]:
scroll_x += SCROLL_AMOUNT
if scroll_x + map_panel_size[0] > (map_image.get_size())[0]:
scroll_x = (map_image.get_size())[0] - map_panel_size[0]
map_panel.blit(map_image, (0, 0), (scroll_x, scroll_y, map_panel_size[0], ma
p_panel_size[1]))

if show_debug_text:
info_panel.fill(color_dim_gray)
pygame.draw.line(screen, color_gray_77, (0, map_panel_size[1]), (map_pan
el_size[0], map_panel_size[1]), 3)
info_panel.blit(large_font.render(event_text, True, color_orange), (0, 0
))
info_panel.blit(large_font.render(hex_coord_text, True, color_orange), (
300, 0))
# draw the GUI elements
# pygame.draw.line(screen, color_gray_77, (map_panel_size[0], 0), (map_panel_
size[0], map_panel_size[1]), 3)
# pygame.draw.line(screen, color_gray_77, (0, map_panel_size[1]), (map_panel_
size[0], map_panel_size[1]), 3)
# pygame.draw.rect(control_panel, color_gray_196, Rect(control_panel_offset,
button_area), 1)
# pygame.draw.rect(control_panel, color_gray_196, Rect((control_panel_offset[
0], control_panel_offset[1] + button_area[1] + button_offset), button_area), 1)
# pygame.draw.rect(control_panel, color_gray_196, Rect((control_panel_offset[
0], (control_panel_offset[1] + button_area[1])*2 + button_offset), button_area),
1)
# control_panel.blit(button_zoom_in, (button_offset, button_offset))
# control_panel.blit(button_zoom_out, (button_offset, button_offset*2 + butto
n_area[1]))
# control_panel.blit(button_randomize_map, (button_offset, button_offset*3 +
button_area[1]*2))

pygame.display.update()
pygame.quit()