コード例 #1
0
ファイル: Grid.cs プロジェクト: timdetering/Endogine
        public void SetBallOnLoc(EPoint a_pnt, Ball a_ball)
        {
            if (a_pnt.X < 0 || a_pnt.X >= GridSize.Width || a_pnt.Y < 0)
            {
                return;
            }
            m_aGrid[a_pnt.X, a_pnt.Y] = a_ball;
            a_ball.GridLoc            = a_pnt;
            a_ball.Loc = GetGfxLocFromGridLoc(a_pnt);

            ResetChainNums();
            m_nCurrentChainNum = 0;
            ArrayList aSameColor = CalcColorChain(a_pnt);

            if (aSameColor.Count > 2)
            {
                ArrayList aAllRemove = new ArrayList();
                //remove balls in color chain, and then all balls that are no longer connected to ceiling!

                //first color chain, and also find all neighbours to the color chain
                ArrayList aAllNeighbours = new ArrayList();
                //make a list of all neighbours:
                foreach (Ball removeball in aSameColor)
                {
                    ArrayList aNeighbours = GetNeighbours(removeball);
                    foreach (Ball neighbour in aNeighbours)
                    {
                        if (aAllNeighbours.Contains(neighbour) == false && aSameColor.Contains(neighbour) == false)
                        {
                            aAllNeighbours.Add(neighbour);
                        }
                    }
                    RemoveBallAtLoc(removeball.GridLoc);
                    removeball.Burst();
                    //aAllRemove.Add(removeball);
                }

                ResetChainNums();
                m_nCurrentChainNum = 0;
                //now for each neighbour, add to remove list if not connected to ceiling:
                foreach (Ball ball in aAllNeighbours)
                {
                    //if one of these balls is connected to another, the recursive function will already have added it to its remove list
                    if (ball.ChainNum < 0)
                    {
                        EndogineHub.Put("New chain");
                        m_aCurrentChainInfo = new ChainInfo();
                        if (RecursiveCalcConnection(ball) == false)                         //the chain is not connected to ceiling
                        {
                            foreach (Ball removeball in m_aCurrentChainInfo.Balls)
                            {
                                aAllRemove.Add(removeball);
                                RemoveBallAtLoc(removeball.GridLoc);
                            }
                        }
                    }
                }

                foreach (Ball removeball in aAllRemove)
                {
                    removeball.Fall();                     //Dispose(); //.Color = Color.FromArgb(100,100,100);
                }

                m_playArea.RemovedBalls(aSameColor.Count, aAllRemove.Count);
            }
        }
