Используйте спрайты для анимации нескольких прыгающих мячей в C#
Этот пример аналогичен описанному в сообщении , за исключением того, что использует спрайты для управления шарами. Предыдущий пример хранит данные шара в группе массивов. Этот подход работает, но он содержит много информации о шарах в массивах основной программы.
В этом примере используется простой класс спрайтов для хранения информации о шаре. Затем основная программа вызывает методы спрайтов для перемещения и рисования шаров вместо того, чтобы делать это напрямую. Такой подход облегчает основную программу координацию объектов спрайтов (спрайтов). Это особенно полезный метод, если спрайты представляют разные объекты, возможно, с разными правилами движения.
В следующем коде показан класс BallSprite. Код достаточно прост. Если вы сравните его с кодом предыдущей программы, вы сможете увидеть, как новая версия предоставляет те же функции, что и старый.
class BallSprite
{
public Rectangle Location;
public Point Velocity;
public Color BackColor, ForeColor;
public int MaxX, MaxY;
// Конструктор, который инициализируется случайным образом.
private static Random rand = new Random();
public BallSprite(int min_r, int max_r,
int max_x, int max_y, int min_v, int max_v)
{
MaxX = max_x;
MaxY = max_y;
int width = rand.Next(min_r, max_r);
Location = new Rectangle(
rand.Next(0, max_x - width),
rand.Next(0, max_y - width),
width, width);
int vx = rand.Next(min_v, max_v);
int vy = rand.Next(min_v, max_v);
if (rand.Next(0, 2) == 0) vx = -vx;
if (rand.Next(0, 2) == 0) vy = -vy;
Velocity = new Point(vx, vy);
BackColor = RandomColor();
ForeColor = RandomColor();
}
// Возвращаем случайный цвет.
private Color[] colors =
{
Color.Red,
Color.Green,
Color.Blue,
Color.Lime,
Color.Orange,
Color.Fuchsia,
};
private Color RandomColor()
{
return colors[rand.Next(0, colors.Length)];
}
// Переместите мяч.
public void Move()
{
// Переместите мяч.
int new_x = Location.X + Velocity.X;
int new_y = Location.Y + Velocity.Y;
bool bounced = ((new_x < 0) || (new_y < 0) ||
(new_x + Location.Width > MaxX) ||
(new_y + Location.Height > MaxY));
if (new_x < 0)
Velocity.X = -Velocity.X;
else if (new_x + Location.Width > MaxX)
Velocity.X = -Velocity.X;
if (new_y < 0)
Velocity.Y = -Velocity.Y;
else if (new_y + Location.Height > MaxY)
Velocity.Y = -Velocity.Y;
if (bounced) Boing();
Location = new Rectangle(
new_x, new_y,
Location.Width,
Location.Height);
}
// Воспроизведение ресурса звукового файла boing.
private static void Boing()
{
using (SoundPlayer player = new SoundPlayer(
Properties.Resources.boing))
{
player.Play();
}
}
/ public void Draw(Graphics gr)
{
using (SolidBrush the_brush = new SolidBrush(BackColor))
{
gr.FillEllipse(the_brush, Location);
}
using (Pen the_pen = new Pen(ForeColor))
{
gr.DrawEllipse(the_pen, Location);
}
}
}
Следующий код показывает, как основная программа отслеживает спрайты. Этот код намного проще, чем предыдущая версия.
// Спрайты.
private BallSprite[] Sprites;
private Size FormSize;
private void Form1_Load(object sender, EventArgs e)
{
// Делаем случайные шары.
Random rand = new Random();
const int num_balls = 10;
Sprites = new BallSprite[num_balls];
for (int i = 0; i < num_balls; i++)
{
Sprites[i] = new BallSprite(10, 40,
ClientSize.Width, ClientSize.Height,
2, 10);
}
// Сохраните размер формы.
FormSize = ClientSize;
// Используйте двойную буферизацию для уменьшения мерцания.
this.SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer,
true);
this.UpdateStyles();
}
// Перемещение шаров и обновление.
private void tmrMoveBall_Tick(object sender, EventArgs e)
{
foreach (BallSprite sprite in Sprites) sprite.Move();
Refresh();
}
// Перерисовать.
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.Clear(BackColor);
foreach (BallSprite sprite in Sprites) sprite.Draw(e.Graphics);
}
Класс спрайтов обрабатывает все детали о том, как каждый объект перемещается и рисует сам. Это означает, что основной программе просто нужно вызвать методы Move и Draw каждого объекта.
