[Gelöst]Funktionen und Timer

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Dicker Hobbit

Betreff: [Gelöst]Funktionen und Timer

BeitragDi, Feb 28, 2012 17:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo ich bin es mal wieder,

Ich habe ein kleines Problem:
Wenn ich eine Animation in der Hauptschleife durchlaufen lasse, dann funktioniert alles wunderbar,
aber wenn ich sie dann in eine Funktion packe stimmt die Animation nicht mehr.

Danke schon im Vorraus!
BlitzBasic: [AUSKLAPPEN]

If MilliSecs()>spielertimer+500 Then
spielertimer=MilliSecs()
spielerframe=spielerframe+1
If spielerframe>1 Then spielerframe=0
EndIf
DrawImage s\pic, s\x, s\y, spielerframe
  • Zuletzt bearbeitet von Dicker Hobbit am Do, März 08, 2012 14:42, insgesamt einmal bearbeitet

Xeres

Moderator

BeitragDi, Feb 28, 2012 17:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Was bedeutet "stimmt nicht mehr"? Wird vermutlich daran liegen, dass die Variablen nicht Global sind. Wenn du einen Type benutzt, könntest du auch gleich die Timer/Animationsvariablen da hinein verschieben.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Dicker Hobbit

BeitragDi, Feb 28, 2012 17:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Es wird nur kurz das 2. Bild angezeigt und dann sofort wieder gewechselt. Das mein ich mit "stimmt nicht mehr"! Wink

Und danke Problem, gelöst !


Edit: Bei mir ist gerade noch ein Fehler entstanden:
BlitzBasic: [AUSKLAPPEN]

If MilliSecs()>spielertimer+500 Then
spielertimer=MilliSecs()
spielerframe=spielerframe+1
If spielerframe>1 Then spielerframe=0
DrawImage s\pic, s\x, s\y, spielerframe
ElseIf KeyDown(30) Then
DrawImage s\pic, s\x, s\y, 2
ElseIf KeyDown(31) Then
DrawImage s\pic, s\x, s\y, 3
ElseIf KeyDown(32) Then
DrawImage s\pic, s\x, s\y, 4


EndIf

Wie kann ich umgehen das der spielerframe nicht auf 0 gesetzt wird, wenn eine Taste gedrückt wurde ?
(If spielerframe>1 Then spielerframe=0)

Hubsi

BeitragDi, Feb 28, 2012 18:10
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzBasic: [AUSKLAPPEN]
.
.
.
ElseIf KeyDown(32)
DrawImage blabla
Else ; hier
spielerframe=0 ; oder was der framne halt sein soll
EndIf


So, oder hab ich das falsch verstanden?
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...

Dicker Hobbit

BeitragDi, Feb 28, 2012 18:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich denke du hast es bestimmt richtig gemacht, aber ich bekomme es nicht auf mein Problem angewendet! Wink

Mein Code nachdem ich deinen Vorschlag ausprobiert habe :

BlitzBasic: [AUSKLAPPEN]
If MilliSecs()>spielertimer+500 Then 


If KeyDown(30) Then DrawImage s\pic, s\x, s\y, 2
If KeyDown(31) Then DrawImage s\pic, s\x, s\y, 3
If KeyDown(32) Then DrawImage s\pic, s\x, s\y, 4
Else
spielertimer=MilliSecs()
spielerframe=spielerframe+1
If spielerframe>1 Then spielerframe=0
DrawImage s\pic, s\x, s\y, spielerframe
EndIf


Leider bringt dies nicht das gewünschte Ergebnis.
(Manchmal ist der Spieler angezeigt, dann wieder nicht usw.)

Addi

BeitragDi, Feb 28, 2012 18:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Wieviele Frames hat den die Animation
Hab grad ne Idee aber keine IDE
Ich komm in 5 mins wieder

Addi

BeitragDi, Feb 28, 2012 19:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Müsste funktionieren Wink

BlitzBasic: [AUSKLAPPEN]


Global PFrame
Global PFrameMin
Global PFrameMax

Global PFrameTimer = MilliSecs()

Global Walk

Function AnimatePlayer()

;Links
If KeyHit(203) Then
PFrameMin = 0
PFrameMax = 5
PFrame = PFrameMin
End If

