Лабораториска вежба 7 - finki-mk/VP GitHub Wiki
Moving Ball
Опис на задачата
Во оваа задача треба да се имплементира цртање на топче кое се движи во рамките на ограничен правоаголник со одредена ширина и висина.
Класа за топче
Најпрво ќе дефинираме класа Ball
која ќе го претсавува објектот топче кое ќе се исцртува на екран.
Во оваа класа ќе се чуваат информации за позицијата на топчето (X, Y), радиусот, брзината со која се движи, како и аголот под кој ќе почне да се движи (0, 2Pi). Исто така ќе се чува и објект од класата Rectangle
во кој ќе се чуваат границите во кои ќе се движи топчето.
Затоа што топчето почнува да се движи под некој агол, неговите брзини по X и Y оските се посебни компоненти и се пресметуваат со едноставна тригонометрија.
public float X { get; set; }
public float Y { get; set; }
public float Radius { get; set; }
public float Velocity { get; set; }
public float Angle { get; set; }
public Rectangle Bounds;
private float velocityX;
private float velocityY;
Конструктор
Во конструкторот се иницијализираат почетната позиција, радиусот, брзината и почетниот агол. Исто така се пресметуваат брзините по двете оски.
public Ball(float x, float y, float radius, float velocity, float angle)
{
X = x;
Y = y;
Radius = radius;
Velocity = velocity;
Angle = angle;
velocityX = (float)Math.Cos(Angle) * Velocity;
velocityY = (float)Math.Sin(Angle) * Velocity;
}
Метод за движење
Со овој метод се придвижува топчето. Притоа се внимава доколку со новата позиција топчето излегува од границите во кои треба да се движи се менува неговата насока на движење (се одбива).
public void Move()
{
float nextX = X + velocityX;
float nextY = Y + velocityY;
if (nextX - Radius <= Bounds.Left || (nextX + Radius >= Bounds.Right))
{
velocityX = -velocityX;
}
if (nextY - Radius <= Bounds.Top || (nextY + Radius >= Bounds.Bottom))
{
velocityY = -velocityY;
}
X += velocityX;
Y += velocityY;
}
Метод за исцртување
Овој метод прима аргументи четката Brush
со која ќе се црта и објект од класата Graphics
врз кој ќе се црта.
public void Draw(Brush brush, Graphics g)
{
g.FillEllipse(brush, X - Radius, Y - Radius, Radius * 2, Radius * 2);
}
Имплементација на формата во која ќе се исцртува
Кодот на формата за исцртување.
Timer timer;
Ball ball;
Graphics graphics;
Brush brush;
Pen pen;
Rectangle bounds;
Bitmap doubleBuffer;
static readonly int FRAMES_PER_SECOND = 30;
public Form1()
{
InitializeComponent();
bounds = new Rectangle(10, 10, this.Bounds.Width - 40, this.Bounds.Height - 60);
doubleBuffer = new Bitmap(Width, Height);
graphics = CreateGraphics();
ball = new Ball(Width / 2, Height / 2, 20, 10, (float)(Math.PI / 4));
ball.Bounds = bounds;
Show();
brush = new SolidBrush(Color.Blue);
pen = new Pen(Color.Red);
timer = new Timer();
timer.Tick += new EventHandler(timer_Tick);
timer.Interval = 1000 / FRAMES_PER_SECOND;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
Graphics g = Graphics.FromImage(doubleBuffer);
g.Clear(Color.White);
g.DrawRectangle(pen, bounds);
ball.Draw(brush, g);
ball.Move();
graphics.DrawImageUnscaled(doubleBuffer, 0, 0);
}