Jump to content

  • Log In with Google      Sign In   
  • Create Account

Help debugging game


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 Tset_Tsyung   Members   -  Reputation: 126

Like
0Likes
Like

Posted 04 September 2012 - 11:17 AM

Hi all,

First of all this is my first post on this site - but not my first visit. I love this place!

Now I'm teaching myself how to program games. I taught myself C++ (dummies guides, online tutorials and the like) and have decided to start with my first game - a tetris clone.

Now I've gotten to a point where the blocks fall, detect collisions and lock into place (albeit in a not so pretty way) but after you drop a block on the central point, or you've played for a minute some really funky stuff hits the rendered fan.

Basically all of a sudden blocks appear at the top. Your piece can't move - but spasmodically rotates to new shapes. And the blocks at the bottom seem to morph as if they're trying out for a remake of "The Blob".

Could I post the code here and have someone help with the debugging?

Unfortunately because this is my first game I haven't used classes (totally my bad) so it may be a little harder to understand, but any help would be appreciated. I don't want to move onto any other projects until this one is nailed.

Thanks all,

Mike

Sponsor:

#2 Faelenor   Members   -  Reputation: 396

Like
0Likes
Like

Posted 04 September 2012 - 12:37 PM

I would suggest to learn how to use the debugger if you don't already know. You should be able to find your problem pretty quickly.

#3 DujekC   Members   -  Reputation: 161

Like
0Likes
Like

Posted 04 September 2012 - 02:04 PM

Definitely post your code here so we can take a look at it. I'll be happy to try and find a problem. Without that, it's really hard to help you.

If you're interested, I made my own C++ Tetris clone and posted it online with the source code. If you want to see how I've solved some of the problems you could take a look. It's hosted here https://sourceforge.net/projects/dujekcgames/files/
But, like yours. It was one of my first projects in C++, and as such it's very badly put together. Using header files wrong and with no classes :) so don't think thats the right way to do it. I could go back now and make it a million times better.

Out of interest, what are you using to render your game? I used SFML.

#4 GlenDC   Members   -  Reputation: 545

Like
0Likes
Like

Posted 04 September 2012 - 04:30 PM

Yeah learn to use your tools, if you don't work in visual studios yet, I would suggest that you do it from now on. you can download the express edition for C++ here: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express

Also as DujekC suggested, post your code online. You could for example use sourceforge for this. There are enough ways to do just this, so you have no excuse to not do it. I and many others would love to help you. Letting other people review you code will increase your programming skills alot. People can say what things you shouldn't do and/or how you should do things better. So please share it and let us help you.

If you don't use classes yet, I would really do that. It's important that you learn how these work and how to use them. I learned C++ with this book. (I had 5th edition, but why buy old books when you can buy the 6th edition). There are also enough free books, articles and webpages available. A great start is maybe the "shiny new FAQ" by GameDev.

Looking forward to see your project!

#5 Tset_Tsyung   Members   -  Reputation: 126

Like
0Likes
Like

Posted 04 September 2012 - 04:57 PM

Hi all,

Thanks for your postings.
@Falaenor - I'm pretty good at using the debugger and stepping through the code... but don't know how to check the contents of multi-dimensional arrays at any time. Think I'll impliment Text file error logging next time. That always worked in PERL for me Posted Image

@Dujekc - Cool, will definitely look at your code... tomorrow, too tired now lol.

@GlenDC - Yup, way ahead of you on the visual studio express. Loving it but as I said in my reply to Falaenor having trouble find full contents of my multi-D array. I will look into using sourceforge as a means of hosting code but in the meantime I've just put the two files I've written as an attachement... Hope that's okay.

Thanks for all your help guys 'n' girls.

Mike

P.S. Pants - can't do .cpp or .h uploads so here's the contents of said files:

main.cpp:
//include the basic windows header files and the Direct3D header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <time.h>
#include "shapes.h"
// define the screen resolution
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 800
#define STARTX 5
#define STARTY 20
// include the Direct3D Library files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
// global declarations
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
LPDIRECT3DINDEXBUFFER9 i_buffer = NULL;
// function prototypes
void initD3D(HWND hWnd);
void render_frame(void);
void cleanD3D();
void init_graphics(void);
void init_light(void);    // sets up the light and the material
void line_check();
bool move_check();

struct CUSTOMVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL;};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL)
bool bDrop = false;
int nCompLines = 0;
int cDropSpeed = 1;
char cCurrentPiece = rand() % 7;
char cRotation = 0;
char board[10][20];
char checkboard[10][20];
char position[2] = {STARTX, STARTY};
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX wc;
srand(clock());
unsigned long timer1, timer2 = NULL;
    ZeroMemory(&wc, sizeof(WNDCLASSEX));
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = "WindowClass";
    RegisterClassEx(&wc);
    hWnd = CreateWindowEx(NULL, "WindowClass", "Our Direct3D Program",
						  WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
						  NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, SW_MAXIMIZE);
    // set up and initialize Direct3D
    initD3D(hWnd);
    // enter the main loop:
    MSG msg;
timer1 = clock();
    while(TRUE)
    {
	    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	    {
		    TranslateMessage(&msg);
		    DispatchMessage(&msg);
	    }
	    if(msg.message == WM_QUIT)
		    break;
  if(nCompLines >= 10)
  {
   nCompLines = 0;
   cDropSpeed++;
  }
  /* MOVEMENT LOGIC
  this controls the basic movements of the falling blocks and checks for basic collisions
  */
  timer2 = clock();
   // first check to see if user is dropping block at increased rate
  if((bDrop == true) && ((timer2 - timer1) >= (CLOCKS_PER_SEC / 20)))
  {
   if(move_check())
    position[1]--;
   timer1 = clock();
   // otherwise check for standard drop rate
  }else if((timer2 - timer1) >= CLOCKS_PER_SEC / cDropSpeed)
  {
   if(move_check())
    position[1]--;
   timer1 = clock();
  }
  line_check();

  //memcpy(checkboard,board, sizeof(board)); // copy the maing board to the checking board
	    render_frame();
}
  // clean up DirectX and COM
cleanD3D();
    return msg.wParam;
}

// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
	    case WM_DESTROY:
		    {
			    PostQuitMessage(0);
			    return 0;
		    } break;
  case WM_KEYDOWN:
   switch(wParam)
   {
    case VK_LEFT:
    {
	 for(char cX = 0; cX < 4; cX++)
	 {
	  char x = position[0] + OurShapes[cCurrentPiece][cRotation][cX][0];
	  char y = position[1] + OurShapes[cCurrentPiece][cRotation][cX][1];
	  if(x == 0)
	  {
	   return 0;
	  } else if(board[x-1][y] == 1)
	  {
	   return 0;
	  }
	 }
	 position[0]--;
	 break;
    }
    case VK_RIGHT:
    {
	 for(char cX = 0; cX < 4; cX++)
	 {
	  char x = position[0] + OurShapes[cCurrentPiece][cRotation][cX][0];
	  char y = position[1] + OurShapes[cCurrentPiece][cRotation][cX][1];
	  if(x == 9)
	  {
	   return 0;
	  } else if(board[x+1][y] == 1)
	  {
	   return 0;
	  }
	 }
	 position[0]++;
	 break;
    }
    case VK_UP:
    {
	 if(cRotation == 3)
	 {
	  cRotation = 0;
	 } else
	 {
	  cRotation++;
	 }
	 break;
    }
    case VK_DOWN:
    {
	 bDrop = true;
	 break;
    }
   } break;
  case WM_KEYUP:
   {
    bDrop = false;
    break;
   }
  default:
   break;
    }
    return DefWindowProc (hWnd, message, wParam, lParam);
}
// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hWnd;
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
    d3dpp.BackBufferWidth = SCREEN_WIDTH;
    d3dpp.BackBufferHeight = SCREEN_HEIGHT;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    // create a device class using this information and the info from the d3dpp stuct
    d3d->CreateDevice(D3DADAPTER_DEFAULT,
					  D3DDEVTYPE_HAL,
					  hWnd,
					  D3DCREATE_SOFTWARE_VERTEXPROCESSING,
					  &d3dpp,
					  &d3ddev);
    init_graphics();    // call the function to initialize the cube
    init_light();    // call the function to initialize the light and material
    d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);    // turn on the 3D lighting
    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer
    d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));    // ambient light
}
// this is the function used to render a single frame
void render_frame(void)
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(50, 50, 255), 1.0f, 0);
    d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(50, 50, 255), 1.0f, 0);
    d3ddev->BeginScene();
    // select which vertex format we are using
    d3ddev->SetFVF(CUSTOMFVF);
    // set the view transform
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH(&matView,
    &D3DXVECTOR3 (30.0f, 60.0f, -175.0f),    // the camera position
    &D3DXVECTOR3 (30.0f, 60.0f, 0.0f),	  // the look-at position
    &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction
    d3ddev->SetTransform(D3DTS_VIEW, &matView);
    // set the projection transform
    D3DXMATRIX matProjection;
    D3DXMatrixPerspectiveFovLH(&matProjection,
							   D3DXToRadian(45),
							   (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT,
							   1.0f,    // the near view-plane
							   500.0f);    // the far view-plane
    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);
    // select the vertex and index buffers to use
    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
    d3ddev->SetIndices(i_buffer);
// start the world transform process
D3DXMATRIX matTranslate;
// render each square of the game board
for(char cBoardx = 0; cBoardx < 10; cBoardx++)
{
  for(char cBoardy = 0; cBoardy < 20; cBoardy++)
  {
   if(board[cBoardx][cBoardy] == 1)
   {
    D3DXMatrixTranslation(&matTranslate, (float)cBoardx * 6.0f, (float)cBoardy * 6.0f,
	 1.0f);
    d3ddev->SetTransform(D3DTS_WORLD, &matTranslate);
    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12);
   }
  }
}
// render each cube in the shape
for(char cX = 0; cX < 4; cX++)
{
  D3DXMatrixTranslation(&matTranslate,
   ((float)(position[0] + OurShapes[cCurrentPiece][cRotation][cX][0])) * 6.0f,
   ((float)(position[1] + OurShapes[cCurrentPiece][cRotation][cX][1]))* 6.0f, 1.0f);
  d3ddev->SetTransform(D3DTS_WORLD, &matTranslate);
	
  // draw the cube
  d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12);
}
    d3ddev->EndScene();
    d3ddev->Present(NULL, NULL, NULL, NULL);

}

// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
    v_buffer->Release();
    i_buffer->Release();
    d3ddev->Release();
    d3d->Release();
}
// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
    // create the vertices using the CUSTOMVERTEX struct
    CUSTOMVERTEX vertices[] =
    {
	    { -3.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },    // side 1
	    { 3.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },
	    { -3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },
	    { 3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },
	    { -3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },    // side 2
	    { -3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },
	    { 3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },
	    { 3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },
	    { -3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, },    // side 3
	    { -3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, },
	    { 3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, },
	    { 3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, },
	    { -3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, },    // side 4
	    { 3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, },
	    { -3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, },
	    { 3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, },
	    { 3.0f, -3.0f, -3.0f, 1.0f, 0.0f, 0.0f, },    // side 5
	    { 3.0f, 3.0f, -3.0f, 1.0f, 0.0f, 0.0f, },
	    { 3.0f, -3.0f, 3.0f, 1.0f, 0.0f, 0.0f, },
	    { 3.0f, 3.0f, 3.0f, 1.0f, 0.0f, 0.0f, },
	    { -3.0f, -3.0f, -3.0f, -1.0f, 0.0f, 0.0f, },    // side 6
	    { -3.0f, -3.0f, 3.0f, -1.0f, 0.0f, 0.0f, },
	    { -3.0f, 3.0f, -3.0f, -1.0f, 0.0f, 0.0f, },
	    { -3.0f, 3.0f, 3.0f, -1.0f, 0.0f, 0.0f, },
    };
    // create a vertex buffer interface called v_buffer
    d3ddev->CreateVertexBuffer(24*sizeof(CUSTOMVERTEX),
							   0,
							   CUSTOMFVF,
							   D3DPOOL_MANAGED,
							   &v_buffer,
							   NULL);
    VOID* pVoid;    // a void pointer
    // lock v_buffer and load the vertices into it
    v_buffer->Lock(0, 0, (void**)&pVoid, 0);
    memcpy(pVoid, vertices, sizeof(vertices));
    v_buffer->Unlock();
    // create the indices using an int array
    short indices[] =
    {
	    0, 1, 2,    // side 1
	    2, 1, 3,
	    4, 5, 6,    // side 2
	    6, 5, 7,
	    8, 9, 10,    // side 3
	    10, 9, 11,
	    12, 13, 14,    // side 4
	    14, 13, 15,
	    16, 17, 18,    // side 5
	    18, 17, 19,
	    20, 21, 22,    // side 6
	    22, 21, 23,
    };
    // create an index buffer interface called i_buffer
    d3ddev->CreateIndexBuffer(36*sizeof(short),
							  0,
							  D3DFMT_INDEX16,
							  D3DPOOL_MANAGED,
							  &i_buffer,
							  NULL);
    // lock i_buffer and load the indices into it
    i_buffer->Lock(0, 0, (void**)&pVoid, 0);
    memcpy(pVoid, indices, sizeof(indices));
    i_buffer->Unlock();
}
// this is the function that sets up the lights and materials
void init_light(void)
{
    D3DLIGHT9 light;    // create the light struct
    D3DMATERIAL9 material;    // create the material struct
    ZeroMemory(&light, sizeof(light));    // clear out the light struct for use
    light.Type = D3DLIGHT_DIRECTIONAL;    // make the light type 'directional light'
    light.Diffuse = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);    // set the light's color
    light.Direction = D3DXVECTOR3(-1.0f, -0.3f, 1.0f);
    d3ddev->SetLight(0, &light);    // send the light struct properties to light #0
    d3ddev->LightEnable(0, TRUE);    // turn on light #0
    ZeroMemory(&material, sizeof(D3DMATERIAL9));    // clear out the struct for use
    material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);    // set diffuse color to white
    material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);    // set ambient color to white
    d3ddev->SetMaterial(&material);    // set the globably-used material to &material
}
void line_check()
{
// run through each line...
for(char cY = 0; cY < 20; cY++)
{
  char counter = 0;
  // checking to see if any areas in the line are block free..
  for(char cX = 0; cX < 10; cX++)
  {
   if(board[cX][cY] == 0)
   {
    // if so line is not complete so move onto next line...
    break;
   }
   counter++;
  }
  // otherwise line obviously full
  if(counter == 10)
  {
   // increment nCompLines as this is controls the speed
   nCompLines++;
   // so clear out all the blocks in the line...
   for(char cClearX = 0; cClearX < 10; cClearX++)
   {
    board[cClearX][cY] = 0;
   }

   // and move all the blocks in the above rows down by one
   for(char cMoveY = cY+1; cMoveY < 19; cMoveY++)
   {
    for(char cMoveX = 0; cMoveX < 10; cMoveX++)
    {
	 board[cMoveX][cMoveY-1] = board[cMoveX][cMoveY];
    }
   }
   // we need to check the same line again after it's all dropped so set it back one
   cY--;
   // top line has to be cleared manually
   for(char cClearX = 0; cClearX < 10; cClearX++)
   {
    board[cClearX][19] = 0;
   }
  }
}
}
bool move_check()
{
for(char block = 0; block < 4; block++)
{
  if((position[1] + OurShapes[cCurrentPiece][cRotation][block][1]) == 0)
   {
    for(char cBlock = 0; cBlock < 4; cBlock++)
    {
	 int x = position[0] + OurShapes[cCurrentPiece][cRotation][cBlock][0];
	 int y = position[1] + OurShapes[cCurrentPiece][cRotation][cBlock][1];
	 board[x][y] = 1;
    }
	 cCurrentPiece = rand() % 7;
	 position[0] = STARTX;
	 position[1] = STARTY;
	 return false;
   }else
   {
   
    if(board[position[0] + OurShapes[cCurrentPiece][cRotation][block][0]]
	 [position[1] + OurShapes[cCurrentPiece][cRotation][block][1] -1] == 1)
    {
	 for(char cBlock = 0; cBlock < 4; cBlock++)
	 {
	  int x = position[0] + OurShapes[cCurrentPiece][cRotation][cBlock][0];
	  int y = position[1] + OurShapes[cCurrentPiece][cRotation][cBlock][1];
	  board[x][y] = 1;
	 }
	  cCurrentPiece = rand() %7;
	  position[0] = STARTX;
	  position[1] = STARTY;
	  return false;
    }
   }
  }
return true;
}



