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.
172 lines
5.1 KiB
172 lines
5.1 KiB
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)) |