[ negative7 @ 22.05.2010. 18:29 ] @
Evo kod za igricu gdje padaju slova i ja kad pogodim dano slovo ono se pobrise.Na ekranu je je max 10 vrsta slova,medjutim problem je sto mogu imat medju tih 10 2 ili 3 ista,i drugi jos veci problem nekad ih nacrta jedne preko druge,pa jel moze netko ispraviti te greske uz dodatno objasnjenje:

Form1.cs:

Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Timer = System.Timers.Timer;

namespace Typer
{
    public partial class Form1 : Form
    {
        const int INTERVAL = 2000;

        Timer timer = new Timer();
        int index = 0;
        int counter = 0;

        private Font font = new Font("Arial", 30f);
        
        public int Bodovi = 0;
        int indikator = 1;
        
        public Form1()
        {
            InitializeComponent();

            timer.Enabled = true;
            timer.Interval = 40;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            foreach (Znak znak in Znak.Znakovi)
            {
                znak.Move();
            }

            counter += (int)timer.Interval;

            if (counter >= INTERVAL)
            {
                Znak.Znakovi[index].Alive = true;
                index++;
                counter = 0;
                index = index % 10;
            }

            if (Bodovi > indikator * 100)
            {
                Znak.Speed += 1;
                indikator++;
            }

            Invalidate();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            foreach (Znak znak in Znak.Znakovi)
            {
                znak.Draw(e.Graphics);
            }

            e.Graphics.DrawString(Bodovi.ToString(), font, Brushes.Green, Point.Empty); 
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                Znak znak = new Znak(this);
            }
        }

        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            foreach (Znak znak in Znak.Znakovi)
            {
                if (znak.Character == e.KeyChar)
                {
                    znak.Initialize();
                    Bodovi += 10;
                }
            }
        }
    }
}



Znak.cs:

Code:

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

namespace Typer
{
    class Znak
    {
        
        private static List<Znak> znakovi;
        private Point position;
        private static int speed = 1;
        private Font font = new Font("Arial", 30f);
        private char character;
        private bool alive;
        private static Random random;
        private Form1 forma;

        public static int Speed
        {
            get { return speed; }
            set { speed = value; }
        }

        public static List<Znak> Znakovi
        {
            get
            {
                return znakovi;
            }
        }

        public char Character
        {
            get { return character; }
        }

        public bool Alive
        {
            get { return alive; }
            set { alive = value; }
        }

        public void Move()
        {
            if (alive)
            {
                position.Y += speed;

                if (position.Y > forma.Height)
                {
                    Initialize();
                    forma.Bodovi -= 20;
                }
            }
        }

        public void Initialize()
        {
            character = OdaberiZnak();
            position = new Point(random.Next(0, forma.Width - 40), -50);
        }

      
        private char OdaberiZnak()
        {
            int start = (int)'a';
            int end = (int)'z';

            int poz = random.Next(start, end + 1);

            return (char)poz;
        }
       

        public void Draw(Graphics g)
        {
            g.DrawString(character.ToString(), font, Brushes.White, position);
        }

        static Znak()
        {
            znakovi = new List<Znak>();
            random = new Random();
        }

        public Znak(Form1 form)
        {
            znakovi.Add(this);//dodajemo objekt u listu
            forma = form;
            Initialize();
        }
    }
}



[Ovu poruku je menjao negative7 dana 23.05.2010. u 23:56 GMT+1]
[ Boris B. @ 24.05.2010. 12:47 ] @
Popravi red
Code:

position = new Point(random.Next(0, forma.Width - 40), -50);  


u

Code:

var ok = false;
do
  position = new Point(random.Next(0, forma.Width - 40), -50);
while (znakovi.Where(znak => (znak.position >= this.position) && (znak.position < this.position + 50)).Count > 0);


Samo pazi, ako je raspoloziva sirina igrackog polja premala moze se desiti da se do-while nikada ne zavrsi.
Napisati deterministicku funkciju koja to radi kako treba je daleko veci izazov, razmislicu malo jer izgleda interesantno.

Isti sistem upotrebi pri generisanju slova, znaci nadjes random ali samo ako neko od prethodnih slova nije vec iskorisceno.

Code:

 private char OdaberiZnak()
        {
            int start = (int)'a';
            int end = (int)'z';
            int poz = ;
            do
              int poz = random.Next(start, end + 1)
            while (znakovi.Where(znak => (int)znak.Znak == poz).Count > 0)
            return (char)poz;
        }
[ negative7 @ 25.05.2010. 09:45 ] @
a jel mozes mi malo poblize objasnit funkciju Where() kao i operator =>
[ Boris B. @ 26.05.2010. 06:59 ] @
"Where" je Linq extension metod, a ono => je tzv. Linq expression, nesto sto su haskel i ostali funkcijski programeri na C# timu uspeli da uglave u jezik kao standard. Ista stvar moze da se zapise i imperativno-iterativno:

Code:

while (znakovi.Where(znak => (znak.position >= this.position) && (znak.position < this.position + 50)).Count > 0);
<=>
bool ok = true;
foreach(var znak in znak.znakovi)
 if (znak.position >= this.position) && (znak.position < this.position + 50)
 {
    ok = false;
    break;
 }


Otprilike ovakav kod se generise posle predkomajliranja onog LINQ-a (nije skroz isti jer onaj LINQ trazi COUNT elemenata koji zadovoljavaju uslov, ali tebi ne treba count nego samo da li ih ima ili nema)

Nisam ni ja nesto odusevljen LINQ-om ali je postao de facto standard i neke stvari je lakse-brze zapisati, mada u rukama experata moze brzo da se otme kontroli i postane totalno necitljiv, kao define-i u C++. ;)


[ Boris B. @ 26.05.2010. 07:31 ] @
Malo sam juce razmisljao o tvom problemu prekrivanja slova. Otprilike bi izgledalo ovako:

1. Znas kolika je sirina igrackog polja, tj. Form>Width, nazovimo ga "TW"
2. Znas koliko ima ukupno slova koje hoces da rasporedis, nazovimo ga "N"
3. Znas kolika je sirina svakog slova, nazovimo ga W.


- Problem je randomizirati prazne prostore kojih ima N+1.
- Ukupna sirina praznog prostora koji ti je na raspolaganju za randomizaciju i rezanje na N+1 delova iznosi DW = TW - N*W
- Kazi neka ti je svaki pojedinacni prazan prostor Random od 1 do npr. 1000. Onda saberi sve dobijene randome i vidi za koliko ti prekoracuju DW. Znaci neki EW = DW - SUM(R1..RN)
- Kada podelis DW sa EW dobices neki broj manji od 1, neki koeficijent K = DW/EW.
- Onda samo taj koeficijent pomnozis sa svakim pojedinacnim randomom koji si dobio i dobices vrednosti praznih prostora izmedju slova koji pasuju u igracko polje a i dalje su random




[ negative7 @ 26.05.2010. 11:07 ] @
- Ukupna sirina praznog prostora koji ti je na raspolaganju za randomizaciju i rezanje na N+1 delova iznosi DW = TW - N*W

ali mi je problem jer se ovo N mijenja,mislim imam kasnije vise prostora nego u pocetku,jer samo u pocetku oni zajedno pocnu padat,kasnije cim ja pogodim jedno slovo izadje drugo,tako da u biti y koordinata im je razlicita a x ista i to mi odgovara,nemogu N fixirat na 10,a za sirinu svakog slova fiksno sam gore uzeo da je manja od 40,nisam racunao,a jesam li trebao preko Sizef i sirinu i visinu?pa da mi onda metoda public void Initialize() izgleda public void Initialize(Sizef ds)

ds->dimenzije slova

[ Boris B. @ 27.05.2010. 08:43 ] @
Sta se desi sa slovom ako padne do dna a korisnik ne klikne na njega?
[ negative7 @ 27.05.2010. 13:01 ] @
Novo slovo se stvori na vrhu ekrana,(odnosno na y=-50 tj, nevidi se odma cim pocne padati) i pocne padati prema dole