DirectDraw7 - помогите

Работа с 2D и 3D графикой, видео, звуком.

Модератор: Mikle

Bazilius
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 87
Зарегистрирован: 14.11.2003 (Пт) 16:07
Откуда: Пермь

DirectDraw7 - помогите

Сообщение Bazilius » 05.08.2004 (Чт) 0:03

Сел разбираться с DirectDraw7 (хочу написать свой движок, сейчас использую чужие) и выскочила проблема - спрайт при выходе за пределы экрана исчезает. Я предполагаю что дело в RECT, но как это исправить - не знаю.

Вот форма:
Код: Выделить всё
Dim MouseX As Long, MouseY As Long
Public Running As Boolean
Private Sub Form_Load()
    Me.Show
    DXInit Me.hWnd, 800, 600, 32
    Running = True
   
        LoadSprite SpriteSurface, "sprite.bmp", RGB(255, 0, 255)
        With SpriteRECT
            .Left = 0
            .Top = 0
            .Right = 64
            .Bottom = 96
        End With
    Main
End Sub
Private Sub Form_KeyPress(KeyAscii As Integer)

    If KeyAscii = vbKeyEscape Then Running = False
End Sub
Private Sub Main()
Do While Running
    DoEvents
        Render
Loop
EndIT
End Sub

Private Sub Render()
Dim rectScreen As RECT
    With rectScreen
        .Top = 0
        .Left = 0
        .Right = 800
        .Bottom = 600
    End With

BackBuffer.BltColorFill rectScreen, 0

    Call BackBuffer.BltFast(MouseX, MouseY, SpriteSurface, SpriteRECT, DDBLTFAST_SRCCOLORKEY Or DDBLTFAST_WAIT)
PrimarySurface.Flip Nothing, DDFLIP_WAIT
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
MouseX = X: MouseY = Y
End Sub


Вот модуль:
Код: Выделить всё
Option Explicit

'NOTE THIS SAMPLES SHOWS HOW TO USE FULL SCREEN FEATURES

Public DirectX As New DirectX7
Public DirectDraw As DirectDraw7
Public PrimarySurface As DirectDrawSurface7
Public BackBuffer As DirectDrawSurface7
Public DirectDrawSurfaceDesc As DDSURFACEDESC2
Public DDSDSprite As DDSURFACEDESC2
Public Caps As DDSCAPS2

Public SpriteSurface As DirectDrawSurface7
Public SpriteRECT As RECT
Public Sub DXInit(SourcehWnd As Long, ScreenWidth As Long, ScreenHeight As Long, ColorDepth As Long)
    On Local Error GoTo errOut
           
    'Dim file As String
   
    Set DirectDraw = DirectX.DirectDrawCreate("")
    'Me.Show
   
    'indicate that we dont need to change display depth
    Call DirectDraw.SetCooperativeLevel(SourcehWnd, DDSCL_FULLSCREEN Or DDSCL_ALLOWMODEX Or DDSCL_EXCLUSIVE)
   
    DirectDraw.SetDisplayMode ScreenWidth, ScreenHeight, ColorDepth, 0, DDSDM_DEFAULT
   

           
    'get the screen surface and create a back buffer too
    DirectDrawSurfaceDesc.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
    DirectDrawSurfaceDesc.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX
    DirectDrawSurfaceDesc.lBackBufferCount = 1
       
    Set PrimarySurface = DirectDraw.CreateSurface(DirectDrawSurfaceDesc)
   
   
   
   
    Caps.lCaps = DDSCAPS_BACKBUFFER
    Set BackBuffer = PrimarySurface.GetAttachedSurface(Caps)
   
    'Backbuffer.GetSurfaceDesc ddsd4
   
   

    'We create a DrawableSurface class from our backbuffer
    'that makes it easy to draw text
    BackBuffer.SetForeColor vbGreen
    BackBuffer.SetFontTransparency True
   
'    ' init the surfaces
'    InitSurfaces
'
'    binit = True
'    brunning = True
'    Do While brunning
'        blt
'        DoEvents
'    Loop
   
   
errOut:
'
'    EndIT
   