and shapes.h
#ifndef _SHAPES_
#define _SHAPES_
char OurShapes[7][4][4][2] =
{
//line
{
  //rotation1
  {
   {0, 0},
   {0, 1},
   {0, 2},
   {0, -1}
  },
  //rotation2
  {
   {0, 0},
   {-1, 0},
   {1, 0},
   {2, 0}
  },
  //rotation3
  {
   {0, 0},
   {0, 1},
   {0, 2},
   {0, -1}
  },
  // rotation4
  {
   {0, 0},
   {-1, 0},
   {1, 0},
   {2, 0}
  }
},
// square
{
  //rotation1
  {
   {0, 0},
   {1, 0},
   {0, -1},
   {-1, -1}
  },
  //rotation2
  {
   {0, 0},
   {1, 0},
   {0, -1},
   {-1, -1}
  },
  //rotation3
  {
   {0, 0},
   {1, 0},
   {0, -1},
   {-1, -1}
  },
  //rotation4
  {
   {0, 0},
   {1, 0},
   {0, -1},
   {-1, -1}
  }
},
// S
{
  //rotation1
  {
   {0, 0},
   {0, 1},
   {1, 1},
   {-1, 0},
  },
  //rotation2
  {
   {0, 0},
   {-1, 0},
   {-1, 1},
   {0, -1}
  },
  //rotation3
  {
   {0, 0},
   {0, 1},
   {1, 1},
   {-1, 0},
  },
  //rotation4
  {
   {0, 0},
   {-1, 0},
   {-1, 1},
   {0, -1}
  }
},
// S reversed
{
  //rotation1
  {
   {0, 0},
   {1, 0},
   {0, 1},
   {-1, 1}
  },
  //rotation2
  {
   {0, 0},
   {0, -1},
   {1, 0},
   {1, 1}
  },
  //rotation3
  {
   {0, 0},
   {1, 0},
   {0, 1},
   {-1, 1}
  },
  //rotation4
  {
   {0, 0},
   {0, -1},
   {1, 0},
   {1, 1}
  }
},
// L
{
  //rotation1
  {
   {0, 0},
   {0, 1},
   {0, -1},
   {1, -1}
  },
  //rotation2
  {
   {0, 0},
   {1, 0},
   {-1, 0},
   {-1, -1}
  },
  //rotation3
  {
   {0, 0},
   {0, -1},
   {0, 1},
   {-1, 1}
  },
  //rotation4
  {
   {0, 0},
   {-1, 0},
   {1, 0},
   {1, 1}
  }
},
// L reversed
{
  //rotation1
{
   {0, 0},
   {0, 1},
   {0, -1},
   {-1, -1}
  },
  //rotation2
  {
   {0, 0},
   {-1, 0},
   {1, 0},
   {-1, 1}
  },
  //rotation3
  {
   {0, 0},
   {0, -1},
   {0, 1},
   {1, 1}
  },
  //rotation4
{
   {0, 0},
   {-1, 0},
   {1, 0},
   {1, -1}
  }
},
// T
{
  //rotation1
  {
   {0, 0},
   {-1, 0},
   {1, 0},
   {0, 1}
  },
  //rotation2
  {
   {0, 0},
   {0, 1},
   {1, 0},
   {0, -1}
  },
  //rotation3
  {
   {0, 0},
   {-1, 0},
   {1, 0},
   {0, -1}
  },
  //rotation4
  {
   {0, 0},
   {-1, 0},
   {0, -1},
   {0, 1}
  }
}
};
#endif
Again,
thanks all

#6 GlenDC   Members   -  Reputation: 545

Like
1Likes
Like

Posted 04 September 2012 - 05:35 PM

I reviewed your code in a fast way. Let me list some fast tips:
  • Don't use the old C preproccesor (#define) way to define constants. Rather use static const variables. These give you what you need without the evil macro's.
    For example: "static const int SCREEN_WIDTH = 1280;" instead of "#define SCREEN_WIDTH 1280"
  • Global declarations is something you should try to avoid. You have no classes so it's hard to have no global variables, but you really should move to classes. Maybe this can give you a start: http://www.cprogramming.com/tutorial/lesson12.html
  • You don't have to write void as a parameter if you want parameters in your function. For example: "void foo(void);" is the same as "void foo();"
  • Initiate all your variables for your structure variables. For example, on line 54-59 you init. your WNDCLASSEX variable, wc. Don't forget to init the icon members. If you want to use the default one you could just type: "//LoadIcon (nullptr, IDI_APPLICATION);"
  • Keep your code clean and readable. Maybe it is because you pasted it here in the forum, but if it isn't you should really use more new lines to group your code. Also try to keep a logical system in your tab system. And once you have a system for your tabs and other characters, like your function block stuff. Then try to keep with that system. ( Again, I don't know if this is also is on your computer, it's just how I see it on my computer )
  • Use more functions. A small example: On line 122 you check the WM_KEYDOWN windows message. Maybe you could then have a function that handles the keyboard input, this keeps your code organized and gives you more control. It also keeps your WndProc function readable.
Didn't debugged your code yet, if someone else doesn't do it, I'll do it later if I find some more spare time.

#7 Tset_Tsyung   Members   -  Reputation: 126

Like
0Likes
Like

Posted 05 September 2012 - 03:13 AM

@GlenDC,

Yeah I see what you mean about the formatting - that must've been from when I copied the text from VS express to notepad, then to here.

I pretty much came to the same conclusion about the global variables just before I uploaded. I know I have read the same thing before but until I actually see the real-life advantage for myself I can't really learn to apply it - it's just the way my brains wired... with coding anyway lol.

Same thing with the functions, I had already come to a similar conclusion when trying to debug... but by that point wasn't up for overhauling the whole thing... maybe after I've got the damn thing running I will.

Many thanks for the tips - it's good to know that I'm STARTING (not there yet) to think along the right lines. And I appreciate your trying to debug it for me... I owe you one dude!

#8 Tset_Tsyung   Members   -  Reputation: 126

Like
0Likes
Like

Posted 08 September 2012 - 07:51 AM

IT'S ALIVE! IT'S ALIIIIVVVEEE!

Well I say alive... it's not as dead at least.

I have found out what was causing the problem. There was a problem with the following line in the function move_check():
[source lang="cpp"] if(board[position[0] + OurShapes[cCurrentPiece][cRotation][block][0]] [position[1] + OurShapes[cCurrentPiece][cRotation][block][1] -1] == 1)[/source]
Forgive my poor explanation skills but I'll do must to explain why this was causing a problem.

My 2-dimensional array for the board was 10*20, but with the above if statement I would sometimes be trying to read OUTSIDE of the array. The coloumns were numbered 0 - 19 (because the first address is 0). However with the shapes it would sometimes try to read from address 20 or above. I'm not sure but I believe this causes C++ to wrap around to the beginning of the array and start again, and therefore reading collisions with items at the bottom of the board DESPITE the piece being at the top. I have resoled this but adjusting it to read as follows:

[source lang="cpp"] int colx = position[0] + OurShapes[cCurrentPiece][cRotation][block][0]; int coly = position[1] + OurShapes[cCurrentPiece][cRotation][block][1] -1; if(coly > 19) { continue; } if(board[colx][coly] == 1)[/source]

So now if the block is "outside the board" it won't bother checking for collisons and will simply move on to the next iteration of the loop.


However I now am working on a second problem and any help would again be greatly appreciated.

Sometimes the keyboard input isn't recognised. This means that the block won't sometimes move left, right, rotate or drop at the increased speed. Once you get the block to respond once it's fine until it stop... but I don't know why this is.

I'm using WindowProc for handling the keyboard input. I have read a LOT of conflicting ideas regarding the use of DirectInput over WindowProc, but since the actual DirectX documentation say use WindowProc (unless using controllers such as gamepads or joysticks).

So why is the input jamming up?




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS