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.