Erstes Spiel//unvollständig

Spiele, Demos, Grafikzeug und anderes unterhaltendes.
Benutzeravatar
Milchshake
Beiträge: 166
Registriert: 30.01.2006 17:47
Wohnort: Zwischen dem Sessel und dem Computer

Erstes Spiel//unvollständig

Beitrag von Milchshake »

Hi,
habe mir mal vorgenommen, ein Samus ähnliches Spiel (aber nicht so Komplex usw.) zu Programmieren.
Hier einmal der Downloadlink
http://rapidshare.com/files/68824043/Ju ... e.zip.html
Der Sourcecode liegt bei.
Open for Feed-Back :mrgreen:

Nur da ich mich schon Öfters in Tile-Engines probiert habe,
bräuchte ich eure hilfe.
Wenn ich etwas mit AddElement Aufrufe, kommt es ja unentlich oft
in einer Schleife. (Also es überlappt sich, der Counter schiest in die Höhe, das Programm wird langsamer)
Wie kann ich das Verhindern, ohne sowas wie ClearList() zu benutzen?

lg Milchshake
Hab jetzt PB 4.02
Muhahaha!!!!
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Milchshake hat geschrieben:Wenn ich etwas mit AddElement Aufrufe, kommt es ja unentlich oft
in einer Schleife. (Also es überlappt sich, der Counter schiest in die Höhe, das Programm wird langsamer)
Wie kann ich das Verhindern, ohne sowas wie ClearList() zu benutzen?
Kann es grad nicht runterladen, muß laut rapidshare 110 Minuten warten :(

Aber vielleicht kannst Du den Code ja hier posten, aus Deiner Erklärung kann ich mir leider überhaupt nicht vorstellen, worum es bei Dir geht und was genau das Problem ist. Vielleicht kannst Du ja auch einfach nochmal genauer erklären, also den konkreten Sinn und Zweck, wo Du das mit der Liste einsetzt.
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
Milchshake
Beiträge: 166
Registriert: 30.01.2006 17:47
Wohnort: Zwischen dem Sessel und dem Computer

Beitrag von Milchshake »

Erstens:
Tut mir leid wegen dem Dummen Rapidshare, meine HP ist gerade down, hätte es nämlich sonst dort hochgeladen.

Zweitens:
Wenn ich jetzt eine Structur,List und eine Procedure (AddElement(blabalbal)usw.)
erstelle, und dann die Proceture benutze, steig die Linked List (die ich via CountList() ) gezählt habe, in das unentliche, und führt somit zur unspielbarkeit.
Habe ich das jetzt besser erklärt?
Hab jetzt PB 4.02
Muhahaha!!!!
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Ehrlich gesagt nicht - es fehlt nämlich der Grund, weshalb Du das eigentlich tust. Erstellst Du dauernd neue Elemente (z.B. Gegner)? Fügst Du alles, was Du rendern willst, in eine Liste ein? Oder wofür ist die Liste gedacht?

Ohne diese Informationen kann Dir hier wahrscheinlich keiner weiterhelfen ;)
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Wenn ich etwas mit AddElement Aufrufe, kommt es ja unentlich oft in einer Schleife
Du kannst nichts mit AddElement() "aufrufen". Diesen Ausdruck gibt es überhaupt nicht!
Mit AddElement() kannst du höchstens etwas in einer LinkedList speichern. Das meinst du sicherlich.

> steig die Linked List (die ich via CountList() ) gezählt habe, in das unentliche, und führt somit zur unspielbarkeit.
> Habe ich das jetzt besser erklärt?
Leider nein.
Es kommt auf die Art und Weise an, wie der Programmier codet bzw. der Coder programmiert. :lol:

Lange Rede, kurzer Sinn: Alles, was du jemals einer LinkedList hinzufügst, wirst du irgendwann löschen!

Als Beispiel mal die Sache mit den Schüssen: Du musst Schüsse nur so lange berechnen, bis sie außerhalb des Bildschirms sind. Dann kannst du sie mit DeleteElement() doch aus der Liste rausschmeißen, oder etwa nicht? Also steigt deine Anzahl doch nicht ins unendliche. :wink:
Speziell bei der Sache mit den Schüssen kannst du sogar eine Limitierung einbauen, sodass der Spieler nicht mehr als 3 Schüsse auf einmal abfeuern kann:

Code: Alles auswählen

