• Apgrejdovali smo forum na XenForo 2.1.1, ukoliko imate predloga vezanih za izgled ili funkcionalnost foruma, ili ukoliko naletite na neki problem, javite nam OVDE

    DEFINISALI SMO PRAVILA FORUMA. Pročitajte ih, pojaviće se automatski kada krenete da čitate nešto!

XNA Programiranje Igara | Tutorijal #12 | Igra Memorije - Drugi Deo

Uni

PCAXE Addicted
Učlanjen(a)
31.08.2018.
Poruka
2.469
Rezultat reagovanja
984
Moja konfiguracija
PC / Laptop Name:
Lenovo ThinkPad X250 - i5 5300U/8GB/256GB EVO 860/6 Cell
Mice & keyboard:
Bloody V7M & Stock Thinkpad X250 Keyboard
OS & Browser:
Windows 10 + Microsoft Edge | ArcoLinux + i3 + Mozilla Firefox Quantum
Ako nemate barem osnovno znanje o C#-u ili ikakvo znanje o programiranju, preporučio bih vam da pročitate moj mali "kurs" napisan o tome koji je dostupan baš na ovom forumu potpuno besplatno. Sastoji se iz samo 13 kratkih tutorijala, koji će vam omogućiti da rešavate razne logičke probleme, a velika većina ovog kursa se takođe bazira na samim osnovama. Sve što je potrebno jeste da u polje "pretraga" unesete pojam #xna-gwid što će vam pokazati sve objavljene tutorijale, među kojima će se naći i ovaj tutorijal. :)

**Predlog** Kod čitajte na AXE Light temi, pošto ova opcija za kod koristi baš tamne boje, mada ću se truditi da je što manje koristim :d

Šta ćemo danas obraditi?
U prethodnom tutorijalu, uspostavili smo grafički korisnički interfejs i sve elemente naše igre. Preostaje samo dodavanje logike koja omogućava selektovanje najviše dve ćelije, a ukoliko su grafički elementi isti, više ih ne sakriva. Ako ste spremni, hajde da počnemo!

Sakrivanje i Prikazivanje Simbola
Da bismo mogli pošteno da igramo igru memorije, moramo "karte" položiti licem okrenute nadole. Mi ćemo se poslužiti jednim malim trikom, prikrivanjem simbola. Ovo znači da kada "karta" nije okrenuta, simbol ćemo obojiti istom bojom kao i pozadinu pa će on biti nevidljiv. Jednostavno, selektujmo sve simbole, držanjem dugmeta Control, a zatim karakteristiku ForeColor promenimo u Crimson ili boju vašeg izbora. Primetićete da su sada simboli stopljeni sa pozadinom i da se više ne vide, što i želimo. Sada, dok su još uvek selektovani svi simboli, pritisnimo dugme Events. Ovde su locirani različiti događaji, koji mogu nastati kao posledica korisničke interakcije sa objektima. To može biti pritisak dugmeta, klik miša, skrolovanje itd. U našem slučaju, želimo da se simbol prikaže pri pritisku istog. Ovo radimo dodavanjem funkcije Click (slika ispod). Imenujemo polje Click po našem izboru (ja sam ga imenovao "tekst_Klik") i zatim pritisnemo Enter. Visual Studio će nas automatski preusmeriti u obradu koda.
Untitled.png
Sada u bloku void tekst_Klik metode, unesimo sledeće :
C#:
Label tekst = (Label)sender;

if (tekst == null)
    return;
if (tekst.ForeColor == Color.White)
    return;
if (prvaKliknuta == null)
{
    prvaKliknuta = tekst;
    prvaKliknuta.ForeColor = Color.White;
    return;
}
Pre svega, sender predstavlja objekat koji daje povratnu informaciju programu, u našem slučaju je to tekst koji sadrži simbol. Naš program će pokušati da prevede sender u label, tj. tekst. U slučaju da je konverzija ispunjena neuspešno, tj. da tekst ima vrednost null (nema vrednost), preskačemo sav naredni kod bloka pomoću prazne komande return. Takođe, trenutno je moguće prevariti igru i dva puta pritisnuti isti simbol. Kako bismo ovo sprečili, ukoliko je boja simbola bela (okrenuta "karta") ponovo preskačemo ceo blok koda i ne dozvoljavamo selekciju tog simbola, jer je on već selektovan. Treći if upit proverava ukoliko je bilo koja "karta" okrenuta. Ako je povratna vrednost null, tj. nema vrednost, prvoj Kliknutoj karti se dodeljuje vrednost kliknutog simbola, a zatim se ona boji u belo (prikazuje na ekranu) i preskače se ostatag bloka. Sada ako probamo našu igru, moći ćemo da selektujemo, samo i isključivo jednu ćeliju.

Sada ćemo korisniku omogućiti i selekciju druge ćelije. Odmah nakon poslednjeg if upita, ubacimo sledeći kod :
C#:
drugaKliknuta = tekst;
drugaKliknuta.ForeColor = Color.White;
Ako nijedan od prethodnih uslova nije ispunjen, to automatski znači da selektovani simbol nije već selektovan, nije prazan i da je prva "karta" već okrenuta. Posledica netačnosti sva tri uslova govori igri da je na redu selekcija druge "karte". Nakon klika na dati objekat, promenljivoj drugaKliknuta se dodeljuje vrednost selektovanog simbola i ona postaje vidljiva (bela). Međutim, ako sada pokrenemo igru, moći ćemo da selektujemo sve simbole, bez povratne informacije programa. Ovo se dešava jer igri ni u jednom trenutku nismo rekli da zaustavi mogućnost selekcije, kada su obe "karte" okrenute licem na gore. Ovaj "bag" popravljamo dodavanjem sledeće linije na samom početku bloka (ispred Label tekst = (Label)sender;) :
C#:
if (prvaKliknuta != null && drugaKliknuta != null)
     return;
Dodavanjem ove dve linije, u slučaju da su obe "karte" otvorene, preskače se ceo blok koda i ništa se ne dešava. Iako igra sasvim funkcioniše, nemoguće je selektovanje više od dve slike.

Tajmeri
Želimo da u slučaju odabira dva različita znaka sakrijemo simbole nakon određenog vremenskog intervala ponovo. Ovo obavljamo pomoću tajmera. Tajmeri nam omogućavaju da obavljamo događaje nakon određenih vremenskih intervala. Da bismo dodali tajmer u našu igru, ponovo otvorimo Toolbox i dva puta pritisnemo Timer. Jednom pritisnemo na tajmer da bismo ga selektovali, a zatim promenimo karakteristiku Interval u 750. Interval određuje dužinu trajanja tajmera u milisekundama. Potrebno je dodati događaj tajmeru, koji se zove Tick tako što iz panela Events pritisnemo dva puta događaj. U bloku metode Timer1_Tick ubacimo sledeći kod :
C#:
timer1.Stop();

prvaKliknuta.ForeColor = Color.Crimson;
prvaKliknuta = null;

drugaKliknuta.ForeColor = Color.Crimson;
drugaKliknuta = null;
Prva linija govori da ne želimo da ponovimo tajmer nakon njegovog isteka. Drugom linijom koda ponovo prikrivamo prvi Kliknuti simbol, promenom njegove boje u crvenu ili boju vašeg izbora. Sledećom linijom uklanjamo vrednost prve Kliknute karte, vraćanjem na null (bez vrednosti). Tajmer i dalje ne radi, ali ćemo ga kasnije uključiti.

Provera Jednakosti Simbola
Vratimo se u blok tekst_Klik metode. Ispod poslednje linije unećemo sledeći kod :
C#:
if (prvaKliknuta.Text == drugaKliknuta.Text)
{
    prvaKliknuta = null;
    drugaKliknuta = null;
}
else
   timer1.Start();
Upitom if proveravamo da li su obe selektovane ćelije popunjene istim vrednostima. Ukoliko je ovo tačno, ne želimo da ih prikrivamo i želimo da ih vratimo na standardne (prazne) vrednost dodeljujući im vrednost null. U suprotnom, želimo da startujemo tajmer, koji poziva događaj opisan prethodnom sekcijom.

Sada vam samo preostaje da se igrate! :)

