parent
							
								
									ae14326fe8
								
							
						
					
					
						commit
						4c59532a9f
					
				
				 6 changed files with 583 additions and 0 deletions
			
			
		| After Width: | Height: | Size: 2.3 KiB | 
| @ -0,0 +1,341 @@ | |||||||
|  | import time, datetime, math | ||||||
|  | from copy import deepcopy | ||||||
|  | from enum import Enum | ||||||
|  | 
 | ||||||
|  | def now(): | ||||||
|  |     return datetime.datetime.now().timestamp() | ||||||
|  | 
 | ||||||
|  | class DroneState(Enum): | ||||||
|  |     Grounded = 0 | ||||||
|  |     InTheAir = 1 | ||||||
|  |     WaitingForTakeOff = 2 | ||||||
|  | 
 | ||||||
|  | class StopType(Enum): | ||||||
|  |     City = 0 | ||||||
|  |     Factory = 1 | ||||||
|  | 
 | ||||||
|  | class Position: | ||||||
|  |     def __init__(self, x, y): | ||||||
|  |         self.x = x | ||||||
|  |         self.y = y | ||||||
|  |     def __str__(self): | ||||||
|  |         return(f"[{self.x}, {self.y}]")  | ||||||
|  | 
 | ||||||
|  | class Drone: | ||||||
|  |     def __init__(self, name, position, route, rate, capacity): | ||||||
|  |         self.__name = name | ||||||
|  |         self.__position = position | ||||||
|  |         self.__route = route | ||||||
|  |         self.__rate = rate # per second | ||||||
|  |         self.__capacity = capacity | ||||||
|  |         self.__cargo = {} | ||||||
|  | 
 | ||||||
|  |         self.__state = DroneState.Grounded | ||||||
|  |         self.__prevousStop = -1 | ||||||
|  |         self.__nextStop = 0 | ||||||
|  |         self.__lastDeparture = 0 | ||||||
|  |         self.__lastDeparturePosition = deepcopy(position) | ||||||
|  | 
 | ||||||
|  |     def set_position(self, position): | ||||||
|  |         self.__position = position | ||||||
|  | 
 | ||||||
|  |     # returns how much was accepted from the load | ||||||
|  |     def load_cargo(self, product, quantity): | ||||||
|  |         cargoTotal = self.get_cargo_total() | ||||||
|  | 
 | ||||||
|  |         if not product in self.__cargo: | ||||||
|  |             self.__cargo[product] = 0 | ||||||
|  | 
 | ||||||
|  |         spaceRemaining = (self.__capacity - cargoTotal) | ||||||
|  | 
 | ||||||
|  |         acceptedQuantity = quantity | ||||||
|  | 
 | ||||||
|  |         # if the quantity is more than space remaining then just return the space remaining | ||||||
|  |         if(quantity > spaceRemaining): | ||||||
|  |             acceptedQuantity = spaceRemaining | ||||||
|  | 
 | ||||||
|  |         self.__cargo[product] += acceptedQuantity | ||||||
|  | 
 | ||||||
|  |         return acceptedQuantity | ||||||
|  |   | ||||||
|  |     def get_cargo_total(self): | ||||||
|  |         total = 0 | ||||||
|  |          | ||||||
|  |         for key in self.__cargo: | ||||||
|  |             total += self.__cargo[key] | ||||||
|  |          | ||||||
|  |         return total | ||||||
|  | 
 | ||||||
|  |     def takeOff(self): | ||||||
|  |         self.__state = DroneState.InTheAir | ||||||
|  |         self.__lastDeparture = now() | ||||||
|  |         self.__lastDeparturePosition = deepcopy(self.__position) | ||||||
|  | 
 | ||||||
|  |         positionFound = False | ||||||
|  | 
 | ||||||
|  |         for idx, stop in enumerate(self.__route.get_stops()): | ||||||
|  |             stopPosition = stop.get_position() | ||||||
|  |              | ||||||
|  |             if (stopPosition.x == self.__position.x) and (stopPosition.y == self.__position.y): | ||||||
|  |                 positionFound = True | ||||||
|  | 
 | ||||||
