Problem beim anzeigen von Sprites

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Defmaster
Beiträge: 130
Registriert: 26.12.2004 21:38
Kontaktdaten:

Problem beim anzeigen von Sprites

Beitrag von Defmaster »

So hier erstmal der code:

Bin anfänger und übe mich gerade im 2D.

Code: Alles auswählen

InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(640,480,16,"Test")

LoadSprite(spieler,"test.bmp",0)
LoadSprite(block1,"test2.bmp",0)

x = 0
y = 0
block1_x = 320
block1_y = 240

Repeat
ExamineKeyboard()
ExamineMouse()
ClearScreen(0,255,0)


If KeyboardPushed(#Pb_Key_Down)
  y=y+5
ElseIf KeyboardPushed(#Pb_Key_Up)
  y=y-5
ElseIf KeyboardPushed(#Pb_Key_Left)
  x=x-5
ElseIf KeyboardPushed(#Pb_Key_Right)
  x=x+5
EndIf 

DisplaySprite(block1,block1_x,block1_y)
DisplayTransparentSprite(spieler,x,y)

FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) 
So wenn ich nun das ding starte wird für beide angezeigten sprites.
Das Bild Block1 genommen. Dabei sage ich ihm doch das er spieler zeichen soll und den anderen block1.

Muss ich da noch etwas mit dem Buffer'n machen oder wie?
Mag vielleicht ne billige anfänger frage sein aber ich bin noch anfänger
Benutzeravatar
bluejoke
Beiträge: 1244
Registriert: 08.09.2004 16:33
Kontaktdaten:

Beitrag von bluejoke »

ganz einfach, der Fehler ist schon bei LoadSprite.
Du vergibst beides mal die ID 0, weil spieler und block1 keinen Wert haben.

mach

Code: Alles auswählen

spieler=1
block1=2

LoadSprite(spieler ,"test.bmp",0)
LoadSprite(block1,"test2.bmp",0) 
oder sowas ähnliches. Sinnvoller ist aber die Verwendung von Konstanten, die du z.B. mit Enumeration durchnummerierst...

Simon
Ich bin Ausländer - fast überall
Windows XP Pro SP2 - PB 4.00
Defmaster
Beiträge: 130
Registriert: 26.12.2004 21:38
Kontaktdaten:

Beitrag von Defmaster »

Oh super danke.

Da bildet sich bei mir noch ne Frage ich will mich mal an nem ganz simplen Maze spiel wagen nun Collision klappt auch ganz gut mit wegstoßung nur bei
SpriteCollision() muss man die x & y werte von beiden eingeben. Nun möcht ich ja nich nur ein block setzen sondern mehrere kann man da irgendwie etwas machen wie das er überprüft ob er mit dem Objekt Block collidiert?
Ich habe keine Lust für jeden Block da ne Colli abfrage zu machen.

Plz help
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Ich verwende da nie SpriteCollision(), sondern ich mach es folgendermaßen:

Ich geh mal davon aus, Du hast für Dein Labyrinth ein Array, z.B.
Block(50,30) oder so in der Art. Wenn ein Element Deines Arrays nun den Wert 1 hat, ist dort eine Mauer, wenn Wert 0, keine Mauer.

Also würd ich jetzt z.B. einfach überprüfen, wenn der Spieler z.B. nach links geht, ob er in eine Mauer läuft. Nehmen wir an, Dein Spieler hat die Koordinaten plx und ply, und ein Block ist 30x30 Pixel breit, dann folgendermaßen:

Code: Alles auswählen

If Block(int((plx-1)/30), int((ply)/30))=0
  plx=plx-1
EndIf
Das wäre jetzt der Code fürs nach-links-laufen. Ich hoffe Du verstehst das in den Klammern, weil ich grad selbst nicht weiß, wie ich das am besten erklären soll ;) aber wenn nicht, dann werd ich mich schon drum bemühen, Dir das verständlich zu machen ;)
Defmaster
Beiträge: 130
Registriert: 26.12.2004 21:38
Kontaktdaten:

Beitrag von Defmaster »

Jo naja ich weiß net genau wie ich dass mit dem array machen soll.
Das mit den 30 kann ich mir denken wegen der Pixelanzahl vom Spieler oder vom Block.
Wäre nett wenn du mir etwas ausführliches posten könntest :)
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Okay also ich werd's mal versuchen ;)

Ich seh eh grad, daß ich in meinem Code-Schnipsel 'nen Fehler gemacht hab. Aber egal, ich erklär's jetzt mal.

Ein Array mußt Du Dir vorstellen wie eine Tabelle. Idealerweise stellen wir uns Dein Labyrinth mal wie ein Schachbrett vor, also eine Tabelle mit einer bestimmten Spalten- und Zeilenanzahl.
Dafür definieren wir ganz am Anfang des Programms (nicht innerhalb einer Procedure) folgendes:

