Seite 1 von 1

Sprites in verschiedenen größen darstellen

Verfasst: 22.02.2007 11:01
von Stefan
Mit DisplaySpriteEx() ist es möglich Sprites in beliebigen Größen darzustellen. :wink:
Vorteile gegenüber 3DSprites:
- Die Größe des Sprites ist egal (Keine Einschränkungen wie 16x16,32x32...)
- Kann in kombination mit UseBuffer() verwendet werden
- Unterstützt Clipping (mit ClipSprite())
- zum zeichnen ist kein 3D Beschleuniger notwendig

Code: Alles auswählen


#DDBLT_WAIT=16777216
#DDBLT_KEYSRC=32768

Structure PB_Sprite 
  Sprite.l 
  Width.w 
  Height.w 
  Depth.w 
  Mode.w 
  FileName.l 
  RealWidth.w 
  RealHeight.w 
  ClipX.w 
  ClipY.w 
EndStructure

Structure DDBLTFX 
  dwSize.l 
  dwDDFX.l 
  dwROP.l 
  dwDDROP.l 
  dwRotationAngle.l 
  dwZBufferOpCode.l 
  dwZBufferLow.l 
  dwZBufferHigh.l 
  dwZBufferBaseDest.l 
  dwZDestConstBitDepth.l 
  dwZDestConst.l 
  dwZSrcConstBitDepth.l 
  dwZSrcConst.l 
  dwAlphaEdgeBlendBitDepth.l 
  dwAlphaEdgeBlend.l 
  dwReserved.l 
  dwAlphaDestConstBitDepth.l 
  dwAlphaDestConst.l 
  dwAlphaSrcConstBitDepth.l 
  dwAlphaSrcConst.l 
  dwFillColor.l 
  dwColorSpaceLowValue.l 
  dwColorSpaceHighValue.l 
  dwColorSpaceLowValue2.l 
  dwColorSpaceHighValue2.l 
EndStructure 

Structure RGN
  dwSize.l
  iType.l
  nCount.l
  nRgnSize.l
  rcBoundLeft.l
  rcBoundTop.l
  rcBoundRight.l
  rcBoundBottom.l  
  rc1Left.l
  rc1Top.l
  rc1Right.l 
  rc1Bottom.l 
  rc2Left.l
  rc2Top.l
  rc2Right.l 
  rc2Bottom.l 
EndStructure

!extrn _PB_Screen_Width 
!extrn _PB_Screen_Height
!extrn _PB_Sprite_CurrentBitmap
!extrn _PB_DDrawBase 

ProcedureDLL.l GetScreenWidth() ; returns the width of the current buffer selected with UseBuffer()
  !MOV Eax,[_PB_Screen_Width] 
  ProcedureReturn 
EndProcedure 

ProcedureDLL.l GetScreenHeight() ; returns the height of the current buffer selected with UseBuffer()
  !MOV Eax,[_PB_Screen_Height] 
  ProcedureReturn 
EndProcedure 

ProcedureDLL.l GetCurrentDDS() ; returns the current used (select with UseBuffer()) directdrawsurface
  !MOV Eax,[_PB_Sprite_CurrentBitmap] 
  ProcedureReturn 
EndProcedure

ProcedureDLL.l GetDDrawBase() ; returns the directdraw interface
  !MOV Eax,[_PB_DDrawBase]
  ProcedureReturn 
EndProcedure

