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})
--- a/atc_single.py	Thu Jul 07 19:51:56 2005 -0400
+++ b/atc_single.py	Fri Jul 08 01:37:01 2005 -0400
@@ -177,7 +177,7 @@
 		if (cmd):
 			font = pygame.font.Font(None, 18)
 			text = font.render(cmd, 1, atc_colors.white)
-			screen.blit(text, (25, 567))
+			screen.blit(text, (25, 735))
 		
 		pygame.display.flip()
 
Binary file data/image/background.png has changed
Binary file data/image/background.xcf has changed
Binary file data/image/menu_multi.png has changed
Binary file data/image/menu_quit.png has changed
Binary file data/image/menu_single.png has changed
Binary file data/image/splash.png has changed
Binary file data/image/splash.xcf has changed