Diskuze: c# form app, e.graphics pls help

C# .NET .NET (C# a Visual Basic) c# form app, e.graphics pls help American English version English version

Avatar
z.hosinsky
Člen
Avatar
z.hosinsky:

Zdravím vás, s c# zacinam a chtel bych udelat piskvorky. Mam vse promyslene ale delami mi problem zobrazovani. Stridam hrace pomoci %2 a vykresluji krizek nebo kolecko, problem je, ze se kazdy click prekresli vsechny obrazky na ten co prave vykresluji. Jinými slovy potrebuji abych si neprepisoval ty obrazky co tam uz jednou nakreslim. Predem dekuji za radu.

using System;
using System.Collec­tions.Generic;
using System.Componen­tModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Window­s.Forms;

namespace piskvorkyy
{
public partial class Form1 : Form
{
Font mujFont = new Font("Ariel", 12);
Brush stetec = new SolidBrush(Co­lor.Blue);
int[,] hodnoty = new int[10, 10];
//new Point kliknuto;
List<Point> oznacenaPole = new List<Point>();
int cnt=0;

public Form1()
{
InitializeCom­ponent();
//hodnoty[5, 5] = 'X';

}

public void tableLayoutPa­nel1_MouseClic­k(object sender, MouseEventArgs e)
{
Point kliknuto = new Point(10 * e.Y / tableLayoutPa­nel1.Height, 10 * e.X / tableLayoutPa­nel1.Width);
oznacenaPole.Ad­d(kliknuto);
tableLayoutPa­nel1.Refresh();
cnt++;
}

public void tableLayoutPa­nel1_CellPain­t(object sender, TableLayoutCe­llPaintEventAr­gs e)
{
Point aktualniBunka = new Point(e.Row, e.Column);
if (oznacenaPole­.Contains(aktu­alniBunka))
{
if (cnt % 2 == 0)
{
e.Graphics.Dra­wImage(piskvor­kyy.Properties­.Resources.kriz,e­.CellBounds);
//string o = "o";
//e.Graphics.Draw­String(o, mujFont, stetec, new PointF(e.CellBou­nds.Left, e.CellBounds.Top));
hodnoty[e.Row, e.Column] = 1;
}
else
{
e.Graphics.Dra­wImage(piskvor­kyy.Properties­.Resources.kruh, e.CellBounds);
//string x = "x";
//e.Graphics.Draw­String(x, mujFont, stetec,new PointF(e.CellBou­nds.Left, e.CellBounds.Top));
hodnoty[e.Row, e.Column] = 2;
}
}

}
}
}

 
Odpovědět 10.4.2014 21:11
Avatar
rwn
Člen
Avatar
Odpovídá na z.hosinsky
rwn:
Zkus to napsat tak, aby se to tady dalo číct - tedy jako kód.
Editováno 10.4.2014 23:53
Nahoru Odpovědět 10.4.2014 23:52
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Michal Žůrek (misaz):

Použij tlačítko vložit zdrojový kód.

Nahoru Odpovědět 11.4.2014 6:39
Nesnáším {}, proto se jim vyhýbám.
Avatar
Richard Závodný:

Co odsazování?

 
Nahoru Odpovědět 11.4.2014 6:42
Avatar
z.hosinsky
Člen
Avatar
Odpovídá na z.hosinsky
z.hosinsky:
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;

namespace piskvorkyy
{
    public partial class Form1 : Form
    {
        Font mujFont = new Font("Ariel", 12);
        Brush stetec = new SolidBrush(Color.Blue);
        int[,] hodnoty = new int[10, 10];
        //new Point kliknuto;
        List<Point> oznacenaPole = new List<Point>();
        int cnt=0;

        public Form1()
        {
            InitializeComponent();
            //hodnoty[5, 5] = 'X';

        }

        public void tableLayoutPanel1_MouseClick(object sender, MouseEventArgs e)
        {
            Point kliknuto = new Point(10 * e.Y / tableLayoutPanel1.Height, 10 * e.X / tableLayoutPanel1.Width);
            oznacenaPole.Add(kliknuto);
            tableLayoutPanel1.Refresh();
            cnt++;
        }

        public void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
        {
            Point aktualniBunka = new Point(e.Row, e.Column);
            if (oznacenaPole.Contains(aktualniBunka))
            {
                if (cnt % 2 == 0)
                {
                    e.Graphics.DrawImage(piskvorkyy.Properties.Resources.kriz,e.CellBounds);
                    //string o = "o";
                    //e.Graphics.DrawString(o, mujFont, stetec, new PointF(e.CellBounds.Left, e.CellBounds.Top));
                    hodnoty[e.Row, e.Column] = 1;
                }
                else
                {
                    e.Graphics.DrawImage(piskvorkyy.Properties.Resources.kruh, e.CellBounds);
                    //string x = "x";
                    //e.Graphics.DrawString(x, mujFont, stetec,new PointF(e.CellBounds.Left, e.CellBounds.Top));
                    hodnoty[e.Row, e.Column] = 2;
                }
            }



        }
    }
}
 
Nahoru Odpovědět 11.4.2014 12:03
Avatar
rwn
Člen
Avatar
Odpovídá na z.hosinsky
rwn:

Můžeš si to udělat třeba tak, že o každém políčku budeš mít bool hodnotu. Tedy, pokud je pole neobsazené, tak bude mít třeba hodnotu true. Pokud bude na něm už něco vykesleno, tak bude mít hodnotu false. Při každém kliknutí na políčko si přes if budeš tuhle hodnotu kontrolovat. Pole mužeš udělat třeba takhle

private bool[,] hraciDeska = new bool[10, 10]; // deska je třeba 10x10 velká

no a teď při kliknutí budeš danému políčko měnit na false:

public void obsadPolicko(int x, int y)
{
        hraciDeska [x, y] = false;
}
Nahoru Odpovědět 11.4.2014 21:15
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
z.hosinsky
Člen
Avatar
Odpovídá na z.hosinsky
z.hosinsky:

Mockrat dekuji za odpoved ale co to resi? ja prece nemusim testovat dvourozmerne pole abych vedel jaky obrazek tam vykreslit a jestli ho vubec vykreslit...problem je ze kliknu, vykresli to X, kliknu na dalsi policko a vykresli to O a zaroven prepise predesle X na O atd...toho se potrebuju nejak zbavit(neco v tom smyslu vykreslit posledni e.Cellbound, nebo nebo po kazdem vykresleni e.Cellbound smazat)...c# se teprve ucim, prominte pokud melu hovadiny a pomaleji chapu.. :( , predem dekuji za dalsi odpovedi

 
Nahoru Odpovědět 11.4.2014 21:37
Avatar
rwn
Člen
Avatar
Odpovídá na z.hosinsky
rwn:

Ahaaa, já jsem myslel, že máš problém s tím, že můžeš kliknout už na zabrané políčko a tam se ti to překresluje. :)
Ale už chápu, kde máš problém. Překreslí se ti všechny, protože ty tak tu událost _CellPaint máš tak napsnou. :) Obecně všechny události _Paint jsou takové povahy, že vykreslují svůj obsah v současnosti a vše ostatní "neaktuální" nevidí. Řešení je jednoduché - musíš si v té události udělat odděleně vykreslení koleček a křížků. A pokud pole není zabrané, tak políčku přiřadíš hodnotu. :) Zkusil jsem si to naprogramovat z toho tvého, takže by to mohlo vypadat nějak takto:

private void tableLayoutPanel1_MouseClick(object sender, MouseEventArgs e)
{
    Point kliknuto = new Point(10 * e.Y / tableLayoutPanel1.Height, 10 * e.X / tableLayoutPanel1.Width);

    if(hodnoty[kliknuto.X, kliknuto.Y] == 0)
    {
        oznacPoziciZnakem(kliknuto.X, kliknuto.Y);
        oznacenaPole.Add(kliknuto);
        tableLayoutPanel1.Refresh();
        cnt++;
    }
}

Oproti tvému kódu, jsem sem přidal to, že na políčko na kterém něco už je (tedy není tam základní nula), tak se bude kreslení ignorovat. (Dokud hráč neklikne na prázdné políčko, tak si může klikat jak chce). Pak jsem přidal metodu oznacPoziciZna­kem(), ta v podstatě udělá to, že přiřadí 1 nebo 2, podle toho kdo je na řadě:

private void oznacPoziciZnakem(int X, int Y)
{
    if (cnt % 2 == 0)
    {
        hodnoty[X, Y] = 1;
    }
    else
    {
        hodnoty[X, Y] = 2;
    }
}

Následně už jen stačí si tableLayoutPanel1 refreshnout, udělal jsem ho tak, aby při refreshnutí vykreslil vždy všechny křížky a kolečka, která máš v seznamu (jak už jsem zminoval v události musí být řečeno vše co se v dané chvíli má vykreslit). Jelikož došlo k přidání do Listu před refreshem, tak tam bude i poslední souřadnice. :)

private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
   Point aktualniBunka = new Point(e.Row, e.Column);
   if (oznacenaPole.Contains(aktualniBunka))
   {
       if (hodnoty[e.Row, e.Column] == 1)
       {
           string o = "o";
           e.Graphics.DrawString(o, mujFont, stetec, new PointF(e.CellBounds.Left, e.CellBounds.Top));
       }
       else
       {
           string x = "x";
           e.Graphics.DrawString(x, mujFont, stetec,new PointF(e.CellBounds.Left, e.CellBounds.Top));
       }
   }
}

Tady se v podstatě projedou všechny možné souřadnice a pokud je daná souřadnice v Listu oznacenaPole, tak se vyhodnotí to jak se má vykreslit podle její hodnoty 1 nebo 2. Pokud chceš ale dělat nějakou složitější/in­teraktivnější hru piškvorky, například s umělou inteligencí, tak být na tvém místě, tak bych od tableLayoutPanelu spíš upustil. :)

Editováno 12.4.2014 3:31
Nahoru Odpovědět 12.4.2014 3:29
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
z.hosinsky
Člen
Avatar
Odpovídá na z.hosinsky
z.hosinsky:

Děkuji mockrát rwn, bylo to úplně všechno co jsem potřeboval vědět a co mi nebylo jasné. Uzavřeno :D

 
Nahoru Odpovědět 14.4.2014 14:41
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.