⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 car.cs

📁 game implemented java
💻 CS
字号:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;

namespace WindowsApplication2
{
	/// <summary>
	/// Each Car object represents an individual car.  It contains the 
	/// Drive() function and is designed to store data on its movements
	/// which can be used for later reporting.
	/// </summary>
	public class Car
	{
		public const int WRONG_DIRECTION = -1;
		public const int STUCK_AT_INTERSECTION = 1;
		public const int GOAL_REACHED = 2;
		public const int NEW_SEGMENT = 3;
		public const int FINAL_BLOCK = 4;

		private Point location;						//Where the Car is
		private readonly Point start, goal;			//Where the Car started and is going
		private int segID,lastStep;					//Sement Car is on and last tick car was driven on
		private readonly int endID;					//Index number of the target segment
		private readonly int myID;					//Car's ID number
		private double distTravelled;				//Semi-accurate accounting of distance driven
		private readonly double totalDist;			//Distance(start,goal)
		private SolidBrush carColor;				//Used to draw cars, never changed from Blue
		private readonly MapSeg startSeg,endSeg;	//Segments car starts and ends on
		private ArrayList shortestPath;				//Ordered list of intersections car must visit

		public Car(CityMap myMap, int carID) 
		{
			myID = carID;
			lastStep = 0;
			segID = myMap.getRandomMapSeg();
			startSeg = myMap.getSegment(segID);
			location = startSeg.getRandomPoint();
			start = new Point(location.X,location.Y);
			endID = myMap.getRandomMapSeg();
			endSeg = myMap.getSegment(endID);
			goal = endSeg.getRandomPoint();
			distTravelled = 0;
			carColor = new SolidBrush (Color.Blue);
			totalDist = Distance(start,goal);  			
			shortestPath = new ArrayList();
		}
		private double Distance(Point a, Point b) 
		{  
			double xdiff = a.X - b.X;  
			double ydiff = a.Y - b.Y;  
			return Math.Sqrt(xdiff * xdiff + ydiff * ydiff);  
		}  

		#region Simple Properties
		public Point getStartPoint
		{
			get {return start;}
		}
		public int getDriveCount
		{
			get {return lastStep;}
		}
		public Point getGoalPoint
		{
			get {return goal;}
		}
		public MapSeg getStartSeg
		{
			get{return startSeg;}
		}
		public MapSeg getGoalSeg
		{
			get{return endSeg;}
		}
		public Point getLocation
		{
			get{return location;}
		}
		public ArrayList path
		{
			get {return shortestPath;}
			set 
			{
				shortestPath = value;
				if (value != null)
					startSeg.PushCar(this, getFromTo(startSeg));
			}
		}
		public int getID
		{
			get {return myID;}
		}
		public int getNextIntersection
		{
			get {return (int)shortestPath[0];}
		}
		#endregion

