Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Профессиональное программирование


Информационный Канал Subscribe.Ru

В начало Клуб программистов Весельчак У Связаться со мной
a

Добрый день.

Сегодня вышли первые две части большой статьи из серии "Советы по Windows"

Советы по Windows 7.2

Автор: Гром

Предисловие

В этой части советов я решил оформить серию статей по работе с графикой в окнах Windows без использования работы DirectX и OpenGL, а только посредством стандартных функций API и MFC.
Кроме того, важно понять после советов в виде отрывочных статей, как правильно планировать и писать программы под Windows с учетом всех ее особенностей.

Для хорошего понимания, как всегда, я использую работу на примере. А писать в этот раз мы будем Тетрис, игрушку вечную, но до сих пор популярную.

1. Планирование данных.

В первую очередь программное планирование начинается с определения и формализации задачи. Саму задачку мы определили, как Тетрис обыкновенный, и теперь понимая нашу цель можем приступить к формализации задачи.

а) разделим программму на данные и методы работы с ними. В качестве данных будут выступать два основных объекта игры - падающий блок и игровое поле.

Создадим обычную апликацию, которая в Wizard-е от студии называется MFC Application. Обзовем ее tris. В окне Application type выберем Single Document, а птичку поддержки структуры Document/View выключим, так как работа с документом в его стандартном виде нам не пригодится.

В результате мы будем иметь простое окошко с менюшкой и белым фоном, на котором ничего нет...

Первым объектом данных будет класс ABlock.

Определим тип данных которым этот объект будет владеть и с которым мы будем работать.


typedef struct _TRIS_BLOCK
{
int block[4][4][4];
} TRIS_BLOCK, * PTRIS_BLOCK;


Можно было бы обойтись и просто описанием массива. Но так получается более наглядно, к тому же в будущем нам можт понадобиться расширить свойства блока, добавив, например, цвет.

Вы спросите почему 3 уровня массива. И я вам отвечу - мы имеем дело с выбором между избыточностью данных и избыточностью (сложностью) кода.
Каждый блок падая, поворачивается на 90 градусов. Мы имеем выбор - либо взять и написать алгоритм поворота объекта, либо держать в данных все 4 его положения, при повороте манипулируя его индексами в массиве. Я выбрал второй путь, так как алгоритм поворота мне писать лень :)

Сам класс блок получился очень простым:

class ABlock
{
public:

ABlock(TRIS_BLOCK ptb);
~ABlock(void);
PTRIS_BLOCK GetBlock();


private:
TRIS_BLOCK tb;

};


В файле ABlock.cpp пропишем содержимое 2-х функций...

ABlock::ABlock(TRIS_BLOCK in_tb)
{
memset(&tb,0,sizeof(int) * 4*4*4);
memcpy(&tb,&in_tb,sizeof(int) * 4*4*4);
}

PTRIS_BLOCK ABlock::GetBlock()
{
return &tb;
}


Обратите внимание на то, что объект не имеет пустого конструктора типа ABlock(), потому что без данных сам по себе объект нам никогда не понадобится.

На этом объект Block мы закончили и приступим к второму типу данных - поле (Place).

Создадим такой - же пока пустой объект APlace, и опишем три константы:

#define MAXX 10 // Ширина поля
#define MAXY 20 // Высота поля

#define PIXFORRECT 20 // Колличество точек на квадрат(ячейку) (в данном случае квадрат - это один элемент стакана тетриса, где может располагаться честь блока)


Значения для поля изначально установим равными нулю, что означает пустой квадрат.

class APlace
{
public:
APlace(void);
~APlace(void);
};


В этом объекте нам понадобятся данные - само поле. Представим поле в виде двухмерного массива ячеек:

private:
int Place[MAXX][MAXY];


Естественно, что в данном случае за ячейку поля мы определяем 1 квадрат.

В секцию public запишем:

int SetPlace(int x, int y, int set_point);
int GetPlace(int x, int y);


Эти функции будут использоваться для управления значениями ячеек поля. И заполним наш APlace.cpp:

APlace::APlace(void)
{
memset(Place,0,sizeof(int)*MAXX*MAXY);
}

APlace::~APlace(void)
{

}

int APlace::SetPlace(int x, int y, int set_point)
{

if (x > MAXX) return 0xFFFF;
if (y > MAXY) return 0xFFFF;
if ((x<0) || (x<0)) return 0xFFFF;
Place[x][y] = set_point;

return 1;

}

int APlace::GetPlace(int x,int y)
{
if ( (x > MAXX) || (x < 0) || (y>MAXY) || (y <0) ) return 0xFFFF;
return Place[x][y];

}


Мы обеспечили минимально необходимую организацию данных, и можем перейти к разработке логики игры - т.е. непосредственно к алгоритму. Все дунные описаны и формализованы.

Полностью статья: http://club.shelek.com/viewart.php?id=228

Советы по Windows 7.2

Автор: Гром

3. Разработка игрового интерфейса

Игровой интерфейс включает в себя:
а) графическое отображение на экране
б) пользовательское управление
в) сам алгоритм игры.


Для отработки каждого действия на игровом поле в нашем случае необходимо будет работать с графическими объектами, которые в Windows вполне неплохо и понятно сделаны.

Нам понадобиться:
а) отобразить игровое поле пустым в начале.
б) отображать объекты типа блок (ABlock) на игровм поле.
г) отображать передвижение и поворот объекта ABlock.
д) отображать оставшиеся объекты в стакане в виде занятых ячеек.
е) отображать процесс уничтожения объектов на поле, когда вся линия в стакане заполнена, и сдвиг всех занятых клеток вниз, после уничтожения полных строк.

Для отображения простой картинки в Windows используют так называемый Device context. В MFC предусмотрено несколько объектов для работы с ними. Это CDC - базовый объект, CClientDC - используется для работы с клиентской частью окна (белый фон) CWindiwDC - полностью все окно, можно накладывать рисунок даже на область шапки, меню и т.д., и CPaintDC который используется программой для собственно вывода в область окна CClientDC в процедуре OnPaint.

OnPaint - процедура обработки соробщения WM_PAINT которое посылается окну каждый раз, когда система считает необходимым перерисовать окно программы (после команды минимизировать или максимизировать окно например), или когда вы вызываете функцию Invalidate();

Таким образом, для постоянного отображения графического контекста на экране, нам необходимо рисовать всю информацию в процедуре OnPaint().

Для нас, немного сложно сразу перейти к разработке полного игрового интерфейса, поэтому переместимся немного в код, и доработаем его под наши нужды...

Полностью статья: http://club.shelek.com/viewart.php?id=229

 

На этом сегодня все.

С уважением, Громозека.


http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.compu
Отписаться

В избранное