Sprites in verschiedenen größen darstellen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Stefan
Beiträge: 125
Registriert: 29.08.2004 10:51
Kontaktdaten:

Sprites in verschiedenen größen darstellen

Beitrag 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
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

ZoomSprite3D ?
Windows 10 Pro, 64-Bit / Outtakes | Derek
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag 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.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
nco2k
Beiträge: 892
Registriert: 08.09.2004 23:13

Beitrag von nco2k »

genial. :allright:

gleich mal fred zeigen. :mrgreen:

c ya,
nco2k
~|__/
..o.o.. <--- This is Einkaufswagen. Copy Einkaufswagen into your signature to help him on his way to world domination.
Antworten