Steinfall Bug

Übersicht BlitzBasic Beginners-Corner

Gehe zu Seite 1, 2, 3  Weiter

Neue Antwort erstellen

Raiden93

Betreff: Steinfall Bug

BeitragDi, Nov 30, 2010 1:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey,
ich habe hier einen kleinen Bug den ich nicht behoben Kriegen.
Der Stein fällt so tief bis keine Luft mehr unter ihm ist.
Aber wenn ein Spieler drunter steht soll der Stein Stoppen.
Zur Zeit fällt der Stein genau auf dem tile wo der Spieler auch steht.



Code: [AUSKLAPPEN]

     For Y=0 To 25
       For X=0 To 25
          If map(X,Y) = 1
              If (map(SpielerX,SpielerY-1) = 2) ;Diamant
                  If map(X,Y-1) = 2
                     map(X,Y-1) = 1
                      map(X,Y) = 2
                 End If
               End If
            
            ;Ab hier beginnt der Bug
               If map(X,Y-1) = 3 ;Ist über der Luft ein Stein dann
               map(X,Y-1) = 1 ;verschwindet der Stein und dort wo der Stein war erschein Luft
               map(X,Y) = 3 ;Stein wird da gezeichnet wo er nicht mehr Fallen kan.
                 End If
           End If
       Next
   Next

BladeRunner

Moderator

BeitragDi, Nov 30, 2010 7:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Sag mal, wieviel threads wollt ihr zwei Superhelden denn noch zu ein und demselben Thema eröffnen?
Wenn es weiter um den selben Themenkomplex gehtr nutzt in Zukunft bitte einen Thread weiter. Genauso wie ich es mir in Zukunft bei Teamarbeiten verbitte dass zwei Leute unabhängig voneinander threads eröffnen. Redet miteinander bevor ihr im Doppelpack postet.
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

Dottakopf

BeitragDi, Nov 30, 2010 11:28
Antworten mit Zitat
Benutzer-Profile anzeigen
hm evt. solltest du den lösungsansatz verändern.

Erstelle die herunterfallenden Steinbrocken als Types. Und trenne so die Objekte von der eigentlichen Tile Map. Wenn du einen Gegner in das Spiel setzt, dann hackt man doch auch nicht auf der Tilemap rum, sondern erstellt einen "wirklichen" gegner mit eignenen animationen und co.

hier ein ungefähres beispiel / psydo code:
Code: [AUSKLAPPEN]

dim Map ( xSize , ySize)
dim Map_besetzt( xSize, ySize)    ;befindet sich auf der Tile map dort irgend ein anderes Objekt?, zb. Spieler, oder ein gegner...


Type Tstein
   field x
   field y
   field speed
end type


code..
code..


;kollidiert fallender Stein mit Tile map?
If Map(    (Tstein\stein_x / Tilesize) , (Tstein\stein_y / Tilesize)+1 )  Then   ;stoppe Stein

;kolliediert der Stein mir irgendwas was dort auf der Tilemap steht
IF Map_besetzt(    (Tstein\stein_x / Tilesize) , (Tstein\stein_y / Tilesize)+1  ) Then  ; irgendwas wurde von dem Stein getroffen



je nach dem welcher wert der Map_besetzt arry hat, kannst du nachvollziehen welches objekt da steht. und dem entsprechend die Reaktion anpassen.
1 = Spieler
2 = Ein Gegner
3 = ....

