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))