If CountList(schuss()) <= 3
    ; Füge neuen Schuss hinzu
EndIf
Dieser Code erlaubt dem Spieler nicht mehr als 3 Schüsse. Das gibt's bei alten Spielen, wo damals die Computer/Konsolen noch nicht schnell genug waren um sehr viele Schüsse zu verarbetien, denke ich. Ein weiterer Grund ist, dass der Spieler es mit nur 3 Schuss gleichzeitig schwerer hat; dies erhöht den Schwierigkeitsgrad eines Spiels.

Alles, was du nicht mehr brauchst, sofort weg damit, raus aus der LinkedList! Es spielt auch keine Rolle, ob du irgendwie Structures in Kombination mit LinkedLists benutzt oder sonstwas.
Es liegt, wie gesagt an der Art, wie du programmierst, ob dein Spiel spielbar wird oder das Spiel doch eher als Benchmark-Test für deine CPU durchgeht.

Alles klar? :wink:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Milchshake
Beiträge: 166
Registriert: 30.01.2006 17:47
Wohnort: Zwischen dem Sessel und dem Computer

Beitrag von Milchshake »

Also, hier mal der Code:

Code: Alles auswählen

InitSprite()
InitKeyboard()

OpenScreen(1024,768,32," ")

Structure Show
  x.w
  y.w
  Width.w
  Height.w
  Image.w
  SpeedX.w
  SpeedY.w
EndStructure

Global NewList Show.Show()
Procedure AddShow(Sprite, x, y, SpeedX, SpeedY)
  AddElement(Show())           
  Show()\x      = x
  Show()\y      = y
  Show()\Width  = SpriteWidth(Sprite)
  Show()\Height = SpriteHeight(Sprite)
  Show()\Image  = Sprite
  Show()\SpeedX = SpeedX
  Show()\SpeedY = SpeedY
