Permalänk
Medlem

Hjälp med tetris C#

Hej!
Håller på och programmerar tetris i C# och skulle behöva ha lite hjälp. Ritar ut alla klossar i en klass med en metod. Dessa klossar sparar jag i en lista. Jag har fått till kollisionsdetektion men inte hur man får bort en hel rad när den är full. Ett av problemen är ju att man inte kan ändra i listan i en foreach-loop. Lägger in koden och skriver kommentarer där jag behöver hjälp. Jag har heller aldrig programmerat innan så om ni inte tycker koden är så snygg så är det därför.

class kloss //klassen för att rita ut klossarna { public int posx = 30; public int posy = 30; public int turn = 1; int i; Random slumpGenerator = new Random(); Image im = Properties.Resources.ruta1; Image im1 = Properties.Resources.ruta2; Image im2 = Properties.Resources.ruta3; Image im3 = Properties.Resources.ruta4; Image im4 = Properties.Resources.ruta5; Image im5 = Properties.Resources.ruta6; Image im6 = Properties.Resources.ruta7; public kloss(int posx, int posy) { this.posx = posx; this.posy = posy; i = slumpGenerator.Next(1, 7); } public void drawImage(Graphics g) { if (i == 1) { switch (turn) // L formen { case 1: turn = 1; g.DrawImage(im, posx, posy, 20, 20); g.DrawImage(im, posx - 20, posy, 20, 20); g.DrawImage(im, posx + 20, posy, 20, 20); g.DrawImage(im, posx + 20, posy - 20, 20, 20); break; case 2: turn = 2; g.DrawImage(im, posx, posy, 20, 20); g.DrawImage(im, posx, posy + 20, 20, 20); g.DrawImage(im, posx, posy - 20, 20, 20); g.DrawImage(im, posx - 20, posy - 20); break; case 3: turn = 3; g.DrawImage(im, posx, posy, 20, 20); g.DrawImage(im, posx + 20, posy, 20, 20); g.DrawImage(im, posx - 20, posy, 20, 20); g.DrawImage(im, posx - 20, posy - 20, 20, 20); break; case 4: turn = 4; g.DrawImage(im, posx, posy, 20, 20); g.DrawImage(im, posx, posy - 20, 20, 20); g.DrawImage(im, posx, posy + 20, 20, 20); g.DrawImage(im, posx + 20, posy + 20, 20, 20); break; } }

private kloss test; private List<kloss> position; public Form1() { InitializeComponent(); timer1.Start(); test = new kloss(20, 20); test.turn = 1; position = new List<kloss>(); position.Add(test); } public void panel1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; test.drawImage(g); foreach(kloss s in position) { s.drawImage(g); } if (test.posy == 190) { test = new kloss(20, 20); position.Add(test); } } private void timer1_Tick(object sender, EventArgs e) { Graphics g = CreateGraphics(); test.posy++; this.Refresh(); foreach (kloss s in position) { if (test.posy + 40 == s.posy) { test = new kloss(20, 20); s.drawImage(g); } } position.Add(test); foreach(kloss s in position) // Här vill jag kolla om det är fullt på någon rad och sedan ta bort dessa ur listan. Det är det jag helt enkelt inte får till { if(nått villkor som kollar alla x-positioner ) { test = new kloss(20, 20); s.drawImage(); //här vill jag ta bort alla som heter s.posy och ligger på den rad som är full } } }

Permalänk
Medlem

Du skulle möjligtvis kunna skapa en ny temporär lista som du fyller med de objekt du vill ha kvar, sen så tilldelar du din befintliga lista den nya temporära.

alternativt använda en while eller for loop. Dock så gäller det att ha koll på din indexering

Visa signatur

CPU: i7 6700k + Fractal Design S24 GPU: ASUS GeForce GTX 1070 8GB DUAL OC RAM: Kingston 16GB 2133MHz CL13 MB: MSI GAMING M7 PSU: EVGA Supernova G2 850W, 80+ Gold SSD: Samsung SM951 256GB M.2 NVMe + Samsung EVO 850 250GB M.2 Chassi: Fractal Design S Skrämar: Acer XB270HU + 2x Dell U2412M
NAS: Synology DS415+ (4x WD RED 6 TB) Console: Xbox One

Permalänk

Om jag förstår ditt problemet rätt så är det hur man stryker element ur en lista (som man loopar på)?

Använd en for-loop och börja bakifrån!

List<int> myList = new List<int>(); myList.Add(10); myList.Add(20); myList.Add(30); myList.Add(40); int currentElement; for (int i = myList.Count - 1; i >= 0; i--) { currentElement = myList[i]; if (currentElement == 20) { myList.RemoveAt(i); } } foreach (int existingElement in myList) { Debug.WriteLine(existingElement); }

Visa signatur

"Mies saa kaatua mutta ei karata." -- Adolf Ehrnrooth IR 7, Äyräpää 1944.

Permalänk
Medlem
Citat:

Om jag förstår ditt problemet rätt så är det hur man stryker element ur en lista (som man loopar på)?

Använd en for-loop och börja bakifrån!

Ja det är ungefär så jag vill. Elementen som är sparade i listan är av element av typ kloss och det ställer till det lite. Jag vill inte radera hela klossar utan bara de delar som ligger på de koordinater som fyller hel rad i x-led. Det bör funka då klossarna ritas upp bit för bit.
Det verkar inte funka med en for-loop då jag inte kommer åt vilka koordinater klossarna är sparade på i listan som jag gör i foreach-loopen nedan. Den här fungerar som kollisionsdetektion.

foreach (kloss s in position) { if (test.posy + 40 == s.posy) { test = new kloss(20, 20); s.drawImage(g); } } position.Add(test);

Som sagt jag är totalnovis inom programmering och kanske är helt fel ute.

Permalänk

Nu hinner jag inte gå igenom din kod för att till 100% förstå hur du har tänkt.

Jag skulle nog föreslå att du skapar en egen klass för själva "klossberget", eftersom så fort som en kloss kolliderar med berget är det irrelevant vilken/vilka klossar som finns där. Men viktigare, eftersom rader försvinner så lämnas ju "halva" klossar kvar, hur ska du lösa det? Informationen du behöver är ju endast vilka positioner nere i spelplanen som är upptagna.

Jag föreslår att du för varje tick kollar om klossen kolliderar med berget (det är väl i princip bara att kolla höjden på berget mot hur lågt klossen hunnit sjunka). Dessutom behöver du en Add/Merge metod på berget som tar en instans av en Kloss och som sätter till klossen till berget. Där behöver du då bara kontrollera om någon rad blir full och stryka den isåfall.

Visa signatur

"Mies saa kaatua mutta ei karata." -- Adolf Ehrnrooth IR 7, Äyräpää 1944.