コード例 #2
0
ファイル: PathCalc.cs プロジェクト: timdetering/Endogine
        /// <summary>
        ///
        /// </summary>
        /// <param name="a_loc">start loc</param>
        /// <param name="a_vel">find first collision/bounce while moving this amount</param>
        /// <param name="pntGridStick"></param>
        /// <returns>true if it hit something to stick to (another ball, or ceiling)</returns>
        public bool GetFirstStickOrBounce(ref EPointF a_loc, ref EPointF a_vel,
                                          out EPoint pntGridStick, out EPointF pntBounce, bool bMoveBallAfterCollision)
        {
            EPointF pntCollision = new EPointF(0, 0);
            EPointF pntCircleAtCollision;
            EPointF pntNormal = new EPointF(0, 0);
            bool    bCollided = false;

            pntGridStick = null;          //new EPoint(0,0);
            pntBounce    = null;          //new EPointF(0,0);

            float     fFirstTime = 1000;
            ArrayList aBalls     = m_playArea.Grid.GetAllBalls();

            foreach (Ball ball in aBalls)
            {
                float   fTime;
                EPointF pntThisCollision;

                if (Endogine.Collision.Collision.CalcFirstCircleCircleCollisions(
                        a_loc, ball.Loc,
                        a_vel, new EPointF(0, 0),
                        m_playArea.Grid.BallDiameter / 2 - 1, m_playArea.Grid.BallDiameter / 2 - 1,         //it's more like the original if we subtract 1
                        out pntThisCollision, out fTime))
                {
                    if (fTime < fFirstTime)
                    {
                        pntCollision = pntThisCollision;
                        fFirstTime   = fTime;
                    }
                }
            }
            if (fFirstTime < 1000)
            {
                EPointF pntfGrid = m_playArea.Grid.GetGridLocFromGfxLoc(pntCollision);
                pntGridStick = m_playArea.Grid.RoundToClosestGridLoc(pntfGrid);
                a_loc        = m_playArea.Grid.GetGfxLocFromGridLoc(pntGridStick);
                a_vel        = new EPointF(0, 0);
                return(true);
            }

            //check wall bounces and ceiling stick
            for (int nLineNum = 0; nLineNum < m_playArea.m_aCollisionLines.Count; nLineNum++)
            {
                ERectangleF rctLine = (ERectangleF)m_playArea.m_aCollisionLines[nLineNum];
                if (Endogine.Collision.Collision.CalcCircleLineCollision(a_loc, m_playArea.Grid.BallDiameter / 2, a_vel, rctLine, out pntCollision, out pntCircleAtCollision))
                {
                    if (nLineNum == 0)
                    {
                        //hit ceiling: make it stick!
                        EPointF pntfGrid = m_playArea.Grid.GetGridLocFromGfxLoc(pntCollision);
                        EndogineHub.Put(pntCollision.ToString() + "  " + pntfGrid.ToString());
                        pntGridStick = m_playArea.Grid.RoundToClosestGridLoc(pntfGrid);
                        a_loc        = m_playArea.Grid.GetGfxLocFromGridLoc(pntGridStick);
                        a_vel.X      = 0;
                        a_vel.Y      = 0;
                        return(true);
                    }

                    //TODO: check all lines, and use the one that is collided with first.
                    //Then a new test should be done from the bounce point

                    pntBounce = pntCollision;
                    //bounce against a wall: which direction will it have afterwards
                    double dNormal = Endogine.Collision.Collision.GetNormalAngle(rctLine);
                    //the line's direction, it shouldn't matter if it's up or down, or left or right - same bounce regardless
                    if (dNormal >= Math.PI)
                    {
                        dNormal -= Math.PI;
                    }
                    if (dNormal >= Math.PI / 2)
                    {
                        dNormal -= Math.PI / 2;
                    }

                    double dVelAngle = Math.Atan2(a_vel.X, -a_vel.Y);

                    double dAfterBounceAngle = dNormal - (dVelAngle - dNormal);
                    //just so it's easier to debug:
                    if (dAfterBounceAngle > Math.PI)
                    {
                        dAfterBounceAngle -= Math.PI;
                    }

                    //how far can it move before hitting wall
                    EPointF pntBefore   = new EPointF(pntCircleAtCollision.X - a_loc.X, pntCircleAtCollision.Y - a_loc.Y);
                    double  dPartOfMove = Endogine.Collision.PointLine.PointIsWhereOnLine(pntBefore, new ERectangleF(0, 0, a_vel.X, a_vel.Y));
                    if (dPartOfMove > 0.99)
                    {
                        dPartOfMove = 0.99;
                    }
                    else if (dPartOfMove < 0 && dPartOfMove > -0.001)
                    {
                        dPartOfMove = 0;
                    }

                    //the rest of the movement will be in bounce direction
                    a_vel = EPointF.FromLengthAndAngle(a_vel.Length, (float)dAfterBounceAngle);
                    //EPointF velNew = EPointF.FromLengthAndAngle(a_vel.Length, (float)dAfterBounceAngle);
                    //a_vel.X = velNew.X;
                    //a_vel.Y = velNew.Y;

                    //TODO: pntCircleAtCollision is not correctly calculated.
                    a_loc = pntCircleAtCollision;

                    if (bMoveBallAfterCollision)
                    {
                        a_loc.X += a_vel.X * (float)(1.0 - dPartOfMove);
                        a_loc.Y += a_vel.Y * (float)(1.0 - dPartOfMove);
                    }

                    bCollided = true;
                    break;
                }
            }
            if (!bCollided)
            {
                a_loc.X += a_vel.X;
                a_loc.Y += a_vel.Y;
            }
            return(false);
        }
