• 1
  • 2
2022-03-28, 19:56
  #1
Medlem
Bonnatorps avatar
Nu är jag på sista uppgiften i Programmering 2, och det känns verkligen skönt.
Men den är svår så här inledningsvis, eftersom studieguiden är väldigt bristfällig i hur man hanterar Windows Forms.

Uppgiften lyder:
Citat:
I denna uppgift ska du bygga ut Joppes hundar (eller dartspelet) med ett grafiskt gränssnitt

Du får alltså själv välja vilket program du ska utgå ifrån.

Det är helt fritt fram att själv välja hur det grafiska gränssnittet ser ut och fungerar. Vi föreslår dock att ni jobbar med Windows Forms.

Studieguiden innehåller lite inledningsvis hur Forms fungerar, men jag tycker inte alls det innehåller hur jag faktiskt kopplar ihop det med ett program i stil med det jag har, så jag vet inte alls hur jag ska göra för att t.ex. trycka på en knapp, prompta vilket värde som ska matas in, och köra hela faderullan efter det.

Bifogar koden jag har nedan:
Kod:
{
    class Program
    {
        static void Main(string[] args)
        {
            var MyGame = new Game(); //Skapar ett nytt spel som ett objekt i klassen Game.
            MyGame.PlayGame(); //Startar spelet genom metoden PlayGame i klassen Game, inom objektet MyGame.
            Console.WriteLine("Press any key to continue");
            Console.ReadKey();
        }
    }
    class Game
    {
        private List<Player> nameList = new List<Player>(); //Genererar lista med spelarnas namn.

        public void AddPlayer(string name) //Metod som skapar ett spelarobjekt och lägger till i spelarlistan.
        {
            Player players = new Player(name);
            nameList.Add(players);
        }
        public void PlayGame()
        {
            int arrow1 = 0; //Lagrinsvariabler för vardera pil som kastas i vardera omgång.
            int arrow2 = 0;
            int arrow3 = 0;
            int total = 0; //Variabel som lagrar spelarens totalpoäng.
            int win = 301; //Variabel som anger hur många poäng som krävs för vinst.
            int numberPlayers = 0; //Variabel som lagrar hur många spelare som är med.
            bool temp = false; //Variabel som används för ett beslut nedan.

            do //Do-sats som avgör om användaren har skrivit ett heltal för antalet spelare.
            {
                Console.Clear();
                Console.WriteLine("Welcome to the awesome dart game");
                Console.WriteLine("Enter the amount of players:");
                if (Int32.TryParse(Console.ReadLine(), out numberPlayers)) //Här sparas antalet spelare, om det är ett heltal.
                {
                    temp = true;
                }
                else //Felmeddelande som körs om användaren ej angivit ett heltal.
                {
                    Console.WriteLine("You have not entered a whole number.\n" +
                        "Press any key to return to the previous menu,\n" +
                        "then enter a whole number stating the amount of players.");
                    Console.ReadKey(true);
                }
            }
            while (temp == false);
            
            for (int i = 0; i < numberPlayers; i++) //For-loop som körs lika många gånger som antalet spelare.
            {
                Console.WriteLine("Enter the name of player {0}", i+1);
                string name = Console.ReadLine();
                AddPlayer(name); //Här läggs en spelare till, med namnet som villkor för metoden.
            }
            do //Do-loop som kör det faktiska spelet. Följande loop repeteras så länge ingen har över 300 poäng.
            {
                foreach (var players in nameList) //Foreach-loop som representerar en spelrunda, och repeterar en gång för varje spelare.
                {
                    arrow1 = ThrowInput(players, "1st");
                    arrow2 = ThrowInput(players, "2nd");
                    arrow3 = ThrowInput(players, "3rd");
                    players.AddThrows(arrow1, arrow2, arrow3); //Sparar varje kastpoäng i den aktuella spelarens throwList lista via metoden AddThrows.
                    total = players.CalculatePoints();

                }
            }
            while (total <= win) ;

            Console.WriteLine("We have a winner!\n"); //Meddelande som skrivs när någon har över 300 poäng.
   
            foreach (var players in nameList) //Foreach-loop som repeterar en gång för varje spelare.
            {
                players.PrintTurns(); //Visar statistiklistan för den spelare som loopen för närvarande räknar.
            }
            static int ThrowInput(Player players, string thrownumber) //Metod som hanterar själva kasten i spelet.
            {
                Console.Clear();
                Console.WriteLine("{0}, enter a whole number between 1 and 20 for the {1} throw:", players, thrownumber);
                int input;
                if (int.TryParse(Console.ReadLine(), out input)) //Ifsats som kör om input är en integer.
                {
                    if (1 <= input && input <= 20) //Ifsats som returnerar inputvärdet om det är ett tall mellan 1 och 20.
                    {
                        return input;
                    }
                    else //Felmeddelande som körs om talet ej är mellan 1 och 20, och repeterar funktionen för det aktuella kastet.
                    {
                        Console.WriteLine("Wrong input, please enter a number between 1 and 20.");
                        Console.WriteLine("Press any key to continue");
                        Console.ReadKey();
                        ThrowInput(players, thrownumber);
                        return 0; //Körs ej då metoden repeterar i raden ovan, men krävs för att programmet ska kompilera.
                    }
                }
                else //Felmeddelande som körs om inputen ej är en integer, och repeterar funktionen för det aktuella kastet.
                {
                    Console.WriteLine("Wrong input, please enter a number between 1 and 20.");
                    Console.WriteLine("Press any key to continue");
                    Console.ReadKey();
                    ThrowInput(players, thrownumber);
                    return 0; //Körs ej då metoden repeterar i raden ovan, men krävs för att programmet ska kompilera.
                }
            }
        }
        

    }

Fortsätter koden nedan, vart lite för många tecken med alla kommentarer.
__________________
Senast redigerad av Bonnatorp 2022-03-28 kl. 19:59.
Citera
2022-03-28, 19:58
  #2
Medlem
Bonnatorps avatar
Kod:
    class Player
    {
        private string name; //Initierar en variabel för spelarens namn.
        private List<Turns> throwList = new List<Turns>(); //Initierar en lista för spelrundorna.

        public Player(string name) //Konstruktor för att hämta spelarens namn från ett villkor och spara inom klassen.
        {
            this.name = name; //Sparar den lokala variabeln name till klassvariabeln name genom att klassvariabeln kallas genom funktionen this.
        }
        public void AddThrows(int kast1, int kast2, int kast3) //Metod som sparar kastvärdena till listan throwList
        {
            throwList.Add(new Turns(kast1, kast2, kast3));
        }

        public void PrintTurns() //Metod som skriver ut slutstatistiken för varje spelare.
        {
            StreamWriter streamWriter = new StreamWriter(@"Resultat.txt", true);
            Console.WriteLine("Statistics for player {0}", name);
            Console.WriteLine("------------------------------------------");
            streamWriter.WriteLine("Statistics for player {0}", name);
            streamWriter.WriteLine("------------------------------------------");
            foreach (var turns in throwList) //Foreach-loop som repeterar en gång för varje runda i spelarens lista över rundor.
            {
                Console.WriteLine(turns); //Skriver ut den runda i throwList som är aktuell i foreach-loopen.
                streamWriter.WriteLine(turns);
            }
            Console.WriteLine("------------------------------------------");
            Console.WriteLine("Total score for {0}: {1}", name, CalculatePoints());
            streamWriter.WriteLine("------------------------------------------");
            streamWriter.WriteLine("Total score for {0}: {1}", name, CalculatePoints());
            streamWriter.Close();
        }
        public int CalculatePoints()
        {
            int score = 0;
            foreach (var turns in throwList) //Foreach-loop som repeterar en gång för varje objekt i listan throwList.
            {
                score = score + turns.GetScore(); //Adderar nuvarande poäng i räkningen med poängen för den runda som foreachloopen är på.
            }
            return score;
        }
        public override string ToString()
        {
            return name;
        }
    }
    class Turns
    {
        private int throwOne; //Lagringsvariabler som lagrar poängvärdet för varje kast i en runda.
        private int throwTwo;
        private int throwThree;

        public Turns(int throw1, int throw2, int throw3) //Konstruktor som kontruerar ett objekt för varje runda, och lagrar tre värden i detta objekt.
        {
            throwOne = throw1;
            throwTwo = throw2;
            throwThree = throw3;
        }
        public int GetScore() //Metod som returnerar poängen för kasten i en runda.
        {
            int totalt = throwOne + throwTwo + throwThree;
            return totalt;
        }
        public override string ToString()
        {
            return string.Format("Throw one: {0}, Throw two: {1}, Throw three: {2} ", throwOne, throwTwo, throwThree);
        }
    }
}
Citera
2022-03-28, 20:03
  #3
