Vyskytly se mi ale komplikace a potřebuji pomoc, vždy se mi to vykreslí za delší čas, třeba více jak 2 s, zkoušel jsem se přes debug podívat na to, kde to bere tolik času, ale docela bez úspěchu, protože nejsem v debugu zase takový znalec, nepohcopil jsem, proč mi to ukazovalo třeba na ukončené složené závorce 210 ms, takže jsem se nehnul z místa. Zkoušel jsem to už dost předělat, nejdříve jsem to měl na WPF, teď ve WF (s WPF nemám moc zkušeností a tak jsem to zkusil takto vyřešit, neúspěšně). Zkoušel jsem to udělat i přes eventy, ale nechápu, co jsem si od toho sliboval.

Kód mám rozdělen do několika tříd a jednoho rozhraní, všechno zde pošlu.
Omlouvám se, že jsou někde nějaké věci navíc (nepoužity), např. Dispatcher ve tříde MainTask, kde není vůbec použit, je to z důvodu, že jsem nejdříve PictureBoxu přiřazoval obrázek přes něj.
Kód: Vybrat vše
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PercentagesPractise.ScreenObjects
{
interface IScreenObject
{
bool isActive();
void Draw(Graphics g);
void _Update();
}
}
Kód: Vybrat vše
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PercentagesPractise.ScreenObjects
{
class ScreenObject : IScreenObject
{
//Click, Hover ...
public EventHandler OnClick { get; set; }
public EventHandler OnDoubleClick { get; set; }
public EventHandler OnHover { get; set; }
//Update
public EventHandler BeforeUpdate { get; set; }
public EventHandler Update { get; set; }
public EventHandler AfterUpdate { get; set; }
public bool isActivated { get; set; }
public bool isActive()
{
return isActivated;
}
public bool Fill
{
get
{
return fill;
}
set
{
fill = value;
}
}
public Color color;
public Rectangle rectangle;
public float width;
public bool fill;
public ScreenObject(Color color, Rectangle rectangle, bool fill = false, float width = 1)
{
BeforeUpdate += (sender, e) => { };
Update += (sender, e) => { };
AfterUpdate += (sender, e) => { };
isActivated = true;
this.color = color;
this.rectangle = rectangle;
this.width = width;
this.fill = fill;
}
public virtual void _Update()
{
BeforeUpdate(null, null);
Update(null, null);
AfterUpdate(null, null);
}
public virtual void Draw(Graphics g)
{
if (fill)
g.FillRectangle(new SolidBrush(color), rectangle.x, rectangle.y, rectangle.width, rectangle.height);
else
{
Pen p = new Pen(color, width);
g.DrawRectangle(p, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
}
}
}
Kód: Vybrat vše
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PercentagesPractise.ScreenObjects
{
class Screen : IScreenObject
{
protected List<ScreenObject> objs { get; set; }
public bool isActivated { get; set; }
public Screen(List<ScreenObject> objs)
{
this.objs = objs;
isActivated = true;
}
public bool isActive()
{
return isActivated;
}
public void Draw(Graphics g)
{
foreach(ScreenObject obj in objs)
{
obj.Draw(g);
}
}
public void _Update()
{
foreach (ScreenObject obj in objs)
{
obj._Update();
}
}
}
}
Kód: Vybrat vše
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
namespace PercentagesPractise.ScreenObjects
{
class MainTask
{
public EventHandler<Bitmap> onDraw { get; set; }
List<IScreenObject> activeObjects
{
get
{
List <IScreenObject> objs = new List<IScreenObject>(objects);
if(objects != null)
foreach(IScreenObject obj in objects)
{
if (!obj.isActive())
objs.Remove(obj);
}
return objs;
}
}
public bool IsRunning {
get
{
return running;
}
set
{
if (value && !running)
Start();
running = value;
}
}
public int Width
{
get
{
return width;
}
set
{
width = value;
}
}
public int Height
{
get
{
return height;
}
set
{
height = value;
}
}
private List<IScreenObject> objects = new List<IScreenObject>();
private Thread updater, drawer;
private Dispatcher dis;
private bool running;
private int width, height;
private System.Windows.Forms.PictureBox pb;
public MainTask(List<IScreenObject> objs, Dispatcher dis, System.Windows.Forms.PictureBox pb)
{
// onDraw += (sender, e) => { };
this.dis = dis;
if(objs != null)
objects = objs;
this.pb = pb;
}
public void Start()
{
running = true;
Bitmap b = new Bitmap(1920, 1024);
// onDraw(null, b);
Graphics g = Graphics.FromImage(b);
drawer = new Thread(new ThreadStart(() => {
while (running)
{
// if (onDraw == null)
// continue;
g.FillRectangle(Brushes.Gray, 0, 0, 1920, 1024);
foreach (IScreenObject obj in objects)
{
obj.Draw(g);
}
pb.Image = new Bitmap(b, new System.Drawing.Size(width, height));
//onDraw(null, );
}
}));
updater = new Thread(new ThreadStart(() =>
{
while (running)
{
foreach (IScreenObject obj in activeObjects)
{
obj._Update();
}
}
}));
updater.Start();
drawer.Start();
}
public void Clicked(PointF pos)
{
MessageBox.Show("CLICKED! " + pos.X + " " + pos.Y);
}
}
}
Kód: Vybrat vše
using PercentagesPractise.ScreenObjects;
using PercentagesPractise.ScreenObjects.AddonFunctions;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PercentagesPractise.Screens
{
class MainScreen : Screen
{
public MainScreen() : base(null)
{
List<ScreenObject> objs = new List<ScreenObject>();
//Background
ScreenObjects.Rectangle bcg = new ScreenObjects.Rectangle(0, 0, 1920, 1080);
ScreenObject bcgso = new ScreenObject(Color.Black, bcg, true);
//objs.Add(bcgso);
ScreenObjects.Rectangle rct = new ScreenObjects.Rectangle(500, 500, 20, 20);
ScreenObject obj = new ScreenObject(Color.Blue, rct, true);
Random r = new Random();
Vector v = new Vector(20f, 20f);
obj.Update += (sender, e) => {
if (obj.rectangle.x < 0 || obj.rectangle.x > 1920)
v.x = -v.x;
if (obj.rectangle.y < 0 || obj.rectangle.y > 1024)
v.y = -v.y;
obj.rectangle.x += v.x;
obj.rectangle.y += v.y;
};
bcgso.isActivated = false;
objs.Add(obj);
this.objs = objs;
}
}
}
Kód: Vybrat vše
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PercentagesPractise.ScreenObjects.AddonFunctions
{
class Vector
{
public float x { get; set; }
public float y { get; set; }
public Vector(float xy)
{
x = y = xy;
}
public Vector(float x, float y)
{
this.x = x;
this.y = y;
}
public Vector()
{
}
public void Reverse()
{
x = -x;
y = -y;
}
}
}
Kód: Vybrat vše
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PercentagesPractise.ScreenObjects
{
struct Rectangle
{
public float x, y;
public float width, height;
public Rectangle(float x, float y, float width, float height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
}
Tohle mám ve třídě WP.
Kód: Vybrat vše
private void app_Load(object sender, EventArgs e)
{
List<IScreenObject> se = new List<IScreenObject>();
ScreenObjects.Screen scr = new MainScreen();
se.Add(scr);
MainTask t = new MainTask(se, Dispatcher.CurrentDispatcher, image);
t.Width = image.Width;
t.Height = image.Height;
t.Start();
}
Děkuji všem, kteří se alespoň na kód podívají.