Problem mit Erzeugung mehrerer Entities
Übersicht

ZaRaKBetreff: Problem mit Erzeugung mehrerer Entities |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hi,
ich möchte ein kleines Weltraumspiel schreiben, in dem es darum geht Raumschiffe zu bauen und Planeten zu erobern. Mein Problem ist, dass ich aktuell jeden Planeten einzeln erstelle und anspreche, was ggfl. später bei größeren Karten mit mehr Planeten umständlich werden könnte. Kann ich per Schleife irgendwie eine gewisse Anzahl von Planeten erzeugen die auch separat ansprechbar sind? Und was mir auch aufgefallen ist, nach mehrmaligem hin und her schicken der Raumschiffe, bleibt das Programm stehen, woran kann das liegen? Linksklick auf ersten Planeten = Planet auswählen Rechtsklick auf zweiten Planeten = Raumschiffe entsenden Schonmal vielen Dank im voraus! Code: [AUSKLAPPEN] Graphics3D 800,600
SetBuffer BackBuffer() Global auswahl=0,klick=0,flotte=0,kollision=False cam=CreateCamera() CameraViewport cam,0,0,800,600 ;licht, start, ziel, schiffe light=CreateLight() start=CreateCube() ScaleMesh start,.01,.01,.01 ziel=CreateCube() ScaleMesh ziel,.01,.01,.01 schiffe=CreateCone() RotateMesh schiffe,90,0,0 ScaleEntity schiffe,.2,.2,.2 ;planeten planet1=CreateSphere() PositionEntity planet1,-5,0,10 EntityPickMode planet1,2 planet2=CreateSphere() PositionEntity planet2,5,0,10 EntityPickMode planet2,2 ;baumenü Global menu=CreateSprite() RotateEntity menu,0,0,90 While Not KeyHit(1) TurnEntity planet1,.1,.2,.3 TurnEntity planet2,.1,.1,.1 If MouseHit(1) Then klick=1 CameraPick(cam,MouseX(),MouseY()) If MouseHit(2) Then klick=2 CameraPick(cam,MouseX(),MouseY()) ;planet 1 auswählen If Not flotte=1 If auswahl=0 And klick=1 If PickedEntity() Baumenue() PositionEntity start, PickedX(),PickedY(),PickedZ()+.1 EntityColor PickedEntity(),255,0,0 auswahl=1 EndIf EndIf EndIf ;planet 2 auswhählen If auswahl=1 And klick=2 If PickedEntity() PositionEntity ziel, PickedX(),PickedY(),PickedZ()+.1 PositionEntity schiffe,EntityX(start),EntityY(start),EntityZ(start) EntityColor PickedEntity(),0,255,0 ShowEntity schiffe auswahl=0 klick=0 EntityColor PickedEntity(),0,255,0 flotte=1 EndIf EndIf ;flotte schicken If flotte=1 If kollision=False vx#=EntityX(ziel)-EntityX(schiffe) vy#=EntityY(ziel)-EntityY(schiffe) vz#=EntityZ(ziel)-EntityZ(schiffe) AlignToVector(schiffe,vx#,vy#,vz#,3,1) MoveEntity schiffe,0.0,0.0,0.04 ;flotte erreicht ziel If EntityDistance(ziel,schiffe)<0.1 kollision=True flotte=0 HideEntity schiffe EndIf EndIf kollision=False EndIf UpdateWorld RenderWorld Text 0,0,"klick: "+klick Text 0,15,"auswahl: "+auswahl Text 0,30,"vx: "+vx# Text 0,45,"vy: "+vy# Text 0,60,"flotte: "+flotte Text 0,75,"menü x: "+EntityX(menu) Text 0,90,"menü y: "+EntityY(menu) Flip Wend End Function Baumenue() PositionEntity menu,EntityX(PickedEntity()),EntityY(PickedEntity())+1.5,EntityZ(PickedEntity()) ScaleSprite menu,1,.5 End Function |
||
![]() |
ToeB |
![]() Antworten mit Zitat ![]() |
---|---|---|
Da helfen Types![]() Einfach die Planeten unter einem Type zusammen fassen, dort die benötigten Variablen (Field ![]() Am besten suchst du dir da mal Tutorials zu raus! mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
ZaRaK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich hab das ganze jetzt mal so versucht, allerdings werden keine Spheres erzeugt.
Woran kann das liegen? Meiner logik nach habe ich dem Type planet die leeren werte px,py und pz gegeben. Diese werden in der For schleife mit werten gefüllt, also Koordinaten zugewiesen und in der Function anschließend an den entsprechenden Koordinaten erstellt. Was hab ich hierbei nicht begriffen? Type liegt ganz oben im Code. Die For Schleife vor While not Keyhit(1). Die Function am Ende des Codes. Die Function Planeten() wird nach While not Keyhit(1) aufgerufen. Code: [AUSKLAPPEN] Type planet
Field px# Field py# Field pz# End Type For i=0 To 2 p.planet=New planet p\px#=Rnd(10) p\py#=Rnd(10) p\pz#=10 Next Function Planeten() For p.planet=Each planet CreateSphere() Next End Function |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich hab leider nicht viel ahnung von BB, aber was ich so lese ist das schon richtig.
Allerdings: Die Sphere solltest du direkt als Field mit ins Type setzen. Ausserdem fehlt eine positionierung - werden sie vielleicht erzeugt und landen alle an 0,0,0 ? |
||
ZaRaK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Die Sphere direkt als Field zu deklarieren geht, glaube ich, nicht.
Zumindest wüsste ich nicht, wie ich dieses Field dann abrufen könnte. Die Positionierung, also die Koordinaten, werden in der For Schleife mir Rnd(10) deklariert (wenn ich das so richtig verstanden habe). Jede Sphere müsste/sollte auf der X und Y Achse also irgendwo zwischen 0 und 10 liegen. Die Kamera liegt über 0,0. Würden die Spheres dort landen, würde ich das sehen, daran kann es also nicht liegen. Die Koordinaten lasse ich mir auch als Text anzeigen, welche aber unverändert bei 0 stehen. |
||
mDave |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Tag,
Du müsstest die Spheren ja dann erstmal irgendwo positionieren, im Moment befinden sie sich an der Position 0,0,0 ;kein Wunder, dass Du sie nicht sehen kannst. Der Spaß könnte so aussehen: Code: [AUSKLAPPEN] Type planet
Field px# Field py# Field pz# Field mesh% End Type For i=0 To 2 p.planet=New planet p\px#=Rnd(10) p\py#=Rnd(10) p\pz#=10 p\mesh%=CreateSphere() PositionEntity p\mesh%,p\px#,p\py#,p\pz# Next Die Funktion Planeten() solltest du übrigens nicht in der Hauptschleife lassen, denn so werden ständig weitere Spheres gemacht und das Programm wird somit nach einiger Zeit immer langsamer. |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nunjut, da muss jemand drübergucken ,der mehr ahnung von Types unter BB hat.
Warum es allerdings nicht gehen soll, eine sphere als field abzulegen, ist mir schleierhaft. BlitzBasic: [AUSKLAPPEN] Type planet Wie gesagt, ich weiß nur ein bisschen was über Types in bb, durch andere quellcodes. Selbst habe ich nie welche benutzt (bin vorher auf blitzmax umgestiegen ![]() Aber so oder so ähnlich sollte es funktionieren. EDIT: Loool ![]() Da war ich wohl n tucken zu langsam. Aber das ich dann noch einen fast identischen code daraus forme, wie mDave das getan hat, lässt mich laut lachen^^ |
||
ZaRaK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ach so geht das.
Vielen Dank! ![]() Jetz klappt es wunderbar. Mein Denkfehler war wohl der, dass ich dachte, man könne die Sphere nur in der Function erzeugen. |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Erzeugen geht immer.
Grade für viele planeten ist es allerdings wichtig, das du dir das Mesh hälst. Ein "Mesh" unter BB wird, wie vieles andere auch, als integer (bzw integer-pointer?) übergeben. DH mit dem field mesh% kannst du dir das Mesh "greifbar" halten. Das wird grade dann wichtig, wenn du Kollisionen genauer unter die Lupe nehmen möchtest, oder auch zb einen Mond um einen Planten kreisen lassen willst. Dann mal viel glück beim einbauen =) |
||
ZaRaK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Soweit funktioniet alles ![]() Danke nochmal für die Hilfe! Kamerasteuerung mit WASD Zoomen mit Mausrad Linksklick = Startplanet wählen Rechtsklick = Zielplanet wählen Falls ihr es euch nochmal ansehen wollt, hier der Code: Code: [AUSKLAPPEN] Type planet
Field px# Field py# Field pz# Field mesh% End Type Graphics3D 800,600 SetBuffer BackBuffer() Global auswahl=0,klick=0,flotte=0,kollision=False,zoomen=0,zentrum#=50,anzahl=10 cam=CreateCamera() CameraViewport cam,0,0,800,600 PositionEntity cam,zentrum#/2,zentrum#/2,-10 ;licht, start, ziel, schiffe light=CreateLight() start=CreateCube() ScaleMesh start,.01,.01,.01 PositionEntity start,0,0,-25 ziel=CreateCube() ScaleMesh ziel,.01,.01,.01 PositionEntity ziel,0,0,-25 schiffe=CreateCone() RotateMesh schiffe,90,0,0 PositionEntity schiffe,0,0,-25 ScaleEntity schiffe,.2,.2,.2 ;baumenü Global menu=CreateSprite() RotateEntity menu,0,0,90 PositionEntity menu,0,0,-25 For i=1 To anzahl p.planet=New planet p\px#=Rnd(zentrum#) p\py#=Rnd(zentrum#) p\pz#=10 p\mesh%=CreateSphere() PositionEntity p\mesh%,p\px#,p\py#,p\pz# EntityPickMode p\mesh%,2 Next While Not KeyHit(1) ;kamera, wasd If KeyDown(17) Then MoveEntity cam,0,.1*-(EntityZ(cam)/10),0 If KeyDown(31) Then MoveEntity cam,0,-.1*-(EntityZ(cam)/10),0 If KeyDown(32) Then MoveEntity cam,.1*-(EntityZ(cam)/10),0,0 If KeyDown(30) Then MoveEntity cam,-.1*-(EntityZ(cam)/10),0,0 ;kamera, zoom mausrad=MouseZSpeed() If mausrad<>0 Then MoveEntity(cam,0,0,mausrad*2) If EntityZ(cam)<=-30 PositionEntity cam,EntityX(cam),EntityY(cam),-30 EndIf If EntityZ(cam)>=-2 PositionEntity cam,EntityX(cam),EntityY(cam),-2 EndIf ;klicken If MouseHit(1) Then klick=1 CameraPick(cam,MouseX(),MouseY()) If MouseHit(2) Then klick=2 CameraPick(cam,MouseX(),MouseY()) ;planet START auswählen If Not flotte=1 If auswahl=0 And klick=1 If PickedEntity() Baumenue() PositionEntity start, PickedX(),PickedY(),PickedZ()+.1 EntityColor PickedEntity(),255,0,0 auswahl=1 EndIf EndIf EndIf ;planet ZIEL auswhählen If auswahl=1 And klick=2 If PickedEntity() PositionEntity ziel, PickedX(),PickedY(),PickedZ()+.1 PositionEntity schiffe,EntityX(start),EntityY(start),EntityZ(start) EntityColor PickedEntity(),0,255,0 ShowEntity schiffe auswahl=0 klick=0 EntityColor PickedEntity(),0,255,0 flotte=1 EndIf EndIf ;flotte schicken If flotte=1 If kollision=False vx#=EntityX(ziel)-EntityX(schiffe) vy#=EntityY(ziel)-EntityY(schiffe) vz#=EntityZ(ziel)-EntityZ(schiffe) AlignToVector(schiffe,vx#,vy#,vz#,3,1) MoveEntity schiffe,0.0,0.0,0.04 ;flotte erreicht ziel If EntityDistance(ziel,schiffe)<0.1 kollision=True flotte=0 HideEntity schiffe EndIf EndIf kollision=False EndIf UpdateWorld RenderWorld Text 0,0,"klick: "+klick Text 0,15,"auswahl: "+auswahl Text 0,30,"vx: "+vx# Text 0,45,"vy: "+vy# Text 0,60,"flotte: "+flotte Text 0,75,"menü x: "+EntityX(menu) Text 0,90,"menü y: "+EntityY(menu) Text 0,105,"cam x: "+EntityX(cam) Text 0,120,"cam y: "+EntityY(cam) Text 0,135,"cam z: "+EntityZ(cam) Flip Wend End Function Baumenue() PositionEntity menu,EntityX(PickedEntity()),EntityY(PickedEntity())+1.5,EntityZ(PickedEntity()) ScaleSprite menu,1,.5 End Function |
||
![]() |
skey-z |
![]() Antworten mit Zitat ![]() |
---|---|---|
Was mir noch aufgefallen ist, du speicherst eigentlich nur Mausrad in einer Variablen,
das gleiche solltest du auch mit allen Tasten und Maustasten machen, die du benötigst. if mousehit(1) Then klick=1 if mousehit(2) then klick=2 funktioniert zwar auch und geht schon in die richtige Richtung, aber du musst dann auch in jedem Schleifendurchlauf klick wieder auf 0 setzen. Hier ist es einfacher: md1 = mousehit(1) md2 = mousehit(2) zu schreiben, und dann nicht auf 'if klick=zahl', sondern einfach nur auf 'if md1 then' bzw 'if md2 then' zu prüfen. genauso bei MouseX() und Mousey(). Spätestens wenn du ein zweites mal die Funktion Mousehit(1) aufrufst und diese im gleichen Schleifendurchlauf schon geprüft wurde, wird ein falsches Ergebnis geliefert, da der Puffer bei jedem Aufruf geleert wird. Bei MouseX() und MouseY() ist es auch schneller, da die Funktion nur einmal aufgerufen werden muss und dann dauerhaft in einem Schleifendurchlauf zur Verfügung steht, als wenn du jedes mal die Funktion an sich aufrufst. OK, zugegeben ist es jetzt vielleicht nicht so einfach beschrieben, aber ich muss leider gleich wieder zur Arbeit, schaue dir einfach mal ein paar Tutorials oder Codes hier im Forum an, da siehst du nochmal in praktischen Beispielen, wie man es umsetzen kann. |
||
Awards:
Coffee's Monatswettbewerb Feb. 08: 1. Platz BAC#57: 2. Platz |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Dann greife ich Ske-Z's intention einmal auf und beschreibe es etwas ausführlicher.
Grundsätzlich sollte man sich benötigte tastenabfragen etc speichern. Dh, einmal am anfang des Mainloops jede Taste / Maustaste / Position abfragen, die du auf jedenfall einmal oder mehrmals im Hauptprogramm (pro schleifendurchlauf//frame) brauchst. BlitzBasic: [AUSKLAPPEN] Global LMB% Zugegeben, das beispiel ist schrott. Aber: Jeder aufruf von MouseDown() etc ist ein sprung den dein Programm macht. Es ist zwar nicht merklich, wenn du es 2-3x aufrufst, aber dennoch ist es ebenso schöner mit variablen zu arbeiten, als auch sicherer. Ske-Z hats richtig gesagt - mehrmaliges aufrufen von MouseHit() etc wird immer null zurückliefern. Es kann ärgerlich sein, wenn man eine neue Funktion testen möchte und diese aus schier unerfindlichem grunde nicht geht - dabei liegt es nur daran, das die abfrage nicht funktioniert hat. PS: Für faule -> aussagekräftige, aber kurze variablennamen sind weniger schreibarbeit ![]() LMB = Left Mouse Button (hit - abfrage) LMD = Left Mouse Button Down (down - abfrage) mX = Mouse X verständlich, aber kürzer wie jedesmal die funktionsnamen zu schreiben ![]() ![]() |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group