		public void Draw (Graphics g, Scaler myScale)
		{
            PointF myPoint = myScale.translate(location);
			g.FillEllipse(carColor,myPoint.X-3,myPoint.Y-3,6.0f,6.0f);
		}
		public int Drive (CityMap myMap)
		{//Allows simple calling from Form1, internal function is for recursion
			return Drive(myMap,-1);
		}
		private int Drive (CityMap myMap, double dist)
		{
			lastStep++;
			MapSeg currSeg = myMap.getSegment(segID);
			currSeg.drivePreviousCars(myID,lastStep,getFromTo(myMap),myMap);

			if (dist < 0)
			{//called from Form1
				dist = (1/52.8/25)* currSeg.SpeedLimit * myMap.scale.UnitsPerMile;
				dist = CongestionAdjust(dist, getFromTo(myMap), myMap.getSegment(segID));
			}
			
			//check if on last block
			if (shortestPath.Count == 0)
			{
				if (Distance(location,goal) <= dist)
					return GOAL_REACHED;
				else
					location = moveInSeg(location,goal,currSeg,dist);
			}
			else
			{
				Point target = (currSeg.From_Intersection==(int)shortestPath[0])? currSeg.from:currSeg.to;
				//Intersection Reached
				if (Distance(location,target) < dist)					
				{
					Intersection at = (Intersection)myMap.getIntersectionList[(int)shortestPath[0]];
					bool thru = at.isThru(segID, (int)shortestPath[0]);
					int passable = at.canGo(segID,lastStep);

					if (thru && passable == 1)
					{//Keep on truckin'
						currSeg.RemoveCar(segID,getFromTo(myMap));
						if (shortestPath.Count > 1)
							segID = at.findSeg(myMap,(int)shortestPath[1]);
						else
							segID = endID;
						currSeg = myMap.getSegment(segID);
						shortestPath.RemoveAt(0);
						location = getFromTo(myMap)? currSeg.from : currSeg.to;
						currSeg.PushCar(this,getFromTo(myMap));
						return Drive(myMap, dist - Distance(location,target));
					}
					else if (passable == -1)
					{//Red Light, don't bother going back
						location = getFromTo(myMap)? currSeg.to : currSeg.from;
						return 0;
					}
					else
					{//Either turning or stop sign (or both)
						location = getFromTo(myMap)? currSeg.to : currSeg.from;
						return STUCK_AT_INTERSECTION;
					}
				}
				else //On an intermediate block out of reach of an intersection
					location = moveInSeg(location,target,currSeg,dist);
			}
			distTravelled += dist;
			return 0;
		}
		public void passThruIntersection(CityMap myMap)
		{//Called on phase 2 of Form1's timer_tick function, passes the car through
		// the intersection it is stuck on.
			MapSeg currSeg = myMap.getSegment(segID);
			Intersection at = (Intersection)myMap.getIntersectionList[(int)shortestPath[0]];
			currSeg.RemoveCar(myID,getFromTo(myMap));
			if (shortestPath.Count > 1)
				segID = at.findSeg(myMap,(int)shortestPath[1]);
			else
				segID = endID;
			currSeg = myMap.getSegment(segID);
			shortestPath.RemoveAt(0);
			location = getFromTo(myMap)? currSeg.from : currSeg.to;
			currSeg.PushCar(this,getFromTo(myMap));					
		}
		private Point moveInSeg(Point loc, Point goal, MapSeg curr, double dist)
		{//Advances the car along the line defined by curr	
		// The function appears to fail occasionally, as the commented exception does fire
			Point newLoc = new Point();
			double Z = dist/Math.Sqrt((curr.to.X - curr.from.X)*(curr.to.X - curr.from.X)
				+ (curr.to.Y - curr.from.Y)*(curr.to.Y - curr.from.Y));
			newLoc.X = (int)(loc.X + Z * (curr.to.X - curr.from.X));
			newLoc.Y = (int)(loc.Y + Z * (curr.to.Y - curr.from.Y));
			if (Distance(newLoc,goal) > Distance(loc,goal))
			{
				newLoc.X = (int)(loc.X - Z * (curr.to.X - curr.from.X));
				newLoc.Y = (int)(loc.Y - Z * (curr.to.Y - curr.from.Y));
			}
			double inline = Distance (loc, newLoc) + Distance (newLoc, goal);
			if (inline * 1.1 > Distance (loc, goal) && inline * 0.9 < Distance (loc,goal))
				return newLoc;
			else
				//throw (new Exception("New location is not on the appropriate block: "+inline+" vs "+Distance (loc, goal)));
				return newLoc;
		}
		private double CongestionAdjust (double dist, bool fromTo, MapSeg mySeg)
		{//Limits the car's movement so that it doesn't run over the cars in front of it
			Point max_move = mySeg.getCarPosition(myID, fromTo);
			if (max_move.X == 0 && max_move.Y == 0)
				return dist;

			return Math.Min(Math.Max(Distance (max_move,location)-15,0),dist);
		}

		private bool getFromTo(CityMap myMap)
		{//Decides which direction the car is moving on the current map segment
			return getFromTo(myMap.getSegment(segID));			
		}
		private bool getFromTo(MapSeg s)
		{
			if (shortestPath.Count >= 1)
				return (s.To_Intersection == (int)shortestPath[0]);
			
			return (Distance(s.from,location) < Distance (s.from,goal));
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -