制作突围游戏

时间:2014-09-29 06:44:50

标签: c# algorithm

我的朋友们我参与了这个游戏的一些部分,但我在这个游戏中有两个问题。

1)区分球碰撞障碍的问题

1-1)第一个问题与复杂的指导方针有关,我将它们用于模拟球与板的碰撞或球撞击。这些指导方针并不准确,特别是当球遇到挡块角落或底部时。 如果它不是更好的碰撞区分我使用更好的代码。我写了这段代码。你认为有更好的方法吗?

2)如果球碰撞任何障碍物,障碍物会报告碰撞,我怎能做一项工作。

我的目标是使用事件。 你是否认为我作为运行时制造障碍? 如果我作为运行时制作,我如何为它们制作碰撞事件?

最诚挚的问候

  private Point MouseDownLocation;

    int step = 2;
    int stepleft = 2;


    bool flagBottom;
    bool flagTop;

    private void Form1_Load(object sender, EventArgs e)
    {

        timer1.Interval = 10;
        timer1.Enabled = true;

    }

    private void timer1_Tick(object sender, EventArgs e)
    {


        ball.Top += step;
        ball.Left += stepleft;

        //board simulate collision
        bool collisonX = ball.Location.X + ball.Width > board.Location.X && ball.Location.X < board.Location.X + board.Width;
        bool collisonY = ball.Top + ball.Height == board.Location.Y || ball.Top + ball.Height - 1 == board.Location.Y;

        //board2(button1) simulate collision
        bool collisonX2 = ball.Location.X + ball.Width > board2.Location.X && ball.Location.X < board2.Location.X + board2.Width;
        bool collisonY2 = ball.Top + ball.Height == board2.Location.Y || ball.Top + ball.Height - 1 == board2.Location.Y;

        //Collision the ball with under buttons 
        bool collsionButtonY = ball.Top - ball.Height == board2.Location.Y || ball.Top - ball.Height == board2.Location.Y - 1;

        //collision leftwall 
        bool leftWall = ball.Left == 0 || ball.Left == -1 || ball.Left == 1;
        //collision rightwall 
        bool topWall = ball.Top == 0 || ball.Top == -1 || ball.Top == 1;

        bool bottomWall = collisonX && collisonY;
        bool toppWall = collisonX2 && collisonY2;

        //collision 
        bool barrier = collisonX2 && collsionButtonY;

        //rightwall
        bool rightWall = ball.Left + ball.Width == this.ClientSize.Width || ball.Left + ball.Width == this.ClientSize.Width - 1;
        // sidewall = collision rightwall or leftwall 
        bool sideWall = leftWall || rightWall;

        //Check the ball hit the ground 
        bool check = ball.Top + ball.Height < this.ClientSize.Height;


        //if topWall true,This means that the ball is hit to the topwall

        if (topWall)
        {
            flagBottom = false;
            flagTop = true;
            if (stepleft > 0)
            {
                step = 2;
            }
            else if (stepleft < 0)
            {
                step = 2;
            }



        }
        //if bottomWall true,This means that the ball is hit to the board

        else if (bottomWall)
        {
            flagBottom = true;
            flagTop = false;
            if (stepleft > 0)
            {
                step = step * -1;

            }
            else if (stepleft < 0)
            {

                step = step * -1;
            }


        }
        //if barrier true and flagbottom true,This means that the ball is hit to the board2(button1)

        else if (barrier && flagBottom)
        {

            if (stepleft > 0)
            {

                step = step * -1;

            }
            else if (stepleft < 0)
            {
                step = step * -1;

            }
        }
        //if toppWall true and flagTop true,This means that the ball is hit to The top button is hit 

        else if (toppWall && flagTop)
        {
            if (stepleft > 0)
            {
                step = step * -1;
            }
            else if (stepleft < 0)
            {
                step = step * -1;

            }
        }
        else if (sideWall)
        {
            //if leftwall true,This means that the ball is hit to the left side wall
            if (leftWall)
            {
                if (flagTop)
                {
                    stepleft = 2;
                }
                else if (flagBottom)
                {

                    stepleft = 2;
                }
            }
            //if rightWall true,This means that the ball is hit to the left side wall
            else if (rightWall)
            {
                if (flagTop)
                {
                    stepleft = -2;
                }
                else if (flagBottom)
                {
                    stepleft = -2;
                }

            }


        }
            //check if ckeck==ture,this mean the ball is hit the ground
        else if (!check)
        {
            timer1.Enabled = false;
        }





    }
  private void board_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            MouseDownLocation = e.Location;
        }

    }

    private void board_MouseMove(object sender, MouseEventArgs e)
    {

        if (e.Button == MouseButtons.Left)
        {
            board.Left = e.X + board.Left - MouseDownLocation.X;

        }



    }

2 个答案:

答案 0 :(得分:0)

定义每个&#34; Wall&#34;作为对象,这将增加您的代码可读性。它还允许您为每个墙定义一个事件,听听t。那样你就知道哪个墙被撞了

