138 lines
5.2 KiB
Python
138 lines
5.2 KiB
Python
|
|
import pygame
|
||
|
|
import math
|
||
|
|
|
||
|
|
class Compass():
|
||
|
|
def __init__(self, font_size, size):
|
||
|
|
pygame.font.init()
|
||
|
|
self.textColor = pygame.Color("white")
|
||
|
|
self.backgroundColor = pygame.Color("White")
|
||
|
|
self.needleColor = pygame.Color("black")
|
||
|
|
|
||
|
|
self.font = pygame.font.Font(pygame.font.get_default_font(), font_size)
|
||
|
|
|
||
|
|
self.surface = pygame.Surface(size, pygame.SRCALPHA)
|
||
|
|
self.size = size
|
||
|
|
|
||
|
|
self.x = 0
|
||
|
|
self.y = 0
|
||
|
|
|
||
|
|
self.backgroundSurface = None
|
||
|
|
|
||
|
|
|
||
|
|
def setX(self, x):
|
||
|
|
self.x = x
|
||
|
|
def getX(self):
|
||
|
|
return self.x
|
||
|
|
|
||
|
|
def setY(self, y):
|
||
|
|
self.y = y
|
||
|
|
def getY(self):
|
||
|
|
return self.y
|
||
|
|
|
||
|
|
def get(self):
|
||
|
|
return self.surface
|
||
|
|
|
||
|
|
def setTextColor(self, color):
|
||
|
|
try:
|
||
|
|
self.textColor = pygame.Color(color)
|
||
|
|
except:
|
||
|
|
self.textColor = pygame.Color("black")
|
||
|
|
|
||
|
|
def setBackgroundColor(self, color):
|
||
|
|
try:
|
||
|
|
self.backgroundColor = pygame.Color(color)
|
||
|
|
except:
|
||
|
|
self.backgroundColor = pygame.Color("white")
|
||
|
|
|
||
|
|
def setNeedleColor(self, color):
|
||
|
|
try:
|
||
|
|
self.needleColor = pygame.Color(color)
|
||
|
|
except:
|
||
|
|
self.needleColor = pygame.Color("black")
|
||
|
|
|
||
|
|
def update(self, value):
|
||
|
|
raise NotImplementedError()
|
||
|
|
|
||
|
|
|
||
|
|
class MiddleNeedle(Compass):
|
||
|
|
def update(self, value):
|
||
|
|
radius = min(self.size[0]//2, self.size[1]//2)
|
||
|
|
pygame.draw.circle( self.surface, self.backgroundColor, (self.size[0]//2, self.size[1]//2), radius)
|
||
|
|
|
||
|
|
|
||
|
|
arrow = pygame.Surface( ((self.size[0]//100*60)//2, self.size[1]//100*60), pygame.SRCALPHA )
|
||
|
|
|
||
|
|
polygon_list = [
|
||
|
|
( arrow.get_width()//2, 0 ), #Middle top
|
||
|
|
( 0, arrow.get_height() ), #bottom left
|
||
|
|
( arrow.get_width()//2, (arrow.get_height()-arrow.get_height()//100*30) ), #middle pos
|
||
|
|
( arrow.get_width(), arrow.get_height() ), #bottom right
|
||
|
|
]
|
||
|
|
|
||
|
|
pygame.draw.polygon(arrow, self.needleColor, polygon_list)
|
||
|
|
arrow = pygame.transform.rotate( arrow, value )
|
||
|
|
self.surface.blit( arrow, ( (self.size[0]//2)-(arrow.get_width()//2), (self.size[1]//2)-(arrow.get_height()//2)))
|
||
|
|
|
||
|
|
text = self.font.render("N", True, self.textColor)
|
||
|
|
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*10) - text.get_height()//2 ) )
|
||
|
|
|
||
|
|
text = self.font.render("W", True, self.textColor)
|
||
|
|
self.surface.blit( text, ( int(self.size[0]/100*10) - (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
|
||
|
|
|
||
|
|
text = self.font.render("O", True, self.textColor)
|
||
|
|
self.surface.blit( text, ( int(self.size[0]/100*90)- (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
|
||
|
|
|
||
|
|
text = self.font.render("S", True, self.textColor)
|
||
|
|
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*90) - text.get_height()//2 ) )
|
||
|
|
|
||
|
|
|
||
|
|
class OuterNeedle(Compass):
|
||
|
|
def update(self, value):
|
||
|
|
radius = min(self.size[0]//2, self.size[1]//2)
|
||
|
|
pygame.draw.circle( self.surface, self.backgroundColor, (self.size[0]//2, self.size[1]//2), radius)
|
||
|
|
|
||
|
|
|
||
|
|
if self.backgroundSurface:
|
||
|
|
self.surface.blit( self.backgroundSurface, (0,0) )
|
||
|
|
|
||
|
|
if self.lineLength is None:
|
||
|
|
self.lineLength = 5
|
||
|
|
|
||
|
|
# 0 is down -> +90
|
||
|
|
# alpha = 2 * arcsin (s / 2r); s is bottom line
|
||
|
|
alpha = 2 * math.asin( self.lineLength / (2*radius) )
|
||
|
|
value = math.radians(value) + math.pi/2 #put 0 to bottom
|
||
|
|
bottom_left = self.getPos(value +alpha/2, radius)
|
||
|
|
bottom_left = ( int(bottom_left[0] + radius), bottom_left[1]+radius) #offset to screen middle
|
||
|
|
bottom_right = self.getPos(value -alpha/2, radius)
|
||
|
|
bottom_right = ( int(bottom_right[0] + radius), bottom_right[1]+radius)
|
||
|
|
height_of_segment = self.lineLength/2 * math.tan( alpha / 4 )
|
||
|
|
height_of_triangle = math.sqrt(3) /2 * self.lineLength
|
||
|
|
top = self.getPos(value, radius-height_of_segment-height_of_triangle)
|
||
|
|
top = ( int(top[0] + radius), top[1]+radius )
|
||
|
|
points = [ bottom_left, top, bottom_right ]
|
||
|
|
|
||
|
|
pygame.draw.lines( self.surface, self.needleColor, False, points,3)
|
||
|
|
|
||
|
|
text = self.font.render("N", True, self.textColor)
|
||
|
|
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*10) - text.get_height()//2 ) )
|
||
|
|
|
||
|
|
text = self.font.render("W", True, self.textColor)
|
||
|
|
self.surface.blit( text, ( int(self.size[0]/100*10) - (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
|
||
|
|
|
||
|
|
text = self.font.render("O", True, self.textColor)
|
||
|
|
self.surface.blit( text, ( int(self.size[0]/100*90)- (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
|
||
|
|
|
||
|
|
text = self.font.render("S", True, self.textColor)
|
||
|
|
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*90) - text.get_height()//2 ) )
|
||
|
|
|
||
|
|
def getPos(self, alpha, radius):
|
||
|
|
return ( int( radius * math.cos(alpha) ), int( radius * math.sin(alpha) ) )
|
||
|
|
|
||
|
|
def setLineLength(self, length):
|
||
|
|
self.lineLength = length
|
||
|
|
|
||
|
|
def setBackgroundSurface(self, surface):
|
||
|
|
self.backgroundSurface = surface
|
||
|
|
|