Sprite zwischenspeichern

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Sprite zwischenspeichern

Beitrag von Skiller »

Hallo Folks,

habe das Forum u. (Archiv) nach vielen Sprite-Copymemory()-Beispielen durchwühlt, konnte aber mein Problem nicht ausmachen. Folgendes: Ich möchte die Screen dynamisch vergrössern bzw. verkleinern. Das Problem dabei ist, das mein Sprite mit CloseScreen gekillt wird. Ich könnte das sprite ja mit SaveSprite() ablegen, aber das kann zu lange dauern.
Habe ein kleines Probebeispiel angehängt.
Ich kann den Fehler nicht ausmachen. Vielleicht bin ich ja auch auf der völlig falschen Spur.

Hat jemand einen Vorschlag bzw. einen Link.!?

Danke schon mal!!!!

Code: Alles auswählen



Global  lAppStart.b, lSwitchScreen.b
Global  WinX.l, winY.l
Global *MemoryAdr.l

WinX = 500
winY = 500

lAppStart = #True

InitSprite()

Procedure LoadSpriteFromMemory() 
  
  Protected nSpriteWidth.l, nSpriteHeight.l
  
  nSpriteWidth  = SpriteWidth(0)
  nSpriteHeight = SpriteHeight(0)
  
  StartDrawing(SpriteOutput(0)) 
  *SpriteAdr = DrawingBuffer() 
  SpriteLen = DrawingBufferPitch() 
  SpriteByt = DrawingBufferPixelFormat()
  StopDrawing()   
  
  ;CopyMemory(*MemoryAdr,*SpriteAdr,SpriteByt)   ; geht nicht !!!!
  
  
  ;.............................  ; geht auch nicht !!!! ..............................
  
  SWidth  = nSpriteWidth  -1
  SHeight = nSpriteHeight -1
  
  For y = 0 To SHeight
    For x = 0 To SWidth
      
      *source  = *MemoryAdr + y * SpriteLen + x * SpriteByt

      nByte.b = PeekB(*source)
      PokeB(*SpriteAdr,nByte)
      
    Next x
  Next y  
  
EndProcedure

Procedure SaveSpriteIntoMemory()

  Protected nSpriteWidth.l, nSpriteHeight.l
  
  nSpriteWidth  = SpriteWidth(0)
  nSpriteHeight = SpriteHeight(0)
  
  StartDrawing(SpriteOutput(0)) 
  SpriteAdr = DrawingBuffer() 
  SpriteLen = DrawingBufferPitch() 
  SpriteByt = DrawingBufferPixelFormat()
  StopDrawing()   
  
  *MemoryAdr = AllocateMemory(nSpriteWidth * nSpriteHeight * SpriteByt)

  SWidth  = nSpriteWidth  -1
  SHeight = nSpriteHeight -1
  
  For y = 0 To SHeight
    For x = 0 To SWidth

     *source  = SpriteAdr + y * SpriteLen + x * SpriteByt
      nByte.b = PeekB(*source)
      PokeB(*MemoryAdr,nByte)

    Next x
  Next y  
  
EndProcedure

  
Procedure MaleWasAufsSprite()
  StartDrawing(SpriteOutput(0)) 
  Box(10,10,SpriteWidth(0)-20,SpriteHeight(0)-20 ,RGB(200,200,245))
  nColor = RGB(200,100,200)
  Circle(100,100,50,nColor) 
  nColor = RGB(100,200,100)
  Box(200,200,100,100,nColor)  
  StopDrawing()  
EndProcedure  

Procedure OpenMyScreen(ScrX.l, ScrY.l)
  OpenWindowedScreen(WindowID(), 20, 20, ScrX, ScrY, 0, 0, 0)
  CreateSprite(0,ScrX-20, ScrY-20) 
  ClearScreen(200,200,200)
  If lAppStart
    lAppStart = #False
    MaleWasAufsSprite()
    SaveSpriteIntoMemory()
  Else
    LoadSpriteFromMemory() 
  EndIf
EndProcedure  


OpenWindow(0, 0, 0, WinX, winY, #PB_Window_WindowCentered | #PB_Window_SystemMenu, "Spritetest")    
OpenMyScreen(460,460)


xMax = 300
x=0 : n=1 : faktor=2   
Quit = 0

Repeat
  
  Event = WindowEvent()
    If Event = #PB_Event_CloseWindow
      Quit = 1
    EndIf
    ExamineKeyboard()
    
    If KeyboardReleased(#PB_Key_F12) 
      CloseScreen()
      lSwitchScreen = lSwitchScreen ! 1
      If lSwitchScreen 
         OpenMyScreen(260,260)
      Else  
         OpenMyScreen(460,460)      
      EndIf
    EndIf

    ; Sprite; irgendwas anzeigen 
    x+n*faktor : If x<-xMax Or x>xMax : n=n*(-1) : EndIf  
    DisplaySprite(0,x+10,x*n+10)
    FlipBuffers()
    
Until Quit = 1 
End

Benutzeravatar
Spirit
Beiträge: 174
Registriert: 13.04.2005 19:09

Beitrag von Spirit »

Probier's mal damit (hab es selbst nicht getestet, weiß also nicht, ob es funzt).

Code: Alles auswählen

Procedure.l SaveSpriteIntoMemory(Sprite)
  sWidth =SpriteWidth(Sprite)
  sHeight=SpriteHeight(Sprite)
  
  StartDrawing(SpriteOutput(Sprite))
  DrwBuffer=DrawingBuffer()
  Pitch    =DrawingBufferPitch()
  
  SprBuffer=AllocateMemory(Pitch*sHeight+8)
  PokeL(SprBuffer, sWidth) : PokeL(SprBuffer+4, sHeight)
  CopyMemory(DrwBuffer, SprBuffer+8, Pitch*sHeight)

  StopDrawing()

  ProcedureReturn SprBuffer
EndProcedure

Procedure LoadSpriteFromMemory(Sprite, SprBuffer)
  sWidth =PeekL(SprBuffer)
  sHeight=PeekL(SprBuffer+4)

  CreateSprite(Sprite, sWidth, sHeight)

  StartDrawing(SpriteOutput(Sprite))
  DrwBuffer=DrawingBuffer()
  Pitch    =DrawingBufferPitch()
  CopyMemory(SprBuffer+8, DrwBuffer, Pitch*sHeight)
  StopDrawing()
EndProcedure
Hinweis: Diese Procedures funktionieren nur, wenn die Farbtiefe beim Screen-Wechsel nicht verändert wird.
Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Beitrag von Skiller »

Hallo BlueSpirit

Funzt!!!!!! :allright:

DANKE!!!!

Vielleicht kannst Du mir ja das noch beantworten,
damit ichs hoffentlich bald kapiert habe.

Also:

1.)

SprBuffer=AllocateMemory(Pitch*sHeight+ 8 )
// die 8 zusaätzlichen Speicher reservierst du also für SWidth u. Sheight !?

PokeL(SprBuffer+0, SWidth)
//Startadresse u. SWidth reinschreiben
//Stehe jetzt auf Startadresse + 4

PokeL(SprBuffer+4, SHeight)
// schreibe ab 5 SWidth rein u. stehe nun auf Startadresse + 8 / richtig?

CopyMemory(DrwBuffer, SprBuffer+8, Pitch*sHeight)

//Damit wir SWidth u. Sheight nicht mitkopieren schiebst du also 8 weiter
und fängst ab 9 an.

2.)

warum musses nicht *SprBuffer heissen ?
in meiner Hilfe steht:

CopyMemory(*SourceMemoryID, *DestinationMemoryID, Länge)

es geht scheinbar aber auch ohne wie sich herausgestellt hat.

????

Skiller
Benutzeravatar
Spirit
Beiträge: 174
Registriert: 13.04.2005 19:09

Beitrag von Spirit »

Freut mich, dass ich helfen konnte! :allright:

Zu deinen Fragen:
1.) stimmt alles

2.)

Den * vor der Variable braucht man nur für Strukturen. Zum Beispiel:

Code: Alles auswählen

Structure Test
  a.l
  b.l
  c.l
EndStructure

MyVar.Test ;Variable deklarieren

MyVar\a=10 ;und ein paar Werte reinschreiben
MyVar\b=20
MyVar\c=30

*Pointer.Test=@MyVar ;den Pointer deklarieren und auf MyVar setzen

Debug *Pointer\a ;Und die Werte ausgeben
Debug *Pointer\b
Debug *Pointer\c
Da aber AllocateMemory() keinen Pointer auf eine Struktur, sondern nur auf den Speicherbereich zurückgibt, kann man den * weglassen (du kannst ihn natürlich trotzdem anfügen, wenn es dir so besser gefällt :wink: ).

Für mehr Informationen über Pointer empfehle ich dir das Pointer-Tutorial auf http://www.robsite.de/tutorials.php?tut=purebasic.
Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Beitrag von Skiller »

Hi BlueSpirit,

GotIt, DANKE nochmal!!!

Skiller
Antworten