C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Memorija
{
    public partial class Form1 : Form
    {
        Random rand = new Random();

        List<string> simboli = new List<string>()
        {
            "u","u","h","h","l","l","r","r",
            "q","q","w","w","t","t","o","o"
        };

        Label prvaKliknuta, drugaKliknuta;

        public Form1()
        {
            InitializeComponent();
            DodeliIkonePoljima();
        }

        private void tekst_Klik(object sender, EventArgs e)
        {
            if (prvaKliknuta != null && drugaKliknuta != null)
                return;

            Label tekst = (Label)sender;

            if (tekst == null)
                return;
            if (tekst.ForeColor == Color.White)
                return;
            if (prvaKliknuta == null)
            {
                prvaKliknuta = tekst;
                prvaKliknuta.ForeColor = Color.White;
                return;
            }

            drugaKliknuta = tekst;
            drugaKliknuta.ForeColor = Color.White;

            if (prvaKliknuta.Text == drugaKliknuta.Text)
            {
                prvaKliknuta = null;
                drugaKliknuta = null;
            }
            else
                timer1.Start();
        }

        private void Timer1_Tick(object sender, EventArgs e)
        {
            timer1.Stop();

            prvaKliknuta.ForeColor = Color.Crimson;
            prvaKliknuta = null;

            drugaKliknuta.ForeColor = Color.Crimson;
            drugaKliknuta = null;
        }

        private void DodeliIkonePoljima()
        {
            Label tekst;
            int nasumicniBroj;

            for (int i = 0; i < tableLayoutPanel1.Controls.Count; i++)
            {
                tekst = (Label)tableLayoutPanel1.Controls[i];

                nasumicniBroj = rand.Next(0, simboli.Count);
                tekst.Text = simboli[nasumicniBroj];

                simboli.RemoveAt(nasumicniBroj);
            }
        }
    }
}

Šta dalje?
gif.gifUspešno ste dovršili još jednu kompletnu igru u C#-u. Sada možete i sami dodavati ili menjati neke od detalja, kao i dorađivati nedorađene delove igre. Ako smatrate neki deo koda ili objašnjenja nejasnim, pitajte u komentaru i naravno tu smo komuna i ja da vam pomognemo! Srećno kucanje! :) Ako želite da znate kako izgleda finalna igra, možete je videti sada na ekranu :)
 
Poslednja izmena:

Raspucin

PCAXE Addicted
Učlanjen(a)
30.09.2017.
Poruka
1.590
Rezultat reagovanja
908
Moja konfiguracija
PC / Laptop Name:
Kompjuter
CPU & cooler:
Intel I7 8700K + Phanteks Glacier One 360MP
Motherboard:
Gigabyte H370 Aorus Gaming 3 WiFi
RAM:
G.Skill TridentZ 32gb (2x16gb) 3200mhz
VGA & cooler:
Gigabyte G1 1060 6Gb
Display:
LG 34'' 34WP65CP-B,1ms, 3440 x 1440, 160Hz
HDD:
Intel 660 512gb Nvme,Samsung 970 Evo Plus Nvme 500gb
Sound:
Razen Kraken X
Case:
Phanteks Enthoo Evolv X TG RGB silver + 3 x Phanteks 140 Fun
PSU:
Gigabyte Aorus 750W 80+ Gold
Optical drives:
Asus ZenDrive external
Mice & keyboard:
Redragon Karura2/HyperX Pulsfire FPS
Internet:
Adsl 20/1
OS & Browser:
Windows 11 Pro 64bit & Firefox
Other:
ThinkPad T14s, MacBook M2 , Think Dock, Xaomi 13, PS 5 Slim,Samsung Galaxy Watch 4
Sugestija,za vise od dva if-a,koristi se swich:):talas:
 
  • Like
Reagovanja: Uni

Uni

PCAXE Addicted
Učlanjen(a)
31.08.2018.
Poruka
2.469
Rezultat reagovanja
984
Moja konfiguracija
PC / Laptop Name:
Lenovo ThinkPad X250 - i5 5300U/8GB/256GB EVO 860/6 Cell
Mice & keyboard:
Bloody V7M & Stock Thinkpad X250 Keyboard
OS & Browser:
Windows 10 + Microsoft Edge | ArcoLinux + i3 + Mozilla Firefox Quantum
Dobro je koristiti switch, ali me je stvarno mrzelo :d

Svakako u poslovnoj aplikaciji ili igri za nekog klijenta to je daleko bolje resenje ;)
 
Vrh