gpt4 book ai didi

c# - 来自列表c#中图片框的碰撞检测

转载 作者:行者123 更新时间:2023-12-04 07:36:24 24 4
gpt4 key购买 nike

我正在创建一个程序,该程序具有由用户插入的预定义数量的图片框,然后添加到列表中。图片框必须增长,每次它们相互碰撞或击中面板边界时,游戏就结束了。我无法检测到它们之间的碰撞。您可以在 2 foreach 部分找到问题。提前致谢

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Boxen
{
public partial class FrmBoxes : Form
{
public FrmBoxes()
{
InitializeComponent();
}

//Defined Global Variables for the User input, points, the biggest box, total of points and the average of points
int UserInput;
int Points = 0, BiggestBox = 0, PointsTotal =0;
double AveragePoints = 0;

//List of points of each box and another one to insert the boxes

List<int> PointsList = new List<int>();
List<PictureBox> picboxsList = new List<PictureBox>();

//Random generator for color in the boxes
Random rnd = new Random();

/// <summary>
/// FrmBoxes_Load means when the formular will load, than Info will be shown and Timer will be set to false
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FrmBoxes_Load(object sender, EventArgs e)
{
// Info will be displayed
LblInfo.Text = "Click Box, as bigger as more points you get";
//Timer set to false
TmrFirst.Enabled = false;
}

/// <summary>
/// TmrFirst_Tick, each time the Timer will tick will write on 3 labels different values according with the total points, average points and size of box es
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TmrFirst_Tick(object sender, EventArgs e)
{
//this tree labels will be written from their variables values and the value that its in that variable will be connverted to string
LblPoints.Text = Convert.ToString(PointsTotal);
LblClickPoints.Text = Convert.ToString(AveragePoints);
LblBiggestBox.Text = Convert.ToString(BiggestBox);



//Loop that counts betwwen 0 and the amount of Boxes inside of the List
for (int i = 0; i < picboxsList.Count; i++)
{
//The index of the List will gain a new size of 2 pixels in height and width at each tick
picboxsList[i].Size = new Size(picboxsList[i].Width + 2, picboxsList[i].Height + 2);
}


//Verificacion if the amount of boxes in the List is inferior to the number inputed bby the user
if (picboxsList.Count < UserInput)
{
//Object Box is created with 20 Pixels height and widht and a random color is generated for their background
PictureBox picBox = new PictureBox();
picBox.Size = new Size(20, 20);
picBox.BackColor = Color.FromArgb(rnd.Next(10, 245), rnd.Next(10, 245), rnd.Next(10, 245));

//Event handler will be added to click the box event
picBox.Click += new EventHandler(PicBox_Click);

//Box will be added to the game field with 30 Pixels distance to the edges
PnlGameField.Controls.Add(picBox);
picBox.Location = new Point(rnd.Next(0, PnlGameField.Width - 30), rnd.Next(0, PnlGameField.Height - 30));

//Each created box will be added to the List
picboxsList.Add(picBox);

foreach (Control x in this.Controls)
{

foreach (Control y in this.Controls)
{

if (x != y)
{
if (x.Bounds.IntersectsWith(y.Bounds)) //&& (picBox.Bounds.IntersectsWith(x.Bounds)PnlGameField.Height)) && (picBox.Bounds.IntersectsWith(x.Bounds)PnlGameField.Width))
{
LblInfo.Text = "Game Over";
TmrFirst.Stop();
}
}
}
}
}


//Check that the list is not nothing and contains more than 1 element before continuing.
//for (outerIndex as Int32 = 0; picboxsList.Count - 2)

//for (innerIndex as Int32 = outerIndex + 1; picboxsList.Count - 1)
//if (picboxsList(outerIndex).Bounds.IntersectsWith(picboxsList(innerIndex).Bounds))
//Then slimeList(outerIndex) and slimeList(innerIndex) have collided.
}

/// <summary>
/// Pic_Box, event handler created at click, will add some values and remove after click
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PicBox_Click(object sender, EventArgs e)
{
//event handler called with click interaccion
PictureBox picBox = (PictureBox)sender;

//remove the box from the game field
picBox.Dispose();
//remove the box from the List
picboxsList.Remove(picBox);
//Width will be used to calculate the total points and add each time that is clicked//
PointsTotal += picBox.Width;
//Width will be used to calculate the points per click
Points = picBox.Width;
//Points will be added to the List
PointsList.Add(Points);
//Max value from a box will be token out from the list Points and saved in the variable BiggestBox
BiggestBox = PointsList.Max();
//AveragePoints variable will hold the double value of all the boxes points saved in the list and will update upon click in each box
AveragePoints = Convert.ToDouble(PointsList.Average());

}

/// <summary>
/// When start button will be clicked it creates the amount of boxes defined by the user
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnStart_Click(object sender, EventArgs e)
{
//new text inserted in the label LblInfo to be displayed upon click on the button start
LblInfo.Text = "When the Boxes hit eachother or the edges it's Game Over";
//User input converted to integer and displayed in text box
UserInput = Convert.ToInt32(TxtNumberOfBoxes.Text);
//Timer will be set to true
TmrFirst.Enabled = true;

//Loop to check the user input and add boxes till his given number
for (int i = 0; i < UserInput; i++)
{
//Object Box is created with 20 Pixels height and widht and a random color is generated for their background
PictureBox picBox = new PictureBox();
picBox.Size = new Size(20, 20);
picBox.BackColor = Color.FromArgb(rnd.Next(10, 245), rnd.Next(10, 245), rnd.Next(10, 245));

//Event handler will be added to click the box event
picBox.Click += new EventHandler(PicBox_Click);

//Box will be added to the game field with 30 Pixels distance to the edges
PnlGameField.Controls.Add(picBox);
picBox.Location = new Point(rnd.Next(0, PnlGameField.Width - 30), rnd.Next(0, PnlGameField.Height - 30));

//Each created box will be added to the List
picboxsList.Add(picBox);

}
}
}
}

最佳答案

回答
您的碰撞检测不起作用,因为您正在检查表单的控件,而不是 PnlGameField 的控件。 .请改用以下游戏循环:

private void timer1_Tick(object sender, EventArgs e)
{
var boxes = PnlGameField.Controls.OfType<PictureBox>().ToArray();
foreach (var box in boxes)
{
box.Size = new Size(box.Size.Width + 2, box.Size.Height + 2);
box.Location = new Point(box.Location.X - 1, box.Location.Y - 1);
}
if (CheckCollisions(boxes))
{
EndGame();
}
PnlGameField.Invalidate();
}

private bool CheckCollisions(PictureBox[] boxes)
{

for (int i = 0; i < boxes.Length; i++)
{
var box = boxes[i];
if (box.Left < 0 || box.Right >= PnlGameField.Width
|| box.Top < 0 || box.Bottom >= PnlGameField.Height)
{
box.BorderStyle = BorderStyle.FixedSingle;
return true;
}
for (int j = i+1; j < boxes.Length; j++)
{
var other = boxes[j];
if (box.Bounds.IntersectsWith(other.Bounds))
{
box.BorderStyle = BorderStyle.FixedSingle;
other.BorderStyle = BorderStyle.FixedSingle;
return true;
}
}
}
return false;
}
我测试过,它有效🗸。

其他有趣的点。
计分
创建一个类来跟踪得分统计信息。将点转换为浮点数,因为 double 太精确了(你得到的平均值是 29.9999999997 而不是 30.0 )并且你在平均后转换为 double 是一个错误。
public class GameScore
{
readonly List<float> pointsList;
public GameScore()
{
pointsList = new List<float>();
}
public int BoxCount { get => pointsList.Count; }
public float Average { get => pointsList.Count >0 ? pointsList.Average() : 0; }
public float Maximum { get => pointsList.Count>0 ? pointsList.Max() : 0; }
public float Total { get => pointsList.Count>0 ? pointsList.Sum() : 0; }

public void Add(int points)
{
pointsList.Add(points);
}
public void Reset()
{
pointsList.Clear();
}

public override string ToString()
{
return $"Total={Total}, Ave={Average}, Max={Maximum}";
}
}
GameScore每次点击一个框时都可以使用 score.Add(box.Width) .更多详细信息,请参阅下面的源代码
框创建/删除
还有一点是,你只需要在点击和删除一个框后添加一个新框,所以不需要检查当前计数是否==用户输入,也不需要重复添加框的代码。放入一个函数并根据需要调用它。
这是一个普遍的观察,如果您将代码拆分为功能单元(添加函数)并从 UI 处理程序调用它们,您将获得更好的服务。无需单独保留图片框列表,使用 Timer.Enabled即可知道游戏是否正在运行。属性(property)。