;Rechts
If KeyHit(205) Then
PFrameMin = 6
PFrameMax = 11
PFrame = PFrameMin
End If

;Hoch
If KeyHit(200) Then
PFrameMin = 12
PFrameMax = 17
PFrame = PFrameMin
End If

;Runter
If KeyHit(208) Then
PFrameMin = 18
PFrameMax = 23
PFrame = PFrameMin
End If

;Animieren falls Walk True ist
If Walk Then

If MilliSecs() > PFrameTimer+500 Then

If PFrame < PFrameMax+1 Then
PFrame = PFrame+1
Else
PFrame = PFrameMin
End If

PFrameTimer = MilliSecs()

End If

End If

;Spieler malen
DrawImage Player,X,Y,PFrame

End Funtion

 

LordCoder

BeitragDi, Feb 28, 2012 19:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,
1)
Ich vermute, du willst eine Spielfigur in 4 Positionen anzeigen lassen?
Dann musst du aber frames von 0 bis 3 verwenden.. und nicht bis 4:
->

Code: [AUSKLAPPEN]
If KeyDown(32) Then DrawImage s\pic, s\x, s\y, 4

macht nicht viel Sinn, falls du nur 4 Bilder hast.
Edit: Hat sich erledigt.. also hast du mehr bilder und ich es falsch interpretiert.
2)

Allgemein würde ich dir raten, eine globale variable zu definieren, die
die etwas über die Richtung aussagt.
zB: spielerframe
Dann kannst du eine solche funktion machen:
Code: [AUSKLAPPEN]

Global spielerframe

Function math_player()
If KeyDown (30) Then spielerframe = 0 ;links
Elseif Keydown (31) Then spielerframe = 1;runter
Elseif Keydown (32) Then spielerframe = 2 ; rechts
Elseif Keydown (28) Then spielerframe = 3 ; rauf
Else
spielerframe =1 ; runter, wenn keine Taste gedrückt ist.
Endif
End Function

Function draw_player(spielerframe)
DrawImage s\pic, s\x, s\y, spielerframe
End Function ; vielleicht s\pic, s\x, s\y auch in der Function einlesen?

Repeat
math_player()
draw_player(spielerframe)
Flip ;?
WaitTimer (timer)

Forever



Edit: Oder so ähnlich.

Ich denke es ist allgemein besser, den zeichnungs-Code vom Mathematik-Code zu trennen, und dann später beide zusammenfügen. Das mit der Zeit würde ich auch direkt im Mainprogram machen.
Ich habe hier einfach WaitTimer verwendet, und damit deine selber gefundene Möglichkeit ignoriert. Es geht einfach schneller.. Siehe hier.

Hoffe ich konnte dir helfen.. sonst einfach weiterfragen.
3. Platz BCC #60
  • Zuletzt bearbeitet von LordCoder am Di, Feb 28, 2012 20:42, insgesamt 2-mal bearbeitet

Dicker Hobbit

BeitragDi, Feb 28, 2012 19:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe nur 2 Frames um das normale Laufen darzustellen, und die anderen Frames sind jeweils Aktionen die die Figur ausführt!
Mein Problem besteht also darin das, wenn keine Taste gedrückt wurde der Frame 0 und 1 immer "wechseln" sollen.
Wenn aber eine Taste gedrückt wird soll kurz das Laufen durch den entsprechenden Frame ersetzt werden

Ich hoffe das ich meinen Wunsch nun verständlich erklärt habe Wink .

Lg Dicker Hobbit

EDIT: Ich habe insgesamt 5 Bilder (also 0-4) 2 Laufframes und 3 Aktionen

Midimaster

BeitragDi, Feb 28, 2012 20:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Du setzt besser die Zeile mit dem autom. Framewechsel vor die Tastaturabfragen. In den Tastaturabfragen änderst du spielerframe statt zu malen. Und das Malen machst du einmal am Ende. So überschreiben die KeyDowns immer den Wechsel:

BlitzBasic: [AUSKLAPPEN]
Global spielerframe%, spielertimer%
...
If MilliSecs()>spielertimer
spielertimer=MilliSecs()+500
spielerframe=spielerframe+1
If spielerframe>1 Then spielerframe=0
EndIf

If KeyDown(30) Then spielerframe=2
If KeyDown(31) Then spielerframe=3
If KeyDown(32) Then spielerframe=4

DrawImage s\pic, s\x, s\y, spielerframe
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Dicker Hobbit

BeitragDi, Feb 28, 2012 23:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo ich bin es noch mal zu später Stunde!

Mein Problem:
Ich möchte verschiedene Gegner zeichnen und wenn sie zerstört sind sollen neue gezeichnet werden.
Leider steht dann bei mir immer "Image does not exist"

Danke im Vorraus!

BlitzBasic: [AUSKLAPPEN]
Function objektezeichnen()
;alle objekte zeichnen, aber nur wenn nicht schon kollidiert!!

If First fels = Null And First mauer= Null And First zombie= Null Then
For i=1 To level*Rand(1,4)
f.fels= New fels
f\x= Rand(900,900*i)

m.mauer= New mauer
m\x= Rand(900,900*i)

z.zombie = New zombie
z\x= Rand(900,900*i)
Next
EndIf


For f.fels= Each fels

DrawImage f\pic, f\x, f\y
f\x=f\x-level

Next

For z.zombie= Each zombie
DrawImage z\pic, z\x, z\y
z\x=z\x-level

Next

For m.mauer= Each mauer
DrawImage m\pic, m\x, m\y
m\x=m\x-level

Next


End Function




Function kollision()
;jedes objekt auf eine Kollision prüfen !
For z.zombie=Each zombie
If ImagesCollide(s\pic, s\x, s\y, spielerframe, z\pic, z\x, z\y, 0 ) Then
If KeyHit(30) Then
DrawImage z\pic, z\x, z\y, 1
WaitTimer(objtimer)
Delete z.zombie
Else
s\leben=s\leben-1
Delete z.zombie
EndIf
EndIf
Next

For m.mauer =Each mauer
If ImagesCollide(s\pic, s\x, s\y, spielerframe, m\pic, m\x, m\y, 0 ) Then

If KeyDown(32) Then
DrawImage m\pic, m\x, m\y, 1
WaitTimer(objtimer)
Delete m.mauer
Else
s\leben=s\leben-1
Delete m.mauer
EndIf
EndIf
Next

For f.fels=Each fels
If ImagesCollide(s\pic, s\x, s\y, spielerframe, f\pic, f\x, f\y, 0 ) Then

If KeyDown(31) Then
DrawImage f\pic, f\x, f\y, 1
WaitTimer(objtimer)
Delete f.fels
Else
s\leben=s\leben-1
Delete f.fels
EndIf
EndIf
Next




End Function

Midimaster

BeitragDi, Feb 28, 2012 23:45
Antworten mit Zitat
Benutzer-Profile anzeigen
was ist denn aus deinem ersten Problem geworden?

zum 2. Problem...

es könnte daran liegen, dass das image nicht existiert... Wink

Du malst ja einige Images, aber den Code, wo man sieht wie sie in die TYPEN reingekommen sein sollen, sendest Du nicht.

Und auch nicht die Stelle, wo man sieht, wie du sie lädst....

Wie soll da jemand helfen können?

Trotzdem mal ein Hilfeversuch:

DEBUGGER an, damit du weißt, in welcher Zeile der Fehler auftritt.

Teste mit DEBUGLOG unmittelbar nach dem Laden eines jeden Bildes, ob es wirklich gefunden wurde.

Teste außerdem unmittelbar nach dem Zuordnen der Bilder zu dem*\pic Fields, ob in den*\pic Field was drin ist.
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Dicker Hobbit

BeitragMi, Feb 29, 2012 15:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Also das erste Problem habe ich durch deine Hilfe gelöst (Danke nochmal Wink )

Ich habe mein 2.Problem anscheinend nicht richtig erläutert!

Die Objekte in den Types zombie, mauer und Fels können gelöscht werden, wenn die entsprechende Taste gedrückt wird und die Objekte mit dem Spieler kollidieren!

Wenn alle Types keine Objekte mehr enthalten (BlitzBasic: [AUSKLAPPEN]
If First fels = Null And First mauer= Null And First zombie= Null  Then 
), dann sollen wieder neue Felsen, Zombies und Mauern außerhalb des Bildschirmes erstellt werden.

BlitzBasic: [AUSKLAPPEN]
For i=1 To level*Rand(1,4)
f.fels= New fels
f\x= Rand(900,900*i)

m.mauer= New mauer
m\x= Rand(900,900*i)

z.zombie = New zombie
z\x= Rand(900,900*i)
Next


Nun erstellt mein Code aber anscheinend keine Gegner mehr wenn, die anderen gelöscht wurden!
Ich habe mal deine Anweisungen befolgt :
- Der Fehler tritt bei der ersten Kollisionsabfrage auf, nachdem die Objekte gelöscht wurden (BlitzBasic: [AUSKLAPPEN]
If ImagesCollide(s\pic, s\x, s\y, spielerframe, z\pic, z\x, z\y, 0 )  Then ...
)
- Das Programm tritt in die If-Abfrage ein und führt die For-Schleife aus

Trotzdem kommt weiter die Fehlermeldung "Image does not exist!"

Xeres

Moderator

BeitragMi, Feb 29, 2012 17:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Du erstellst zwar neue Objekte mit einer X-Koordinate, aber du setzt das Bild nicht.
Ich würde auch empfehlen, die Teile mit "New <Type>" je in eine eigene Funktion zu stecken. Es ist sauberer und du kannst dir sicher sein, dass alle Werte korrekt in der Funktion gesetzt werden, wo auch immer du ein neues Objekt erstellst.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Jamagin

BeitragMi, Feb 29, 2012 18:04
Antworten mit Zitat
Benutzer-Profile anzeigen
@Dicker Hobbit

Kannst du mal den ganzen Code einfügen?

lg. Jamagin
Bevor du etwas neues beginnst, erledige das alte

Dicker Hobbit

BeitragDo, März 01, 2012 15:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Sicher kein Problem Jamagin!

Für Hinweise an meinem Code bin ich sehr dankbar:

BlitzBasic: [AUSKLAPPEN]
Graphics 800, 480, 32, 2
SetBuffer BackBuffer()
SeedRnd MilliSecs()


;Variablen, Types etc.
;Schrift
font=LoadFont("Arial", 22)
SetFont font

Color 0, 100,20
;Types

Type spieler
Field x, y
Field pic
Field leben
End Type

Global s.spieler=New spieler
s\x=100
s\y=280
s\pic=LoadAnimImage("spieler.png", 94.5, 160, 0, 5)
MaskImage s\pic, 255, 0, 255
s\leben=3
Global spielerframe=0

Type fels
Field x, y
Field pic
End Type


f.fels= New fels
f\x=Rnd(600,1500)
f\y=220
f\pic=LoadAnimImage("fels.png", 200, 200, 0, 2)
MaskImage f\pic, 255, 0, 255

Type mauer
Field x, y
Field pic
End Type


m.mauer= New mauer
m\x=Rnd(600,1500)
m\y=220
m\pic=LoadAnimImage("mauer.png", 200, 200, 0, 2)
MaskImage m\pic, 255, 0, 255

Type zombie
Field x, y
Field pic
End Type


z.zombie= New zombie
z\x=Rnd(600,1500)
z\y=220
z\pic=LoadAnimImage("zombie.png", 100, 200, 0, 2)
MaskImage z\pic, 255, 0, 255

Global zombie, mauer, fels

;Types Ende
;Hintergrund
hinterx=0
bbild=LoadImage("hintergrund.png")
;bewegung
Global level=3
;ende bewegung
;timer
algtimer=CreateTimer(60)
Global spielertimer=MilliSecs()
Global objtimer=CreateTimer(1000)



;Hauptschleife

While Not (KeyDown(1))
Cls
info()
DrawImage bbild, hinterx, 0
hinterx=hinterx-level
If hinterx<0 Then DrawImage bbild, hinterx+900, 0
If hinterx<-900 Then hinterx=0
Text 20,20,"Leben: "+ s\leben
Text 500,20, "Level: "+level

spielerzeichnen()
objektezeichnen()
kollision()




WaitTimer(algtimer)
Flip

Wend




; Funktionen

Function spielerzeichnen()

;bewegungsanimation
If MilliSecs()> spielertimer Then
spielertimer= MilliSecs()+500
spielerframe=spielerframe+1
If spielerframe>1 Then spielerframe=0
EndIf