|  |                 self.__prevousStop = idx | ||||||
|  |                  | ||||||
|  |                 # if the next stop is out of range, loop back home | ||||||
|  |                 if(idx + 1 == len(self.__route.get_stops())): | ||||||
|  |                     self.__nextStop = 0 | ||||||
|  |                 else: | ||||||
|  |                     self.__nextStop = idx + 1 | ||||||
|  |          | ||||||
|  |         if(not positionFound): | ||||||
|  |             self.__prevousStop = -1 | ||||||
|  |             self.__nextStop = 0 | ||||||
|  |             print(f"{self.__name}: Taking off from: {self.__position}") | ||||||
|  |         else: | ||||||
|  |             print(f"{self.__name}: Taking off from: {self.__route.get_stops()[self.__prevousStop]}") | ||||||
|  | 
 | ||||||
|  |     def cargo_report(self): | ||||||
|  |         str = "" | ||||||
|  |         for product in self.__cargo: | ||||||
|  |             str += f"{product}: {self.__cargo[product]}" | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |     def update(self): | ||||||
|  | 
 | ||||||
|  |         state = DroneState.Grounded.name | ||||||
|  |         position = f"Position: {self.__position}" | ||||||
|  |         prevousStop = self.__route.get_stops()[self.__prevousStop] | ||||||
|  |         nextStop = self.__route.get_stops()[self.__nextStop] | ||||||
|  | 
 | ||||||
|  |         # print cargo levels | ||||||
|  |         print(f"{self.__name}: On Board {self.__cargo}") | ||||||
|  | 
 | ||||||
|  |         # are we at a unknown location? | ||||||
|  |         if(self.__prevousStop == -1): | ||||||
|  |             location = self.__lastDeparturePosition | ||||||
|  |         else: | ||||||
|  |             location = prevousStop | ||||||
|  | 
 | ||||||
|  |         # is the drone in the air? | ||||||
|  |         if(self.__state == DroneState.Grounded): | ||||||
|  |             print(f"{self.__name}: {state}: {location}") | ||||||
|  |         elif(self.__state == DroneState.WaitingForTakeOff): | ||||||
|  |             currentStop = prevousStop | ||||||
|  | 
 | ||||||
|  |             print(f"{self.__name}: Waiting For Take Off: {location}") | ||||||
|  | 
 | ||||||
|  |             # load cargo/receive_supplies if at a factory | ||||||
|  |             if(currentStop.get_stop_type() == StopType.Factory): | ||||||
|  |                 print(f"{self.__name}: Loading Inventory") | ||||||
|  | 
 | ||||||
|  |                 products = currentStop.get_output_quantity() | ||||||
|  | 
 | ||||||
|  |                 for key in products: | ||||||
|  |                     acceptedQuantity = self.load_cargo(key, products[key]) | ||||||
|  | 
 | ||||||
|  |                     # adjust inventory by accepted quantity | ||||||
|  |                     currentStop.update_inventory(-acceptedQuantity) | ||||||
|  | 
 | ||||||
|  |                 currentStop.receive_supplies(self.__cargo) | ||||||
|  | 
 | ||||||
|  |             if(self.__nextTakeOff <= now()): | ||||||
|  |                 self.takeOff() | ||||||
|  |         else: | ||||||
|  |             print(f"{self.__name}: Traveling Between: {location} and {nextStop}") | ||||||
|  | 
 | ||||||
|  |             # time in the air since take off | ||||||
|  |             timeDifference = math.floor(now() - self.__lastDeparture) | ||||||
|  |              | ||||||
|  |             x2 = float(nextStop.get_position().x) | ||||||
|  |             y2 = float(nextStop.get_position().y) | ||||||
|  | 
 | ||||||
|  |             if(self.__prevousStop == -1): | ||||||
|  |                 x1 = float(self.__lastDeparturePosition.x) | ||||||
|  |                 y1 = float(self.__lastDeparturePosition.y) | ||||||
|  |             else: | ||||||
|  |                 x1 = prevousStop.get_position().x | ||||||
|  |                 y1 = prevousStop.get_position().y | ||||||
|  | 
 | ||||||
|  |             #print(f"{self.__name}: {x1},{y1} -> {x2},{y2}") | ||||||
|  | 
 | ||||||
|  |             # total distance: d=√((x2 – x1)² + (y2 – y1)²) | ||||||
|  |             totalDistance = (math.sqrt(abs(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))))) | ||||||
|  | 
 | ||||||
