Hjälp med C# console RPG (Nybörjare)

Trädvy Permalänk
Inaktiv
Registrerad
Okt 2015

Hjälp med C# console RPG (Nybörjare)

Hej sweclockers!

Håller på med ett dungeon crawl-inspirerat rpg-spel i C#, är väldigt ny inom detta så ha förståelse. Går direkt till mitt problem;

Har en class som heter Enemy.cs, vill göra en lista med "enemies" och kunna lägga till olika sorters "enemies" som har olika egenskaper från classen Enemy.cs.

Vill kunna göra något sånt här, om det är möjligt;

List<Enemy> enemies = new List<Enemy>(); enemies.Add(new Enemy.Rat(Location = new Point(5, 5)); enemies.Add(new Enemy.Snake(Location = new Point(10, 5));

Där man lägger ut fiendens "Location" direkt när man skapar den.

Just nu har jag olika fiender i olika classer, ex. Rat.cs och Snake.cs, och skapar dem på detta vis;

List<Rat> Enemies = new List<Rat>(); Enemies.Add(new Rat()); Enemies.Add(new Rat()); Enemies.Add(new Rat()); Enemies[0].Location = new Point(5, 5); Enemies[1].Location = new Point(10, 10); Enemies[2].Location = new Point(15, 5);

Detta är mitt försök i Enemy.cs, men vet inte hur jag ska gå vidare...

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; namespace ConsoleTest345 { public class Enemy { public Point Location { get; set; } public string Name { get; set; } public string Symbol { get; set; } public int HP { get; set; } public int MaxHP { get; set; } public int RewardXP { get; set; } public int RewardGold { get; set; } public int dmg { get; set; } public int minDamage { get; set; } public int maxDamage { get; set; } public Enemy Rat() { Name = "Rat"; Symbol = "r"; MaxHP = 5; HP = MaxHP; RewardXP = 7; RewardGold = 7; minDamage = 1; maxDamage = 2; } public Enemy Snake() { Name = "Snake"; Symbol = "s"; MaxHP = 7; HP = MaxHP; RewardXP = 10; RewardGold = 11; minDamage = 1; maxDamage = 3; } } }

Dessa funktioner(?) Rat och Snake ger "not all code paths return a value", vilket jag förstår, men jag vet inte hur jag ska gå tillväga för att få det som jag vill ha det.

Hoppas att någon förstår vad jag menar och kan ge mig en ledtråd i rätt riktning!

//Peter

Trädvy Permalänk
Inaktiv
Registrerad
Okt 2015

Om någon är nyfiken så ser spelet för tillfället ut såhär

Trädvy Permalänk
Medlem
Plats
Zion
Registrerad
Apr 2004

Aldrig använt C# och inte programmerat aktivt på ett bra tag så jag kan ha helt fel men kan vara att du måste sätta placeholder värden på de saker som inte har något tilldelat, alternativt se till att de finns med i constructor delen? Annars vet ju inte datorn vart den ska hitta dessa?

[ i5-6600K @ 4.7Ghz || Corsair H110 GTX || 16GB DDR4 || ASUS Z170 Pro Gaming || Asus ROG 1080 Strix @ 2100+/11Ghz+ ]
Unigine Superposition 1080p; 17487 @ Medium; 4594 @ Extreme
"One is always considered mad, when one discovers something that others cannot grasp."
- Ed Wood

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Nov 2009

Om vi bortser från just C#, då jag inte har full koll.

Det du vill göra

List<Enemy> enemies = new List<Enemy>(); enemies.Add(new Enemy.Rat(Location = new Point(5, 5)); enemies.Add(new Enemy.Snake(Location = new Point(10, 5));

Första tipset: Använd arv redan från början om du senare vill utöka din funktionalitet av vissa enemies, kanske speciella attacker eller attribut som att flyga etc.

Säg då att du kanske har

public class Rat : Enemy { protected SpecialAbility ability { get; set; } public Rat(Point position, ... [andra parametrar som har med Enemy att göra], SpecialAbility sAbility){ //Ärvda från Superklassen Enemy this.position = position; this.rewardXp = .... etc etc // Speficikt för klassen Rat this.ability = sAbility; } public override void Attack() { // Råttor attackerar med sina klor? Console.WriteLine("Attacking with claws"); } }

Genom att använda polymorfism kan du då underlätta ditt arbete lite, exempelvis då

List<Enemy> enemies = new List<Enemy>(); enemies.add(new Rat(1,2,3,4,5,[alla parametrar som du redan har för en enemy],new Point(5,5), new SpecialAbility(....); enemies.add(new Bird(...., new Point(3,2)) foreach (Enemy e in enemies) { e.attack(); }

och då kommer t.ex att bli

"Rat is attacking with claws"
"Bird is attacking with.. näbb?"

EDIT:

Själva frågan handlade nog egentligen om att du behövde en parameter när du skapar din enemy för att kunna tilldela en position när du skapar objektet

Tips
Försök att vara consistent i hur du skriver dina variabelnamn, kolla vilken standard som gäller för C# men viktigast är att inte blanda.
Exempelvis har du både variabler som ser ut såHär, SåHär , såhÄR, såhär

Lite om just arv och polymorfism
https://msdn.microsoft.com/en-us/library/ms173149.aspx
https://msdn.microsoft.com/en-us/library/ms173152.aspx

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Sep 2005

Du blandar ihop metoder och klasser. Rat() och Snake() är metoder på klassen Enemy, de kan inte användas som typer i List<Rat> eller new Rat(). Vad du vill göra är att göra en klass för Rat och en klass för Snake som ärver av Enemy såhär:

namespace ConsoleTest345
{
public class Enemy
{
public Point Location { get; set; }
public string Name { get; set; }
public string Symbol { get; set; }
public int HP { get; set; }
public int MaxHP { get; set; }
public int RewardXP { get; set; }
public int RewardGold { get; set; }
public int dmg { get; set; }
public int minDamage { get; set; }
public int maxDamage { get; set; }

}

public class Rat : Enemy
{
public Rat()
{
Name = "Rat";
Symbol = "r";
MaxHP = 5;
HP = MaxHP;
RewardXP = 7;
RewardGold = 7;
minDamage = 1;
maxDamage = 2;
}
}

public class Snake : Enemy
{
public Snake()
{
Name = "Snake";
Symbol = "s";
MaxHP = 7;
HP = MaxHP;
RewardXP = 10;
RewardGold = 11;
minDamage = 1;
maxDamage = 3;
}
}
}

Trädvy Permalänk
Inaktiv
Registrerad
Okt 2015
Skrivet av Ferrat:

Aldrig använt C# och inte programmerat aktivt på ett bra tag så jag kan ha helt fel men kan vara att du måste sätta placeholder värden på de saker som inte har något tilldelat, alternativt se till att de finns med i constructor delen? Annars vet ju inte datorn vart den ska hitta dessa?

Skrivet av NoToes:

Om vi bortser från just C#, då jag inte har full koll.

Det du vill göra

List<Enemy> enemies = new List<Enemy>(); enemies.Add(new Enemy.Rat(Location = new Point(5, 5)); enemies.Add(new Enemy.Snake(Location = new Point(10, 5));

Första tipset: Använd arv redan från början om du senare vill utöka din funktionalitet av vissa enemies, kanske speciella attacker eller attribut som att flyga etc.

Säg då att du kanske har

public class Rat : Enemy { protected SpecialAbility ability { get; set; } public Rat(Point position, ... [andra parametrar som har med Enemy att göra], SpecialAbility sAbility){ //Ärvda från Superklassen Enemy this.position = position; this.rewardXp = .... etc etc // Speficikt för klassen Rat this.ability = sAbility; } public override void Attack() { // Råttor attackerar med sina klor? Console.WriteLine("Attacking with claws"); } }

Genom att använda polymorfism kan du då underlätta ditt arbete lite, exempelvis då

List<Enemy> enemies = new List<Enemy>(); enemies.add(new Rat(1,2,3,4,5,[alla parametrar som du redan har för en enemy],new Point(5,5), new SpecialAbility(....); enemies.add(new Bird(...., new Point(3,2)) foreach (Enemy e in enemies) { e.attack(); }

och då kommer t.ex att bli

"Rat is attacking with claws"
"Bird is attacking with.. näbb?"

EDIT:

Själva frågan handlade nog egentligen om att du behövde en parameter när du skapar din enemy för att kunna tilldela en position när du skapar objektet

Tips
Försök att vara consistent i hur du skriver dina variabelnamn, kolla vilken standard som gäller för C# men viktigast är att inte blanda.
Exempelvis har du både variabler som ser ut såHär, SåHär , såhÄR, såhär

Lite om just arv och polymorfism
https://msdn.microsoft.com/en-us/library/ms173149.aspx
https://msdn.microsoft.com/en-us/library/ms173152.aspx

Skrivet av DrXll:

Du blandar ihop metoder och klasser. Rat() och Snake() är metoder på klassen Enemy, de kan inte användas som typer i List<Rat> eller new Rat(). Vad du vill göra är att göra en klass för Rat och en klass för Snake som ärver av Enemy såhär:

namespace ConsoleTest345
{
public class Enemy
{
public Point Location { get; set; }
public string Name { get; set; }
public string Symbol { get; set; }
public int HP { get; set; }
public int MaxHP { get; set; }
public int RewardXP { get; set; }
public int RewardGold { get; set; }
public int dmg { get; set; }
public int minDamage { get; set; }
public int maxDamage { get; set; }

}

public class Rat : Enemy
{
public Rat()
{
Name = "Rat";
Symbol = "r";
MaxHP = 5;
HP = MaxHP;
RewardXP = 7;
RewardGold = 7;
minDamage = 1;
maxDamage = 2;
}
}

public class Snake : Enemy
{
public Snake()
{
Name = "Snake";
Symbol = "s";
MaxHP = 7;
HP = MaxHP;
RewardXP = 10;
RewardGold = 11;
minDamage = 1;
maxDamage = 3;
}
}
}

Tack för hjälpen!! Uppskattas!

Ska tänka på variabelnamnen...

Lösningen som @DrXll hade blev kanon!
Visste inte att man kunde "bädda in" classer i en class, trodde att man behövde göra nya .cs-filer. Det här blev precis som jag ville ha det.

Nästa fråga, går det att ange deras Location direkt när man skapar dom eller behöver man göra som jag har nu, ge dom en Location på en egen rad?

Så här ser det ut nu:

List<Enemy> Enemies = new List<Enemy>(); Enemies.Add(new Enemy.Rat()); Enemies.Add(new Enemy.Rat()); Enemies.Add(new Enemy.Snake()); Enemies[0].Location = new Point(5, 5); Enemies[1].Location = new Point(10, 10); Enemies[2].Location = new Point(15, 5);

Det jag vill åstadkomma är något sånt här:

Enemies.Add(new Enemy.Rat(Location = new Point(5, 5)));

Vet inte om det finns någon lösning på detta? Man kanske måste ange egenskaper på en egen rad.

//Peter

Trädvy Permalänk
Inaktiv
Registrerad
Okt 2015

Hittade lösningen!!

Provade Google igen och hittade den här gången det jag sökte. Det går att sätta egenskaper direkt med hjälp av dessa {}.

List<Enemy> Enemies = new List<Enemy>(); Enemies.Add(new Enemy.Rat(){Location = new Point(5, 5)}); Enemies.Add(new Enemy.Rat(){Location = new Point(10, 10)}); Enemies.Add(new Enemy.Snake(){Location = new Point(15, 5)});

Tack för hjälpen allihopa, ni är guld.

//Peter

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Sep 2008
Skrivet av Peter Avokado:

Hittade lösningen!!

Provade Google igen och hittade den här gången det jag sökte. Det går att sätta egenskaper direkt med hjälp av dessa {}.

List<Enemy> Enemies = new List<Enemy>(); Enemies.Add(new Enemy.Rat(){Location = new Point(5, 5)}); Enemies.Add(new Enemy.Rat(){Location = new Point(10, 10)}); Enemies.Add(new Enemy.Snake(){Location = new Point(15, 5)});

Tack för hjälpen allihopa, ni är guld.

//Peter

Notera att du hellre vill ha följande:

List<Enemy> Enemies = new List<Enemy>(); Enemies.Add(new Rat(new Point(5,5))) Enemies.Add(new Rat(new Point(10,10))) Enemies.Add(new Snake(new Point(15,5)))

Det koden säger är att Rat & Snake är en subclass till superclass Enemy. Sedan säger det att constructor tar emot en ny koordinat som argument [Googla även på c# parameter, då det går hand i hand] och läggs till för respektive subklass.

För att uppnå det behöver du refactor din kod från att klassen Enemy hanterar skapandet av Snake och Rat till att dem är två separata classes i ditt program.

Anledningen till att jag använder svengelska är för att dem understrukna orden kan du googla på (eventuellt lägg till programming/c# + understruket ord, ex programming subclass eller c# subclass) för att lära dig hur du ska använda dem.

Refaktorering kan vara ett lite svårare koncept att lära sig om man är ny, men det handlar främst om att gå tillbaka till sin kod, och ta bort dupliceringar(Hitta repetitiv kod och flytta det till en mer lämplig plats) eller ersätta dålig skriven kod med en bättre lösning. Nedan är ett exempel på refaktorering.

// Ursprungskod int Foo() { int a = 1; int b = 2; int c = a + b; return c; } int Bar() { int a = 2; int b = 3; int c = a + b; return c; } // Steg 1, bryt ut gemensamma operationer. // I vårt fall bryter vi ut summeringen av // två tal till en method som gör det. int Foo() { int c = sum(1,2); return c; } int Bar() { int c = sum(2,3); return c; } int Sum(int a, int b) { return a + b; } // Steg 2, kombinera allt, från en komplex lösning till // något som blir mycket mer lätthanterligt. // Notera att foobar är ett extremt dåligt metod namn. // Hellre skulle du vilja använda SumOfTwoValues/SumValues eller dylikt int Foobar(int a, int b) { .... .... return sum(a, b); } int Sum(int a, int b) { return a + b; } // EDIT: rent teoretiskt sett är Foobar en // duplicering av Sum och gör ingen mer nytta // och skulle kunna tas bort, men använd din // fantasi att Foobar gör något mer än summerar.

Dold text

Återkom om du har någon fundering.