如果图像福尔斯第一个if语句中,我尝试让它旋转。这可以工作,但是旋转速度非常快(由于动画是60 fps,所以它旋转60次/秒)。我怎样才能把它分开,使它像其他的一样向下移动,但是旋转又好又慢呢?多线程是这里显而易见的方法,但是我尝试过的任何方法(几乎任何你可以在2小时内从谷歌或chatgpt得到的东西)都会导致访问错误,因为有两个不同的线程修改同一个对象。Here is a short clip to demonstrate the issue和here is the repo,如果这有帮助的话。
public void AniLoop()
{
System.Windows.Forms.Timer loop = new System.Windows.Forms.Timer();
//60fps
loop.Interval = 16;
loop.Tick += (object sender, EventArgs e) =>
{
Animate(precip_type);
};
loop.Start();
}
//setup values shared by all precip types
static int list_index;
static List<PictureBox> temp_list;
static Rectangle hit_detection;
static bool hit_edge;
static Random rn_index;
//shared between all precip types, with rotation added for snow
public void Animate(string pt)
{
rn_index = new Random();
rn_index.Next(0, precalculations_list.Count - 1);
temp_list = picture_boxes.ToList();
hit_detection = pm.ClientRectangle;
hit_edge = false;
foreach (PictureBox pb in temp_list)
{
list_index = rn_index.Next(0, precalculations_list.Count - 1);
pb.Top += added_pix_int + precalculations_list[list_index];
pb.Left += s_d;
if (pt != "Rain")
{
Image img = pb.Image;
img.RotateFlip(RotateFlipType.Rotate90FlipNone);
pb.Image = img;
}
//when one touches the edge of the screen, clear the list/boxes
if (pb.Left < hit_detection.Left ||
pb.Right > hit_detection.Right ||
pb.Bottom > hit_detection.Bottom)
{
pm.Controls.Remove(pb);
picture_boxes.Remove(pb);
hit_edge = true;
}
}
//cannot modify collection, so happens afterward
//todo: check if hit left or right too, if skew is active
if (hit_edge && picture_boxes.Count < img_count)
{
temp_list.Clear();
AddBoxes();
}
}
};
1条答案
按热度按时间m1m5dgzv1#
您应该只示例化Random一次。
变更:
收件人:
并删除animate()方法中创建Random的行。
如果你想让它们以不同于Tick()事件的速度旋转,你可以创建一个
DateTime
变量来保存它们下一次应该旋转的时间,只要超过这个时间,就执行旋转并重置为下一个目标时间:在animate()中: