BitBlt или PaintPicture для создания карточных игр


 главная
 обо мне
 языки
 веб-дизайн
 гитара
 блок-флейта
 ссылки
 фотоальбом
 литература
 разное
 анекдоты
 макраме
 общение
 обновления



http://www.uralweb.ru/

Раскрути свой сайт

поэтический сайт Веры Степановой




BitBlt или PaintPicture для создания карточных игр


Справочная информация по методу PaintPicture PaintPicture.rtf!!!

Чтобы писать карточные игры, нужно прежде всего иметь колоду карт. Этот вопрос решается очень просто,
нужно лишь использовать в проекте библиотечку cards.dll или cards32.dll , обычно одна из этих библиотек уже
присутствует на компе, и используется в играх. По использованию этой библиотечки громадное колличество 
публикаций и море исходников, поэтому я не буду на этом останавливаться. 
Чтобы написать красивую игрушку использование cards32.dll не поможет,так как карты там примитивные, "рубашек"мало
и размер карт маленький.И вообще приятно со своими картами что-то соорудить :)
Для себя я выбрал не самый лёгкий путь, но результат идеальный. 
Это метод , когда карта рассматривается как обычный спрайт.  Для реализации этой идеи сначало я хотел использовать 
API функцию BitBlt .  По этой ссылочке можете ознакомиться с этой функцией поподробнее,
http://vsokovikov.narod.ru/New_MSDN_API/Bitmaps/fn_bitblt.htm
к тому же я в свою демку включил эту функцию, так что там всё понятно. 
Спрайт создаётся двумя вызовами, сначало выводится маска с наложением по "И", а затем картинка карты с наложением по "ИЛИ",
при этом маска должна быть чёрной на белом фоне, а сама карта должна быть на чёрном фоне!!! 
По идее у карты надо закрасить чёрным только уголки. Маска одна на всю колоду. Ещё надо сделать одну карту пустой, только 
залитую фоновым цветом и конечно же с чёрными уголками, эта карта будет использоваться в дальнейшем для удаления карты!
Но я всё таки в своих проектах API функцию BitBlt не использую, так как в самом VB есть более мощный и удобный инструмент,
это метод - PaintPicture ! Он чуток медлительней чем BitBlt , но скорость то при карточной игре не нужна, это ведь не шутер
по летающим тарелкам и не гоночное дерби.
Ну приступим к написанию демки. 
Для начала на форме разместим три пикчербокса и две кнопки. 
пикчерсы должны иметь размеры картинок карт!!! 
На форме и пикчерсах  установите ScaleMode в 3-pixel, а свойство AutoRedraw в true.
У пикчерсов ещё установите BorderStyle в 0 !!! 
Установите у формы BackColor нужного цвета. ( я уже писал чуть выше , что нужна третья карта цвета фона). 
Теперь напишем код. 
Прежде всего декларация функции BitBlt

Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, _
ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _
ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

А теперь в наши три пикчерса зальём три наши картинки, в первый пикчерс зальём маску, во второй карту, а в третий пустую карту.

Private Sub Form_Load()
Picture1.Picture = LoadPicture(CurDir + "\mackcfrd01.bmp")
Picture2.Picture = LoadPicture(CurDir + "\card01.bmp")
Picture3.Picture = LoadPicture(CurDir + "\mackcfrd02.bmp")
End Sub

В реальной программе надо ещё свойство Visible  не забыть установить в false . Но в демке для наглядности всё как есть оставил.
Далее по нажатию кнопки выведем карту два раза, чтобы продемонстрировать оба метода!


Private Sub Command1_Click()

BitBlt Form1.hDC, 100, 10, Picture1.ScaleWidth, Picture1.ScaleHeight, Picture1.hDC, 0, 0, vbSrcAnd
BitBlt Form1.hDC, 100, 10, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture2.hDC, 0, 0, vbSrcPaint

Form1.PaintPicture Picture1, 200, 20, Picture1.ScaleWidth, Picture1.ScaleHeight, , , , , vbSrcAnd
Form1.PaintPicture Picture2, 200, 20, Picture2.ScaleWidth, Picture2.ScaleHeight, , , , , vbSrcPaint

Form1.Refresh
End Sub


