Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.03.2014, 14:10   #1
farshmaker
 
Регистрация: 29.02.2012
Сообщений: 8
По умолчанию Некоторые проблемы с игрой "5 в ряд"

Пока сделал следующее:
Код:
#include <Windows.h>

#define width 516 //416
#define height 438
char szText[]="Клетка занята";
//char szText1[]="Клетка занята";
bool Field[20][20];
int FieldCheck [20][20];
bool firstClick=true;


LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

BOOL Line(HDC hdc, int x1, int y1, int x2, int y2)
{
	HPEN hPen;
	hPen=CreatePen(PS_SOLID, 2, RGB(255,0,0));
	SelectObject(hdc, hPen);
	MoveToEx(hdc, x1, y1, NULL); //сделать текущими координаты x1, y1
	return LineTo(hdc, x2, y2);
} 

int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	WNDCLASSEX windowClass;
	HWND hWnd;
	MSG uMsg;

	memset(&windowClass, 0, sizeof(WNDCLASSEX));
	windowClass.cbSize = sizeof(WNDCLASSEX);
	windowClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
	windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	windowClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
	windowClass.hInstance = hInstance;
	windowClass.lpfnWndProc = WindowProc;
	windowClass.lpszClassName = "5InARow";

	RegisterClassEx(&windowClass);

	hWnd = CreateWindow(windowClass.lpszClassName, "5InARow", 
	WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 
	(GetSystemMetrics(SM_CXSCREEN) - width)/2, (GetSystemMetrics(SM_CYSCREEN) - height)/2, 
	width, height, NULL, NULL, NULL, NULL);

	ShowWindow(hWnd, nCmdShow);

	while (GetMessage(&uMsg, hWnd, NULL, NULL))
	{
		TranslateMessage(&uMsg);
		DispatchMessage(&uMsg);
	}
	
	return uMsg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){
	PAINTSTRUCT ps;
	HDC hdc = GetDC(hWnd);
	RECT r;
	int f = 20;
	int x,y; //координаты
	switch (uMsg)
	{
	case WM_CLOSE: 
		ExitProcess(0);
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		for (int j = 0; j < 400; j+=20)
		{
			for (int i = 0; i < 400; i+=20)
			{
				Rectangle(hdc, j, i, f+j+1, f+i+1);
			}
		}
		ValidateRect(hWnd, NULL);
		//заканчиваем рисовать
		EndPaint(hWnd, &ps);
	case WM_LBUTTONDOWN:

		if(!firstClick)
		{
			//char *str;
			//HDC hDC;
			//Field[0][0] = true;
			//hDC=GetDC(hWnd);
			x=LOWORD(lParam); //узнаём координаты
			y=HIWORD(lParam);
			//MessageBox(hWnd,"Клетка занята",0,0);
			//_itoa(x, szText, 10);
			//TextOut(hDC, x, y, szText, strlen(szText));
			//_itoa(y, szText, 10);
			//TextOut(hDC, x, y+20, szText, strlen(szText));
			//_itoa(Field[x/20][y/20],szText, 10);
			//TextOut(hDC, x, y+40, szText, strlen(szText));
			if (Field[x/20][y/20] == false)
			{
				Field[x/20][y/20] = true;
				for (int i = 0; i < 20; i++)
				{
					for (int j = 0; j < 20; j++)
					{
						if(Field[i][j])
						{
							Line(hdc, i*20+2, j*20+2, i*20+18, j*20+18);
							Line(hdc, i*20+18, j*20+2, i*20+2, j*20+18);
						}
					}
				}
			}
			else MessageBox(hWnd,"Клетка занята",0,0); //TextOut(hDC, 404, 360, szText, strlen(szText));
		}
		else firstClick = false;
		break;
	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	
}
Отрисовывается поле 20х20 и ставится по клику левой кнопки мыши крестик.

Возникли проблемы:
1. Когда запускаю после отладки игру, изначально ставится крестик в первую клетку. Т.е. почему-то при запуске игры обрабатывается сообщение клика мыши в координате [0:0].
Решил вводом булевской переменной firstClick, из-за которой мы не обрабатываем первое сообщение мыши. Но считаю, что так не должно быть. Ни какой клик при первом запуске не должен обрабатываться.

2. Если попытаться поставить крестик в клетку в которой он уже есть, то выполняется метод TextOut(). Как сделать что бы при следующем клике то сообщение, что оставляет метод TextOut(), удалилось?
3. Пытался выводить MessageBox после повторного клика в ту же клетку, но он почему то выводится 17 раз. Т.е. вылетает 17 окон каскадом. Следовательно TextOut() метод тоже отрисовывает одно и то же сообщение в одном месте 17 раз.

Заметил еще пару багов:
4. Если свернуть и развернуть окно, то все нарисованные крестики пропадают, пока не поставишь еще 1. Тогда они проявляются
5. Если навести мышь на 1 из 3х элементов (свернуть, развернуть, закрыть), дождаться всплывающего соответствующего окна элемента, а затем убрать фокус с него, то обрабатывается сообщение клика левой кнопки мыши в координате [0:0] (WM_LBUTTONDOWN) и в соответствии с пишет, что клетка занята.
Изображения
Тип файла: png 2014-03-27 13-04-08 5InARow.png (16.8 Кб, 68 просмотров)
farshmaker вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Постоянно слетает галочка "автоматически" в "Параметры Excel", "Формулы", "Вычисления в книге" Alexsandrr Microsoft Office Excel 4 19.10.2013 14:22
Проблема с игрой "Танчики" на C++ Builder batnik.com C++ Builder 2 03.05.2013 14:24
помоги с игрой "змейка" Aleksa92 Помощь студентам 0 18.12.2011 20:49
Двухуровневая ИС, схожая с математической игрой "Жизнь" Pavel_Ine Помощь студентам 2 18.04.2009 21:37
Помогите с игрой "Змейка". spamer Общие вопросы Delphi 2 26.12.2008 21:17