Diskuze: c# form app, e.graphics pls help
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 9 zpráv z 9.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Zkus to napsat tak, aby se to tady dalo číct - tedy jako kód.
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;
}
}
}
}
}
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;
}
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
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 oznacPoziciZnakem(), 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ší/interaktivnější hru piškvorky, například s umělou
inteligencí, tak být na tvém místě, tak bych od tableLayoutPanelu spíš
upustil.
Děkuji mockrát rwn, bylo to úplně všechno co jsem potřeboval vědět a
co mi nebylo jasné. Uzavřeno
Zobrazeno 9 zpráv z 9.