|  |             # d = rt | ||||||
|  |             distanceTraveled = self.__rate * (now() - self.__lastDeparture) | ||||||
|  | 
 | ||||||
|  |             #print(f"{self.__name}: Distance Traveled: {distanceTraveled}, Total Distance: {totalDistance}") | ||||||
|  | 
 | ||||||
|  |             # slope m = (y2 - y1) / (x2 - x1) | ||||||
|  |             if(x2 == x1): | ||||||
|  |                 m = 0 | ||||||
|  |             else: | ||||||
|  |                 m = (y2 - y1) / (x2 - x1) | ||||||
|  | 
 | ||||||
|  |             travelingEast = x2 > x1 | ||||||
|  |             travelingNorth = y2 > y1 | ||||||
|  | 
 | ||||||
|  |             # if traveled the distance, ground the drone and update stops | ||||||
|  |             if(distanceTraveled >= totalDistance): | ||||||
|  |                 # force position | ||||||
|  |                 self.__position.x = nextStop.get_position().x | ||||||
|  |                 self.__position.y = nextStop.get_position().y | ||||||
|  | 
 | ||||||
|  |                 self.__state = DroneState.WaitingForTakeOff | ||||||
|  |                 self.__nextTakeOff = now() + 5 | ||||||
|  |                 self.__prevousStop = self.__nextStop | ||||||
|  |                 self.__nextStop += 1 | ||||||
|  | 
 | ||||||
|  |                 # if next stop out of range, sent back to first stop | ||||||
|  |                 if(self.__nextStop >= len(self.__route.get_stops())): | ||||||
|  |                     self.__nextStop = 0 | ||||||
|  |             else: | ||||||
|  |                 # what percentage of the journey has passed? | ||||||
|  |                 per = (distanceTraveled/totalDistance) | ||||||
|  | 
 | ||||||
|  |                 # compute X | ||||||
|  |                 if(travelingEast): | ||||||
|  |                     x = x1 + ((x2 - x1) * per) | ||||||
|  |                 else: | ||||||
|  |                     x = x1 - ((x1 - x2) * per) | ||||||
|  | 
 | ||||||
|  |                 # compute y | ||||||
|  |                 if(m > 0): | ||||||
|  |                     # if there is a slope | ||||||
|  |                     #(y – y1) = m(x – x1)  | ||||||
|  |                     y = (m * (x - x1)) + y1 | ||||||
|  |                 else: | ||||||
|  |                     if(travelingNorth): | ||||||
|  |                         y = y1 + ((y2 - y1) * per) | ||||||
|  |                     else: | ||||||
|  |                         y = y1 - ((y1 - y2) * per) | ||||||
|  | 
 | ||||||
|  |                     # if no slope, either x or y is constant | ||||||
|  |                     if(x1 == x2): | ||||||
|  |                         x = x1 | ||||||
|  | 
 | ||||||
|  |                     if(y1 == y2): | ||||||
|  |                         y = y1 | ||||||
|  | 
 | ||||||
|  |                 self.__position.x = x | ||||||
|  |                 self.__position.y = y | ||||||
|  | 
 | ||||||
|  |                 print(f"{self.__name} {position}") | ||||||
|  |     def get_state(self): | ||||||
|  |         return self.__state | ||||||
|  | 
 | ||||||
|  | class Route: | ||||||
|  |     def __init__(self, name, stops): | ||||||
|  |         self.__name = name | ||||||
|  |         self.__stops = stops | ||||||
|  |     def get_stops(self): | ||||||
|  |         return self.__stops | ||||||
|  |      | ||||||
|  | class Product(): | ||||||
|  |     def __init__(self, name): | ||||||
|  |         self.__name = name | ||||||
|  |     def __str__(self): | ||||||
|  |         return f"{self.__name}" | ||||||
|  |     def get_name(self): | ||||||
|  |         return self.__name | ||||||
|  | 
 | ||||||
|  | class Stop: | ||||||
|  |     def __init__(self, stopType, name, position): | ||||||
|  |         self.__stopType = stopType | ||||||
|  |         self.__name = name | ||||||
|  |         self.__position = position | ||||||
|  |     def __str__(self): | ||||||
|  |         return f"{self.__name} {self.__position}" | ||||||
|  |     def get_position(self): | ||||||
|  |         return self.__position | ||||||
|  |     def get_name(self): | ||||||
|  |         return self.__name | ||||||
|  |     def get_stop_type(self): | ||||||
|  |         return self.__stopType | ||||||
|  | 
 | ||||||
