Mercurial > atc
changeset 0:919a9eff76a3
Initial import
author | Josef "Jeff" Sipek <jeffpc@optonline.net> |
---|---|
date | Thu, 07 Jul 2005 01:00:05 +0000 |
parents | |
children | 4c7bb645fd75 |
files | atc.py atc_colors.py atc_message.py atc_plane.py atc_utils.py |
diffstat | 5 files changed, 356 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/atc.py Thu Jul 07 01:00:05 2005 +0000 @@ -0,0 +1,74 @@ +try: + import sys + import threading + import pygame + + import atc_colors + import atc_utils + import atc_plane + import atc_message +except ImportError, err: + print "Couldn't load module %s" % (err) + sys.exit() + +size = width, height = 800, 600 + +def main(): + """ Main fn to run the main thread """ + + # Init + pygame.init() + screen = pygame.display.set_mode(size) + pygame.display.set_caption('Air Traffic Controller') + + # background music + pygame.mixer.init() + #pygame.mixer.music.load('data/music.mp3') + #pygame.mixer.music.set_volume(0.1) + #pygame.mixer.music.play() + + # Set background + background = pygame.Surface(screen.get_size()).convert() + background.fill(atc_colors.black) + + (back_image, back_rect) = atc_utils.load_png('background.png') + background.blit(back_image, (0, 0)) + + # Some text +# font = pygame.font.Font(None, 36) +# text = font.render("Air Traffic Controller", 1, atc_colors.red) +# textpos = text.get_rect() +# textpos.centerx = background.get_rect().centerx +# background.blit(text, textpos) + + #blit! + screen.blit(background, (0, 0)) + pygame.display.flip() + + planes = [] + planes.append(atc_plane.Plane(callsign="N12422",vel=(atc_plane.m2pix(50), atc_plane.m2pix(50), atc_plane.m2pix(10)))) + planes.append(atc_plane.Plane(callsign="N48975",pos=(400, 30, 500),vel=(atc_plane.m2pix(-50), atc_plane.m2pix(50), atc_plane.m2pix(10)))) + planes.append(atc_plane.Plane(callsign="N86124",pos=(400, 400, 500),vel=(atc_plane.m2pix(-50), atc_plane.m2pix(-50), atc_plane.m2pix(-1500)))) + planes.append(atc_plane.Plane(callsign="N64554",pos=(30, 400, 500),vel=(atc_plane.m2pix(50), atc_plane.m2pix(-50), atc_plane.m2pix(-2000)))) + + mess = atc_message.Message() + + while 1: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + mess.pickup_kill = 1 + sys.exit() + + screen.blit(background, (0, 0)) + + for plane in planes: + plane.display(screen) + plane.update() + if (plane.status == atc_plane.plane_CRASHED): + mess.write(screen,plane.callsign + ": PLANE CRASHED") + plane.status = atc_plane.plane_DEAD + + pygame.display.flip() + +if (__name__ == '__main__'): + main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/atc_colors.py Thu Jul 07 01:00:05 2005 +0000 @@ -0,0 +1,14 @@ +black = 0, 0, 0 +blue1 = 0, 182, 227 +blue2 = 57, 108, 149 +brown = 199, 103, 0 +gray = 131, 131, 131 +green1 = 0, 227, 0 +green2 = 0, 149, 0 +red = 255, 0, 0 +snow = 227, 227, 227 +white = 255, 255, 255 + +planeinfo_ok = green1 +planeinfo_crashed = red +background = black
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/atc_message.py Thu Jul 07 01:00:05 2005 +0000 @@ -0,0 +1,101 @@ +import pygame +import threading + +class Message: + """ Interface to display a message and beep it off in morse code """ + def __init__(self): + """ Set up everything """ + self.snd = {} + self.snd["."] = pygame.mixer.Sound('data/sbeep.wav') + self.snd["."].set_volume(0.4) + self.snd["-"] = pygame.mixer.Sound('data/lbeep.wav') + self.snd["-"].set_volume(0.4) + self.snd[" "] = pygame.mixer.Sound('data/nosnd.wav') + self.snd[" "].set_volume(0.4) + + self.delay = {} + self.delay["."] = 250 + self.delay["-"] = 400 + self.delay[" "] = 330 + + self.morse = {} + self.morse["A"] = ".-" + self.morse["B"] = "-..." + self.morse["C"] = "-.-." + self.morse["D"] = "-.." + self.morse["E"] = "." + self.morse["F"] = "..-." + self.morse["G"] = "--." + self.morse["H"] = "...." + self.morse["I"] = ".." + self.morse["J"] = ".---" + self.morse["K"] = "-.-" + self.morse["L"] = ".-.." + self.morse["M"] = "--" + self.morse["N"] = "-." + self.morse["O"] = "---" + self.morse["P"] = ".--." + self.morse["Q"] = "--.-" + self.morse["R"] = ".-." + self.morse["S"] = "..." + self.morse["T"] = "-" + self.morse["U"] = "..-" + self.morse["V"] = "...-" + self.morse["W"] = ".--" + self.morse["X"] = "-..-" + self.morse["Y"] = "-.--" + self.morse["Z"] = "--.." + self.morse["1"] = ".----" + self.morse["2"] = "..---" + self.morse["3"] = "...--" + self.morse["4"] = "....-" + self.morse["5"] = "....." + self.morse["6"] = "-...." + self.morse["7"] = "--..." + self.morse["8"] = "---.." + self.morse["9"] = "----." + self.morse["0"] = "-----" + self.morse[" "] = " " + self.morse[":"] = "" + + self.statusmess = "" + + self.messages = [] + + self.pickup_kill = 0 + self.pickup_thread = threading.Timer(0, self.__pickup) + self.pickup_thread.start() + + def write(self,screen,mess): + """ Add message to the queue """ + code = "" + for letter in mess: + code += self.morse[letter] + " " + + self.messages.append(code) + + def __beep(self,char): + """ Beep one . or - """ + self.snd[char].play() + + def __beeper(self,mess): + """ Beep out all . and - in a message """ + for char in mess: + self.__beep(char) + pygame.time.delay(self.delay[char]) + + def __pickup(self): + """ The message pickup thread code, it picks up new messages + and calls the appropreate functions to beep them out """ + while(not self.pickup_kill): + try: + message = self.messages.pop() + self.statusmess = message + self.__beeper(message) + pygame.time.delay(1400) + self.statusmess = "" + except IndexError: + pass + + pygame.time.delay(100) + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/atc_plane.py Thu Jul 07 01:00:05 2005 +0000 @@ -0,0 +1,146 @@ +import os +import sys +import pygame +from math import * + +import atc_colors +import atc_utils + +mperpix = 750.0 + +def m2pix(m): + """ Meters to pixels conversion fn """ + return m/mperpix + +def pix2m(pix): + """ Pixels to meters conversion fn """ + return pix*mperpix + +plane_OK = 0 +plane_RANGE = 1 +plane_CRASHED = 2 +plane_STALL = 3 +plane_DEAD = 4 +plane_PROXY = 5 + +plane_PROP = 16.667 # meters/sec +plane_JET = 62.572 + + +class Plane(pygame.sprite.Sprite): + """ Class to manage one plane's motion """ + def __init__(self,callsign,pos=(0.0, 0.0, 0.0),vel=(0.0, 0.0, 0.0)): + """ Set up everything """ + pygame.sprite.Sprite.__init__(self) + + # screen + screen = pygame.display.get_surface() + self.area = screen.get_rect() + + # plane image + (self.image, self.rect) = atc_utils.load_png('plane.png') + + # call sign + self.callsign = callsign + + # position + self.X = pos[0] + self.Y = pos[1] + self.Z = pos[2] + + # velocity + self.i = vel[0] + self.j = vel[1] + self.k = vel[2] + + # plane specs + self.stallspeed = m2pix(plane_PROP) + + # status flag + self.status = plane_OK + + def update(self): + """ Move the plane, and check for collisions """ + if (self.status != plane_OK): + return + + self.X += self.i + self.Y += self.j + self.Z += self.k + + if (self.X <= 0) or (self.Y <= 0): # FIXME: max values + self.status = plane_RANGE + + if (self.Z <= 0): + self.i = 0 + self.j = 0 + self.k = 0 + self.status = plane_CRASHED + + if (self.calc_vel()<self.stallspeed) and (not self.status==plane_CRASHED): + self.status = plane_STALL + + self.rect.move(self.i,self.j) + + def calc_vel(self): + """ Calculate magnitude of the velocity """ + return sqrt(self.i**2 + self.j**2 + self.k**2) + + def calc_head(self): + """ Calculate heading of the airplane """ + if (self.i == self.j == 0): # no movement + return 0 + + try: + head = fabs(atan(self.i/-self.j)) + except ZeroDivisionError: + if (self.i>0): + return pi/2 # east + return 3*pi/2 # west + + if (self.i>0) and (-self.j>0): # east and north + return pi/2 - head + if (self.i<0) and (-self.j>0): # west and north + return head + 3*pi/2 + if (self.i>0) and (-self.j<0): # east and south + return head + pi/2 + if (self.i==0) and (-self.j>0): # north + return head + return head + pi # west and south / south + + def calc_rc(self): + """ Calculate rate of climb """ + return atan(self.k/self.i) # REDO!! + + def recalc_vel(self,vel,heading,rc): + """ Set velocity to new value """ + self.i = vel*cos(rc) + self.j = vel*cos(heading) + self.k = vel*sin(rc) + + def display(self,screen): + """ Put everything onto the screen """ + screen.blit(self.image, (int(self.X), int(self.Y))) + + # Plane info + font = pygame.font.Font(None, 16) + + color = atc_colors.planeinfo_ok + if (self.status == plane_CRASHED) or (self.status == plane_DEAD): + color = atc_colors.planeinfo_crashed + + x = int(self.X) + 10 + y = int(self.Y) - 5 + + strings = ( self.callsign + str(self.status), + "Alt: " + str(int(self.Z)), + "Lat: " + str(int(self.X)), + "Long: " + str(int(self.Y)), + "Head: " + str(int(atc_utils.todeg(self.calc_head())))) + + for stri in strings: + alt = font.render(stri, 1, color) + altpos = alt.get_rect() + altpos.topleft = (x,y) + screen.blit(alt, altpos) + (x,y) = (x,y+10)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/atc_utils.py Thu Jul 07 01:00:05 2005 +0000 @@ -0,0 +1,21 @@ +import pygame +import os +from math import * + +def load_png(name): + """ Load image and return image object""" + fullname = os.path.join('data', name) + try: + image = pygame.image.load(fullname) + if image.get_alpha() is None: + image = image.convert() + else: + image = image.convert_alpha() + except pygame.error, message: + print 'Cannot load image:', fullname + raise SystemExit, message + return image, image.get_rect() + +def todeg(rad): + """ Convert radians to degrees """ + return rad*180.0/pi