Глава 1
При щелчке пользователем на правой кнопке, происходит поворот корабля на 90 градусов
по часовой стрелке, но только в том случае, если при повороте корабля не будет задета
стенка (край поля боя). Поэтому в каждом из 4-х случаев осуществляется проверка:
При многократных щелчках правой кнопкой, корабль устраивает некое шоу, вертясь вокруг
одной точки по часовой стрелке.
void CField::OnRButtonDown(UINT nFlags, CPoint point)
{
if(m_Mode == OWN_FIELD && m_Operation == PLACEMENT)
{
switch(m_Direction)
{
case LEFT:
if(m_Position.y - (m_Decks-1)*20 >= 0)
{
m_Draw = false;
//предыдущая позиция
InvalidateRect(CRect(m_Position.x - (m_Decks-1)*20, m_Position.y,
m_Position.x+20, m_Position.y + 21));
UpdateWindow();
m_Draw = true;
m_Direction = TOP;
//новая позиция
InvalidateRect(CRect(m_Position.x, m_Position.y - (m_Decks-1)*20,
m_Position.x + 20, m_Position.y+21));
}
break;
case TOP:
if(m_Position.x + m_Decks*20 <= 200)
{
m_Draw = false;
InvalidateRect(CRect(m_Position.x, m_Position.y - (m_Decks-1)*20,
m_Position.x + 21, m_Position.y+21));
UpdateWindow();
m_Draw = true;
m_Direction = RIGHT;
InvalidateRect(CRect(m_Position.x, m_Position.y,
m_Position.x + m_Decks*20 + 1, m_Position.y + 21));
}
break;
case RIGHT:
if(m_Position.y + m_Decks*20 <= 200)
{
m_Draw = false;
InvalidateRect(CRect(m_Position.x, m_Position.y,
m_Position.x + m_Decks*20 + 1, m_Position.y + 21));
UpdateWindow();
m_Draw = true;
m_Direction = BOTTOM;
InvalidateRect(CRect(m_Position.x, m_Position.y,
m_Position.x + 20, m_Position.y + m_Decks*20));
}
break;
case BOTTOM:
if(m_Position.x - (m_Decks-1)*20 >= 0)
{
m_Draw = false;
InvalidateRect(CRect(m_Position.x, m_Position.y,
m_Position.x + 21, m_Position.y + m_Decks*20+1));
m_Direction = LEFT;
UpdateWindow();
m_Draw = true;
InvalidateRect(CRect(m_Position.x - (m_Decks-1)*20, m_Position.y,
m_Position.x+20, m_Position.y + 20));
}
break;
}
}
CStatic::OnRButtonDown(nFlags, point);
}
Анализ:
При щелчке пользователем на правой кнопке, происходит поворот корабля на 90 градусов
void CField::OnRButtonDown(UINT nFlags, CPoint point)
{
Проверка: если щелчек на нашем поле и если операция при этом - постановка корабля:
В случаях TOP и BOTTOM проверяется позиция x, не выйдет ли новое изображение
изображение корабля за пределы поля слева либо справа?
В случаях RIGHT и LEFT проверяется позиция y, не выйдет ли новое изображение
Это проверка, чтобы не выйти за рамки поля боя.
Внутри if код имеет в общем одинаковую структуру:
case LEFT:
Суть данного кода в том, что в инструкции:
InvalidateRect(CRect(m_Position.x - (m_Decks-1)*20, m_Position.y,
даны размеры холста (прямоугольника) точно такие, что это прямоугольник,
Далее обновляется окно, затем переменным m_Draw и m_Direction даются новые значения.
UpdateWindow();
А в следующей инструкции:
InvalidateRect(CRect(m_Position.x, m_Position.y - (m_Decks-1)*20,
даны размеры точно такие, что это прямоугольник, расположенный:
При условии, что здесь m_Decks = 4, четырехклеточный корабль.
Интересно, что во всех случаях сначала рисуется прежняя позиция корабля,
Интересно, что переданные параметры используются только в последней инструкции:
А в самой функции используются переменные класса Field: m_Operation, m_Position,
А так же четыре глобальные константы означающие направление
//directions
public-переменные класса
private-переменные класса
Назад |
Начало урока |
Вверх |
Вперед
по часовой стрелке, но только в том случае, если при повороте корабля не будет задета
стенка (край поля боя). Поэтому в каждом из 4-х случаев осуществляется проверка этого.
if(m_Mode == OWN_FIELD && m_Operation == PLACEMENT)
{
switch(m_Direction)
{
case TOP:
изображение корабля за пределы поля сверху либо снизу?
case RIGHT:
//предыдущая позиция
InvalidateRect(CRect(m_Position.x - (m_Decks-1)*20, m_Position.y,
UpdateWindow();
m_Draw = true;
m_Direction = TOP;
//новая позиция
InvalidateRect(CRect(m_Position.x, m_Position.y - (m_Decks-1)*20,
расположенный по длине влево на три ячейки и вправо на одну ячейку начиная
от заданной точки. По ширине вниз на одну ячейку начиная от заданной плюс
один пиксел. При условии, что здесь m_Decks = 4, четырехклеточный корабль.
Это предыдущая позиция корабля.
m_Draw = true;
m_Direction = TOP;
по длине - вверх на три ячейки и вниз на одну ячейку плюс один пиксел
начиная от заданной точки.
по ширине - вправо на одну ячейку начиная от заданной.
Это новая позиция корабля.
потом обновляется окно и устанавливается новая позиция корабля.
CStatic::OnRButtonDown(nFlags, point);
m_Direction, m_Mode, m_Decks, m_Draw.
Доступ к этим переменным из функции своего класса свободный.
#define RIGHT 3000
#define BOTTOM 3001
#define LEFT 3002
#define TOP 3003
int m_Operation
int m_Mode
POINT m_Position
int m_Direction
int m_Decks - размер одной ячейки корабля равен 4 пиксела
int m_Draw
Содержание