简体   繁体   English

如何检测 c# forms 上的粘连

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM