我正在做关于 WinForms、继承、接口(interface)和抽象类的书中的练习。练习是创建几个沿随机方向移动的球,并让形状像盒子一样的障碍物与球相互作用。
书中的思路是,有一个 Ball
类和另一个名为 Engine
的类来处理椭圆的创建。我的工作是制造障碍物并让它们与球互动。
这是要求
All obstacles should be treated the same w.r.t. the engine; perhaps by using an interface. Do not use fully abstract classes
All obstacles should share as much code as possible, but only code that makes sense to share; use abstract classes if necessary to avoid inheriting methods that do not make sense or empty methods.
Ball
和 Engine
,给定的类。
位置:
public class Position
{
public float X, Y;
public Position(float x, float y)
{
X = x; Y = y;
}
}
向量:
public class Vector
{
public float X, Y;
public Vector(float x, float y)
{
X = x; Y = y;
}
}
球:
public class Ball
{
static Pen Pen = new Pen(Color.Black);
Position Position;
Vector Speed;
float Radius;
static Random Random = new Random();
public Ball(float x, float y, float radius)
{
Position = new Position(x,y);
var xd = Random.Next(1, 6);
var yd = Random.Next(1, 6);
if (Random.Next(0, 2) == 0) xd = -xd;
if (Random.Next(0, 2) == 0) yd = -yd;
Speed = new Vector(xd,yd);
Radius = radius;
}
public void Draw(Graphics g)
{
g.DrawEllipse(Pen,Position.X - Radius, Position.Y - Radius, 2 * Radius, 2 * Radius);
}
public void Move()
{
Position.X += Speed.X;
Position.Y += Speed.Y;
}
}
引擎:
public class Engine
{
MainForm Form = new MainForm();
Timer Timer = new Timer();
List<Ball> Balls = new List<Ball>();
Redbox RBox = new Redbox(); //My added code
Random Random = new Random();
public void Run()
{
Form.Paint += Draw;
Timer.Tick += TimerEventHandler;
Timer.Interval = 1000/25;
Timer.Start();
Application.Run(Form);
}
private void Form_Paint(object sender, PaintEventArgs e)
{
throw new NotImplementedException();
}
void TimerEventHandler(Object obj, EventArgs args)
{
if (Random.Next(100) < 25)
{
var ball = new Ball(400, 300, 10);
Balls.Add(ball);
}
foreach (var ball in Balls)
{
ball.Move();
}
Form.Refresh();
}
void Draw(Object obj, PaintEventArgs args)
{
foreach (var ball in Balls)
{
ball.Draw(args.Graphics);
}
RBox.Draw(args.Graphics); //Testing
}
}
这是我创建的界面:
interface IObstacles
{
void Draw(Graphics g);
}
class Redbox : IObstacles
{
public void Draw(Graphics g)
{
Pen Pen = new Pen(Color.Red);
Random Random = new Random();
Position Position = new Position(Random.Next(100, 700), Random.Next(100, 700));
var width = Random.Next(30, 100);
var height = Random.Next(30, 100);
g.DrawRectangle(Pen, Position.X , Position.Y, width, height);
}
}
我一直想弄清楚如何绘制我的一个(目前)矩形而不每次都刷新它。我可能听起来像个白痴,但我是相当新的。我得到的结果是相同的矩形以相同的刻度出现和消失。我还注意到 Ball
类在列表中创建并存储了新的“球”,但由于我的接口(interface)实现,我认为我不能这样做。我正在为所有 Obstacles
创建界面,因为它们相同但形状不同。我的实现可能有误,但至少对我来说这听起来合乎逻辑。
任何帮助将不胜感激,因为我是 C# 的新手。
最佳答案
使用 Jimi's建议 :
事实证明他是对的 Draw
中声明的随机性这不是正确的解决方案,就像他所说的那样,每次都会用随机重新绘制障碍 position
.这一切都通过将它们移到外面来解决我还修改了类,以便可以选择绘制框的位置。
我发布了答案,以便其他偶然发现这个问题的人可以看看我是如何解决我的问题的,感谢 Jimi's解决方案。
接口(interface):
interface IObstacles
{
void Draw(Graphics g);
}
class Redbox : IObstacles
{
Pen Pen = new Pen(Color.Red);
Random Random = new Random();
Position Position;
float width;
float height;
public Redbox(float x, float y)
{
Position = new Position(x, y);
width = Random.Next(30, 100);
height = Random.Next(30, 100);
}
public void Draw(Graphics g)
{
g.DrawRectangle(Pen, Position.X , Position.Y, width, height);
}
}
引擎:
public class Engine
{
MainForm Form = new MainForm();
Timer Timer = new Timer();
List<Ball> Balls = new List<Ball>();
List<IObstacles> RBox = new List<IObstacles>();
Random Random = new Random();
public void Run()
{
Form.Paint += Draw;
Timer.Tick += TimerEventHandler;
Timer.Interval = 1000/25;
Timer.Start();
Application.Run(Form);
}
private void Form_Paint(object sender, PaintEventArgs e)
{
throw new NotImplementedException();
}
void TimerEventHandler(Object obj, EventArgs args)
{
if (Random.Next(100) < 25)
{
var ball = new Ball(400, 300, 10);
Balls.Add(ball);
}
if (RBox.Count() < 2)
{
RBox.Add(new Redbox(100 * Random.Next(1, 8), 100 * Random.Next(0, 6)));
}
foreach (var ball in Balls)
{
ball.Move();
}
Form.Refresh();
}
void Draw(Object obj, PaintEventArgs args)
{
foreach (var ball in Balls)
{
ball.Draw(args.Graphics);
}
foreach (var rbox in RBox)
{
rbox.Draw(args.Graphics);
}
}
}
如果还有任何问题或建议有人想补充,请随时发表评论。
关于c# - 使用 WinForms 连续绘制椭圆同时保留矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74778602/