Medlem
Det är ganska lätt att komma igång med. Skapa ett nytt winform projekt i VS och drag-droppa en knapp i det formet som finns där från början. Dubbelklicka på knappen och du är rätt inne i koden.
https://docs.microsoft.com/en-us/vis...o?view=vs-2022
Citera
2022-03-28, 20:12
  #4
Medlem
Bonnatorps avatar
Citat:
Ursprungligen postat av NilsHlt
Det är ganska lätt att komma igång med. Skapa ett nytt winform projekt i VS och drag-droppa en knapp i det formet som finns där från början. Dubbelklicka på knappen och du är rätt inne i koden.
https://docs.microsoft.com/en-us/vis...o?view=vs-2022
Jo det är uppenbart, men för att börja med det allra mest banala:
Hur gör jag för att ta texten i en textbox och använda i programmet, och sedan se till att programmet körs och visar sin output i en ruta efter att jag tryckt på knappen?
Citera
2022-03-28, 20:14
  #5
Moderator
Pontiac-Garages avatar
Enklast är att du bara start upp ett nytt Windows Forms-projekt, samt adderar knappar mm. Hur man startar upp ett nytt Windows Forms-projekt ser du här.

När du adderar knappar så kopplar du i nästa steg instruktioner till knapptryck, där du kan använda den kod du har byggt för att utföra resp. instruktion. Resultaten visas lämpligen i en label eller i pop up-meddelanden.
Citera
2022-03-28, 20:16
  #6
