Sono nuovo di questa cosa, quindi per favore dimmi se sto sbagliando se c'è un posto migliore per la mia domanda.
Sto facendo un gioco con i sistemi di base per proiettili, npc e oggetti. Questo gioco avrà più varianti di ciascuno di questi tipi. Ai fini di questo esempio, ci sarà un proiettile proiettile, un proiettile missilistico e una pistola che sparerà ai proiettili.
L'unica esperienza che ho con un tale sistema è all'interno del codice sorgente di Terraria, in cui gli oggetti sono tutti definiti in un albero di grandi dimensioni if-else, ad es.
else if (this.type == 467)
{
this.name = "Fireball";
this.width = 40;
this.height = 40;
this.aiStyle = 1;
this.hostile = true;
this.damage = 10;
}
Il problema con questo approccio è (a parte il pasticcio terribile che fa) che aggiungere nuovi elementi richiede modifiche a 4-5 diverse aree di codice, specialmente se si desidera aggiungere effetti aggiuntivi, come emettere luce, nemici ardenti ecc.
Sto provando a farlo in un formato molto migliore. Sono arrivato con un semplice sistema che con classi nidificate, ad es.
public class ProjectileData
{
public class Bullet : Projectile
{
public float speed;
public Bullet() : base()
{
this.type = ProjectileID.Bullet;
this.damage = 25;
this.origin = new Vector2(9.5f, 2.5f);
speed = 10;
}
public override void AI()
{
this.velocity += new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * speed;
}
public override void OnHit()
{
Game.CreateExplosion(this.position);
}
}
public class Rocket : Projectile
{ ... }
}
Con questo sistema, per creare un proiettile, invece di usare qualcosa come
Projectile.CreateProjectile(int id, ...)
{
Projectile projectile = new Projectile(id);
}
...
Projectile.CreateProjectile(ProjectileID.Bullet, ...);
Ho
Projectile.CreateProjectile<T>(...) where T : Projectile, new()
{
T projectile = new T(id);
}
...
Projectile.CreateProjectile<ProjectileData.Bullet>(...);
che sembra e funziona bene.
Tuttavia, ho incontrato un problema: se voglio creare un oggetto che spara un proiettile, non posso farvi riferimento. Ad esempio, con il sistema basato su ID, potrei scrivere qualcosa come
item.projectileType = ProjectileID.Bullet
ma non è possibile assegnare una Classe a una proprietà del genere.
Immagino che questo si riduce a 2 domande:
- È questo il modo "corretto" per passare i dati a un oggetto o esiste una struttura migliore, con o senza ereditarietà?
- Esiste un modo per fare riferimento a una classe e utilizzare tale riferimento in fase di esecuzione in una chiamata di metodo generica?