Hello! I'm not sure if this belongs here, or in the beginners' section, so excuse me if this code is too bad, or too basic.
I had set a short term goal for myself as an amateur programmer: To implement a hexagonal grid, similar to the one found in the original Fallout. You should be able to move your mouse around and the hexagon that contains the mouse pointer should be highlighted. I thought it would be a good exercise, because unlike a square grid, determining which hexagon contains the mouse pointer is trickier.
I did finish the program, and it does exactly what I want, but I do tend to overcomplicate things and I would appreciate it if people with more experienced took a look at it and gave me any tips. This was coded in python with pygame.
import pygame
import math
INITIAL_HEXAGON_VERTICES = ((-40,-40),(40,-40),(45,0),(40,40),(-40,40),(-45,0))
GRID_HEIGHT = 10
GRID_WIDTH = 10
VERTEX_COUNT = 6
X_ELEMENT = 0
Y_ELEMENT = 1
FIXED_ANGLE = 0.122 #7 degrees in radians
NOT_MOVING = (0,0)
def calculate_angle(fixed_point,var_point):
opposite = math.fabs(fixed_point[X_ELEMENT] - var_point[X_ELEMENT])
adjacent = math.fabs(fixed_point[Y_ELEMENT] - var_point[Y_ELEMENT])
if adjacent == 0:
adjacent = 0.1
angle = math.atan((opposite/adjacent))
return angle
class Hexagon:
def __init__(self,num,ver):
self.number = num
self.vertices = ver
class InputManager:
def check_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
game.running = False
def mouse_in_grid(self,mouse_pos,hexagons):
result = 0
for counter,hexagon in enumerate(hexagons):
if (mouse_pos[X_ELEMENT] > hexagon.vertices[5][X_ELEMENT]
and mouse_pos[X_ELEMENT] < hexagon.vertices[2][X_ELEMENT]
and mouse_pos[Y_ELEMENT] >= hexagon.vertices[0][Y_ELEMENT]
and mouse_pos[Y_ELEMENT] < hexagon.vertices[3][Y_ELEMENT]):
result = hexagon.number
if (mouse_pos[X_ELEMENT] < hexagon.vertices[0][X_ELEMENT]
and mouse_pos[Y_ELEMENT] < hexagon.vertices[5][Y_ELEMENT]):
angle = calculate_angle(hexagon.vertices[0],mouse_pos)
if angle < FIXED_ANGLE:
result = hexagon.number
if (mouse_pos[X_ELEMENT] > hexagon.vertices[1][X_ELEMENT]
and mouse_pos[Y_ELEMENT] < hexagon.vertices[2][Y_ELEMENT]):
angle = calculate_angle(hexagon.vertices[1],mouse_pos)
if angle < FIXED_ANGLE:
result = hexagon.number
if (mouse_pos[X_ELEMENT] > hexagon.vertices[3][X_ELEMENT]
and mouse_pos[Y_ELEMENT] > hexagon.vertices[2][Y_ELEMENT]):
angle = calculate_angle(hexagon.vertices[3],mouse_pos)
if angle < FIXED_ANGLE:
result = hexagon.number
if (mouse_pos[X_ELEMENT] < hexagon.vertices[4][X_ELEMENT]
and mouse_pos[Y_ELEMENT] > hexagon.vertices[5][Y_ELEMENT]):
angle = calculate_angle(hexagon.vertices[4],mouse_pos)
if angle < FIXED_ANGLE:
result = hexagon.number
return result
class Game:
def __init__(self,resolution,caption):
self.screen = pygame.display.set_mode(resolution)
pygame.display.set_caption(caption)
self.clock = pygame.time.Clock()
self.running = True
self.gray = (220,220,220)
self.green = (50,240,50)
self.black = (0,0,0)
self.hexagons = []
self.current_hexagon = 0
def draw_screen(self):
self.screen.fill(self.gray)
if pygame.mouse.get_rel() != NOT_MOVING:
self.current_hexagon = input_manager.mouse_in_grid(pygame.mouse.get_pos(),self.hexagons)
pygame.draw.polygon(self.screen,self.green,self.hexagons[self.current_hexagon].vertices,3)
pygame.display.flip()
def calculate_grid_points(self):
number = 0
for column in range(GRID_WIDTH):
for row in range(GRID_HEIGHT):
points = []
lift_hexagon = 0
if column % 2 != 0:
lift_hexagon = 40
for point in range(VERTEX_COUNT):
points.append( ((INITIAL_HEXAGON_VERTICES[point][X_ELEMENT] + (85 * column)),
((INITIAL_HEXAGON_VERTICES[point][Y_ELEMENT] + (80 * row))-lift_hexagon) ) )
new_hexagon = Hexagon(number,points)
self.hexagons.append(new_hexagon)
number += 1
def main_loop(self,framerate):
self.calculate_grid_points()
while self.running:
self.clock.tick(framerate)
input_manager.check_events()
self.draw_screen()
pygame.quit()
input_manager = InputManager()
game = Game((800,600),"Game")
game.main_loop(60)
Thanks in advance!