Moderator
Pontiac-Garages avatar
Citat:
Ursprungligen postat av Bonnatorp
Jo det är uppenbart, men för att börja med det allra mest banala:
Hur gör jag för att ta texten i en textbox och använda i programmet, och sedan se till att programmet körs och visar sin output i en ruta efter att jag tryckt på knappen?

Varje skapad textbox har sin egen identifierare, och du kan koppla ett knapptryck till att hämta värdet i TextBox.Text från vald textbox.

Output visas i t.ex. en label, eller i ett pop up-meddelande. Enklast är att ta en sak i taget när du "översätter" din konsolapplikation till en Windows Forms-applikation.
Citera
2022-03-28, 20:18
  #7
Moderator
Pontiac-Garages avatar
Här har du en video som verkar gå igenom det hela på en nybörjarvänlig nivå:

https://www.youtube.com/watch?v=zfz49gjnjcY
Citera
2022-03-29, 14:04
  #8
Medlem
Bonnatorps avatar
Tack för hjälpen hittills, men nu har jag en mer specifik fråga.

Jag har en knapp som kör beräkningen jag vill (vet i teorin hur jag ska göra, tror jag, har bara inte pysslat ihop det än), genom att hämta värdet från textrutan, och skriva något i en annan textruta.
Hur gör jag för att samma knapp så att säga ska gå till nästa del i programmet?

Funktionen i fråga är att jag ska skriva in ett värde för den poäng man får i rutan (jag har förstås alla funktioner för programmet i fråga färdiga, kan nog bara klippa om en stor del av det för att passa här), spara till en variabel, och sedan visa en annan text i den ovanstående textrutan.
Men sedan vill jag skriva nästa värde i samma ruta och spara i en annan variabel. När jag gjort detta tre gånger så ska samma sak repeteras, fast för nästa spelare. Samma variabler, fast i nytt objekt.

Hur gör jag detta?
Alltså att gå vidare i knappens funktionalitet för nästa gång jag trycker på knappen.
Citera
2022-03-29, 14:09
  #9
Medlem
Enterprises avatar
Citat:
Ursprungligen postat av Bonnatorp
Tack för hjälpen hittills, men nu har jag en mer specifik fråga.

Jag har en knapp som kör beräkningen jag vill (vet i teorin hur jag ska göra, tror jag, har bara inte pysslat ihop det än), genom att hämta värdet från textrutan, och skriva något i en annan textruta.
Hur gör jag för att samma knapp så att säga ska gå till nästa del i programmet?

Funktionen i fråga är att jag ska skriva in ett värde för den poäng man får i rutan (jag har förstås alla funktioner för programmet i fråga färdiga, kan nog bara klippa om en stor del av det för att passa här), spara till en variabel, och sedan visa en annan text i den ovanstående textrutan.
Men sedan vill jag skriva nästa värde i samma ruta och spara i en annan variabel. När jag gjort detta tre gånger så ska samma sak repeteras, fast för nästa spelare. Samma variabler, fast i nytt objekt.

Hur gör jag detta?
Alltså att gå vidare i knappens funktionalitet för nästa gång jag trycker på knappen.
Drar detta från mitt dammiga minne, men det funkar väl på samma sätt i Visual Studio som i Visual Basic och Delphi som jag pulat med en gång i tiden.

Om du dubbelklickar på knappen så öppnas automatisk kodfönstret och skapas en metod som heter något i stil med Button1_On_Click eller liknande. Där ligger du i den kod som ska köras när du trycker på knappen.

Om samma knapp ska göra olika saker i olika skeden (vilket kanske är lite tveksamt användarvänligt) så får du sätta upp flaggor inuti objektet som håller reda på vilken status som knappen just nu har, sen kör du en switch i event handlern (On_Click)