コード例 #3
0
        public static XmlNode Serialize(object a_obj, XmlNode a_node, string a_name)
        {
            System.Type type = a_obj.GetType();
            System.Reflection.PropertyInfo[] propInfos = type.GetProperties();

            if (a_name == null)
            {
                a_name = "GNode";
            }
            XmlElement elm = a_node.OwnerDocument.CreateElement(a_name);             //type.Name);

            XmlAttribute attrib;

            attrib           = a_node.OwnerDocument.CreateAttribute("Assembly", null);
            attrib.InnerText = "Endogine";             //TODO: type.Assembly.AssemblyQualifiedName (=GetName())
            elm.Attributes.Append(attrib);

            //TODO: we should optionally be able to specify which base class to serialize.
            //For example, we might want to serialize all different sprite-based objects as sprites,
            //not as Players, Balls, Ships etc...
            attrib           = a_node.OwnerDocument.CreateAttribute("Type", null);
            attrib.InnerText = type.FullName;
            elm.Attributes.Append(attrib);

            a_node.AppendChild(elm);

            foreach (System.Reflection.PropertyInfo propInfo in propInfos)
            {
                if (propInfo.PropertyType.IsSerializable &&                 //!propInfo.PropertyType.IsArray &&
                    propInfo.CanRead && propInfo.CanWrite && propInfo.PropertyType.IsPublic)
                {
                    object propValue = null;
                    try
                    {
                        propValue = propInfo.GetValue(a_obj, null);
                    }
                    catch
                    {
                        EndogineHub.Put(propInfo.Name + " failed");
                        continue;
                    }

                    if (propValue == null)
                    {
                        continue;
                    }

                    object[] attribs;

//					attribs = propInfo.GetCustomAttributes(typeof(BrowsableAttribute), true);
//					if (attribs.Length > 0)
//					{
//						BrowsableAttribute propAttrib = (BrowsableAttribute)attribs[0];
//						if (propAttrib.Browsable == false)
//							continue;
//					}

                    attribs = propInfo.GetCustomAttributes(typeof(DesignerSerializationVisibilityAttribute), true);
                    if (attribs.Length > 0)
                    {
                        DesignerSerializationVisibilityAttribute propAttrib = (DesignerSerializationVisibilityAttribute)attribs[0];
                        if (propAttrib.Visibility == DesignerSerializationVisibility.Hidden)
                        {
                            continue;
                        }
                    }

//					//don't serialize if default value:
                    attribs = propInfo.GetCustomAttributes(typeof(DefaultValueAttribute), true);
                    if (attribs.Length > 0)
                    {
                        DefaultValueAttribute propAttrib = (DefaultValueAttribute)attribs[0];
                        if (propAttrib.Value.Equals(propValue))
                        {
                            continue;
                        }
                    }

                    if (propInfo.PropertyType.IsValueType == false &&
                        propInfo.PropertyType.IsSerializable &&
                        propInfo.PropertyType.UnderlyingSystemType != typeof(string))
                    {
                        Serialize(propValue, elm, propInfo.Name);
                    }
                    else
                    {
                        string sVal = Convert.ToString(propValue);
                        System.Xml.XmlElement prop = a_node.OwnerDocument.CreateElement(propInfo.Name);
                        prop.SetAttribute("v", null, sVal);
                        elm.AppendChild(prop);
                    }
                }
            }
            return(elm);
        }
コード例 #4
0
ファイル: XMLEditor.cs プロジェクト: timdetering/Endogine
        private void dataGrid1_CurrentCellChanged(object sender, System.EventArgs e)
        {
            ArrayList aVisibleNodes = TreeViewHelper.GetFlatVisibleTreeNodes(treeView1);
            int       nNumVisible   = aVisibleNodes.Count;
            //TODO: ugly way to stop the extra line in dataview (for adding new rows) from being available:
            int nCurrRow = dataGrid1.CurrentCell.RowNumber;

            if (nCurrRow >= nNumVisible)
            {
                //dataGrid1.Select(nCurrRow-1);
                dataGrid1.CurrentRowIndex = nCurrRow - 1;
            }
            else
            {
                dataGrid1.ReadOnly = false;
            }

            if (m_pntLastDataGridCell.X >= 0)
            {
                string   sVal     = Convert.ToString(((DataTable)dataGrid1.DataSource).Rows[m_pntLastDataGridCell.Y][m_pntLastDataGridCell.X]);
                TreeNode treeNode = (TreeNode)aVisibleNodes[m_pntLastDataGridCell.Y];
                XmlNode  xmlNode  = (XmlNode)treeNode.Tag;

                if (m_pntLastDataGridCell.X == 0)
                {
                    string      sForXMLParse = "<temp " + sVal + "/>";
                    XmlDocument xmlDoc       = new XmlDocument();
                    try
                    {
                        xmlDoc.LoadXml(sForXMLParse);
                        xmlNode.Attributes.RemoveAll();

                        foreach (XmlAttribute attrib in xmlDoc.ChildNodes[0].Attributes)
                        {
                            XmlAttribute newAttrib = (XmlAttribute)m_doc.CreateNode(XmlNodeType.Attribute, attrib.Name, null);
                            newAttrib.InnerText = attrib.InnerText;
                            xmlNode.Attributes.Append(newAttrib);
                        }
                    }
                    catch
                    {
                        ((DataTable)dataGrid1.DataSource).Rows[m_pntLastDataGridCell.Y][m_pntLastDataGridCell.X] = CreateAttributesString(xmlNode);
                        //MessageBox.Show("Attributes formatting invalid");
                    }
                    EndogineHub.Put(sVal);
                }
                else if (m_pntLastDataGridCell.X == 1)
                {
                    bool bFound = false;
                    foreach (XmlNode childNode in xmlNode.ChildNodes)
                    {
                        if (childNode.NodeType == XmlNodeType.Text)
                        {
                            childNode.InnerText = sVal;
                            bFound = true;
                            break;
                        }
                    }
                    if (!bFound)
                    {
                        XmlNode newNode = m_doc.CreateTextNode(sVal);
                        xmlNode.AppendChild(newNode);
                    }
                }
            }
            m_pntLastDataGridCell.Y = dataGrid1.CurrentRowIndex;
            m_pntLastDataGridCell.X = dataGrid1.CurrentCell.ColumnNumber;
        }