N.b。这是伪代码。它不会编译:P

public class Wall
{
    int X,Y,W,H;

    //Define an event, add a listener to this, becuase we will fire this when there is a collision
    public event EventHandler OnCollision;


    public void CollisionCheck(Ball playerBall)
    {
       //1 Check for a collision with the "Ball" object
       if(Ball.Rectangle().Intersects(this.Rectangle))
         this.OnCollision(this, EventArgs.Empty); //Fire the event, null check might be requried

    }
}

答案 1 :(得分:0)

我不知道你的游戏但是(怀疑是2D砖状游戏)

  1. 对象/障碍

    • 所有物体/障碍物都可以简化为矩形物体
    • 所以使用大小和位置等定义的参数列出它们的列表
    • 如果它们是可移动的/可丢弃的,那么速度和状态......
    • 对象类型(影响颜色,评分,功能......)
    • 创建成员函数,如update(dt),draw()
    • 创建你喜欢的事件OnHIt,OnCollision,......
  2. 例如(C ++伪代码):

    // game object types ...
    enum _game_object_type_enum
     {
     _game_object_type_none=0,
     _game_object_type_wall,
     _game_object_type_brick1,
     _game_object_type_brick2,
     _game_object_type_brick3,
     _game_object_type_bomb,
     _game_object_type_joker1,
     _game_object_type_joker2,
     ...
     };
    
    // game object class
    class game_object
     {
    public;
     int type;                // type of object  
     float x,y,vx,vy,hx,hy; // position,speed,half size of rectangle
     void update(float dt); // this call periodicaly in some timer updates positions,... and call events, dt is time passed
     void draw(); // can add some rendering device context ...
     };
    
    // whole game class holds the game world/board/map and player(s) ...
    class game_board
     {
    public;
     game_object *go; int gos; // list of all objects in game
     void update(float dt) { for (int i=0;i<gos;i++) go[i].update(dt); }
     void draw() { for (int i=0;i<gos;i++) go[i].draw(); }
     }
    
    1. 事件和流量控制

      • 首先定义一些您需要的事件
      • 要么使用全局函数/指针,要么使用成员
      • 取决于您的平台以及您习惯的内容
    2. 例如:

      void OnCollisionFX(game_object o1,game_object o2)
       {
       // do something ...
       }
      
      void (*OnCollision)(game_object o1,game_object o2)=OnCollisionFX;
      
      • 仅适用于玩家互动(仅限玩家控制的对象碰撞测试)
      • 最好在game_object::update(dt)中处理此问题,但您需要添加播放器上下文
      • 类似于game_object::update(dt,plr)
      • 的内容
      • 其中plr是指向玩家控制的对象或玩家类的指针
      • 如果游戏对象之间存在大量交互(如砖块/砖块碰撞)
      • 然后最好在game_board::update(dt)
      • 中处理此问题
      • 因为否则您需要为更新调用
      • 中的所有内容提供参考
      • 这将很快导致堆/堆栈垃圾和非常慢的性能
      • 在主游戏类中,更高级的多对象碰撞/交互方法更好

      这是第一种情况的例子:

      void game_object::update(float dt,game_object &plr)
       {
       // update position
       x+=vx*dt;
       y+=vy*dt;  
      
       // here you should make your own collision test of coarse
       if (fabs(x-plr.x)<=hx+plr.hx) 
        if (fabs(y-plr.y)<=hy+plr.hy) 
        {
        ... do what you need like mirror or stop speed or clamp position ...
        if (OnCollision) OnCollision(this,plr);
        }
      
       }
      

      在第二种情况下,你应该互相检查每个对象

      void game_board::update(float dt)
       {
       int i,j;
       // update position
       for (i=0;i<gos;i++)
        {
        go[i].x+=go[i].vx*dt;
        go[i].y+=go[i].vy*dt;
        }
      
       // here you should make your own collision test of coarse
       for (i=0;i<gos;i++)
        for (j=i+1;j<gos;j++) // the lower indexes are already tested
         if (fabs(go[i].x-go[j].x)<=go[i].hx+go[j].hx) 
          if (fabs(go[i].y-go[j].y)<=go[i].hy+go[j].hy) 
        {
        ... do what you need like mirror or stop speed or clamp position ...
        if (OnCollision) OnCollision(go[i],go[j]);
        }
      
       }
      
      1. 性能

        • 您可以使用类型属性
        • 来提高性能
        • 例如,如果某些游戏对象是静态的,则不需要更新位置
        • 如果有些是坚不可摧的,那么也可以避免一些处理等等......
      2. [注释]

        • dt / fps / speed应合并
        • 所以在每个帧中你的玩家控制对象或任何移动物体不会进一步移动
        • 然后是最小物体的一半大小
        • 如果不是这样,那么你需要更好的碰撞测试
        • 使用线交叉算法
        • 最后一个位置和实际位置为您提供一行
        • 和object edge为您提供另一个
        • 如果展位对象正在移动,那就更复杂了:)