Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

the_moo

help with making blocks disappear...

This topic is 5327 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi all, im having a bit of trouble finding a way to get the blocks in my game to disappear when they are next to each other. here's the situation: the blocks fall in pairs and when 4 or more of the same colour touch, they disappear. in need to find out how to go about doing this - testing block colours, testing touching blocks etc. ive provided my entire source code in hopes that someone can help me in regards to my code .cpp file (main)
 /***Functions***/
 void Story()
 {
  //Show field

  BMP_Copy(lpfield,lpddsback,0,0);
  //Show PL1 preview blocks

  preview1.ShowBlocks(lptemp,lpddsback);
  //Show PL1 controlled blocks

  control1.ShowBlocks(lptemp,lpddsback);
  //Store the block data in the field object

  if (!control1.CollisionTest(0,1,fplay1))
  {
   split1.x = control1.x1; split1.y = control1.y1;
   split1.colour = control1.colour1;
   split2.x = control1.x2; split2.y = control1.y2;
   split2.colour = control1.colour2;
   arraynum = ((465-split1.y)/24)*9-9+((8+split1.x)/24);
   fplay1.blockdata[arraynum] = split1;
   arraynum = ((465-split2.y)/24)*9-9+((8+split2.x)/24);
   fplay1.blockdata[arraynum] = split2;
   //Setup position of PL1 new blocks

   control1.MakeControl(preview1,1);
   preview1.MakePreview(1); 
  }
  fplay1.ShowField(lptemp,lpddsback);
 }

 int GameStart()
 {
  /*DirectDraw setup*/
  DDraw7_Setup(hwndMain,DDSCL_FEAA,ScreenWidth,ScreenHeight,BPP,
               SurfDescBack,1,SurfCapsBack);
  
  ScreenBPPWidth = ScreenWidth*BPP >> 3;
  
  /*load images*/
  lptitle = bitmap_surface("title.bmp");
  lpmenu = bitmap_surface("menu.bmp");
  lpfield = bitmap_surface("field.bmp");
  lpsingfield = bitmap_surface("singlefield.bmp");
  lpname = bitmap_surface("name.bmp");
  lpsolomenu = bitmap_surface("solomenu.bmp",RGB(255,255,255));
  lpoptionmenu = bitmap_surface("optionmenu.bmp",RGB(255,255,255));
  lpmainmenu = bitmap_surface("mainmenu.bmp",RGB(255,255,255));
  lptemp = bitmap_surface("temp.bmp", RGB(255,255,255));
  
  /*DDraw Clipper Setup*/
  RECT rect_list[1] = {0,0,ScreenWidth,ScreenHeight};
  lpddclipper = DDraw_Attach_Clipper(lpddsback,1,rect_list);
  
  fplay1.SetData();
  state = title;
  speed = 50;
  //Set first preview block

  preview1.MakePreview(1);
  srand((unsigned int)GetTickCount);
 }
 
 int MainLoop()
 {
  StartClock();
  if(cooldown>0)
  {cooldown--;}
   
  lpddsback->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|
                            DDLOCK_WAIT,
                            NULL);
                            
  int lpitch = (int)(ddsd.lPitch>>1); /*>>1 for 16 Bit mode*/
  USHORT *back_buffer = (USHORT*)ddsd.lpSurface;
  
  /***Clear back buffer***/
  /*As a whole*/
  if(lpitch == ScreenBPPWidth)
  {memset(back_buffer,0,ScreenBPPWidth*ScreenHeight);}
  /*Or line by line*/
  else
  {
   USHORT *dest_ptr = back_buffer;
   for(int y = 0; y<ScreenHeight; y++)
   {
    memset(dest_ptr,0,ScreenBPPWidth);
    dest_ptr+=lpitch;
   }
  }
  
  /*Controls*/
  if((KEYDOWN(VK_DOWN))&&(cooldown <= 0))
  {control1.Move(0,1,fplay1);
   cooldown = speed>>3;}
  if(KEYUP(VK_DOWN))
  {fall = TRUE;}
  /*Title screen - state = title or 1*/
  if(state == title)
  {
   BMP_Copy(lptitle,lpddsback,0,0);
   y += namefall;
   if((y>=55)||(y <= 15))
   {namefall = -namefall;}
   if((y<30)||(y>40))
   {
    if(namefall<0)
    {namefall = -2;}
    else
    {namefall = 2;}
   }
   if((y<25)||(y>45))
   {
    if(namefall<0)
    {namefall = -1;}
    else
    {namefall = 1;}
   }
   BMP_Copy(lpname,lpddsback,x,y);
  }
  
  /*Menu screen - state = menu or 2*/
  if(state == menu)
  {
   BMP_Copy(lpmenu,lpddsback,0,0);
   BMP_Copy(lpmainmenu,lpddsback,mainmenu[0].x+25,mainmenu[0].y);
   if(menuselect == 1)
   {BMP_Copy(lpsingfield,lpddsback,10,20,.4);}
   if(menuselect == 2)
   {BMP_Copy(lpfield,lpddsback,10,20,.4);}
   for(i=0;i<=3;++i)
   {
    if(mainmenu[i].minum == menuselect)
    {TEMP_Copy(lptemp,lpddsback,24,32,1,2,263,mainmenu[i].y);}
   }
  }
  
  /*Solo Menu - state = solome or 6*/
  if(state == solome)
  {
   BMP_Copy(lpmenu,lpddsback,0,0);
   BMP_Copy(lpsolomenu,lpddsback,solomenu[0].x+25,solomenu[0].y);
   for(i=0;i<=4;++i)
   {
    if(solomenu[i].minum == menuselect)
    {TEMP_Copy(lptemp,lpddsback,24,32,1,1,solomenu[0].x,
               solomenu[i].y);}
   }
  }
  
  /*Story mode - state = story or 7*/
  if(state == story)
  {
   Story();
  }
  
  /*Versus mode - state = play1 or 4*/
  if(state == versus)
  {
  }
  
  /*Options - state = options or 5*/
  if(state == options)
  {
   BMP_Copy(lpmenu,lpddsback,0,0);
   BMP_Copy(lpoptionmenu,lpddsback,optionmenu[0].x+25,
            optionmenu[0].y);
   TEMP_Copy(lptemp,lpddsback,24,32,1,3,optionmenu[1].x,
             optionmenu[1].y);
  }
  if((cooldown <= 0)&&(!KEYDOWN(VK_DOWN)))
  {
   control1.Move(0,1,fplay1);
   cooldown = speed;
  }
  if(state == story)
  {
    if (dropspeed == 0)
    {//Drop blocks

     fplay1.DropBlocks();
     if (!control1.drop)
     dropspeed = speed>>3;}
    --dropspeed;
  }
  WaitClock(1000/45>>1);
  lpddsback->Unlock(NULL);
  lpddspri->Flip(NULL, DDFLIP_WAIT);
 }