|  | class Factory(Stop): | ||||||
|  |     def __init__(self, name, position, product, buildRate, acceptedSupplies): | ||||||
|  |         super().__init__(StopType.Factory, name, position) | ||||||
|  | 
 | ||||||
|  |         #product name | ||||||
|  |         self.__product = product | ||||||
|  |         #build rate (units per second) | ||||||
|  |         self.__buildRate = buildRate | ||||||
|  |         #units ready to ship | ||||||
|  |         self.__inventory = {product: 0} | ||||||
|  |         #last time inventory was updated | ||||||
|  |         self.__lastCheck = 0 | ||||||
|  |         #acceptedSupplies = products accepted by this factory | ||||||
|  |         self.__acceptedSupplies = acceptedSupplies | ||||||
|  |      | ||||||
|  |     # returns a dictionary of the product and inventory level | ||||||
|  |     def get_output_quantity(self): | ||||||
|  |         # only return finished goods | ||||||
|  |         return {self.__product: math.floor(self.__inventory[self.__product])} | ||||||
|  |      | ||||||
|  |     # adds to inventory level | ||||||
|  |     def update_inventory(self, quantity): | ||||||
|  |         self.__inventory[self.__product] += quantity | ||||||
|  | 
 | ||||||
|  |     def update_supply_inventory(self, product, quantity): | ||||||
|  |         if product not in self.__inventory: | ||||||
|  |             self.__inventory[product] = 0 | ||||||
|  |              | ||||||
|  |         self.__inventory[product] += quantity | ||||||
|  | 
 | ||||||
|  |     def receive_supplies(self, supplies): | ||||||
|  |         for supply in supplies: | ||||||
|  |             if supply in self.__acceptedSupplies: | ||||||
|  |                 self.update_supply_inventory(supply, supplies[supply]) | ||||||
|  | 
 | ||||||
|  |     def inventory_report(self): | ||||||
|  |         str = f"{self.get_name()}: " | ||||||
|  |         for product in self.__inventory: | ||||||
|  |             str += f"{product}: {self.__inventory[product]} " | ||||||
|  |         return str | ||||||
|  | 
 | ||||||
|  |     # runs on timer tick | ||||||
|  |     def update(self): | ||||||
|  |         now = datetime.datetime.now().timestamp() | ||||||
|  | 
 | ||||||
|  |         if(self.__lastCheck > 0): | ||||||
|  |             timeDifference = (now - self.__lastCheck) | ||||||
|  |             self.update_inventory(timeDifference * self.__buildRate) | ||||||
|  |              | ||||||
|  |         print(self.inventory_report()) | ||||||
|  | 
 | ||||||
|  |         self.__lastCheck = datetime.datetime.now().timestamp() | ||||||
|  | 
 | ||||||
|  | chicago = Stop(StopType.City, "Chicago", Position(1, 45)) | ||||||
|  | miami = Stop(StopType.City, "Miami", Position(50, 1)) | ||||||
|  | newYork = Stop(StopType.City, "New York", Position(50, 50)) | ||||||
|  | 
 | ||||||
|  | widget = Product("Widget") | ||||||
|  | gizmo = Product("Gizmo") | ||||||
|  | 
 | ||||||
|  | widgetFactory = Factory("Widget Inc", Position(50, 25), widget, .25, []) | ||||||
|  | 
 | ||||||
|  | gizmoSupplies = [widget] | ||||||
|  | gizmoFactory = Factory("Gizmo Inc", Position(50, 30), gizmo, .25, gizmoSupplies) | ||||||
|  | 
 | ||||||
|  | factories = [widgetFactory, gizmoFactory] | ||||||
|  | 
 | ||||||
|  | route = Route(name="Express Route", stops=(widgetFactory, gizmoFactory)) | ||||||
|  | routeRev = Route(name="Express Route Reverse", stops=(miami, newYork, chicago, widgetFactory))  | ||||||
|  | 
 | ||||||
|  | alphaDrone = Drone("Alpha", Position(25, 25), route, 1, 10) | ||||||
|  | betaDrone = Drone("Beta", Position(35, 25), routeRev, 5, 10) | ||||||
|  | 
 | ||||||
