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