End Sub
Public Sub LoadSprite(TempSurface As DirectDrawSurface7, FileName As String, TransColor As Long)
    'load the bitmap into the second surface
    DDSDSprite.lFlags = DDSD_CAPS
    DDSDSprite.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
    Set TempSurface = DirectDraw.CreateSurfaceFromFile(FileName, DDSDSprite)
   
    'use black for transparent color key
    Dim key As DDCOLORKEY
    key.low = TransColor
    key.high = key.low
    TempSurface.SetColorKey DDCKEY_SRCBLT, key
End Sub
Public Sub EndIT()
    Call DirectDraw.RestoreDisplayMode
    Call DirectDraw.SetCooperativeLevel(0, DDSCL_NORMAL)
   
    Set PrimarySurface = Nothing 'Уничтожаем первичную поверхность
    Set BackBuffer = Nothing 'и задний буфер
    Set DirectDraw = Nothing 'DirectDraw уничтожаем в послежнюю очередь!!!
    End
End Sub


Если не сложно, расскажите еще пожалуйста про прозрачность...[/code]

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Re: DirectDraw7 - помогите

Сообщение Yurich » 05.08.2004 (Чт) 2:35

Bazilius писал(а):спрайт при выходе за пределы экрана исчезает. Я предполагаю что дело в RECT, но как это исправить - не знаю.


Так и есть, исчезает. На границах экрана изменяй SpriteRECT!

mad_Max
Бывалый
Бывалый
 
Сообщения: 203
Зарегистрирован: 15.09.2002 (Вс) 21:17
Откуда: Russia, Cherepovets

Сообщение mad_Max » 05.08.2004 (Чт) 22:28

Я для простоты использую процедуру
Код: Выделить всё
Public Sub FitScreen(ByRef coordX As Long, ByRef coordY As Long, ByRef tmpRECT As DxVBLib.RECT)
  If coordX < 0 Then
  tmpRECT.Left = tmpRECT.Left - coordX
  coordX = 0
  End If
  If coordY < 0 Then
  tmpRECT.Top = tmpRECT.Top - coordY
  coordY = 0
  End If
  If coordX > scrSizeX - (tmpRECT.Right - tmpRECT.Left) Then
  tmpRECT.Right = tmpRECT.Right - (coordX - (scrSizeX - (tmpRECT.Right - tmpRECT.Left)))
  End If
  If coordY > scrSizeY - (tmpRECT.Bottom - tmpRECT.Top) Then
  tmpRECT.Bottom = tmpRECT.Bottom - (coordY - (scrSizeY - (tmpRECT.Bottom - tmpRECT.Top)))
  End If
End Sub

Здесь scrSizex и scrSizeY - разрешение экрана.
После расчета координат и RECT'а их нужно предать этой процедуре в качестве параметров. После этого их можно спокойно использовать - процедура при необходимости "обрежет" спрайт до нужных размеров.

Dagobert
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 141
Зарегистрирован: 21.12.2002 (Сб) 6:48
Откуда: Russia

Сообщение Dagobert » 18.08.2004 (Ср) 4:49

Что за движок, для чего. Может мы можем работать вместе:
http://dagobert.nm.ru/project-orden/
dagobert@nm.ru

Anatron
Обычный пользователь
Обычный пользователь
 
Сообщения: 62
Зарегистрирован: 21.08.2002 (Ср) 20:22
Откуда: Златоуст, Челябинская обл.

Сообщение Anatron » 16.09.2004 (Чт) 22:37

Я использую вот такую функцию:

Public Function Clipping(rcInto As RECT, rcFrom As RECT, x As Long, y As Long) As RECT
Clipping = rcFrom
OffsetRect Clipping, x, y
IntersectRect Clipping, rcInto, Clipping
If Not IsRectEmpty(Clipping) Then OffsetRect Clipping, -x, -y
End Function

Где, rcInto - Rect, в который происходит копирование картинки, в твоём случае это Rect экрана(0,0,800,600);
rcFrom - Rect, который описывает какую по размерам область копируем. Обычно (0,0,Ширина картинки,Высота картинки).
x,y - координаты, куда копировать rcFrom в rcInto.

Возвращает, уже готовый, обрезанный как надо Rect.

Мудрёно, но работает 100%.

Необходимые API-функции:

Public Declare Function OffsetRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long
Public Declare Function IntersectRect Lib "user32" (lpDestRect As RECT, lpSrc1Rect As RECT, lpSrc2Rect As RECT) As Long
Public Declare Function IsRectEmpty Lib "user32" (lpRect As RECT) As Long


Вернуться в Мультимедиа

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 26

    TopList