|  | drones = [alphaDrone] | ||||||
|  | 
 | ||||||
|  | while(True): | ||||||
|  |     for drone in drones: | ||||||
|  |         if(drone.get_state() == DroneState.Grounded): | ||||||
|  |             drone.takeOff() | ||||||
|  |         else: | ||||||
|  |             drone.update() | ||||||
|  |     for factory in factories: | ||||||
|  |         factory.update() | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     time.sleep(1) | ||||||
| @ -0,0 +1,30 @@ | |||||||
|  | import pygame | ||||||
|  | 
 | ||||||
|  | from settings import Settings | ||||||
|  | from spritesheet import SquareSpriteSheet | ||||||
|  | from ship import Drone | ||||||
|  | 
 | ||||||
|  | settings = Settings() | ||||||
|  | 
 | ||||||
|  | screen = pygame.display.set_mode((settings.width, settings.height)) | ||||||
|  | pygame.display.set_caption(settings.caption) | ||||||
|  | 
 | ||||||
|  | pygame.init() | ||||||
|  | 
 | ||||||
|  | ship = Drone(screen, (0, 0)) | ||||||
|  | 
 | ||||||
|  | run = True | ||||||
|  | 
 | ||||||
|  | while run: | ||||||
|  |     #update background | ||||||
|  |     screen.fill(settings.background_color) | ||||||
|  | 
 | ||||||
|  |     ship.update() | ||||||
|  | 
 | ||||||
|  |     #event handler | ||||||
|  |     for event in pygame.event.get(): | ||||||
|  |         if event.type == pygame.QUIT: | ||||||
|  |             run = False | ||||||
|  |      | ||||||
|  |     pygame.display.update() | ||||||
|  | 
 | ||||||
| @ -0,0 +1,6 @@ | |||||||
|  | class Settings(): | ||||||
|  |     def __init__(self) -> None: | ||||||
|  |         self.width = 500 | ||||||
|  |         self.height = 500 | ||||||
|  |         self.caption = "My Game" | ||||||
|  |         self.background_color = (50, 50, 50) | ||||||
| @ -0,0 +1,172 @@ | |||||||
|  | import pygame | ||||||
|  | from enum import Enum | ||||||
|  | import math | ||||||
|  | import random | ||||||
|  | 
 | ||||||
|  | from spritesheet import SquareSpriteSheet | ||||||
|  | 
 | ||||||
|  | class DroneStatus(Enum): | ||||||
|  |     GROUNDED = 0 | ||||||
|  |     TAKINGOFF = 1 | ||||||
|  |     TURNING = 2 | ||||||
|  |     INTHEAIR = 3 | ||||||
|  |     LANDING = 4 | ||||||
|  | 
 | ||||||
|  | class Drone: | ||||||
|  |     def __init__(self, screen, pos = (0, 0)) -> None: | ||||||
|  |          | ||||||
|  |         # image | ||||||
|  |         self.screen = screen | ||||||
|  |         self.sheet = sheet = SquareSpriteSheet('assets/ship-sheet.png', 96, 4) | ||||||
|  |         self.scale = 1 | ||||||
|  |         self.angle = 0 | ||||||
|  |          | ||||||
|  |         # animation | ||||||
|  |         self.frame = 0 | ||||||
|  |         self.animation_cooldown = 75 | ||||||
|  |          | ||||||
|  |         # tracking | ||||||
|  |         self.scale = .25 | ||||||
|  |         self.last_update = 0 | ||||||
|  |         self.pos = pos | ||||||
|  |         self.prev_index = 0 | ||||||
|  |         self.next_index = 1 | ||||||
|  | 
 | ||||||
|  |         self.route = [(400,400),(0,400),(400,0),(0,0),(400,0)] | ||||||
|  |          | ||||||
|  |         # status | ||||||
|  |         self.status = DroneStatus.TAKINGOFF | ||||||
|  |         self.animate = False | ||||||
|  |         self.last_departure = 0 | ||||||
|  | 
 | ||||||
|  |         self.rate = 100/1000 #(units per second) | ||||||
|  | 
 | ||||||
|  |     def update(self): | ||||||
|  | 
 | ||||||
|  |         current_time = pygame.time.get_ticks() | ||||||
|  | 
 | ||||||
|  |         if(self.status == DroneStatus.GROUNDED): | ||||||
|  |             self.prev_index = 0 | ||||||
|  |             self.next_index = 1 | ||||||
|  | 
 | ||||||
|  |             self.scale = .25 | ||||||
|  |             self.animate = False | ||||||
|  | 
 | ||||||
|  |         elif(self.status == DroneStatus.TAKINGOFF): | ||||||
|  |             self.scale += .001 | ||||||
|  | 
 | ||||||
|  |             if(self.scale >= 1): | ||||||
|  |                 self.scale = 1 | ||||||
|  |                 self.status = DroneStatus.TURNING | ||||||
|  | 
 | ||||||
|  |             self.animate = True | ||||||
|  |         elif(self.status == DroneStatus.TURNING): | ||||||
|  |             x1 = self.route[self.prev_index][0] | ||||||
|  |             y1 = self.route[self.prev_index][1] | ||||||
|  | 
 | ||||||
|  |             x2 = self.route[self.next_index][0] | ||||||
|  |             y2 = self.route[self.next_index][1] | ||||||
|  | 
 | ||||||
|  |             #https://replit.com/@Rabbid76/PyGame-RotateWithMouse#main.py | ||||||
|  | 
 | ||||||
|  |             correction_angle = 90 | ||||||
|  |             dx = x2 - x1 | ||||||
|  |             dy = y2 - y1 | ||||||
|  |             new_angle = math.degrees(math.atan2(-dy, dx)) - correction_angle | ||||||
|  | 
 | ||||||
|  |             if(int(self.angle) > int(new_angle)): | ||||||
|  |                 self.angle -= .1 | ||||||
|  |             elif(int(self.angle) < int(new_angle)): | ||||||
|  |                 self.angle += .1 | ||||||
|  | 
 | ||||||
|  |             if((int(self.angle) + int(new_angle)) == 0): | ||||||
|  |                 self.angle = new_angle | ||||||
|  |                 self.last_departure = current_time | ||||||
|  |                 self.status = DroneStatus.INTHEAIR | ||||||
|  | 
 | ||||||
|  |             if((int(self.angle) - int(new_angle)) == 0): | ||||||
|  |                 self.angle = new_angle | ||||||
|  |                 self.last_departure = current_time | ||||||
|  |                 self.status = DroneStatus.INTHEAIR | ||||||
|  |              | ||||||
|  |             self.animate = True | ||||||
|  | 
 | ||||||
|  |         elif(self.status == DroneStatus.INTHEAIR): | ||||||
|  |              | ||||||
|  |             x1 = self.route[self.prev_index][0] | ||||||
|  |             y1 = self.route[self.prev_index][1] | ||||||
|  | 
 | ||||||
|  |             x2 = self.route[self.next_index][0] | ||||||
|  |             y2 = self.route[self.next_index][1] | ||||||
|  | 
 | ||||||
|  |             going_north = y2 >= y1 | ||||||
|  |             going_east = x2 >= x1 | ||||||
|  | 
 | ||||||
|  |             slope = 0 | ||||||
|  | 
 | ||||||
|  |             if(x2 - x1 != 0): | ||||||
|  |                 slope = (y2 - y1) / (x2 - x1) | ||||||
|  | 
 | ||||||
|  |             # total distance: d=√((x2 – x1)² + (y2 – y1)²) | ||||||
|  |             total_distance = (math.sqrt(abs(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))))) | ||||||
|  | 
 | ||||||
|  |             # d = rt | ||||||
|  |             distance_traveled = self.rate * (current_time - self.last_departure) | ||||||
|  | 
 | ||||||
|  |             # if traveled the distance, ground the drone and update stops | ||||||
|  |             if(distance_traveled >= total_distance): | ||||||
|  |             # force position | ||||||
|  |                 self.pos = self.route[self.next_index] | ||||||
|  | 
 | ||||||
|  |                 self.status = DroneStatus.LANDING | ||||||
|  |             else: | ||||||
|  |                 # what percentage of the journey has passed? | ||||||
|  |                 per = (distance_traveled/total_distance) | ||||||
|  | 
 | ||||||
|  |                 # compute X | ||||||
|  |                 if(going_east): | ||||||
|  |                     x = x1 + ((x2 - x1) * per) | ||||||
|  |                 else: | ||||||
|  |                     x = x1 - ((x1 - x2) * per) | ||||||
|  | 
 | ||||||
|  |                 # compute y | ||||||
|  |                 if(slope > 0): | ||||||
|  |                     # if there is a slope | ||||||
|  |                     #(y – y1) = m(x – x1)  | ||||||
|  |                     y = (slope * (x - x1)) + y1 | ||||||
|  |                 else: | ||||||
|  |                     if(going_north): | ||||||
|  |                         y = y1 + ((y2 - y1) * per) | ||||||
|  |                     else: | ||||||
|  |                         y = y1 - ((y1 - y2) * per) | ||||||
|  | 
 | ||||||
|  |                     # if no slope, either x or y is constant | ||||||
|  |                     if(x1 == x2): | ||||||
|  |                         x = x1 | ||||||
|  | 
 | ||||||
|  |                     if(y1 == y2): | ||||||
|  |                         y = y1 | ||||||
|  | 
 | ||||||
|  |                 self.pos = (x, y) | ||||||
|  |             self.scale = 1 | ||||||
|  |             self.animate = True | ||||||
|  | 
 | ||||||
|  |         elif(self.status == DroneStatus.LANDING): | ||||||
|  |             self.scale -= .001 | ||||||
|  | 
 | ||||||
|  |             if(self.scale <= .25): | ||||||
|  |                 self.scale = .25 | ||||||
|  |                 self.status = DroneStatus.TAKINGOFF | ||||||
|  |                 self.prev_index = self.next_index | ||||||
|  |                 self.next_index = self.prev_index + 1 if self.prev_index + 1 < len(self.route) else 0 | ||||||
|  | 
 | ||||||
|  |             self.animate = True | ||||||
|  | 
 | ||||||
|  |         if(self.animate): | ||||||
|  |             if current_time - self.last_update >= self.animation_cooldown: | ||||||
|  |                 self.frame += 1 | ||||||
|  |                 self.frame = self.frame if self.frame < len(self.sheet.images) else 0 | ||||||
|  |                 self.last_update = current_time | ||||||
|  | 
 | ||||||
|  |         current_image = self.sheet.get_image_by_frame(self.frame, self.scale, self.angle) | ||||||
|  |         self.screen.blit(current_image, (self.pos)) | ||||||
| @ -0,0 +1,34 @@ | |||||||
|  | import pygame | ||||||
|  | 
 | ||||||
|  | class SquareSpriteSheet(): | ||||||
|  |     def __init__(self, filename, size, numberOfImages, transparency_color=(0,0,0)) -> None: | ||||||
|  |         self.sheet = pygame.image.load(filename).convert_alpha() | ||||||
|  |         self.size = size | ||||||
|  |         self.numberOfImages = numberOfImages | ||||||
|  |         self.transparency_color = transparency_color | ||||||
|  |         self.images = [] | ||||||
|  | 
 | ||||||
|  |         self.load_images() | ||||||
|  | 
 | ||||||
|  |     def load_images(self): | ||||||
|  |         for i in range(self.numberOfImages): | ||||||
|  |             image = pygame.Surface((self.size, self.size)).convert_alpha() | ||||||
|  |             image.blit(self.sheet, (0,0), ((i * self.size), 0, self.size, self.size)) | ||||||
|  |             image.set_colorkey(self.transparency_color) | ||||||
|  |             self.images.append(image) | ||||||
|  | 
 | ||||||
|  |     def get_image_by_frame(self, frame, scale=1, angle=0): | ||||||
|  |             image = self.images[frame] | ||||||
|  |             image = pygame.transform.scale(image, (self.size * scale, self.size * scale)) | ||||||
|  |             image = self.rot_center(image, angle) | ||||||
|  |             image.set_colorkey(self.transparency_color) | ||||||
|  |             return image | ||||||
|  | 
 | ||||||
|  |     def rot_center(self, image, angle): | ||||||
|  |         """rotate an image while keeping its center and size""" | ||||||
|  |         orig_rect = image.get_rect() | ||||||
|  |         rot_image = pygame.transform.rotate(image, angle) | ||||||
|  |         rot_rect = orig_rect.copy() | ||||||
|  |         rot_rect.center = rot_image.get_rect().center | ||||||
|  |         rot_image = rot_image.subsurface(rot_rect).copy() | ||||||
|  |         return rot_image | ||||||
					Loading…
					
					
				
		Reference in new issue