Dim Labyrinth.b(100,60)

Dein Labyrinth besteht nun also aus 100 Spalten und 60 Zeilen, wenn man sich das mal so vorstellen will.
Nun speicherst Du einfach überall dort, wo 'ne Mauer stehen soll, eine 1 z.B.
Das machst Du am besten, indem Du diese Daten aus einer Datei lädst.

Jetzt brauchst Du nur fragen, wenn einer nach links läuft:
Ist in dem Feld, das links von dem Feld liegt, auf dem der Spieler sich gerade befindet, eine Mauer? Wenn nicht, dann darf der Spieler sich nach links bewegen.

Noch was wichtiges:
Wenn Deine Figur nicht kästchenweise laufen soll, sondern pixelweise, und Deine Kästchen 30 Pixel breit sind, dann befindet sich der Spieler, wenn er im 5. Kästchen von links ist, natürlich 5*30=150 Pixel von links. Also steht in Deiner Variable plx die Zahl 150. Es kann aber auch sein, daß er nicht genau auf 150 ist, sondern vielleicht auf 167, was aber auch noch in diesem Kästchen wäre.
Deshalb teilst Du die plx durch 30, schreibst das aber in die int()-Funktion, die dann einfach alles nach dem Komma abschneidet. Somit käme bei 167/30 = 5,57 raus, durch das int() allerdings nur eine 5. Somit hätten wir wieder unser 5. Kästchen von links.

Nun müssen wir also das 4. Kästchen von links überprüfen, wenn der Spieler im 5. ist und nach links laufen will. Allerdings brauchen wir das ja erst tun, wenn er genau am Rand des Kästchens ist, also erst bei Position 150 und nicht z.B. 167.
Ob der Spieler sich dort befindet, prüfen wir einfach, indem wir int(plx/30) mit plx/30 (ohne int()) vergleichen. Es gibt auch noch eine andere Möglichkeit, die erklär ich später.

Jedenfalls muß der richtige Code erstmal so aussehen:

Code: Alles auswählen

If int(plx/30)=plx/30
  If Labyrinth((plx/30)-1, ply/30)=0
    plx=plx-1
  EndIf
EndIf
Erklärung: Wenn wir also genau auf dem Kästchen sind, und es somit relevant wird, ob wir nach links können, wird überprüft, ob in unserem Labyrinth ein Kästchen weiter links eine Mauer ist. Wenn nicht (=0), dann darf die Figur ein Pixel weiter nach links.

Das Kästchen wird so überprüft:
Der Spieler befindet sich ja an Position plx, aber um die Nummer des Kästchens rauszufinden, teilen wir einfach wieder durch 30. Das gleiche machen wir auch mit ply. Bei plx müssen wir allerdings noch 1 abziehen, denn wir wollen ja das Kästchen, das sich eine Position weiter links befindet, überprüfen.

Ich hoffe mal, das ist einigermaßen verständlich. Natürlich kann das noch komplizierter werden, denn Du willst ja auch die Kästchen rechts, oben und unten vergleichen, und manchmal ist es auch nötig, z.B. das oben UND das rechts gleichzeitig zu überprüfen, aber ich denk mal, das wirst Du dann schon hinkriegen. Notfalls mach erstmal ein Spiel, wo der Spieler immer gleich um 30 Pixel läuft (also Kästchenbreite), das ist etwas einfacher.

Noch was zu dem Vergleich (die bessere Möglichkeit):
Du kannst auch einfach plx durch 30 teilen und schauen, ob ein Rest übrig bleibt. Das funktioniert mit dem Modulo-Operator (dargestellt durch ein Prozent-Zeichen).

Wenn also plx % 30 = 0 ergibt, heißt das, es gibt keinen Rest, sprich, wir befinden uns genau auf dem Kästchen.

Also könnte der Code auch so lauten:

Code: Alles auswählen

If plx % 30 = 0
  If Labyrinth((plx/30)-1, ply/30)=0
    plx=plx-1
  EndIf
EndIf
Ich hoffe mal, das war jetzt alles zu kapieren ;)
Defmaster
Beiträge: 130
Registriert: 26.12.2004 21:38
Kontaktdaten:

Beitrag von Defmaster »

Jo danke erstmal das mit das Mit nem Array macht habe ich schonma von BB gesehen nur wußte ich nicht wie man es in PB verwendet.
Auch was ein Array ist weiß ich gut ;)
Ich danke dir nochmals für die erklärung und werde diese Testen sobald ich mein anderes Prog fertig habe.
Antworten