Назад | Начало урока | Вперед
Содержание

Глава 5


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

Функцию OnPaint() в ветви "Чужое поле" изменили следующим образом:


GetClientRect(&rect);
if(m_Mode == FOREIGN_FIELD) {
dc.BitBlt(dc.m_ps.rcPaint.left, dc.m_ps.rcPaint.top,
dc.m_ps.rcPaint.right - dc.m_ps.rcPaint.left,
dc.m_ps.rcPaint.bottom - dc.m_ps.rcPaint.top,
&WaterDC, dc.m_ps.rcPaint.left,
dc.m_ps.rcPaint.top, SRCCOPY);

for(i=(dc.m_ps.rcPaint.top/20)*20; i<=(dc.m_ps.rcPaint.bottom/20)*20; i+=20) {
dc.MoveTo(dc.m_ps.rcPaint.left, i);
dc.LineTo(dc.m_ps.rcPaint.right, i);
}
for(i=(dc.m_ps.rcPaint.left/20)*20; i<=(dc.m_ps.rcPaint.right/20)*20; i+=20) {
dc.MoveTo(i, dc.m_ps.rcPaint.top);
dc.LineTo(i, dc.m_ps.rcPaint.bottom);
}
for(i=0; i<10; i++)
for(j=0; j<10; j++) {
count = 0;
if(m_Event[i][j] == SHIPKILLED) {
if(m_Event[i][j+1] == SHIPKILLED && j+1<10) {
count = 1;
do {
count++;
} while(m_Event[i][j+count] == SHIPKILLED && j+count<10);
DrawShip(CRect(j*20, i*20, (j+count)*20, (i+1)*20), &dc);
j+=count;
continue;
}
else {
if(m_Event[i+1][j] == SHIPKILLED
&& (m_Event[i-1][j] != SHIPKILLED || i-1==-1)
&& i+1 <10)
{
count = 1;
do {
count++;
} while(m_Event[i+count][j] == SHIPKILLED
&& i+count<10);
DrawShip(CRect(j*20, i*20, (j+1)*20, (i+count)*20), &dc);
continue;
}
if((m_Event[i+1][j] != SHIPKILLED
&& i+1<10)||(i+1==10))
if((m_Event[i-1][j] != SHIPKILLED
&& i-1 >= 0) || (i-1<0))
if((m_Event[i][j+1] != SHIPKILLED
&& j+1<10) || (j+1==10))
if((m_Event[i][j-1] != SHIPKILLED
&& j-1>=0) || (j-1<0))
DrawShip(CRect(j*20, i*20, (j+1)*20, (i+1)*20), &dc);

}//else
}//if
}//for
}//if(m_Mode == FOREIGN_FIELD)

pn1.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
oldpn1 = dc.SelectObject(&pn1);
br.CreateSolidBrush(RGB(22, 60, 84));
for(i=0; i<10; i++)

for(j=0; j<10; j++) {
if(m_Event[i][j] == CANNOT) {
dc.MoveTo(j*20, i*20);
dc.LineTo((j+1)*20, (i+1)*20);
dc.MoveTo(j*20, (i+1)*20);
dc.LineTo((j+1)*20, i*20);
}
if(m_Event[i][j] == NEARKILLEDSHIP)
dc.FillRect(CRect(j*20+1, i*20+1, (j+1)*20, (i+1)*20), &br);
if(m_Event[i][j] == SHIPKILLED || m_Event[i][j] == SHIPWOUND){
DrawObject(CRect(j*20, i*20, (j+1)*20, (i+1)*20), &dc, m_bFire);

}
}

dc.SelectObject(oldpn1);
pn1.DeleteObject();
br.DeleteObject();

Даю пояснения к коду:

В этой функции первый вызов DrawShip() рисует корабль в горизонтальном направлении,
второй вызов может нарисовать корабль в вертикальном положении, третий вызов DrawShip()
рисует однопалубный корабль. По условию рисуются на поле только убитые корабли.

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

Для того, чтобы этот код работал правильно, необходимо в ресурсы проекта добавить
изображение взрыва на палубе. Добавляется изображение в ресурсы аналогично тому,
как мы добавляли изображения кораблей - скопировать графический файл Fire.bmp в папку
res, и добавить соответствующий код в файлы resource.h, SeaBattle.rc и SeaBattle.vcproj.

Надо еще в функцию OnCreate() добавить такой ресурс как картинку взрыва m_bFire.

m_bFire = (HBITMAP)::LoadImage(hInst, MAKEINTRESOURCE(IDB_FIRE), IMAGE_BITMAP,

0, 0, LR_DEFAULTSIZE|LR_LOADTRANSPARENT);

Теперь все отлично и программа работает как надо!
Мы стреляем по краблям и подбиваем их.


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz