Quindi sto creando un gioco di Tower Defense e voglio avere diversi modi per le torri per dare la priorità ai loro bersagli (sto usando Python ma sto cercando una risposta generica al design):
class TargetPriority(enum.Enum):
LOW_HEALTH = 1
HIGH_HEALTH = 2
FIRST = 3
LAST = 4
CLOSEST = 5
class Tower(Entity):
def __init__(self, *args, **kwargs, target_priority=TargetPriority.FIRST):
super().__init__(*args, **kwargs)
self.target_priority = target_priority
def find_target(self, all_monsters):
sort_functions = {
TargetPriority.LOW_HEALTH: lambda monster: monster.health,
TargetPriority.HIGH_HEALTH: lambda monster: -monster.health,
TargetPriority.FIRST: ???,
TargetPriority.LAST: ???,
TargetPriority.CLOSEST: self.distance_to,
}
func = sort_functions[self.target_priority]
return next(sorted(all_monsters, key=func), None)
Come puoi vedere, non sono sicuro di come ottenere il mostro "primo" o "ultimo" dall'ondata di mostri. Il modo in cui i miei mostri funzionano in questo momento è ottenere un oggetto Checkpoint
e una volta raggiunto il checkpoint, chiamano il metodo check_in()
per ottenere nuove istruzioni:
class Monster(Entity):
def __init__(self, *args, **kwargs, health, checkpoint):
super().__init__(*args, **kwargs)
self.health = health
self.checkpoint = checkpoint
def update(self, dt):
travel = self.velocity / 1000 * dt
remaining_distance = self.distance_to(self.checkpoint)
if travel.length < remaining_distance:
self.position += travel
else:
self.checkpoint.check_in(self)
Il metodo Checkpoint.check_in(monster)
può richiamare qualsiasi callback assegnata al checkpoint, di solito modifica semplicemente il checkpoint del mostro al prossimo checkpoint, ma può anche fare qualcos'altro come togliere una vita dal giocatore e rimuovere il mostro (il l'ultimo checkpoint lo fa sempre). Posso cambiare il modo in cui funzionano questi checkpoint (o come i mostri si muovono in generale) se richiesto da una soluzione "ottimale".
Ecco alcune cose che ho considerato:
- Non posso usare l'ordine dei mostri nella lista
all_monsters
perché alcune torri potrebbero rallentare alcuni mostri, cambiando così il loro ordine - Per la stessa ragione, non posso usare nessun altro tipo di indicizzazione
- Non posso usare la posizione dei mostri sulla mappa perché non c'è modo di sapere da che parte sta andando il mostro o dove sono i checkpoint
- Non posso usare la distanza dei mostri per i checkpoint perché i mostri possono già trovarsi a diversi checkpoint
Finora l'unica soluzione effettiva che ho potuto trovare era di memorizzare un total_distance_travelled
per ogni mostro, quindi in update()
avrei:
self.position += travel
self.total_distance_travelled += travel.length
Ma ci sono due ragioni per le quali esito:
- Non è una prova di fallimento al 100%: anche se non è attualmente possibile, cosa succede se avrò qualcosa di simile a torri che teletrasporteranno i mostri al loro precedente checkpoint?
- Sto aggiungendo un attributo di istanza solo per il solo motivo che le torri sono in grado di ordinare questi mostri
Mi preoccupo troppo, o c'è una soluzione migliore che mi manca?