[英]How to detect colision on c# forms
I'm trying to detect collisions between a Player obj and any other PhisicalEntity in the objectList
List in C#, but I can't get it to work.我试图在 C# 的
objectList
列表中检测 Player obj 和任何其他 PhisicalEntity 之间的冲突,但我无法让它工作。 any thoughts?有什么想法吗?
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Media;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyGame
{
public partial class GameCanvas : Form
{
public int BlockSize = 10;
public Timer timer1;
private static PlayerInputHandler UINPUT = new PlayerInputHandler();
private static List<ObjContainer> playerList = new List<ObjContainer>();
private static List<ObjContainer> objectList = new List<ObjContainer>();
struct speedVec
{
public int NormalizeSpeedVector(int value)
{
return (value == 0) ? 0 : ((value < 0) ? -1 : 1);
}
}
class PlayerInputHandler
{
public int x = 0;
public int y = 0;
public PlayerInputHandler()
{
}
public void SenceUp()
{
this.y = (new speedVec()).NormalizeSpeedVector(this.y - 1);
}
public void SenceDown()
{
this.y = (new speedVec()).NormalizeSpeedVector(this.y + 1);
}
public void SenceRight()
{
this.x = (new speedVec()).NormalizeSpeedVector(this.x + 1);
}
public void SenceLeft()
{
this.x = (new speedVec()).NormalizeSpeedVector(this.x - 1);
}
public void SenceNull()
{
this.x = 0;
this.y = 0;
}
}
class ObjContainer
{
private int OID;
public PhisicalEntity OBJ;
public ObjContainer(int OID, PhisicalEntity OBJ)
{
this.OID = OID;
this.OBJ = OBJ;
}
}
abstract class PhisicalEntity
{
public static PictureBox OnScreenRepresentation;
public abstract void Step();
public int GetX()
{
return OnScreenRepresentation.Location.X;
}
public int GetY()
{
return OnScreenRepresentation.Location.Y;
}
}
class Player : PhisicalEntity
{
public int x;
public int y;
public int xs;
public int ys;
public int health;
public int gravity;
public int friction;
public Player(int x, int y, int xs, int ys, int health, int gravity, int friction, PictureBox repr)
{
this.x = x;
this.y = y;
this.xs = xs;
this.ys = ys;
this.health = health;
this.gravity = gravity;
this.friction = friction;
OnScreenRepresentation = repr;
}
override public void Step()
{
if (CheckColision(this.x, this.y, this.xs, this.ys))
{
this.xs = UINPUT.x;
this.ys = UINPUT.y;
UINPUT.SenceNull();
this.x += this.xs * 3;
this.y += this.ys * 3;
OnScreenRepresentation.Location = new Point(this.x, this.y);
}
}
public bool isBetwen(int value, int min, int max)
{
return (value < max) ? ((value > min) ? true : false) : false;
}
private bool CheckColision(int x, int y, int xs, int ys)
{
foreach (ObjContainer phisicalEmu in objectList)
{
PhisicalEntity obj = phisicalEmu.OBJ;
int phiX = obj.GetX();
int phiY = obj.GetY();
if (isBetwen(x + xs, phiX + 10, phiX) || isBetwen(x + 10 + xs, phiX + 10, phiX))
{
return true;
}
if (isBetwen(y + ys, phiY + 10, phiY) || isBetwen(y + 10 + ys, phiY + 10, phiY))
{
return true;
}
}
return false;
}
}
class Structural : PhisicalEntity
{
public int x;
public int y;
public int xs;
public int ys;
public int health;
public int gravity;
public int friction;
public PictureBox OnScreenRepresentation;
public Structural(int x, int y, int xs, int ys, int health, int gravity, int friction, PictureBox repr)
{
this.x = x;
this.y = y;
this.xs = xs;
this.ys = ys;
this.health = health;
this.gravity = gravity;
this.friction = friction;
this.OnScreenRepresentation = repr;
}
override public void Step()
{
this.xs = UINPUT.x;
this.ys = UINPUT.y;
UINPUT.SenceNull();
this.x += this.xs * 3;
this.y += this.ys * 3;
OnScreenRepresentation.Location = new Point(this.x, this.y);
}
}
public void InitTimer()
{
Timer timer = new Timer();
timer.Tick += new EventHandler(Step);
timer.Interval = 20;
timer.Start();
}
public void Step(object sender, EventArgs e)
{
foreach (ObjContainer obj in playerList)
{
obj.OBJ.Step();
}
}
public GameCanvas()
{
InitializeComponent();
}
private void GC_onLoad(object sender, EventArgs e)
{
RegisterNewPlayer(new Player(0, 0, 0, 0, 100, 3, 0, o_934), (new Random()).Next(((new Random()).Next())));
RegisterNewStruc(new Structural(0, 0, 0, 0, 0, 0, 0, o_980), (new Random()).Next(((new Random()).Next())));
InitTimer();
}
private void RegisterNewPlayer(Player obj, int KeyGen)
{
int num = ((new DateTime()).Year + (new DateTime()).Month + (new DateTime()).Day + (new DateTime()).Hour + (new DateTime()).Second + (new DateTime()).Millisecond) * KeyGen;
ObjContainer OnRegst = new ObjContainer(num, obj);
playerList.Add(OnRegst);
}
private void RegisterNewStruc(Structural obj, int KeyGen)
{
int num = ((new DateTime()).Year + (new DateTime()).Month + (new DateTime()).Day + (new DateTime()).Hour + (new DateTime()).Second + (new DateTime()).Millisecond) * KeyGen;
ObjContainer OnRegst = new ObjContainer(num, obj);
objectList.Add(OnRegst);
}
private void ProccessKeyEvents(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Up)
{
UINPUT.SenceUp();
}
if (e.KeyData == Keys.Down)
{
UINPUT.SenceDown();
}
if (e.KeyData == Keys.Left)
{
UINPUT.SenceLeft();
}
if (e.KeyData == Keys.Right)
{
UINPUT.SenceRight();
}
}
}
}
Try looking at the methods for Rectangle https://docs.microsoft.com/en-us/dotnet/api/system.drawing.rectangle?view=netcore-3.1尝试查看 Rectangle https://docs.microsoft.com/en-us/dotnet/api/system.drawing.rectangle?view=netcore-3.1的方法
Also consider having a debug mode and when running in debug mode you can draw debug items to display boundaries, collisions, to aid development.还可以考虑使用调试模式,在调试模式下运行时,您可以绘制调试项目以显示边界、碰撞,以帮助开发。
An example fix using the code you provided with minor updates.使用您提供的带有小更新的代码的示例修复。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Media;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyGame
{
public partial class GameCanvas : Form
{
public int BlockSize = 10;
public Timer timer1;
private static PlayerInputHandler UINPUT = new PlayerInputHandler();
private static List<ObjContainer> playerList = new List<ObjContainer>();
private static List<ObjContainer> objectList = new List<ObjContainer>();
struct speedVec
{
public int NormalizeSpeedVector(int value)
{
return (value == 0) ? 0 : ((value < 0) ? -1 : 1);
}
}
class PlayerInputHandler
{
public int x = 0;
public int y = 0;
public PlayerInputHandler()
{
}
public void SenceUp()
{
this.y = (new speedVec()).NormalizeSpeedVector(this.y - 1);
}
public void SenceDown()
{
this.y = (new speedVec()).NormalizeSpeedVector(this.y + 1);
}
public void SenceRight()
{
this.x = (new speedVec()).NormalizeSpeedVector(this.x + 1);
}
public void SenceLeft()
{
this.x = (new speedVec()).NormalizeSpeedVector(this.x - 1);
}
public void SenceNull()
{
this.x = 0;
this.y = 0;
}
}
class ObjContainer
{
private int OID;
public PhisicalEntity OBJ;
public ObjContainer(int OID, PhisicalEntity OBJ)
{
this.OID = OID;
this.OBJ = OBJ;
}
}
abstract class PhisicalEntity
{
protected PictureBox OnScreenRepresentation;
public abstract void Step();
public int GetX()
{
return OnScreenRepresentation.Location.X;
}
public int GetY()
{
return OnScreenRepresentation.Location.Y;
}
public int GetHeight()
{
return OnScreenRepresentation.Height;
}
public int GetWidth()
{
return OnScreenRepresentation.Width;
}
}
class Player : PhisicalEntity
{
//public int x;
//public int y;
//public int xs;
//public int ys;
public int health;
public int gravity;
public int friction;
public Player(int health, int gravity, int friction, PictureBox repr)
{
//this.x = x;
//this.y = y;
//this.xs = xs;
//this.ys = ys;
this.health = health;
this.gravity = gravity;
this.friction = friction;
OnScreenRepresentation = repr;
}
override public void Step()
{
if (CheckColision(this.GetX() + UINPUT.x, this.GetY() + UINPUT.y))
{
//this.xs = UINPUT.x;
//this.ys = UINPUT.y;
//UINPUT.SenceNull();
//this.x += this.xs * 3;
//this.y += this.ys * 3;
//this.x += this.xs;
//this.y += this.ys;
OnScreenRepresentation.Left += UINPUT.x;
OnScreenRepresentation.Top += UINPUT.y;
}
UINPUT.SenceNull();
//else
//{
// UINPUT.x = this.x;
// UINPUT.y = this.y;
//}
}
public bool isBetwen(int value, int min, int max)
{
return (value < max) ? ((value > min) ? true : false) : false;
}
private bool CheckColision(int x, int y)
{
var height = this.GetHeight();
var width = this.GetWidth();
var coordinates = new List<int[]>() { new[] {x,y }, new[] { x, y+height }, new[] { x+width, y }, new[] { x+width, y+height } };
foreach (ObjContainer phisicalEmu in objectList)
{
PhisicalEntity obj = phisicalEmu.OBJ;
int phiX = obj.GetX();
int phiY = obj.GetY();
var phiHeight = obj.GetHeight();
var phiWidth = obj.GetWidth();
var phiCoordinates = new List<int[]>() { new[] { phiX, phiY }, new[] { phiX, phiY + phiHeight }, new[] { phiX + phiWidth, phiY }, new[] { phiX + phiWidth, phiY + phiHeight } };
int maxPhiX = phiX + phiWidth;
int maxPhiY = phiY + phiHeight;
//Check if edge points in phi are directly part of the player object
foreach(var coordinate in coordinates)
{
if (isBetwen(coordinate[0], phiX, maxPhiX) && isBetwen(coordinate[1], phiY, maxPhiY))
{
return false;//Collision
}
}
int maxX = x + width;
int maxY = y + height;
//Check if edge points in the player object are directly part of phi
foreach (var coordinate in phiCoordinates)
{
if (isBetwen(coordinate[0], x, maxX) && isBetwen(coordinate[1], y, maxY))
{
return false;//Collision
}
}
}
return true;
}
}
class Structural : PhisicalEntity
{
//public int x;
//public int y;
//public int xs;
//public int ys;
public int health;
public int gravity;
public int friction;
//public PictureBox OnScreenRepresentation;
public Structural(int health, int gravity, int friction, PictureBox repr)
{
//this.x = x;
//this.y = y;
//this.xs = xs;
//this.ys = ys;
this.health = health;
this.gravity = gravity;
this.friction = friction;
this.OnScreenRepresentation = repr;
}
override public void Step()
{
//this.xs = UINPUT.x;
//this.ys = UINPUT.y;
//UINPUT.SenceNull();
//this.x += this.xs * 3;
//this.y += this.ys * 3;
//OnScreenRepresentation.Location = new Point(this.x, this.y);
OnScreenRepresentation.Top += UINPUT.y;
OnScreenRepresentation.Left += UINPUT.x;
UINPUT.SenceNull();
}
}
public void InitTimer()
{
Timer timer = new Timer();
timer.Tick += new EventHandler(Step);
timer.Interval = 20;
timer.Start();
}
public void Step(object sender, EventArgs e)
{
foreach (ObjContainer obj in playerList)
{
obj.OBJ.Step();
}
}
public GameCanvas()
{
InitializeComponent();
}
private void GC_onLoad(object sender, EventArgs e)
{
RegisterNewPlayer(new Player(100, 3, 0, o_934), (new Random()).Next(((new Random()).Next())));
RegisterNewStruc(new Structural(0, 0, 0, o_980), (new Random()).Next(((new Random()).Next())));
InitTimer();
}
private void RegisterNewPlayer(Player obj, int KeyGen)
{
int num = ((new DateTime()).Year + (new DateTime()).Month + (new DateTime()).Day + (new DateTime()).Hour + (new DateTime()).Second + (new DateTime()).Millisecond) * KeyGen;
ObjContainer OnRegst = new ObjContainer(num, obj);
playerList.Add(OnRegst);
}
private void RegisterNewStruc(Structural obj, int KeyGen)
{
int num = ((new DateTime()).Year + (new DateTime()).Month + (new DateTime()).Day + (new DateTime()).Hour + (new DateTime()).Second + (new DateTime()).Millisecond) * KeyGen;
ObjContainer OnRegst = new ObjContainer(num, obj);
objectList.Add(OnRegst);
}
private void ProccessKeyEvents(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Up)
{
UINPUT.SenceUp();
}
if (e.KeyData == Keys.Down)
{
UINPUT.SenceDown();
}
if (e.KeyData == Keys.Left)
{
UINPUT.SenceLeft();
}
if (e.KeyData == Keys.Right)
{
UINPUT.SenceRight();
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.