【发布时间】:2021-07-20 13:27:09
【问题描述】:
我有一个抽象类“元素”,它的实例必须使用 System.Drawing 中的函数 DrawRectangle()。 问题是因为这个类是抽象的,所以它不能从 FORM 继承,所以程序不能识别这些类。 我该如何解决这个问题? 我尝试在 Element 中放置一个 Form 类型的变量,但没有成功。 我也尝试了相反的方法,将一个 Element 变量放在 Form 中。 这是我第一次使用 Winform 和 C#... 它应该是一个鼠标竞赛游戏,页面中绘制的对象应该是追逐鼠标或向其他方向移动,但我需要它是面向对象的。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace MyMouseGame
{
public abstract class Element
{
//Form1 myForm = new Form1();// not sure I need it
public enum EnumShape { Square, Circle, Triangle }
public enum EnumType { Chase, Escape, Random }
//variables
private double X { get; set; }
private double Y { get; set; }
private int Size { get; }
private int Speed { get; }
private EnumShape Shape { get; set; }
protected EnumType Type { get; set; }
private static Random R = new Random();
//methods
public int generateRandomNum()
{
int randomNum = R.Next(20, 100);
return randomNum;
}
public Element()
{
X= 0;
Y = 0;
Shape = 0;
Size = generateRandomNum();
Speed = generateRandomNum();
Type = 0;
}
public void ElementsFactory()
{
}
public void hitTarget(e) { }
public abstract void Draw(Form1 g); //here I tried to pass a form inside
public abstract void Move();
}
}
//example of one of the instances classes of element
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace MyMouseGame
{
class E_Escape : Element
{
int move_circleX = 0;
int move_circleY = 0;
bool flag = false;
Rectangle circle = new Rectangle(10, 70, 35, 35);
Pen p = new Pen(Color.Black);
//circle
public E_Escape()
{
}
public override void Draw(Form1 g) {
g.DrawEllipse(p, circle);
g.FillEllipse(new SolidBrush(Color.Red), circle);
}
public override void Move() {
if (!flag)
{
if (circle.X >= panel1.Width - 2)
flag = true;
circle.X += 10;
}
else
{
if (circle.X <= 30)
flag = false;
circle.X -= 10;
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace MyMouseGame
{
public partial class Form1 : Form
{
Graphics g;
Element [] elements= new Element[3];
public Form1()
{
this.DoubleBuffered = true;
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
g = panel1.CreateGraphics();
//timer set
t.Interval = 100;
t.Tick += new EventHandler(timer1_Tick);
t.Start();
}
private void recThreadTracker()
{
//move rectangle
while (true)//here I tried to call element finction draw
{
elements[0].Draw(g);
elements[1].Draw(g);
elements[2].Draw(g);
}
}
public void threadCounter()
{
long counter = 0;
while (true)
{
counter++;
this.Invoke(new Action(() =>
{
lcountRes.Text = counter.ToString();
}));
Thread.Sleep(1000);
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Thread counterThread = new Thread(threadCounter);
counterThread.Start();
Thread recTrackThread = new Thread(recThreadTracker);
recTrackThread.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
foreach (Element elements in elements)
{
elements.Move();
}
//Refresh();
Invalidate();
}
}
}
【问题讨论】:
-
Element不需要是抽象的,不是吗? -
我认为它确实是因为它本身并没有实现它的方法,但它的“孩子”做
-
表单类不需要继承自
Element- 它需要传递具体实例才能进行绘制。 -
g = panel1.CreateGraphics(); Paint 事件应该使用 e.Graphics 参数。另外:如果您想要持久图形,切勿尝试缓存 Graphics 对象。 - 另外:
t.Tick += new EventHandler(timer1_Tick);这会在每次 Paint 调用时添加另一个 Tick 调用。肯定不是你想要的。 -
从不尝试缓存 Graphics 对象是什么意思?另外: e.CreateGaphics() 无法识别创建图形方法。该怎么办?另外:如果我想绘制不同的元素,我应该在不同的线程中进行吗?非常感谢
标签: c# winforms oop abstract-class factory