sehr viele bilder laden, performance

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

[MES]Masta

Betreff: sehr viele bilder laden, performance

BeitragMi, Apr 09, 2008 14:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo alle zusammen,

ich fummle seit ein paar wochen mit blitz3d in der version 1.90 rum (d.h. programmieranfänger*malwieder*Smile).

bisher funktioniert auch alles was ich getestet habe problemlos.

nun bin ich dabei ein "karten" spiel zu proggen a`la magic, yugioh, pokemon etc. .

um ersteinmal eine grundstruktur zu bekommen habe ich eine test txt datei ausgelesen die sozusagen die anzahl der karten enthält die zur verfügung stehen. und das sind bzw. werden sehr viele (ca. 9000 stück).

momentan erstelle ich mit dim,types,creatimage etc. die anzahl an bilder die ich aus der test txt ausgelesen habe und lasse sie untereinander anzeigen. dazu habe ich eine scroll funktion mit der ich auch bis zur letzten "karte" herunter scrollen kann. wie gesagt, bisher alles problemlos.

das problem was sich nun auftut ist die geschwindigkeit des spieles beim laden aller karten.
wenn ich aus der test txt sagen wir 100 "karten" auslesen lasse dauert es schon ein paar sekunden bis mein fenster eine anzeige bringt. bei 500 "karten" ist es eine ewige prozedur bis etwas zu sehen ist.
sprich bei 7000x createimage wird das alles hmm, etwas zäh.

hier al der code zu sicherheit. er besteht aus 2. teilen. der erste erstellt eine txt mit einträgen, der 2. teil ist "das spiel"

1. teil karten.txt erstellen
Code: [AUSKLAPPEN]

test_txt = WriteFile("karten.txt")
a = 0
For i = 0 To 100
a = a + 1
If a < 10 Then WriteLine( test_txt, "Sp-Nr.:000"+a )
If a > 10 And a < 100 Then WriteLine( test_txt, "Sp-Nr.:00"+a )
If a > 10 And a >= 100 And a < 1000 Then WriteLine( test_txt, "Sp-Nr.:0"+a )
If a >= 1000 Then WriteLine( test_txt, "Sp-Nr.:"+a )
Next


2. teil "das spiel"
Code: [AUSKLAPPEN]

Const fensterbreite=800,fensterhoehe=600,tiefe=16
Graphics fensterbreite,fensterhoehe,tiefe,2

Global start = 0, start2 = 0, y_start = 5
Global scroll_rechts_x = 700, scroll_rechts_y = 0, karten_scroll_y = 0, karten_scroll_y_2 = 0
Global mz = MouseZ(), mz_2 = MouseZ(), mz_pruef = MouseZ()
Global mx, my, mx_scroll_1, my_scroll_1, mx_scroll_2, my_scroll_2
Global karte_gross_width = 120, karte_gross_height = 90
Global karte_mittel_width = 55, karte_mittel_height = 75
Global karte_klein_width = 35, karte_klein_height = 55
Global karte_abstand = 5
Global scrollbalken = LoadImage("scrollbalken.png")
Global scrollbalken_width = 5, scrollbalken_height = 100, scrollbalken_x = 785, scrollbalken_y = 5
Global maus = LoadImage("maus.png")
ResizeImage maus,15,30
RotateImage maus,10
;HidePointer
;MaskImage maus,0,0,0
Global datei$ = "karten.txt"

;-------------------
;--Karten-definieren
Type karte
Field nr
Field name$
Field bild_width
Field bild_height
Field bild_abstand
Field bild
Field x
Field y
Field text_x
Field text_y
End Type

Dim eintraege$(datei_eintraege_zaehlen()-1)
Dim karte.karte(datei_eintraege_zaehlen()-1)
For i = 0 To datei_eintraege_zaehlen()-1
test = test + 1
karte(i) = New karte
karte(i)\nr = i
karte(i)\name = test
karte(i)\bild_width = karte_mittel_width
karte(i)\bild_height = karte_mittel_height
karte(i)\bild_abstand = karte_abstand
karte(i)\bild = CreateImage(karte(i)\bild_width,karte(i)\bild_height)
karte(i)\x = 5
karte(i)\y = 5
karte(i)\text_x = 10
karte(i)\text_y = 5
;Print karte(i)\name
;Print karte(i)\nr
;Print test
SetBuffer ImageBuffer(karte(i)\bild)
;;;Color 0,0,255
;;;Rect 0,0,70,90
;;;Color 255,255,255
    Color 0,255,0
    For a = 0 To 119
       Color a*2,a*2,255
      Line 0,a,159,a
Next
Text karte(i)\text_x,karte(i)\text_y,karte(i)\name
SetBuffer BackBuffer()
Next
;---------------
;---------------
;--Hauptschleife

While Not KeyDown(1)
datei_eintraege(x)
scrolleiste_rechts()

Text 10,30,"mz_pruef: " + mz_pruef
Text 10,43,"letzte karten_y position " + karte(datei_eintraege_zaehlen()-1)\y
Text 10,54,"karten_scroll_y " + karten_scroll_y
Text 10,67,"karten_scroll_y_2 " + karten_scroll_y_2
Text 10,80,"datei_eintraege_zaehlen: " + datei_eintraege_zaehlen()
Text 10,93,"datei_eintraege: " + eintraege$(0)
;-tests
test = karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe
Text 10,120,"rech. letzte_y_pos abzüglich bildschirmhöhe " + test
test2# = test/600
Text 10,133,"rech. letzte_y_pos auf bildschirmhöhe rechnen " + test2#
Text 10,146,"rech. (((kartenges.*kartenbreite) + (kartenges.*kartenbreite)) + anfangsabstand): " + (((datei_eintraege_zaehlen() * 75) + (datei_eintraege_zaehlen() * 5)) + 5)
Text 10,159,"rech. (kartenges. * (kartenhoehe+abstand)+anfangsabstand): " + (datei_eintraege_zaehlen() * (75+5)+5)
Text 10,172,"rech. (fensterhoehe/((letzte_y_pos-fensterhoehe)/kartenges.)): " + (fensterhoehe / ((karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe) / datei_eintraege_zaehlen()))

;------------------Mauszeiger zeichen und Scrollbalken kollision
;-----
;mx = MouseX() ; MouseX und MouseY liefern die Mousekoordinaten als Rückgabewert zurück.
;my = MouseY() ; Deshalb müssen diese in jeder Mainloop neu abgerufen werden

;    If MouseHit(1) Then
;         If ImagesCollide(maus,MouseX(),MouseY(),0,scrollbalken,scrollbalken_x,scrollbalken_y,0) Then
;            mx = MouseX()-scrollbalken_x
;            my = MouseY()-scrollbalken_y
;            BildAnMaus= 1
;         EndIf
;      End If
;      If MouseDown(1) And BildAnMaus = 1 Then
;         scrollbalken_x = MouseX() -mx
;         scrollbalken_y = MouseY() -my
;      Else
;      BildAnMaus= 0
;      EndIf

;DrawImage maus,MouseX(),MouseY()

Flip
Cls
Wend
;--------------------
;--Hauptschleife-ende
;--------------------
;--------------------
;--------------------
;----------Funktionen
;--------------------
;--zaehlen
;------------------------------------------------------
;--karten.txt_lesen
;--function datei öffnen und zählen
Function datei_eintraege_zaehlen()
inhalt_datei = ReadFile(datei$)
anzahl = 0
Repeat
anzahl = anzahl + 1
zeilen$ = ReadLine(inhalt_datei)
Until Eof(inhalt_datei)
CloseFile(inhalt_datei)
Return anzahl
End Function
;-----------------------------------------------------
;--function datei öffnen und einträge in dim speichern
Function datei_eintraege(x)
inhalt_datei$ = ReadFile(datei$)
inhalt = 0
For i = 0 To datei_eintraege_zaehlen()-1
inhalt = inhalt + 1
eintraege$(i) = ReadLine(inhalt_datei$)
;Print eintraege$(i)
Next
CloseFile(inhalt_datei$)
Return x
End Function
;------------------------------------------------------

;----------------
;--Karte-Zeichnen
Function karte_zeichnen()
For g = 0 To datei_eintraege_zaehlen()-1

DrawImage karte(g)\bild,karte(g)\x,karte(g)\y
If g < datei_eintraege_zaehlen()-1

karte(g+1)\y = karte(g)\y + (karte(g)\bild_height + karte(g)\bild_abstand)
Else
karte(g)\y = karte(g)\y + (karte(g)\bild_height + karte(g)\bild_abstand)
EndIf
Next
Return
End Function
;----------------
;--viewport_scroll
Function scrolleiste_rechts()
;-prüfen ob maus über scrollleiste
   mx_scroll_1 = MouseX()
   my_scroll_1 = MouseY()
   If mx_scroll_1 > (fensterbreite -100) And mx_scroll_1 < fensterbreite
    If my_scroll_1 > 0 And my_scroll_1 < fensterhoehe
   Select MouseZSpeed()
   Case 0:
   mz = 0
   mz_2 = 0
   Case -1:
   mz = mz - (karte_mittel_height + karte_abstand)
   mz_2 = mz_2 - (fensterhoehe / ((karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe) / datei_eintraege_zaehlen()))
   mz_pruef = mz_pruef - 1
   Case +1:
   mz = mz + (karte_mittel_height + karte_abstand)
   mz_2 = mz_2 + (fensterhoehe / ((karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe) / datei_eintraege_zaehlen()))
   mz_pruef = mz_pruef + 1
   Default:
   End Select      
    karten_scroll_y = karten_scroll_y + mz ;* 2
   karten_scroll_y_2 = karten_scroll_y_2 + mz_2 ;* 2
   karten_scroll_y_pruef = karten_scroll_y_pruef + mz_pruef
;   mz = 0
;   mz_2 = 0
;--karten_scroll_y_2, karten_scroll_pruef,mz_2 und mz_pruef als prüfvariablen
   If karten_scroll_y > 0 Then karten_scroll_y = 0
   If karten_scroll_y_2 > 0 Then karten_scroll_y_2 = 0
   If karten_scroll_y_pruef > 0 Then karten_scroll_y_pruef = 0
   If karten_scroll_y < -(karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe) Then karten_scroll_y = -(karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe); -904
    If karten_scroll_y_2 < -(karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe) Then karten_scroll_y_2 = -(karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe); -904
    If karten_scroll_y_pruef < -(karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe) Then karten_scroll_y_pruef = -(karte(datei_eintraege_zaehlen()-1)\y - fensterhoehe); -904
   End If
   End If

   ;viewport
    Origin scroll_rechts_x,scroll_rechts_y + karten_scroll_y
    ;Viewportkoordinaten  werden nicht von Orgin beinflußt
    Viewport scroll_rechts_x,scroll_rechts_y,100,600

    ; farbe viewportfenster
    ClsColor 0 ,0, $C0C0C0
    Cls
   
    ;textfarbe
    Color 0 ,0, 0;$FFFF00
    ;inhalt des fensters
   karte_zeichnen()   
   
   Color 255 ,255, 255

    ;zurücksetzten
    Origin 0 ,0
    Viewport 0 ,0,GraphicsWidth () ,GraphicsHeight ()
    ClsColor 0 ,0,0
;   scrolleiste
   Color 255,255,255
   Rect 780,0,80,600
   Color 0,0,0
   DrawImage scrollbalken,scrollbalken_x,scrollbalken_y - my

   ;Rect 785,5 - karten_scroll_y_2,10,55
   ;Rect 785,580,5,5
;   Color 255,0,0
;   Rect 780,5 - karten_scroll_y_pruef,5,5
   Color 255,255,255
   End Function
;------------
;------
;--Ende
End


vielen dank schonmal für eure mühe, ich hoffe es kann mir wer ein paar tipps geben

grüsse

denis

prolapper

BeitragMi, Apr 09, 2008 15:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi [MES]Masta

ich kenne das Problem ... Also erstmal würde ich statt Drawimage, Drawblock verwenden. Ist a bissi schneller.
Der Nachteil ist, dass du keine Transparenz anzeigen lassen kannst.
Außerdem ist es doch so, dass bei so einem Karten-spiel nie alle Karten gleichzeitig geladen\angezeigt werden müssen. Ich würde das so machen, dass, wenn man nun ein Spiel starten und ein bestimmtes Deck sich zusammengestellt hat, dass dann nur die Karten für das eine Spiel geladen werden die benötig sind.
Das dürften dann nicht mehr als 120 Karten sein.
P.S: ICH SUCHE NOCH EINEN GRAFIKER UND EINEN PROGRAMMIERER FÜR EIN RPG
E-Mail: prolapper@gmx.net

robotx

BeitragMi, Apr 09, 2008 15:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Erst einmal solltest du die Anzahl der Karten nur einmal am Anfang des Programms auslesen.
So wie es jetzt ist, rufst du ständig die Funktion "datei_eintraege_zaehlen()" auf, was Zeit kostet.


Code: [AUSKLAPPEN]
Global datei_eintraege_anzahl = datei_eintraege_zaehlen()


Das am Anfang und dann mit dieser Variable weiterarbeiten.

mfg robotx
www.botbomb.robotzgames.de
www.robotzgames.de
 

[MES]Masta

BeitragMi, Apr 09, 2008 15:37
Antworten mit Zitat
Benutzer-Profile anzeigen
hi ihrs,

dank ersteinmal für die schnelle antwort.

@ prolapper

das im spiel nicht alle karten benötigt werden ist richtig. soweit bin ich allerdings noch nicht.

der code für "das spiel" ist ersteinmal der "screen" für den deckaufbau. dort werden noch alle karten benötigt für die individuelle deckkonfiguration.
wenn ich damit fertig bin werde ich das ergebniss dieses screens in einer "deck.txt" oder sowas speichern und diese dann im eigentlichen spiel verwenden.

aber solange benötige ich leider noch alle karten Sad

@ robotx

thx, werde gleich mal umschreiben und testen

nachtrag:

@ robotx

das war ein mächtiger performance schub, thx.
eigentlich ja auch logisch wenn man drüber nachdenkt das es "eetwas" länger dauert wenn die datei immer wieder neu geöffnet wird Smile. thx nochmals
 

TimM.

BeitragMi, Apr 09, 2008 17:08
Antworten mit Zitat
Benutzer-Profile anzeigen
[MES]Masta hat Folgendes geschrieben:


@ prolapper

das im spiel nicht alle karten benötigt werden ist richtig. soweit bin ich allerdings noch nicht.

der code für "das spiel" ist ersteinmal der "screen" für den deckaufbau. dort werden noch alle karten benötigt für die individuelle deckkonfiguration.
wenn ich damit fertig bin werde ich das ergebniss dieses screens in einer "deck.txt" oder sowas speichern und diese dann im eigentlichen spiel verwenden.

aber solange benötige ich leider noch alle karten Sad



Eine andere Möglichkeit wäre, eine Listbox zu erstellen, in der alle Karten aufgelistet sind, und du erst eine Vorschau der Karte anzeigst, wenn die Karte ausgewählt wurde oder ein Button "Vorschau" gedrückt wurde.

-> Immer nur ein Bild ohne auf die Einsicht der Karten zu verzichten.
 

[MES]Masta

BeitragMi, Apr 09, 2008 17:52
Antworten mit Zitat
Benutzer-Profile anzeigen
was meinst du genau mit listbox?

also die karten müssen beim deckaufbau von vornerein zu sehen sein, da man sie je nach den eigenschaften auswählen muss. sie müssen also so oder so aufgedeckt sein.

eine andere überlegung, wenn es eine gewisse zeit zum laden der karten braucht und sich das nicht verschnellern lässt, einen ladenbalken/ladescreen einzubauen solange bis eben die letzte karte geladen ist?
 

Gast

BeitragMi, Apr 09, 2008 18:00
Antworten mit Zitat
Ja, aber dann mache es nich behilfsweise mit Text,Rect, Oval, o.ä., das zieht mächtig performance(*auserfahrunsprech*)...
 

Dreamora

BeitragMi, Apr 09, 2008 18:01
Antworten mit Zitat
Benutzer-Profile anzeigen
das problem sollte eigentlich weniger CreateImage sein. Mehr was du danach damit machst.
Denn du nutzt die langsamste Art das zu lösen.
Die um einiges schnellere Art ist die, Lockbuffer / Unlockbuffer zu nutzen und mit WritePixelFast und einem eigenen Line Algorithmus zu arbeiten (Bresenham Algorithmen am sinnvollsten, glaub die waren sogar ma hier oder im blitzbasic.com code archiv, line als auch circle / ellipsoid)

Ein weiteres Problem ist das, dass es dauert ein Image zu erzeugen. Es wäre von daher vielleicht ratsam den zeichencode am schluss in eine zweite loop direkt danach zu verpacken. also erst die karten 1 - n erzeugen , loop fertig und dann in ner neuen loop die images bemalen. dadurch steigt die wahrscheinlichkeit das die bilder schon da und nutzbar sind.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
 

[MES]Masta

BeitragMi, Apr 09, 2008 19:28
Antworten mit Zitat
Benutzer-Profile anzeigen
auf die gefahr hin etwas dummes zu sagen.

mit createimage arbeite ich momentan nur um mein "gerüst" zu testen, später werden dahinter noch richtige bilder stehen (was wahrscheinlich wieder ein performance verlust verursacht)

in die writepixelfast sache mit lock, und unlockbuffer muss ich mich noch einlesen und arbeiten, ich habe dazu die testcodes versucht die bb mitliefert, bekomme dabei allerdings eine "memory acess violation".

die sache mit dem unterteilen der schleifen werde ich noch testen.
bin für jeden tipp dankbar Wink

grüsse

denis

nachtrag:

habe aus der bemalenfunktion mit setbuffer front/backbuffer eine eigene funktion gemacht.

dann habe ich aus der bemalen funktion, die bisher aus einem farbverlauf aus einzeln gezeichneten linien für jede karte bestand, ein einfaches farbiges rechteck gezeichnet und es dauerte mit 10000 gezeichneten objekten nur knapp 6 sekunden. vorher dauerte es mit knapp 1000 bildern 20 sekunden oder so.
ich denke das war es was du mit dem writepixelfast meintest. dies anstatt der linien zu nutzen. liege ich da so halbwegs richig?
  • Zuletzt bearbeitet von [MES]Masta am Mi, Apr 09, 2008 20:35, insgesamt einmal bearbeitet

BladeRunner

Moderator

BeitragMi, Apr 09, 2008 20:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Es geht sicher wesentlich flotter bilder einzuladen als sie zu erstellen, von daher wird dich ein Test mit fertigen Bildern sicher schon angenehm überraschen.
Zum anderen:
Erstelle Dir einfach eine Funktion die Du in jedem Hauptschleifendurchgang aufrufst und die die jeweils sagen wir nächsten 10 Bilder lädt. Daqzu benötigst Du ne Globale Variable in der der derzeitige Ladeposition gespeichert ist, mehr nicht.
Bis der User auch nur die Maus auf dem 'Scrollbutton' hat sollten schon ein bis zweihunddert Bilder geladen sein. Genug um den User zu beschäftigen bis der Rest geladen ist Wink
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group