源列表
下面是我用于测试的完整代码 list ,它主要基于您的代码,但重新安排了一些内容。我希望您能得到启发,以了解如何更好地构建代码。
public partial class Form1 : Form
{
static Random rnd = new Random();

readonly GameScore score = new GameScore();

public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);

timer1.Enabled = false;
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
if (timer1.Enabled)
{
EndGame();
}
else
{
StartGame();
}
}

private void StartGame()
{
toolStripButton1.Text = "Stop";
toolStripButton1.BackColor = Color.FromArgb(255, 128, 128);
if (int.TryParse(toolStripTextBox1.Text, out int count) && count > 0)
{
PnlGameField.Controls.Clear();
for (int i = 0; i < count; i++)
{
AddRandomBox();
}
score.Reset();
toolStripTextBox2.Text = score.ToString();
timer1.Enabled = true;
}
}
private void EndGame()
{
toolStripButton1.Text = "Start";
toolStripButton1.BackColor = Color.FromArgb(128, 255, 128);
timer1.Enabled = false;
}

private void AddRandomBox()
{
//Object Box is created with 20 Pixels height and width and a random color is generated for their background
PictureBox picBox = new PictureBox();
picBox.Size = new Size(20, 20);
picBox.BackColor = Color.FromArgb(rnd.Next(10, 245), rnd.Next(10, 245), rnd.Next(10, 245));

//Event handler will be added to click the box event
picBox.Click += PicBox_Click;

//Box will be added to the game field with 30 Pixels distance to the edges
PnlGameField.Controls.Add(picBox);
picBox.Location = new Point(rnd.Next(0, PnlGameField.Width - 30), rnd.Next(0, PnlGameField.Height - 30));
}

private void PicBox_Click(object sender, EventArgs e)
{
var target = (PictureBox)sender;
if (timer1.Enabled)
{
RemoveBox(target);
}
}
private void RemoveBox(PictureBox box)
{
score.Add(box.Width);
box.Dispose();
PnlGameField.Controls.Remove(box);
AddRandomBox();
toolStripTextBox2.Text = score.ToString();
PnlGameField.Invalidate();
}

private void timer1_Tick(object sender, EventArgs e)
{
var boxes = PnlGameField.Controls.OfType<PictureBox>().ToArray();
foreach (var box in boxes)
{
box.Size = new Size(box.Size.Width + 2, box.Size.Height + 2);
box.Location = new Point(box.Location.X - 1, box.Location.Y - 1);
}
if (CheckCollisions(boxes))
{
EndGame();
}
PnlGameField.Invalidate();
}

private bool CheckCollisions(PictureBox[] boxes)
{

for (int i = 0; i < boxes.Length; i++)
{
var box = boxes[i];
if (box.Left < 0 || box.Right >= PnlGameField.Width
|| box.Top < 0 || box.Bottom >= PnlGameField.Height)
{
box.BorderStyle = BorderStyle.FixedSingle;
return true;
}
for (int j = i+1; j < boxes.Length; j++)
{
var other = boxes[j];
if (box.Bounds.IntersectsWith(other.Bounds))
{
box.BorderStyle = BorderStyle.FixedSingle;
other.BorderStyle = BorderStyle.FixedSingle;
return true;
}
}
}
return false;
}
}

关于c# - 来自列表c#中图片框的碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67721533/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com