štvrtok, 22 december 2011 19:12 Written by 69780 times
Rate this item
(2 votes)

C# - Hadík

Ukážeme si ako spraviť jednoduchú hru "hadika - snake". Princíp hry: Používaj šípky na klávesnici. Snaž sa pozbierať hadíkom čo najviac jabĺčok (červených štvorčekov) a začni rásť, ale nenaraz do stien alebo do tela hadíka .

Najprv si vytvoríme triedu (class) segment , ktorá  bude reprezentovať jednu kocku z nášho hadika. Mohla by vyzerať napr. takto:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace hra_hadik
{
    class Segment : ICloneable
    {
        private Rectangle rectangle; 
      
        public Segment(int width, int height, int x, int y)
        {
            this.rectangle = new Rectangle(x, y, width, height);
        }
        public int X
        {
            get { return this.rectangle.X; }
            set { this.rectangle.X = value; }
        }

        public int Y
        {
            get { return this.rectangle.Y; }
            set { this.rectangle.Y = value; }
        }
        public Rectangle ToRectangle()
        {
            return this.rectangle;
        }

        public object Clone()
        {
            return MemberwiseClone();
        }
    }
}

Ďalej nám treba spraviť triedu hadika, ktorú nazveme napr snake a bude vyzerať takto:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace hra_hadik
{
    class Snake
    {
        private readonly List<Segment> segments;
        public static readonly int width = 10;
        public static readonly int height = 10;
        private int skore = 0;

        public Snake()
        {
            this.segments = new List<Segment>();

            Segment segment = new Segment(width, height, 0, 0);
            this.segments.Insert(0, segment);

            segment = new Segment(width, height, width, 0);
            this.segments.Insert(1, segment);

            //hlava hadika
            segment = new Segment(width, height, 2 * width, 0);
            this.segments.Insert(2, segment);
        }
        public bool RovnakySegment(Segment mySegment1, Segment mySgment2)
        {
            return ((mySegment1.X == mySgment2.X) && (mySegment1.Y == mySgment2.Y));
        }
        public bool PohniHadika()
        {


            //posunieme telo hadika
            for (int i = 0; i < this.PoziciaHlavy; i++)
            {
                this.segments[i] = this.segments[i + 1].Clone() as Segment;
            }

            //posunieme hlavu na novu poziciu
            switch (SmerHadika)
            {
                case Pohyb.Left:

                    this.segments[this.PoziciaHlavy].X -= width;

                    break;

                case Pohyb.Right:

                    this.segments[this.PoziciaHlavy].X += width;

                    break;

                case Pohyb.Up:

                    this.segments[this.PoziciaHlavy].Y -= height;

                    break;

                case Pohyb.Down:

                    this.segments[this.PoziciaHlavy].Y += height;

                    break;
            }

            //skontroluje ci hlava hadika sa nedotkla tela

            //posunieme zbytok tela
            for (int i = 0; i < this.PoziciaHlavy; i++)
            {
                if (this.RovnakySegment(this.segments[i], this.segments[this.PoziciaHlavy]))
                {
                    return false;
                }
            }

            return true;

        }
        public void PridajSegmentHadika()
        {
            Segment segment = new Segment(width, height, -10, -10);
            this.segments.Insert(0, segment);
            this.skore += 10;
        }
        public List<Segment> ToSegments
        {
            get { return this.segments; }
        }

        public int PoziciaHlavy
        {
            get { return this.segments.Count - 1; }
        }
        public int Skore
        {
            get { return this.skore; }
        }
        public Pohyb SmerHadika { get; set; }
        public enum Pohyb
        {
            Left,
            Right,
            Up,
            Down
        }
    }
}

Na začiatku si vykreslíme samotného hadika,ktorý sa bude skladať z 3 segmentov. Ešte vykreslime náhodne jedno jabĺčko, ktorého súradnice sa budu meniť vždy keď ho hadik "zje".Zdrojový kód samotnej hry by mohol vyzerať nejako dakto:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;

namespace hra_hadik
{    
    class SnakeGame
    {
        private readonly static int WidtHracejPlochy = 500;
        private readonly static int HeightHracejPlochy = 500;
        private readonly PictureBox canvas;
        private readonly Snake hadik = new Snake();
        private readonly SolidBrush farbaTela = new SolidBrush(Color.LightBlue);
        private readonly SolidBrush farbaTextu = new SolidBrush(Color.Gray);
        private readonly SolidBrush farbaJedla = new SolidBrush(Color.Red);
        Segment jedlo1 = new Segment(Snake.width, Snake.height, 50, 50);
        Random random = new Random();

        public SnakeGame(PictureBox canvas)
        {
            this.canvas = canvas;         

            this.hadik.SmerHadika = Snake.Pohyb.Right;     
            
            this.canvas.Paint += new PaintEventHandler(canvas_Paint);

        }
       /// <summary>
       /// nastavime novy smer pre hadika
       /// </summary>
       /// <param name="novySmer"></param>
        public void NastavSmer(hra_hadik.Snake.Pohyb novySmer)
        {
            this.hadik.SmerHadika = novySmer;          
        }
        /// <summary>
        /// Overime ci je hadik v hracom poli
        /// </summary>
        /// <returns></returns>
        public bool KoniecHry()
        {
            if (this.hadik.ToSegments[this.hadik.PoziciaHlavy].X < 0 || this.hadik.ToSegments[this.hadik.PoziciaHlavy ].Y < 0)
            {
                return true;
            }
            if (this.hadik.ToSegments[this.hadik.PoziciaHlavy].X > WidtHracejPlochy  || this.hadik.ToSegments[this.hadik.PoziciaHlavy].Y > HeightHracejPlochy)
            {
                return true;
            }

            return false;

        }
        /// <summary>
        /// Vykreslime hracie pole
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void canvas_Paint(object sender, PaintEventArgs e)
        {

               
            e.Graphics.DrawString("Score :"+this.hadik.Skore, new Font(FontFamily.GenericSansSerif, 12, FontStyle.Bold), this.farbaTextu,0,0);
               
            e.Graphics.FillRectangle(this.farbaJedla, jedlo1.ToRectangle());

            if (this.KoniecHry())
            {
                e.Graphics.DrawString("Koniec hry", new Font(FontFamily.GenericSansSerif, 24, FontStyle.Bold), this.farbaTextu, 150, 150);
                return;
            }

            if (this.hadik.PohniHadika() == false)
            {
                e.Graphics.DrawString("Koniec hry", new Font(FontFamily.GenericSansSerif, 24, FontStyle.Bold), this.farbaTextu, 150, 150);
                return;
            }
            if(this.hadik.RovnakySegment(this.hadik.ToSegments[this.hadik.PoziciaHlavy],this.jedlo1))
            {
                jedlo1 = new Segment(Snake.width, Snake.height, Snake.width * this.random.Next(0, 50), Snake.height * this.random.Next(0, 50));
                this.hadik.PridajSegmentHadika();
            }

            foreach (Segment telo in this.hadik.ToSegments)
                e.Graphics.FillRectangle(this.farbaTela, telo.ToRectangle());

            Thread.Sleep(20);
           
            //budeme zvysovat rychlost,ak sa zmeni skore
            if(this.hadik.Skore < 100)
                Thread.Sleep(20);
            if (this.hadik.Skore < 150)
                Thread.Sleep(20);
            if (this.hadik.Skore < 200)
                Thread.Sleep(20);
            if (this.hadik.Skore < 250)
                Thread.Sleep(20);
            if (this.hadik.Skore < 300)
                Thread.Sleep(20);
            if (this.hadik.Skore < 350)
                Thread.Sleep(20);
            
            e.Graphics.DrawString("www.projectik.eu", new Font(FontFamily.GenericSansSerif, 10, FontStyle.Bold), this.farbaTextu, 150, 150);
            
           this.canvas.Invalidate();
            
        }
    }
}

V prílohe si môžete stiahnuť kompletné zdrojové kódy tejto hry.

Last modified on pondelok, 19 december 2016 21:33
Ing.Jaroslav Vadel

Som zakladateľom www.projectik.eu.

Hrám sa na programátora, ktorý ovláda:

c#,cpp,java,unity3d,php,html,NI testand,NI Vision Builder,Cognex In-Sight,NI LabView

"Naprogramovať program, ktorý funguje vie každy. Ale to, že program funguje ešte neznamena, že je napísany správne "

Website: www.projectik.eu