Also zusammengefasst:
- Erstelle für Objekte ,wie Steine,Types (Hier mein Tutorial über Types für Dummies : https://www.blitzforum.de/foru...hp?t=25321)
- Spreichere die aktuelle Position des Types in einem Map_besetzt Arry welcher über die Tile map gelegt wird. Somit ist der Bezug zwischen Tile Map und Objekt darauf geschaffen.
- Überprüfe den Map_besetzt Arry mit der Tilemap bei bewegungsänderungen
- Der Spieler muss natürlich auch seine Position im Map_besetzt arry speichern.
- Je nachdem welcher wert im Besetzt arry steht, kannst du erkennen welches objekt da ist und kannst dem entsprechend reagieren.

...
ich finde das wesentlich eleganter und vorallem wird der Code übersichtlicher. Leider auch minimal langsamer, aber dass solle doch noch drin sein...

Gruß
Dottakopf

Raiden93

BeitragDi, Nov 30, 2010 14:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Werde mich mal mit befassen das muss ja wohl zu schaffen sein ;P
nur eine Frage wie mache ich das mit dem Speichern würde es mir so vorstellen.

Code: [AUSKLAPPEN]
For Y=0 To 25
   For X=0 To 25
      Read map_besetzt(SpielerX,SpielerY)
   Next
Next
 

mDave

BeitragDi, Nov 30, 2010 15:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Beim Speichern etwas einlesen? Ja das macht Sinn.
Nicht.

Beim Speichern schreibst du etwas in eine ausgelagerte Datei, deswegen solltest du wohl eher WriteLine benutzen. Und dann immer die Werte der Array speichern.
Ungefähr so:
Code: [AUSKLAPPEN]

For Y=0 To 25
   For X=0 To 25
      WriteLine Stream,Map(X,Y)
   Next
Next

Dann musst du, wenn du die Map wieder laden willst, das ganze wieder in der richtigen Reihenfolge einlesen. Aber das schaffst du schon.

Ach ja. . .

Raiden93

BeitragDi, Nov 30, 2010 15:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Warum Writeline ? muss ich das nicht mit normal Write machen weil da steht ja auch nicht Readline sondern einfach Read map(x,y)?

Dottakopf

BeitragDi, Nov 30, 2010 15:19
Antworten mit Zitat
Benutzer-Profile anzeigen
äh was genau meinst du mit Speichern ? Wenn du einen Spielstand Speichern möchtest braucht du die die Befehle Writefile, Writeline, Readfile,readline.


wenn du jetzt nur die aktuellen werte des arrys speichern möchstest muss du nur:

Code: [AUSKLAPPEN]

IF Keydown(205) then hero_x = hero_x +1 ;hero bewegen
Map_besetzt(      (Hero_x / TileSize) , (hero_y  / TileSize)   ) = 1  ;Position des Heros im besetzt arry Speichern




Dieser Code ergibt absolut 0 Sinn! Schreibe direkt in den arry wie oben gezeigt und nicht in irgendein Pseudo datenfeld.
Code: [AUSKLAPPEN]

For Y=0 To 25
   For X=0 To 25
      Read map_besetzt(SpielerX,SpielerY)
   Next
Next


Nur um Missverständnisse aus dem weg zu räumen.

~Edit~ oder lädst du evt. deine Tile map aus deinem Quellcode ?
also sowas:
Code: [AUSKLAPPEN]

.level
Data 1,1,1,1
Data 1,0,0,1
data 1,0,0,1
Data 1,1,1,1


Das musst du natürlich mit read lesen Smile. Aber am besten wäre es wenn du dir einen Tile Editor schreibst und das in eine Txt schreibst. Und Weg von Datenfeldern in deinem Code!
Rechtschreibfehler gelten der allgemeinen Belustigung!
  • Zuletzt bearbeitet von Dottakopf am Di, Nov 30, 2010 15:28, insgesamt einmal bearbeitet

Raiden93

BeitragDi, Nov 30, 2010 15:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja ein Tile Editor habe ich mir schon gebastelt.Funktioniert auch alles.Maps können mit dem Clienten auch geladen werden.

Dottakopf

BeitragDi, Nov 30, 2010 15:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Aus dem Kopf wie eine Bewegung aussehen könnte:


Code: [AUSKLAPPEN]

Dim Tile_Map( 30 , 30 )
Dim Tile_MapBesetzt(30,30)   ;der besetzt layer wird einfach über die tile map gelegt, dient nur zur prüfung



code..
code...


If Keydown(205) and Tile_MapBesetzt( hero_x+1 , hero_y ) = 0 and Tile_map( hero_x +1 , hero_y) = 0 then
         Tile_mapBesetzt(hero_x,hero_y) = 0  ;aktuelles tile wird nun freigeräumt
          Hero_x = hero_x +1  ;um ein tile nach rechts bewegen
         Tile_mapBesetzt(hero_x,hero_y) = 1 ; neues aktuelles Tile wird nun wieder besetzt
end if

       



du kannst auch ganz lustig sein und sagen, du definierst in deinem Tile Editor nachträglich die nicht zugänglichen stellen. Hierbei legst du wieder deinen Tile_besetzt arry über die Tilemap und schreibst einfach an den stellen die auf der Tile map nicht zugänglich sind, in deinen Tile_besetzt arry eine 1 oder sonst einen wert rein hin.

Das bringt gleich ein paar vorteile mit sich. Du kannst somit verschiedene Kollisionsarten festlegen. In dem du z.B. sagst
Tile_besetzt(x,y) = 1 ;Harte Kollison nichts kommt durch
Tile_besetzt(x,y) = 2 ;Schlamm , spieler kommt nur langsam vorwärts
.... und so weiter und so weiter


Meine eigentliche Botschaft lautet : Die Tile map dient nur zum darstellen der Grafiken(Tiles) alle überprüfungen auf die Tile Map laufen über den Besetzt Arry welcher genau über die Tile Map gelegt wird

Gruß
Dottakopf
Rechtschreibfehler gelten der allgemeinen Belustigung!

Raiden93

BeitragDi, Nov 30, 2010 18:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Wen aber Dim TIle_map(30,30) für die Grafik zuständig ist.
Warum dann ist der Code dann so :/ wie folgt:
Code: [AUSKLAPPEN]
 Tile_mapBesetzt(hero_x,hero_y) = 0  ;aktuelles tile wird nun freigeräumt
          Hero_x = hero_x +1  ;um ein tile nach rechts bewegen
         Tile_mapBesetzt(hero_x,hero_y) = 1 ; neues aktuelles Tile wird nun wieder besetzt


Muss es nicht so aussehen.
Code: [AUSKLAPPEN]
 Tile_map(hero_x,hero_y) = 0  ;aktuelles tile wird nun freigeräumt
          Hero_x = hero_x +1  ;um ein tile nach rechts bewegen
         Tile_map(hero_x,hero_y) = 1 ; neues aktuelles Tile wird nun wieder besetzt


Da ja das teil sonst nicht sichtbar weg gemacht wird? da blicke ich noch nicht ganz durch.

Dottakopf

BeitragDi, Nov 30, 2010 19:05
Antworten mit Zitat
Benutzer-Profile anzeigen
ok ich sags jetzt nochmal.... die Tile Map zeichnet NUR die Grafiken. Der Besetzt Arry wird einfach "über" die Tile Map gelegt. Und sämtliche überprüfungen finden auf dem Besetzt arry statt.


deine Spieler Grafik ist doch nicht mit im Tile Set... sondern ist eine Extra Grafik! (sollte zumindest so sein).
Und wie schon gesagt, der Arry mit dem namen "Tile_map" malt nur die Tiles.


also hast du ganz normal eine Schleife die so aussieht
Code: [AUSKLAPPEN]

for x = 1 to mapsize_x
     for y = 1 to mapSize_y
           IF tile_map(x,y) <>0  then drawimage tile_set , x*32, y*32, tile_map(x,y)
     next
next





und eine überprüfung auf kollision sieht dann so aus
Code: [AUSKLAPPEN]

IF Tile_mapbesetzt(hero_x + 1 , hero_y) = 0 then  ; ist dieses Tile zugänglich


natürlich kannst du in deinem Map editor auch sagen, "hey ich will aber das der spieler durch match/dunkle materie oder Nutella rennt" und deswegen langsamer werden soll....

dann schreibst du halt in den Tile_mapbesetzt arry einen gewissen wert rein den du dan abfragen kannst.



Kurz und knapp...
du hast einfach einen 2ten layer der genau über deine Tile map gelegt wird, nur das diese zur überprüfung dient.

Gruß
Dottakopf
Rechtschreibfehler gelten der allgemeinen Belustigung!

Dottakopf

BeitragDi, Nov 30, 2010 19:27
Antworten mit Zitat
Benutzer-Profile anzeigen
und in meiner unendlichen großen großzügigkeit präsentiere ich dir hier einen lauffähigen code.
Lade es in dein BB... schau dir an was die Tile map macht, und was der Besetzt arry. Spiel mit den Map daten rum und sehe was passiert... verstehe es.


hier der lauffähige code:
Code: [AUSKLAPPEN]


Graphics 800,600,16,2
SetBuffer BackBuffer()
timer = CreateTimer(60)


;globals
Global hero_x = 2
Global hero_y = 2




;arry
Dim tile_map(20,20) ;tile map lesen
For y = 0 To 11
   For x = 0 To 11
      Read tile_map(x,y)
   Next
Next


Dim tile_mapbesetzt(20,20) ;Besetzt arry wird über die tile map gelegt
For y = 0 To 11
   For x = 0 To 11
      Read tile_mapbesetzt(x,y)
   Next
Next



;//////////////////////////////////////////////////// MAIN LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Repeat
Cls


      draw_map()
      update_hero()


WaitTimer(timer)
Flip
Until KeyHit(1)
;//////////////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\




Function update_hero()

     
      If KeyHit(205) And tile_mapbesetzt(hero_x+1,hero_y)=0 Then ;rechts
            tile_mapbesetzt(hero_x,hero_y)=0;feld unter spieler wird als nicht besetzt gekennzeichnet
            hero_x = hero_x +1              ;spieler nach rechts bewegen
            tile_mapbesetzt(hero_x,hero_y)=1;Aktuelle spielerpostion bzw. tile unter spieler wird als "besetzt" markiert
      End If



      If KeyHit(203) And tile_mapbesetzt(hero_x-1,hero_y)=0 Then ;links
            tile_mapbesetzt(hero_x,hero_y)=0
            hero_x = hero_x -1
            tile_mapbesetzt(hero_x,hero_y)=1
      End If




      If KeyHit(200) And tile_mapbesetzt(hero_x,hero_y-1)=0 Then ;oben
            tile_mapbesetzt(hero_x,hero_y)=0
            hero_y = hero_y -1
            tile_mapbesetzt(hero_x,hero_y)=1
      End If



      If KeyHit(208) And tile_mapbesetzt(hero_x,hero_y+1)=0 Then ;unten
            tile_mapbesetzt(hero_x,hero_y)=0
            hero_y = hero_y +1
            tile_mapbesetzt(hero_x,hero_y)=1
      End If


       

         
         ;hero malen
         Color 0,0,255:Rect hero_x*32,hero_y*32,31,31,1

End Function
;----------------------------------------------------------------------------------------------------------------------------



Function draw_map()
   Color 200,200,200
   For x = 0 To 11
      For y = 0 To 11
       Color 255,255,255
         If tile_map(x,y)<>0 Then Rect x*32,y*32,32,32,tile_map(x,y) ;NUR TILES Malen
       Color 255,0,0
       If tile_mapbesetzt(x,y)<>0 Then Rect x*32,y*32,32,32,0     ;Aus debug zwecken die Besetz map malen
      Next
   Next
End Function
;----------------------------------------------------------------------------------------------------------------------------


;das level
.level
Data 1,1,1,1,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,1,0,0,1,0,0,0,1
Data 1,0,0,0,0,1,1,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,1,0,1
Data 1,0,0,1,1,1,0,0,0,1,1,1
Data 1,0,0,0,0,1,0,0,0,1,0,1
Data 1,0,0,0,0,1,0,0,0,0,0,1
Data 1,1,1,1,1,1,1,1,1,1,1,1


;Die Tile_mapBesetzt  "map / Layer "...
.kollision
Data 1,1,1,1,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,1,0,0,1,0,0,0,1
Data 1,0,0,0,0,1,1,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,1,0,1
Data 1,0,0,1,1,1,0,0,0,1,1,1
Data 1,0,0,0,0,1,0,0,0,1,0,1
Data 1,0,0,0,0,1,0,0,0,0,0,1
Data 1,1,1,1,1,1,1,1,1,1,1,1




Gruß
Dottakopf
Rechtschreibfehler gelten der allgemeinen Belustigung!

Raiden93

BeitragDi, Nov 30, 2010 19:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Ahhhh jetzt habe ich es glaub gecheckt Razz also mein map(x,y) dient nur dafür das die Tiles gezeichnet wird. und map_besetzt(SpielerX,SpielerY) ist für die ganzen Kollisionen und solche Sachen zuständig und deswegen wird map_besetzt auch in Verbindung mit Type gebracht.

Endlich mal jemand der es schön erklärt (Daumen Hoch).

Dottakopf

BeitragDi, Nov 30, 2010 19:55
Antworten mit Zitat
Benutzer-Profile anzeigen
ja der type bekommt halt auch sonen "index" in dem Besetzt arry.

drum meinte ich ja am anfang
tile_mapbesetzt(x,y) = 1 ; ist der Spieler
tile_mapbesetzt(x,y) = 2 ; eine Wand Harte Kollision
tile_mapbesetzt(x,y) = 3 ; ein Type genauer ein felsbrocken
usw...

aber nicht auf der Tile map direkt rumhacken ! das ist vielleicht schneller aber meiner meinung nach unsauber.
Rechtschreibfehler gelten der allgemeinen Belustigung!

Raiden93

BeitragDi, Nov 30, 2010 20:13
Antworten mit Zitat
Benutzer-Profile anzeigen
okay, dann hätte ich noch eine kleine Frage.
Bei deinem Beispiel ist ganz unter Level mit einem Punkt geschrieben was hat das zu bedeuten?
(.level )

Dottakopf

BeitragDi, Nov 30, 2010 20:17
Antworten mit Zitat
Benutzer-Profile anzeigen
uff.. soweit ich weis ist das eine Sprungmarke mit der du auf einen codeteil in deinem source verweist.

siehe BlitzBasic: [AUSKLAPPEN]
Restore


ist ein kleiner trick um die maps nicht wie mit einem Map editor in eine extra datei zu schreiben.
Des ganze zeug kannst du löschen und ganz normal mit deinem Map editor arbeiten.

ist nur zu demonstration gedacht.
Rechtschreibfehler gelten der allgemeinen Belustigung!

Raiden93

BeitragDi, Nov 30, 2010 20:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay werde ich machen aber vorher Experimentiere ich noch mit deinem Beispiel rum^^.

Raiden93

BeitragDi, Nov 30, 2010 21:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe es jetzt eingebaut aber es scheint mir das gleiche zu sein nur das ich jetzt jeden Vorgang 2 mal machen muss.Oder habe ich das doch Falsch verstanden den das Diamanten Einsammeln Funktioniert nur noch so:
Code: [AUSKLAPPEN]
Function Diamanten_einsammeln()
   If map_Kollision(SpielerX,SpielerY) = 2
      map_Kollision(SpielerX,SpielerY) = 1
      map(SpielerX,SpielerY) = 1
      diamonds_left = diamonds_left -1
   End If
   Text 10,10,+diamonds_left
End Function

Belion

BeitragDi, Nov 30, 2010 23:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Jemand eine Ahnung was wir falsch machen?

PSY

BeitragMi, Dez 01, 2010 1:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Hiho,

also erstmal hacke ich direkt auf der Tilemap rum bei meinem Boulder Dash Clone. Das ist sogar sehr sauber und auch viel unkomplizierter. In der Tilemap steht ja eben drin um was fuer ein Tile es sich handelt. Warum sollte ich da noch n Array drueberlegen? Macht das ganze nur unuebersichtlicher und unnoetig kompliziert.

Das Diamantensammeln hab ich uebrigens direkt bei der Tastenabfrage drin. Ganz grob (fehlen natuerlich noch jede Menge Abfragen, aber das kommt sowieso alles nach und nach....)

BlitzBasic: [AUSKLAPPEN]

If KeyDown(rechts)
If level(px+1,py)=diamant
moving(px,py)=rechts ; das bedeutet das das feld px,py sich nach rechts bewegt. braucht man zum scrollen und fuer diverse abfragen
diamanten=diamanten+1
EndIf
EndIf


L8er,
PSY
PSY LABS Games
Coders don't die, they just gosub without return

Gehe zu Seite 1, 2, 3  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group