Функция BitBlt предполагает, что надо перерисовать форму Form1.Refresh, я тестироват без Form1.Refresh и у меня всё работало)

Результат того, что получилось, смотрите ниже на картинке!!!

А теперь о том как стереть карту. Всё конечно очень просто, для этого мы и делали третью карту  цвета фона, так что сначало выводим эту карту,
а затем выводим карту которую она прикрывала. в общем всё как в обычной растровой графике, никакого велосипеда я не изобретал.

Private Sub Command2_Click()

Form1.PaintPicture Picture1, 200, 20, Picture1.ScaleWidth, Picture1.ScaleHeight, , , , , vbSrcAnd
Form1.PaintPicture Picture3, 200, 20, Picture3.ScaleWidth, Picture3.ScaleHeight, , , , , vbSrcPaint

BitBlt Form1.hDC, 100, 10, Picture1.ScaleWidth, Picture1.ScaleHeight, Picture1.hDC, 0, 0, vbSrcAnd
BitBlt Form1.hDC, 100, 10, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture2.hDC, 0, 0, vbSrcPaint

Form1.Refresh
End Sub

В большинстве пасьянсов можно вообще обойтись без вывода карт с маской.Так как карты там накладываются 
лишь с небольшим отступом сверху. Можно для каждой карты сделать свой пикчербокс, а уголки карт которые должны быть
цвета фона просто зарисовать используя PSet,Line и любой другой способ на любителя.)
Ну вот с картами разобрались, и на последок несколько советов об организации собственно колоды. 
Я свою колоду селал в виде отдельных карт, разместил их в корневой директории и подгружаю нужную карту
по её названию. Названия карт сделал числовыми. с 1 по 52 это карты, потом 2 джокера(чёрный и красный),
затем маска, несколько пустых карт разного цвета( под разный фон формы) и много карт рубашек. Вообще я люблю сам рисовать 
рубашки для карт. 
Первые 52 карты логически рассортированы по четвёркам одного достоинства но разных мастей, 
это позволяет элементарно применять математику, для определения по номеру , какая это карта и наоборот. хотя это очень редко 
надо,далеко не во всех играх.
Ещё такая организация помогает в более эффективной тасовке, но это уже отдельная тема. Я реализую тасовку 
через генерацию трёх псевдослучайных чисел , первое в пределах от 10 до 20 -колличество перестановок в цикле.
второе число от 2 до 5 - шаг внутри перестановок, то есть допустим шаг 3, то есть я буду менять текущую карту с третьей вверх.
Третье число это шаг внутри тасовки, то есть переход на новый элемент, это число в диапазоне от 3 до 9, если достигнут конец 
массива, то переход в начало массива + смещение в 1.
Если в игре несколько раздач, то я начинаю тасовку с предыдущего состояния массива. Вот улучшенный вариант моего алгоритма 
тасовки который я описал, немного пределы случайных чисел подправил и перед перебором масива в цикле сразу 
три пары меняю с хвоста массива.
В общем это кусок одной из моих программуль, всё работает великолепно.

Dim masiw(52) As Integer
Dim r1, r2, r3, swpp, n1, n2 As Integer

Private Sub initmasiw()
Dim i As Integer
For i = 0 To 51
masiw(i) = i + 1
Next i
End Sub


Private Sub tasowwka()
Randomize
r1 = Int((Rnd * 10) + 10)
r2 = Int((Rnd * 4) + 2)
r3 = Int((Rnd * 8) + 4)
swpp = masiw(51)
masiw(51) = masiw(r1)
masiw(r1) = swpp
swpp = masiw(50)
masiw(50) = masiw(r2)
masiw(r2) = swpp
swpp = masiw(49)
masiw(49) = masiw(r3)
masiw(r3) = swpp
Dim k As Integer
n1 = 0
n2 = 0
For k = 0 To r1
If (n1 > 51) Then n1 = n1 - 50
n2 = n2 + r2
If (n2 > 51) Then n2 = r1 + r3
swpp = masiw(n1)
masiw(n1) = masiw(n2)
masiw(n2) = swpp
n1 = n1 + r3
Next k
End Sub

Удачного вам написания карточных игр!!!




© ЯКВ-мистери 2000-2014     kestrens@mail.ru

Hosted by uCoz