EndProcedure
CreateSprite(1, 64, 64)
StartDrawing(SpriteOutput(1))
  Box(0,  16, 32, 32, RGB(192,192,192))
  Box(32, 16, 32, 32, #Gray)
StopDrawing()

Repeat 
FlipBuffers()
ExamineKeyboard()
ClearScreen(0)

 StartDrawing(ScreenOutput())
 DrawingMode(1)
 DrawText(0,0," List :"+Str(CountList(Show())),#White)
 StopDrawing()
 
AddShow(1,500,500,0,0)

  ResetList(Show())
While NextElement(Show())

If Show()\y < 0        
  DeleteElement(Show())
Else
If Show()\x < 0       
  DeleteElement(Show())
Else
If Show()\x > 1024-Show()\Width
  DeleteElement(Show())
Else
If Show()\y > 760
  DeleteElement(Show())
Else
  DisplayTransparentSprite(Show()\Image, Show()\x, Show()\y)   ; Display the bullet
  
  Show()\y + Show()\SpeedY
  Show()\x + Show()\SpeedX
  EndIf
EndIf
EndIf
EndIf  
Wend

Until KeyboardPushed(#PB_Key_Escape) 
Mein Problem ist noch immer noch das Gleiche
Hab jetzt PB 4.02
Muhahaha!!!!
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Mein Problem ist noch immer noch das Gleiche
Dann erklär es doch bitte mal!

Dein Code fügt pro Schleifendurchlauf ein neues Element rein, und wenn eins den Bildschirm verläßt (was keines tut, da SpeedX und SpeedY beide = 0 sind), würde er sie wieder aus der Liste entfernen. Passiert aber nie.

Das wird Dich ja nun sicherlich kaum überraschen, denn daß Du laufend Elemente hinzufügst, sie aber nicht löscht, wirst Du sicher selbst wissen.

Nun hast Du aber ein Spiel programmiert, und dort scheint es sich wohl um die Schüsse zu handeln. Diese werden auch in einer Liste verwaltet, aber doch rechtzeitig auch wieder gelöscht, wie ich sehe. Du hast ja sogar oben einen Bullet-Zähler, der irgendwann wieder auf 0 geht. Also kann es doch jetzt kein Problem mehr geben, oder nicht? Zumindest verstehe ich nicht, wo genau das Problem liegen soll, daher wäre es doch sinnvoll, wenn Du es einfach nochmal ein wenig genauer erläuterst. Im momentanen Code gibt es kein Problem, und da man es sowieso nie schafft, mehr als 10 Schüsse auf den Bildschirm zu bringen, kann es auch keine Performance-Probleme geben.


///


Ein Tip noch, hat jetzt nix mit dem eigentlichen Problem zu tun. Die "Clipping-Phasen" solltest Du nicht von hand definieren, das ist viel zu umständlich, sondern Du solltest die errechnen. Du hast ja einen Zähler namens ClippingPhase, den solltest Du ausnutzen. Ordne die Bilder in der Bitmap so an, daß sie alle im selben Raster sind (Deinem Code zufolge ist das leider nicht der Fall), und dann multipliziere ClippingPhase mit der Rasterbreite. Und fang bei x=0 an, und nicht bei x=12. Darüber hinaus ist es am besten, wenn Du die Bilder für "nach rechts laufen" alle in der ersten und die Bilder für "nach links laufen" alle in der zweiten Zeile hast (oder auch umgekehrt), weil Du dann auch die Variable für die Laufrichtung zur Berechnung nutzen kannst. Somit ersparst Du Dir hunderte von Zeilen, in denen Du mühselig von Hand alles berechnen mußt.

Hier mal ein Beispiel:
Bild
Es sind jetzt weniger Phasen wie bei Dir, aber das ist wurscht. Zudem wird bei uns die erste, dann die zweite, dann die erste, und dann die dritte angezeigt, aber das ist egal, stell Dir einfach vor, es wären pro Zeile 4 Figuren.

Der Code hierfür wäre dann z.B. sowas in der Art:

Code: Alles auswählen

#LEFT = 0
#RIGHT = 1
#UP = 2
#DOWN = 3
#DEATH = 4

#PLAYER_WIDTH = 20
#PLAYER_HEIGHT = 20

ClippingPhase = (ElapsedMilliSeconds() % 400) / 4

ClipX = ClippingPhase * #PLAYER_WIDTH
ClipY = Player\Direction * #PLAYER_HEIGHT
ClipSprite(Player\Sprite, ClipX, ClipY)
Deutlich kürzer, wie Du siehst ;)
Wichtig ist halt nur, daß Du auch die Richtung irgendwo speicherst. Vielleicht willst Du lieber die Richtung für X und Y getrennt benutzen, kommt halt aufs Spiel drauf an, aber letztendlich ist das Prinzip das selbe. Immer schön alles rechnen, dafür hat man ja auch 'nen "Rechner" ;)
Stell Dir nur mal vor, Du willst auf einmal größere Sprites verwenden. In meinem Fall genügt es, #PLAYER_WIDTH und #PLAYER_HEIGHT anzupassen, sodaß es mit den neuen Grafiken funktioniert. In Deinem Fall müßtest Du aber wieder von Hand die ganzen Werte ändern, was natürlich nicht nur mühsam, sondern auch fehleranfällig ist.
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
Milchshake
Beiträge: 166
Registriert: 30.01.2006 17:47
Wohnort: Zwischen dem Sessel und dem Computer

Beitrag von Milchshake »

Danke, für die Antwort ;)
Und wegen der Idee, ich habe die Sprites nicht selber gemacht (wär schön), desswegen haben diese auch keinen Regelmäßigen abstand, worauf dein Code ja Basiert (soweit ich das richtig verstanden habe)

und ich glaube, das Problem habe ich jetzt auch gelöst, indem ich das so mache:

If Showshow = 0
AddShow(1,500,500,0,0)
AddShow(1,600,500,0,0)
Showshow = 1
EndIf

Dadurch werden die Elemente nur ein mal erstellt, und ich habe keine Probleme mit der List ;)

Für bessere Ideen bin ich immer noch offen.
Hab jetzt PB 4.02
Muhahaha!!!!
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

1. Du hast noch nicht auf meinen Post geantwortet
2. Warum nimmst du für AddShow() eine Prozedur? Nimm doch lieber Macros! Ist schneller und hat den Vorteil dass die LinkedList nicht global gemacht werden muss.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Milchshake
Beiträge: 166
Registriert: 30.01.2006 17:47
Wohnort: Zwischen dem Sessel und dem Computer

Beitrag von Milchshake »

Ich habe mir mal die Macros angeschaut, verstehe aber nicht genau, wie ich
die Macros einbauen soll (kann).
Könntest du mir das netterweise auch mal erklären?
lg Milchshake
Hab jetzt PB 4.02
Muhahaha!!!!
Antworten