All pastes #1373724 Raw Edit

some bad physics code

public text v1 · immutable
#1373724 ·published 2009-03-27 05:15 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace WindowsGame1
{
    class Physics
    {
        const int PUSH_UP_DIVISOR = 4;
        const int GRAVITY = 5;
        const int MAX_JUMP_TIME = 300;
        const int JUM_STICK_TIME = 50;
        const int JUMP_PER_TICK = -5;

        public enum Directions { UP, DOWN, LEFT, RIGHT };

        public static void actOn(Mob m, GameTime t)
        {
            Console.WriteLine(Physics.GRAVITY);
            if (!m.IsJumping || m.jumpTime > MAX_JUMP_TIME)
            {
                m.IsOnGround = CheckGroundCollide(m, Directions.DOWN);
                if (m.IsOnGround)
                {
                    m.resetJumping();
                }
                Rectangle bottomRect = new Rectangle(m.X, m.Y + m.height, m.width, 1);
                if (!IntersectPixels(bottomRect, null, m.level.rect, m.level.textureData))
                {
                    m.Y += (int)TryMove(m, 0, GRAVITY).Y;
                }
            }
            else
            {
                int dy = (int) TryMove(m, 0, JUMP_PER_TICK).Y;
                m.Y += dy;
                m.jumpTime += t.ElapsedGameTime.Milliseconds;
                if (dy != JUMP_PER_TICK)
                {
                    //collision, stop jumping
                    m.jumpTime = MAX_JUMP_TIME + 1;
                }
            }
        }

        public static bool CheckGroundCollide(Mob m, Directions d)
        {
            Rectangle use = new Rectangle();
            switch (d)
            {
                case Directions.RIGHT:
                    use = new Rectangle(m.X + m.width, m.Y, 1, m.height);
                    break;
                case Directions.LEFT:
                    use = new Rectangle(m.X, m.Y, 1, m.height);
                    break;
                case Directions.UP:
                    use = new Rectangle(m.X, m.Y, m.width, 1);
                    break;
                case Directions.DOWN:
                    use = new Rectangle(m.X, m.Y + m.height, m.width, 1);
                    break;
            }
            return IntersectPixels(m, use);
        }

        //returns new mx, my
        public static Vector2 TryMove(Mob m, int mx, int my)
        {
            int rx = mx, ry = my; //final values
            if (mx > 0) {
                //moving right
               Rectangle rightRect = new Rectangle(m.X + m.width, m.Y, 1, m.height);
                for (int i = 0; i < mx; i++) {
                    if (IntersectPixels(m, rightRect))
                    {
                        rx = i;
                        ry -= PushUpIntersect(m, rightRect);
                        break;
                    }
                }
            }
            else if (mx < 0)
            {
                //moving left
                Rectangle leftRect = new Rectangle(m.X, m.Y, 1, m.height);
                for (int i = 0; i > mx; i--)
                {
                    if (IntersectPixels(m, leftRect))
                    {
                        rx = i;
                        ry -= PushUpIntersect(m, leftRect);
                        break;
                    }
                }
            }
            if (my < 0)
            {
                //moving up
                Rectangle upRect = new Rectangle(m.X, m.Y, m.width, 1);
               
                for (int i = 0; i > my; i--)
                {
                    if (IntersectPixels(m, upRect))
                    {
                        ry = i;
                        break;
                    }
                }
            }
            else if (my > 0)
            {
                //moving down
                Rectangle downRect = new Rectangle(m.X, m.Y + m.height, m.width, 1);
                for (int i = 0; i < my; i++)
                {
                    if (IntersectPixels(m, downRect))
                    {
                        ry = i;
                        break;
                    }
                }
            }
            return new Vector2(rx, ry);
        }

        public static bool IntersectPixels(Mob m, Rectangle useRect) {
                return IntersectPixels(useRect, null, m.level.rect, m.level.textureData);
        }

        public static int PushUpIntersect(Mob m, Rectangle rect)
        {
            Rectangle rectangleA = rect;
            Rectangle rectangleB = m.level.rect;
            Color[] dataB = m.level.textureData;
            // Find the bounds of the rectangle intersection
            int top = Math.Max(rectangleA.Top, rectangleB.Top);
            int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
            int left = Math.Max(rectangleA.Left, rectangleB.Left);
            int right = Math.Min(rectangleA.Right, rectangleB.Right);

            // Check every point within the intersection bounds
            for (int y = top; y < bottom; y++)
            {
                for (int x = left; x < right; x++)
                {
                    Color colorB = dataB[(x - rectangleB.Left) +
                                         (y - rectangleB.Top) * rectangleB.Width];
                    if (colorB.A != 0)
                    {
                        Rectangle pushRect = new Rectangle(rect.X, rect.Y + (rect.Height - rect.Height / PUSH_UP_DIVISOR), rect.Width, rect.Height / PUSH_UP_DIVISOR);
                        Rectangle oppRect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height - pushRect.Height);
                        if (pushRect.Contains(x, y) && !IntersectPixels(oppRect, null, m.level.rect, m.level.textureData)) {
                            return rect.Bottom - y + GRAVITY;
                        }
                    }

                }
            }

            // No pushing can be done
            return 0;
        }

        public static bool IntersectPixels(Rectangle rectangleA, Color[] dataA,
                                    Rectangle rectangleB, Color[] dataB)
        {
            // Find the bounds of the rectangle intersection
            int top = Math.Max(rectangleA.Top, rectangleB.Top);
            int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
            int left = Math.Max(rectangleA.Left, rectangleB.Left);
            int right = Math.Min(rectangleA.Right, rectangleB.Right);            

            // Check every point within the intersection bounds
            for (int y = top; y < bottom; y++)
            {
                for (int x = left; x < right; x++)
                {
                    Color colorB = dataB[(x - rectangleB.Left) +
                                         (y - rectangleB.Top) * rectangleB.Width];
                 
                    if (colorB.A != 0)
                    {
                        return true;
                    }
                    
                }
            }

            // No intersection found
            return false;
        }
    }
}