För att ta en analogi från spelvärlden:
* Vi har en eventloop i spelmotorn som snurrar runt evigt
* Det finns tre olika lägen i spelet: 1) Intro 2) Spelläget och 3) Slut/High Score
* Spelmotorn håller reda på vilket läge man är i genom flaggan gameMode
* Om gameMode är 1 så ritar spelmotorn introduktionsgrafik och väntar på användarinput
* Om gameMode är 2 så ritar spelmotorn den vanliga spelgrafiken och tar in användarinput för att flytta på objekt etc
* Om gameMode är 3 så visar spelmotorn high score-skärmen.

I ditt visual studio-fall så behöver du inte göra eventloopen, eftersom den sköts automatiskt.
Du gör istället en eventhandler som hanterar klick på knappen. Däremot måste du sätta upp din egen gameMode-property för att hålla reda i vilket skede du befinner dig, vilket - beroende på gameModes innehåll vid tidpunkten - innebär olika funktions/metodanrop från event handlern.
__________________
Senast redigerad av Enterprise 2022-03-29 kl. 14:32.
Citera
2022-03-29, 15:51
  #10
Moderator
Pontiac-Garages avatar
Citat:
Ursprungligen postat av Bonnatorp
Tack för hjälpen hittills, men nu har jag en mer specifik fråga.

Jag har en knapp som kör beräkningen jag vill (vet i teorin hur jag ska göra, tror jag, har bara inte pysslat ihop det än), genom att hämta värdet från textrutan, och skriva något i en annan textruta.
Hur gör jag för att samma knapp så att säga ska gå till nästa del i programmet?

Funktionen i fråga är att jag ska skriva in ett värde för den poäng man får i rutan (jag har förstås alla funktioner för programmet i fråga färdiga, kan nog bara klippa om en stor del av det för att passa här), spara till en variabel, och sedan visa en annan text i den ovanstående textrutan.
Men sedan vill jag skriva nästa värde i samma ruta och spara i en annan variabel. När jag gjort detta tre gånger så ska samma sak repeteras, fast för nästa spelare. Samma variabler, fast i nytt objekt.

Hur gör jag detta?
Alltså att gå vidare i knappens funktionalitet för nästa gång jag trycker på knappen.

Enklast är ju att du representerar resp. spelare som egna objekt, där du har dina tre variabler som attribut till resp. spelare. Sedan får du har en variabel som räknar antalet knapptryck, som du sedan ökar för varje gång knappen trycks ned. När alla variablerna är fyllda så växlar du över till nästa objekt/spelare. Spelarna kan då lämpligen lagras i t.ex. en lista.

Dock är det nog bättre att du filar på ett lite mer användarvänligt gränssnitt, en enda knapp som ska styra hela programmet och som ska tryckas ned om och om igen riskerar nog att leda till missförstånd.
__________________
Senast redigerad av Pontiac-Garage 2022-03-29 kl. 15:53.
Citera
2022-03-29, 17:40
  #11
Medlem
Bonnatorps avatar
Citat:
Ursprungligen postat av Pontiac-Garage
Enklast är ju att du representerar resp. spelare som egna objekt, där du har dina tre variabler som attribut till resp. spelare. Sedan får du har en variabel som räknar antalet knapptryck, som du sedan ökar för varje gång knappen trycks ned. När alla variablerna är fyllda så växlar du över till nästa objekt/spelare. Spelarna kan då lämpligen lagras i t.ex. en lista.

Dock är det nog bättre att du filar på ett lite mer användarvänligt gränssnitt, en enda knapp som ska styra hela programmet och som ska tryckas ned om och om igen riskerar nog att leda till missförstånd.
Nja särskilt användarovänligt behöver det inte vara.

Knappen kan heta "Enter", bara för att göra det extra drygt och mena på att det fungerade bättre med konsolapplikationen.
Spelet har ändå bara en enda funktion åt gången hela tiden, så det finns ingen orsak att ha fler än en knapp, utom möjligen att det blir lättare att koda flera knappar.
Citera
2022-03-29, 18:28
  #12
Medlem
Enterprises avatar
Citat:
Ursprungligen postat av Bonnatorp
Nja särskilt användarovänligt behöver det inte vara.

Knappen kan heta "Enter", bara för att göra det extra drygt och mena på att det fungerade bättre med konsolapplikationen.
Spelet har ändå bara en enda funktion åt gången hela tiden, så det finns ingen orsak att ha fler än en knapp, utom möjligen att det blir lättare att koda flera knappar.
Du kan ha samma knapp, men ändra på knapptexten genom Propertyn Caption beroende på vad den ska göra.
Det är lika enkelt som att ändra en variabel.
Om du vill förenkla så kan du också lägga in en event handler på key press och fånga upp Enter-knappen
Citera
  • 1
  • 2

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in