Procedure DisplaySpriteEx(Sprite,x.l,y.l,Width.l,Height.l,transparent.l)
  Protected *Sprite.PB_Sprite,rgn.RGN,*DD.IDirectDraw7,*Clipper.IDirectDrawClipper,SrcRe.Rect,DstRe.Rect,*DDS.IDirectDrawSurface7,fx.DDBLTFX,Result.l
  
  *DDS=GetCurrentDDS()
  *Sprite=IsSprite(Sprite)
  
  If *DDS=0 Or *Sprite=0 Or Width<1 Or Height<1
    ProcedureReturn #False
  EndIf
  
  DstRe.Rect
  DstRe\left=x
  DstRe\top=y
  DstRe\right=x+Width
  DstRe\bottom=y+Height
  
  SrcRe\left=*Sprite\ClipX
  SrcRe\right=*Sprite\ClipX+*Sprite\Width
  SrcRe\top=*Sprite\ClipY
  SrcRe\bottom=*Sprite\ClipY+*Sprite\Height
  
  DestWidth=GetScreenWidth()
  DestHeight=GetScreenHeight()
  
  fx\dwSize=SizeOf(DDBLTFX)
  
  If x<0 Or y<0 Or DstRe\right=>DestWidth Or DstRe\bottom=>DestHeight ; use only a clipper, if we need it
    
    rgn\dwSize=SizeOf(RGNDATAHEADER)
    rgn\iType=#RDH_RECTANGLES
    rgn\nCount=1
    rgn\nRgnSize=16
    
    rgn\rcBoundLeft=0
    rgn\rcBoundTop=0
    rgn\rcBoundRight=DestWidth
    rgn\rcBoundBottom=DestHeight
    
    rgn\rc1Left=0
    rgn\rc1Top=0
    rgn\rc1Right=DestWidth
    rgn\rc1Bottom=DestHeight
    
    *DD=GetDDrawBase()
    If *DD=0:ProcedureReturn #False:EndIf
    *DD\CreateClipper(0,@*Clipper,0)
    If *Clipper=0:ProcedureReturn #False:EndIf
    
    If *Clipper\SetClipList(rgn,0)<>#S_OK
      *Clipper\Release()
      ProcedureReturn #False
    EndIf
    
    If *DDS\SetClipper(*Clipper)<>#S_OK
      *Clipper\Release()
      ProcedureReturn #False
    EndIf
    
    If transparent
      Result=*DDS\Blt(DstRe,*Sprite\Sprite,SrcRe,#DDBLT_KEYSRC|#DDBLT_WAIT,fx)
    Else
      Result=*DDS\Blt(DstRe,*Sprite\Sprite,SrcRe,#DDBLT_WAIT,fx)
    EndIf
    
    *DDS\SetClipper(0)
    *Clipper\Release()
    
  Else
    
    If transparent
      Result=*DDS\Blt(DstRe,*Sprite\Sprite,SrcRe,#DDBLT_KEYSRC|#DDBLT_WAIT,fx)
    Else
      Result=*DDS\Blt(DstRe,*Sprite\Sprite,SrcRe,#DDBLT_WAIT,fx)
    EndIf
    
  EndIf
  
  If Result=#S_OK
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
  
EndProcedure





InitSprite()

OpenWindow(1,0,0,640,480,"DisplaySpriteEx() example")
OpenWindowedScreen(WindowID(1),0,0,640,480,0,0,0)


CreateSprite(1,100,100)
TransparentSpriteColor(1,#Magenta)


StartDrawing(SpriteOutput(1))
Box(0,0,100,100,#Magenta)

For n=50 To 1 Step -1
  Circle(45+Random(10),45+Random(10),n,RGB(255-n,255-n*4,0))
Next
StopDrawing()


Repeat
  
  ClearScreen(#Blue)
  
  For T=0 To 20
    k.f+0.001
    DisplaySpriteEx(1,Sin(k+T/10)*260+260,Cos(k+T/5)*180+180,Cos(k+T/5)*30+50,Cos(k+T/5)*30+50,#True)
  Next
  
  FlipBuffers()
Until WindowEvent()=#PB_Event_CloseWindow

Verfasst: 22.02.2007 15:17
von Fluid Byte
ZoomSprite3D ?

Verfasst: 22.02.2007 15:20
von DarkDragon
Fluid Byte hat geschrieben:ZoomSprite3D ?
Bahnhof?
Er hat doch ganz klar die Vorteile erläutert. Lies doch auch mal was anstatt nur schwachsinn zu schreiben.

Verfasst: 22.02.2007 17:29
von nco2k
genial. :allright:

gleich mal fred zeigen. :mrgreen:

c ya,
nco2k