You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

187 lines
5.7 KiB

import pygame
from enum import Enum
import math
import random
from spritesheet import SquareSpriteSheet
from route import Route
from stop import Stop
class DroneStatus(Enum):
GROUNDED = 0
TAKINGOFF = 1
TURNING = 2
INTHEAIR = 3
LANDING = 4
class Drone:
def __init__(self, screen, pos = (0, 0), route=[]) -> 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 = route
# status
self.status = DroneStatus.GROUNDED
self.animate = False
self.last_departure = 0
self.rate = 100/1000 #(units per second)
self.status_message = ""
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
self.status_message = "On The Ground"
elif(self.status == DroneStatus.TAKINGOFF):
if(len(self.route.stops) >= 2):
self.scale += .001
if(self.scale >= 1):
self.scale = 1
self.status = DroneStatus.TURNING
print(self.status, self.scale)
self.animate = True
else:
self.status_message = "Cannot take off. No Route."
elif(self.status == DroneStatus.TURNING):
x1 = self.route.stops[self.prev_index].pos[0]
y1 = self.route.stops[self.prev_index].pos[1]
x2 = self.route.stops[self.next_index].pos[0]
y2 = self.route.stops[self.next_index].pos[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
self.status_message = "Turning."
elif(self.status == DroneStatus.INTHEAIR):
x1 = self.route.stops[self.prev_index].pos[0]
y1 = self.route.stops[self.prev_index].pos[1]
x2 = self.route.stops[self.next_index].pos[0]
y2 = self.route.stops[self.next_index].pos[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.stops[self.next_index].pos
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
self.status_message = "In The Air."
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.stops) else 0
self.animate = True
self.status_message = "Landing."
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))

Powered by TurnKey Linux.