Mercurial > atc
changeset 10:7bb4cd2fa1bc
Changed window size from 800x600 to 1024x768
Fixed scaling factors to represent real world values
Moved aircraft specs into a separate file
Moved all the velocity and position vars into few dictionaries
Internal vars hold meter or meters/second values
committer: Jeff Sipek <jeffpc@jeff.(none)> 1120786621 -0400
author | Jeff Sipek <jeffpc@jeff.(none)> |
---|---|
date | Fri, 08 Jul 2005 01:37:01 -0400 |
parents | 480ccfc8a57e |
children | 300ba3412449 |
files | TODO atc.py atc_plane.py atc_plane_specs.py atc_single.py data/image/background.png data/image/background.xcf data/image/menu_multi.png data/image/menu_quit.png data/image/menu_single.png data/image/splash.png data/image/splash.xcf |
diffstat | 12 files changed, 126 insertions(+), 72 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TODO Fri Jul 08 01:37:01 2005 -0400 @@ -0,0 +1,1 @@ +* Increase goto altitude accuracy (ALT xyz)
--- a/atc.py Thu Jul 07 19:51:56 2005 -0400 +++ b/atc.py Fri Jul 08 01:37:01 2005 -0400 @@ -39,7 +39,7 @@ print "Couldn't load module %s" % (err) sys.exit() -size = width, height = 800, 600 +size = width, height = 1024, 768 def main(): """ Main fn to run the main thread """ @@ -84,7 +84,7 @@ screen.blit(background, (0, 0)) (menu_img, menu_rect) = atc_utils.load_png('data/image/menu_' + menustr[optsel & 3] + '.png') - screen.blit(menu_img, (200, 200)) + screen.blit(menu_img, ((width - 334)/2.0, (height - 225)/2.0)) pygame.display.flip()
--- a/atc_plane.py Thu Jul 07 19:51:56 2005 -0400 +++ b/atc_plane.py Fri Jul 08 01:37:01 2005 -0400 @@ -22,14 +22,16 @@ import os import sys +import time import pygame from math import * import atc_colors import atc_utils +from atc_plane_specs import * -mperpix = 750.0 -mperdeg = 950.0 +mperpix = 30000.0/800.0 # 800 px == 30 km +mperdeg = 1852.0*60.0 # == 1852 m/min * 60 min/deg def m2pix(m): """ Meters to pixels conversion fn """ @@ -49,14 +51,6 @@ plane_DEAD = 4 plane_PROXY = 5 -# all measurements in meters/sec or meters -plane_PROP = {"stall_speed": 16.667, - "climb_normal": 182.0, - "max_altitude": 6500.0} -plane_JET = {"stall_speed": 62.572, - "climb_normal": 900.0, - "max_altitude": 13000.0} - class Plane(pygame.sprite.Sprite): """ Class to manage one plane's motion """ def __init__(self,callsign,flightno,pos=(0.0, 0.0, 0.0),vel=(0.0, 0.0, 0.0)): @@ -76,87 +70,110 @@ # flight number self.flightno = flightno - # position - self.X = m2pix(pos[0]) - self.Y = m2pix(pos[1]) - self.Z = m2pix(pos[2]) + # position (X, Y, Z) + self.pos = { \ + "X":pos[0], \ + "Y":pos[1], \ + "Z":pos[2]} # target position - self.targetX = None - self.targetY = None - self.targetZ = None + self.targetPos = { \ + "X":None, \ + "Y":None, \ + "Z":None} # velocity - self.i = m2pix(vel[0]) - self.j = m2pix(vel[1]) - self.k = m2pix(vel[2]) + self.vel = { \ + "i":vel[0], \ + "j":vel[1], \ + "k":vel[2], \ + + "heading":0, \ + "speed":0, \ + "climb":0} + self.complete_vel(ijk=1) + + self.timer = 0 # this is timeout the next time we try to recalculate position # plane specs - self.specs = plane_PROP + self.specs = plane_SPECS[0] # default to a simple prop plane, FIXME: add param to override # status flag self.status = plane_OK + def complete_vel(self, ijk=None, hac=None): + """ Recalculate all the velocity variables """ + if ijk == None and hac == None: + print "Nothing calculated" + return + + if ijk == None: + self.vel["i"] = self.vel["speed"]*cos(self.vel["climb"]/self.vel["speed"]) + self.vel["j"] = self.vel["speed"]*cos(self.vel["heading"]) + self.vel["k"] = self.vel["climb"] + else: + self.vel["heading"] = self.calc_head() + self.vel["speed"] = sqrt(self.vel["i"]**2 + self.vel["j"]**2 + self.vel["k"]**2) + self.vel["climb"] = self.vel["k"] + def update(self): """ Move the plane, and check for collisions """ + if (self.timer > time.time()): + return + if (self.status != plane_OK): return - self.X += self.i - self.Y += self.j - self.Z += self.k + self.pos["X"] += self.vel["i"]/10.0 + self.pos["Y"] += self.vel["j"]/10.0 + self.pos["Z"] += self.vel["k"]/10.0 # FIXME: need physics - if (self.targetZ != None) and (self.Z >= (self.targetZ - m2pix(50))) and (self.Z <= (self.targetZ + m2pix(50))): - self.k = 0 - self.targetZ = None + if (self.targetPos["Z"] != None) and (self.pos["Z"] >= (self.targetPos["Z"] - 25)) and (self.pos["Z"] <= (self.targetPos["Z"] + 25)): + self.vel["k"] = 0 + self.targetPos["Z"] = None + + self.complete_vel(ijk=1) - if (self.X < 0) or (self.Y < 0): # FIXME: max values + if (self.pos["X"] < 0) or (self.pos["Y"] < 0): # FIXME: max values self.status = plane_RANGE - if (self.Z < 0): - self.i = 0 - self.j = 0 - self.k = 0 + if (self.pos["Z"] < 0): + self.vel["i"] = self.vel["j"] = self.vel["k"] = 0 self.status = plane_CRASHED - if (self.calc_vel()<m2pix(self.specs["stall_speed"])) and (not self.status==plane_CRASHED): + if (self.vel["speed"]<m2pix(self.specs["stall_speed"])) 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) - + self.rect.move(self.vel["i"]/10.0,self.vel["j"]/10.0) + + self.timer = time.time() + m2pix(self.vel["speed"])**-1/10.0 + def calc_head(self): - """ Calculate heading of the airplane """ - if (self.i == self.j == 0): # no movement + """ Calculate heading of the airplane (in radians)""" + if (self.vel["i"] == self.vel["j"] == 0): # no movement return 0 try: - head = fabs(atan(self.i/-self.j)) + head = fabs(atan(self.vel["i"]/-self.vel["j"])) except ZeroDivisionError: - if (self.i>0): + if (self.vel["i"]>0): return pi/2 # east return 3*pi/2 # west - if (self.i>0) and (-self.j>0): # east and north + if (self.vel["i"]>0) and (-self.vel["j"]>0): # east and north return pi/2 - head - if (self.i<0) and (-self.j>0): # west and north + if (self.vel["i"]<0) and (-self.vel["j"]>0): # west and north return head + 3*pi/2 - if (self.i>0) and (-self.j<0): # east and south + if (self.vel["i"]>0) and (-self.vel["j"]<0): # east and south return head + pi/2 - if (self.i==0) and (-self.j>0): # north + if (self.vel["i"]==0) and (-self.vel["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 calc_geo(self, xy): - df = pix2geo(xy) + """ Return a geographic coodrinate-formated xy """ + df = m2pix(pix2geo(xy)) d = floor(df) mf = (df-d) * 60.0 m = floor(mf) @@ -164,25 +181,28 @@ return "%dd %02dm %02ds" % (int(d), int(m), int(s)) - 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 process(self,cmd): + """ Process a user command """ + + # FIXME: convert multiple spaces to single parts = cmd.split(' ') if (parts[0] == "ALT"): print "Changing altitude to " + parts[1] + "m" - self.targetZ = m2pix(int(parts[1])) - self.k = m2pix(self.specs["climb_normal"]) - if (self.Z > self.targetZ): - self.k *= -1 + self.targetPos["Z"] = int(parts[1]) + self.vel["k"] = self.specs["climb_normal"] + if (self.pos["Z"] > self.targetPos["Z"]): + self.vel["k"] *= -1 + self.complete_vel(ijk=1) + + if (parts[0] == "HEAD"): + print "Changing heading to " + parts[1] + self.targetHead = int(parts[1]) + def display(self,screen): """ Put everything onto the screen """ - screen.blit(self.image, (int(self.X), int(self.Y))) + screen.blit(self.image, (int(m2pix(self.pos["X"])), int(m2pix(self.pos["Y"])))) # Plane info font = pygame.font.Font(None, 16) @@ -191,16 +211,17 @@ 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 + x = int(m2pix(self.pos["X"])) + 10 + y = int(m2pix(self.pos["Y"])) - 5 # FIXME: display geographic coordinates with NSWE appended/prepended strings = ( self.flightno, self.callsign + " " + str(self.status), - "Alt: " + str(int(pix2m(self.Z))), - "Lat: " + self.calc_geo(self.X), - "Long: " + self.calc_geo(self.Y), - "Head: " + str(int(atc_utils.todeg(self.calc_head())))) + "Alt: " + str(int(self.pos["Z"])), + "Lat: " + self.calc_geo(self.pos["X"]), + "Long: " + self.calc_geo(self.pos["Y"]), + "Head: " + str(int(atc_utils.todeg(self.calc_head()))), + "AS: " + str(int(self.vel["speed"]*3.6))) for stri in strings: alt = font.render(stri, 1, color)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/atc_plane_specs.py Fri Jul 08 01:37:01 2005 -0400 @@ -0,0 +1,32 @@ +#/* +# * ATC - Air Traffic Controller simulation game +# * +# * Copyright (C) 2004 Josef "Jeff" Sipek <jeffpc@optonline.net> +# * +# * This program is free software; you can redistribute it and/or modify +# * it under the terms of the GNU General Public License as published by +# * the Free Software Foundation; either version 2 of the License, or +# * (at your option) any later version. +# * +# * This program is distributed in the hope that it will be useful, +# * but WITHOUT ANY WARRANTY; without even the implied warranty of +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# * GNU General Public License for more details. +# * +# * You should have received a copy of the GNU General Public License +# * along with this program; if not, write to the Free Software +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# * +# * @(#) %M% %I% %E% %U% +# */ + +# all measurements in meters/sec or meters +plane_SPECS = ({"name": "Piper PA28-140 Cherokee", + "stall_speed": 16.667, + "climb_normal": 182.0, + "max_altitude": 6500.0}, + + {"name": "Boeing 747-400", + "stall_speed": 62.572, + "climb_normal": 900.0, + "max_altitude": 13000.0})