2021/11/19(Fri) 02:31:31 編集(投稿者)
■No98483 (魔界の仮面弁士 さん) に返信
なんか面白そうなのでボール画像を作って 20 個ほど動かしてみました。
ちょっとカクつくかなーという気がしますが、ちらつきはしないと思います。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
Bitmap ballBmp;
List<CBall> balls;
private void Form2_Load(object sender, EventArgs e)
{
pictureBox1.BackgroundImage = new Bitmap(@"D:\TEST\back.jpg");
ballBmp = new Bitmap(300, 300);
using (var g = Graphics.FromImage(ballBmp))
{
g.Clear(Color.Black);
g.FillEllipse(Brushes.Brown, new Rectangle(1, 1, ballBmp.Width - 2, ballBmp.Height - 2));
g.FillEllipse(Brushes.MistyRose, new Rectangle(4, 4, ballBmp.Width - 8, ballBmp.Height - 8));
using (var titleFont = new Font("MS UI Gothic", 40, FontStyle.Bold))
{
const string title = "\u308F\u3093\u304F\u307E\u540C\u76DF";
var sz = g.MeasureString(title, titleFont);
var location = new Point((int)((ballBmp.Width - sz.Width) / 2), (int)((ballBmp.Height - sz.Height) / 2));
g.DrawString(title, titleFont, Brushes.Brown, location);
}
}
ballBmp.MakeTransparent(Color.Black);
balls = new List<CBall>();
for (int i = 0; i < 20; i++)
{
CBall ball = new CBall(ballBmp, ClientSize);
balls.Add(ball);
}
timer1.Interval = 16;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
foreach (var ball in balls)
{
ball.Draw(e.Graphics, pictureBox1.ClientRectangle);
}
}
class CBall
{
readonly Bitmap ballBmp;
readonly Size size;
readonly int mag;
int left, top, dx, dy;
const int MinBallSize = 100;
const int MaxBallSize = 300;
static Random random = new Random();
public CBall(Bitmap bmp, Size clientSize)
{
ballBmp = bmp;
int height = random.Next(MinBallSize, MaxBallSize);
size = new Size(height, height);
mag = random.Next(10, 20);
left = random.Next(10, clientSize.Width);
top = random.Next(10, clientSize.Height);
dx = random.Next(0, 2) * 2 - 1;
dy = random.Next(0, 2) * 2 - 1;
}
private Rectangle NextRectangle(Rectangle drawArea)
{
left += mag * dx;
top += (int)(mag * mag * 0.1) * dy;
if (left + size.Width > drawArea.Right)
{
dx = -1 * Math.Abs(dx);
left += mag * dx;
}
if (left < drawArea.Left)
{
dx = Math.Abs(dx);
left += mag * dx;
}
if (top + size.Height > drawArea.Bottom)
{
dy = -1 * Math.Abs(dy);
top += (int)(mag * mag * 0.1) * dy;
}
if (top < drawArea.Top)
{
dy = Math.Abs(dy);
top += (int)(mag * mag * 0.1) * dy;
}
return new Rectangle(left, top, size.Width, size.Height);
}
public void Draw(Graphics graphics, Rectangle drawArea)
{
var rect = NextRectangle(drawArea);
graphics.DrawImage(ballBmp, rect);
}
}
}