.h file (classes etc.)
#define SMPIC 100

//Structs//

//Basic Block

typedef struct _BBlock {
    int x, y, colour;
    }BBlock;

//Classes//


class Field {
    int columns, rows, spacesize;
    RECT coords;
public:
    BBlock blockdata[126];
    void SetSize(int,int,int,RECT);
    void SetData(void);
    void DropBlocks(void);
    void ShowField(LPDIRECTDRAWSURFACE7,LPDIRECTDRAWSURFACE7);
};

class Block {
public:
    int x1,y1,x2,y2,colour1,colour2,ronum;
    bool drop;
    void MakePreview(int);
    void MakeControl(Block,int);
    void ShowBlocks(LPDIRECTDRAWSURFACE7,LPDIRECTDRAWSURFACE7);
    int CollisionTest(int,int,Field);
    void Move(int,int,Field);
    void Rotate(Field);
};

//Class Functions//

/*Block*/
    //Sets the block to the coordinates of preveiw

    void Block::MakePreview (int player)
        { if (player == 1)
            { x1 = 245; x2 = 245; y1 = 162; y2 = 186; }
          if (player == 2)
            { x1 = 371; x2 = 371; y1 = 162; y2 = 186; } 
          colour1 = rand()%5+1; colour2 = rand()%5+1; }
    //Sets the block to become the next controlled block

    void Block::MakeControl (Block preview, int player)
        { colour1 = preview.colour1; colour2 = preview.colour2;
          x1 = 112; y1 = 125; x2 = 112; y2 = 149; ronum = 0;}
    //Shows the block whether it be a preview or controlled block

    void Block::ShowBlocks (LPDIRECTDRAWSURFACE7 lpsource,
                     LPDIRECTDRAWSURFACE7 lpdest)
        { TEMP_Copy(lpsource,lpdest,24,32,1,colour1,x1,y1);
          TEMP_Copy(lpsource,lpdest,24,32,1,colour2,x2,y2); }
    //Tests for block collisions and returns values to allow or

    //deny movement in Move and Rotate

    int Block::CollisionTest (int x, int y, Field playfield)
        { //Tests for Left and Right field edges

          if (x1+x < 16 || x2+x < 16 || x1+x > 208 || x2+x > 208)
            {return 0;}
          //Tests for the bottom of the field

          if (y1+y > 437 || y2+y > 437)
            {return 0;}
          for (int count = 0; count <= 126; ++count)
          {
            BBlock temp = playfield.blockdata[count];
            int sx = x*24;
            //Tests for contact with the top of other blocks

            if (temp.colour != 0)
            {
              if ((x1 == temp.x || x2 == temp.x) &&
                  (y1+24 == temp.y || y2+24 == temp.y))
              {return 0;}
              //Tests for right and left sides of blocks on field

              if ((x1+sx == temp.x || x2+sx == temp.x)&&
                  (y1 == temp.y || y2 == temp.y))
              {return 0;}
            }
          }
          return 1; }
    //Moves the block in the given directions

    void Block::Move (int x, int y, Field playfield)
        { if (CollisionTest(x,y,playfield))
            { x = x*24; y = y*24;
              x1 += x; x2 += x; y1 += y; y2 += y; } }
    //Rotates blocks according to position

    void Block::Rotate (Field playfield)
        { switch (ronum)
            {
             case 0:
             { if(CollisionTest(1,-1,playfield))
                {x1 += 24; y1 += 24; ++ronum;}
               else
                {if(CollisionTest(-1,0,playfield))
                  {x2 -= 24; y1 += 24; ++ronum;} }
             }break;
             case 1:
             { if(CollisionTest(0,-1,playfield))
                {x1 -= 24; y1 += 24; ++ronum;}
             }break;
             case 2:
             { if(CollisionTest(-1,1,playfield))
                {x1 -= 24; y1 -= 24; ++ronum;}
               else
                {if(CollisionTest(1,1,playfield))
                  {x2 += 24; y1 -= 24; ++ronum;} }
             }break;
             case 3:
             { x1 += 24; y1 -= 24; ronum = 0;
             }break;
            }
        }
              
/*Field*/
    void Field::SetSize (int col, int row, int size,RECT coordinates)
        { columns = col; rows = row;
          spacesize = size; coords = coordinates; }
    void Field::SetData (void)
        { for (int cy = 1; cy <= 14; ++cy)
          {
            for (int cx = 1; cx <= 9; ++cx)
            {
              int sx = -8+(cx*24);
              int sy = 461-(cy*24);
              int array = ((461-sy)/24)*9-9+((8+sx)/24);
              blockdata[array].x = sx;
              blockdata[array].y = sy;
              blockdata[array].colour = 0;
            }
          }
        }
    void Field::DropBlocks (void)
        { for (int count = 1; count <= 126; ++count)
            {
               if ((blockdata[count-9].colour == 0) &&
                   (blockdata[count].colour > 0) &&
                   (count > 9))
               {
                 int col = blockdata[count].colour;
                 blockdata[count-9].colour = col;
                 blockdata[count].colour = 0;
               }
            }
        }
    void Field::ShowField (LPDIRECTDRAWSURFACE7 lpsource,
                           LPDIRECTDRAWSURFACE7 lpdest)
        { int arraypos;
          for (arraypos = 0; arraypos <= 126; ++arraypos)
            { BBlock temp = blockdata[arraypos];
              TEMP_Copy(lpsource,lpdest,24,32,1,
              temp.colour,temp.x,temp.y); } 
        }
thanks to anyone who can let me in on any ideas they have. all help is greatly appreciated [edit]: removed lots of irrelevant code for ease on u readers [edited by - the_moo on April 17, 2004 9:04:34 AM]

Share this post


Link to post
Share on other sites
Advertisement
There is no way I am reading that much code.

Google "bucket fill" or "flood fill" and see if you find it inspirational. You''re looking to see if the "flooded" regions from either square of the most recently dropped block, have size >= 4.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!