If KeyDown(30) Then spielerframe= 2
If KeyDown(31) Then spielerframe= 3
If KeyDown(32) Then spielerframe= 4



DrawImage s\pic, s\x, s\y, spielerframe





End Function

Function objektezeichnen()
;alle objekte zeichnen, aber nur wenn nicht schon kollidiert!!

For f.fels= Each fels

DrawImage f\pic, f\x, f\y
f\x=f\x-level

Next

For z.zombie= Each zombie
DrawImage z\pic, z\x, z\y
z\x=z\x-level

Next

For m.mauer= Each mauer
DrawImage m\pic, m\x, m\y
m\x=m\x-level

Next

If First fels = Null And First mauer= Null And First zombie= Null Then

For i=1 To level*Rand(1,4)
f.fels= New fels
f\x= Rand(900,900*i)

m.mauer= New mauer
m\x= Rand(900,900*i)

z.zombie = New zombie
z\x= Rand(900,900*i)
Next
EndIf

End Function




Function kollision()
;jedes objekt auf eine Kollision prüfen !
For z.zombie=Each zombie
If ImagesCollide(s\pic, s\x, s\y, spielerframe, z\pic, z\x, z\y, 0 ) Then
If KeyHit(30) Then
DrawImage z\pic, z\x, z\y, 1
WaitTimer(objtimer)
Delete z.zombie
Else
s\leben=s\leben-1
Delete z.zombie
EndIf
EndIf
Next

For m.mauer =Each mauer
If ImagesCollide(s\pic, s\x, s\y, spielerframe, m\pic, m\x, m\y, 0 ) Then

If KeyDown(32) Then
DrawImage m\pic, m\x, m\y, 1
WaitTimer(objtimer)
Delete m.mauer
Else
s\leben=s\leben-1
Delete m.mauer
EndIf
EndIf
Next

For f.fels=Each fels
If ImagesCollide(s\pic, s\x, s\y, spielerframe, f\pic, f\x, f\y, 0 ) Then

If KeyDown(31) Then
DrawImage f\pic, f\x, f\y, 1
WaitTimer(objtimer)
Delete f.fels
Else
s\leben=s\leben-1
Delete f.fels
EndIf
EndIf
Next





End Function

Function info()
If KeyDown(59)

Cls
Text 20, 20, "Taste D --> zerstört Mauer"
Text 20, 70, "Taste A --> zerstört Zombie"
Text 20, 120, "Taste S --> zerstört Fels"
Flip
WaitKey()
EndIf
End Function





@Xeres: Danke, Ich werde es versuchen einzubauen!

Xeres

Moderator

BeitragDo, März 01, 2012 16:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Hatten wir das nicht erst kürzlich?
BlitzBasic: [AUSKLAPPEN]
f\pic=LoadAnimImage("fels.png", 200, 200, 0, 2)

1. Für jedes Objekt das selbe Bild neu zu laden wird sehr schnell den Speicher füllen, bis er überläuft. Benutze dafür eine Globale Bild-Variable und/oder mache eine Zuweisung zu dieser:
BlitzBasic: [AUSKLAPPEN]
Global Fels_img=LoadAnimImage("fels.png", 200, 200, 0, 2)
;[...]
f\pic=Fels_img

2. Da du neuen Objekten gar kein Bild zu weist, gibt es eben die Fehlermeldung...

Das hier ist doof:
BlitzBasic: [AUSKLAPPEN]
Global zombie, mauer, fels

Du benutzt schon Types, die exakt so heißen - die musst du nicht Global machen. Das sorgt höchstens für Verwirrung.


Schön, dass du begonnen hast, alle Variablen im Spieler-Type zu bündeln - nur solltest du es Einheitlich halten und die Globale zu einem Field machen (genauso wie spielertimer):
BlitzBasic: [AUSKLAPPEN]
s\leben=3
Global spielerframe=0


Beim Objekttimer...
BlitzBasic: [AUSKLAPPEN]
DrawImage z\pic, z\x, z\y, 1
WaitTimer(objtimer)
Delete z.zombie
...bin ich mir nicht sicher, was du erreichen willst.

Und zu guter Letzt: Timer+Flip(0).

Wie gesagt noch ein paar mehr Funktionen verwenden, ansonsten ist es ja schon gut strukturiert.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group