Connection

Spiele, Demos, Grafikzeug und anderes unterhaltendes.
teamO
Beiträge: 56
Registriert: 01.03.2010 20:01

Re: Connection

Beitrag von teamO »

echt cool :o
besonders die Leuchteffekte auf der Startseite gefallen mir. Sind die Bahnen irgendwie vorprogrammiert oder werden die jedes mal neu berechnet?

Erinnert mich irgendwie an das Mehrkörperproblem in der Himmelsmechanik. Aber wie schaffst du es, das keiner der körper heraus katapultiert wird?
Würde mich echt interessieren, wie das gelöst ist, da ich mal was ähnliches programmiert habe und da waren dann am ende immer nur 2 oder 3 Körper übrig. Der rest hat irgendwann die Fluchtgeschwindigkeit überschritten...
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Re: Connection

Beitrag von Josef Sniatecki »

Ich glaube STARGATE hat da etwas aus seinem GSP verwendet. :wink: Ich weiß zwar nicht, was er wirklich gemacht hat, aber ich glaube das sind ganz einfache Gravitationsgesetze plus einer zufälligen (aber eingegrenzten) geringen Verschiebung der Körper und des Gravitationsschwerpunktes. Demnach wird alles zur Laufzeit berechnet und keine vordefinierten Bahnen verwendet.

@STARGATE: Wenn ich richtig liege, dann bekomme ich ein virtuelles Eis von dir. :mrgreen:
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Connection

Beitrag von STARGÅTE »

@Josef Sniatecki
Bild

Fast komplett richtig.

Ja ich verwende ein abgeändertes Gravitationsgesetzt, wodurch sich alle 6 Punkte anziehen.
Würden nun alle genau alle 60° positioniert sein, würden sie aufeinander zufliegen und wieder auseinander (kollision außeracht gelassen)
deswegen werden sie leicht verschoben.

Außerdem verwende ich keine 1/r² abhängigkeit, weil die hier einfach zu kurzsreichweitig ist, und dann zum den von teamO angesprochenen Problem führt, dass die Teilchen früher oder später hinaus katapultiert werden.

Ich verwende hier eine 1/Wurzel(r) abhänigkeit.

Ich habs mal auf eine kleine Demo reduziert:

An Anfang kommen ein paar Vektor-Macros die ich in einem Include habe,
weiter unten kommt der eigentliche Kern, dort mit ein paar Kommentaren:

Code: Alles auswählen

InitSprite()

Enumeration
  #Window
EndEnumeration


Structure Vector2D
  x.f
  y.f
EndStructure

Macro Vector2DSub(Vector2D_1, Vector2D_2, ResultVector2D)
  ResultVector2D\x = Vector2D_1\x - Vector2D_2\x : ResultVector2D\y = Vector2D_1\y - Vector2D_2\y
EndMacro
Macro Vector2DLength(Vector2D)
  Sqr( Vector2D\x*Vector2D\x+Vector2D\y*Vector2D\y )
EndMacro
Macro MoveVector2D(Vector2D, MoveVector2D)
  Vector2D\x + MoveVector2D\x
  Vector2D\y + MoveVector2D\y
EndMacro
Procedure NormVector2D(*Vector2D.Vector2D)
  Protected Length.f = Vector2DLength(*Vector2D)
  If Length
    *Vector2D\x / Length
    *Vector2D\y / Length
  Else
    *Vector2D\x = 0
    *Vector2D\y = 0
  EndIf
EndProcedure
Macro RaiseVector2D(Vector2D, Factor)
  Vector2D\x * (Factor)
  Vector2D\y * (Factor)
EndMacro
Macro LengthVector2D(Vector2D, Length)
  NormVector2D(Vector2D)
  RaiseVector2D(Vector2D, Length)
EndMacro
 
 
Structure Photon
 Position.Vector2D
 Velocity.Vector2D
EndStructure
 
Global NewList Photon.Photon() 
 
 
#Anzahl = 6
 

OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 800, 600, "Beispiel", #PB_Window_MinimizeGadget|#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)

RandomSeed(3)
For n = 1 To #Anzahl
 AddElement(Photon())
 With Photon()
  Angle.f = Radian(n*60+Random(30))
  \Position\x = WindowWidth(#Window)/2  + Cos(Angle)*200
  \Position\y = WindowHeight(#Window)/2 + Sin(Angle)*200
 EndWith
Next 
 
Repeat

  Delay(5)
  If WindowEvent() = #PB_Event_CloseWindow : End : EndIf

  Difference.Vector2D
  ForEach Photon() : With Photon()
    *Photon.Photon = Photon()
    While NextElement(Photon())
      ;----------------
      ; Distanzvektor beider Teilchen
      Vector2DSub(\Position, *Photon\Position, Difference)
      ; Abstand beider Teilchen
      Distance.f = Vector2DLength(Difference)
      ; Umwandlung zum Kraftvektor (-5/Wurzel(Abstand))
      LengthVector2D(Difference, -10/Pow(Distance,0.5))
      ; Veränderung der beiden Geschwindigkeiten
      MoveVector2D(\Velocity, Difference)
      MoveVector2D(*Photon\Velocity, -Difference)
      ;----------------
    Wend
    ChangeCurrentElement(Photon(), *Photon)
  EndWith : Next

  ClearScreen(0)

  StartDrawing(ScreenOutput())
    ForEach Photon() : With Photon()
      MoveVector2D(\Position, 0.030*\Velocity)
      Circle(\Position\x, \Position\y, 10, $FFFFFF)
    EndWith : Next 
  StopDrawing()
 
  FlipBuffers()
 
ForEver
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
ullmann
Beiträge: 205
Registriert: 28.10.2005 07:21

Re: Connection

Beitrag von ullmann »

Ich habe mal ein wenig an der kleinen Demo herumgespielt:

- Elementanzahl: 2 - 50
- Elemente zufällig verteilt
- Elemente farbig (schwarz ist möglich, = dunkle Materie?)
- mit Taste Esc erfolgt eine neue zufällige Verteilung

Code: Alles auswählen

; PureBasic 4.51

; Taste Esc: neue Anordnung

InitSprite()
InitKeyboard()

Enumeration
  #Window
EndEnumeration


Structure Vector2D
  x.f
  y.f
EndStructure

Macro Vector2DSub(Vector2D_1, Vector2D_2, ResultVector2D)
  ResultVector2D\x = Vector2D_1\x - Vector2D_2\x : ResultVector2D\y = Vector2D_1\y - Vector2D_2\y
EndMacro
Macro Vector2DLength(Vector2D)
  Sqr( Vector2D\x*Vector2D\x+Vector2D\y*Vector2D\y )
EndMacro
Macro MoveVector2D(Vector2D, MoveVector2D)
  Vector2D\x + MoveVector2D\x
  Vector2D\y + MoveVector2D\y
EndMacro
Procedure NormVector2D(*Vector2D.Vector2D)
  Protected Length.f = Vector2DLength(*Vector2D)
  If Length
    *Vector2D\x / Length
    *Vector2D\y / Length
  Else
    *Vector2D\x = 0
    *Vector2D\y = 0
  EndIf
EndProcedure
Macro RaiseVector2D(Vector2D, Factor)
  Vector2D\x * (Factor)
  Vector2D\y * (Factor)
EndMacro
Macro LengthVector2D(Vector2D, Length)
  NormVector2D(Vector2D)
  RaiseVector2D(Vector2D, Length)
EndMacro


Structure Photon
  Position.Vector2D
  Velocity.Vector2D
  Rot.i
  Gruen.i
  Blau.i
EndStructure

Global NewList Photon.Photon() 

ExamineDesktops()
OpenWindow(#Window, #PB_Ignore, #PB_Ignore, DesktopWidth(0) - 200, DesktopHeight(0) - 200, "Photon", #PB_Window_MinimizeGadget|#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)

Repeat  
  
  ClearList(Photon())
  
  Gruppe = Random(4)
  Select Gruppe
    Case 0
      Anzahl = Random(3)+2
    Case 1
      Anzahl = Random(4)+6
    Case 2
      Anzahl = Random(9)+11
    Case 3
      Anzahl = Random(29)+21
  EndSelect
   
  WeiteX = WindowWidth(#Window)
  WeiteY = WindowHeight(#Window)
  RadiusX = Random(WeiteX/4) + WeiteX/4
  RadiusY = Random(WeiteY/4) + WeiteY/4
    
  For n = 1 To Anzahl
  AddElement(Photon())
  With Photon()
    \Position\x = Random(WindowWidth(#Window))
    \Position\y = Random(WindowHeight(#Window))
    \Rot=Random(255)
    \Gruen=Random(255)
    \Blau=Random(255)
  EndWith
  Next 
  
  Repeat
    
    ClearScreen(0)
    
    Delay(5)
    If WindowEvent() = #PB_Event_CloseWindow : End : EndIf
  
    Difference.Vector2D
    ForEach Photon() : With Photon()
      *Photon.Photon = Photon()
      While NextElement(Photon())
        ;----------------
        ; Distanzvektor beider Teilchen
        Vector2DSub(\Position, *Photon\Position, Difference)
        ; Abstand beider Teilchen
        Distance.f = Vector2DLength(Difference)
        ; Umwandlung zum Kraftvektor (-5/Wurzel(Abstand))
        LengthVector2D(Difference, -10/Pow(Distance,0.5))
        ; Veränderung der beiden Geschwindigkeiten
        MoveVector2D(\Velocity, Difference)
        MoveVector2D(*Photon\Velocity, -Difference)
        ;----------------
      Wend
      ChangeCurrentElement(Photon(), *Photon)
    EndWith : Next
  
    StartDrawing(ScreenOutput())
    
      Plot(1,1,1) ; if ClearScreen(0) does'nt work, this command helps
     
      ForEach Photon() : With Photon()
        MoveVector2D(\Position, 0.030*\Velocity)
        Circle(\Position\x, \Position\y, 10, RGB(\Rot,\Gruen,\Blau))
      EndWith : Next 
    
    StopDrawing()
  
    FlipBuffers()
      
    ExamineKeyboard()
    
  Until KeyboardReleased(#PB_Key_Escape)
  
ForEver
ullmann
Beiträge: 205
Registriert: 28.10.2005 07:21

Re: Connection

Beitrag von ullmann »

Ich habe in obigem Code die Taste M (ClearScreen-Mode) entfernt und dafür einen Plot(1,1,1) Befehl in die
Zeichenschleife eingefügt. Dies hilft, falls ClearScreen nicht funktioniert.
Benutzeravatar
Makke
Beiträge: 156
Registriert: 24.08.2011 18:00
Computerausstattung: AMD Ryzen 7 5700X - AMD Radeon RX 6800 XT - 32 GB DDR4 SDRAM
Wohnort: Ruhrpott
Kontaktdaten:

Re: Connection

Beitrag von Makke »

Toll, das Spiel ist Klasse und die Effekte usw.

wirklich prima.
---
Windows 11 (64 bit)
xperience2003
Beiträge: 965
Registriert: 04.10.2004 18:42
Computerausstattung: Amiga, LinuxMint, Windows7
Wohnort: gotha
Kontaktdaten:

Re: Connection

Beitrag von xperience2003 »

mich haben die effekte jetz nich wirklich umgehauen ^^

Bild
stuerzt uebel ab
amiga rulez...
Rebirth Software
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Connection

Beitrag von STARGÅTE »

Anhand der zwei Rechtecke unten links, müsste es ein Problem mit der Font geben.
Die scheint irgendwie nicht richtig erstellt zu werden.

Kannst du ein paar angaben zu deinem System machen?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
xperience2003
Beiträge: 965
Registriert: 04.10.2004 18:42
Computerausstattung: Amiga, LinuxMint, Windows7
Wohnort: gotha
Kontaktdaten:

Re: Connection

Beitrag von xperience2003 »

winxp sp2
1gb ram
nvidia gforce7300 512mb ram
2x2ghz intel cpu dualcore
dx9c (lib 40 oder so), gl1.4

..das lustige, als ich den screenshot (mit printscreen) gemacht hatte
und ihn in paint pasten wollte, hatte ich deine colorfont

also das fenster geht auf und bleibt sofort stehen
dann kommt das requester, keinerlei sound, keine anims
steht sofort
amiga rulez...
Rebirth Software
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Connection

Beitrag von STARGÅTE »

jo, das mit der Zwischenablage war noch von Debug-Zeiter her drin, hatte ich wohl vergessen zu deaktivieren ...

und bezüglich des bugs: liegt es wohl an meiner SpriteFromImage()-Prozedur.

Kannst du mal folgenden Code bei dir ausführe:
Du müsstest ein großes dunkelblaues Quadrat sehen.

Code: Alles auswählen

Procedure SpriteFromImage(Image, Sprite, x, y, Width, Height, Mode=#Null)
	Protected Row
	Protected ImageHeight = ImageHeight(Image)
	Protected ImageWidth  = ImageWidth(Image)
	Protected *ReadBuffer,  ReadPitch,  ReadFormat 
	Protected *WriteBuffer, WritePitch, WriteFormat 
	StartDrawing(ImageOutput(Image))
	*ReadBuffer = DrawingBuffer()
	ReadPitch = DrawingBufferPitch()
	ReadFormat = DrawingBufferPixelFormat()
	StopDrawing()
	If Sprite = #PB_Any
		Sprite = CreateSprite(#PB_Any, Width, Height, Mode)
	Else
		CreateSprite(Sprite, Width, Height, Mode)
	EndIf
	If x < 0 : x = 0 : EndIf
	If x+Width > ImageWidth : Width = ImageWidth-x : EndIf
	If y < 0 : y = 0 : EndIf
	If y+Height > ImageHeight : Height = ImageHeight-y : EndIf
	StartDrawing(SpriteOutput(Sprite))
	*WriteBuffer = DrawingBuffer()
	WritePitch = DrawingBufferPitch()
	WriteFormat = DrawingBufferPixelFormat()
	If ReadFormat & #PB_PixelFormat_ReversedY XOr WriteFormat & #PB_PixelFormat_ReversedY
		For Row = 0 To Height-1
			CopyMemory(*ReadBuffer+(ImageHeight-1-y-Row)*ReadPitch+x*SizeOf(Long), *WriteBuffer+Row*WritePitch, Width*SizeOf(Long))
		Next
	Else
		For Row = 0 To Height-1
			CopyMemory(*ReadBuffer+(y+Row)*ReadPitch+x*SizeOf(Long), *WriteBuffer+Row*WritePitch, Width*SizeOf(Long))
		Next
	EndIf
	StopDrawing()
	ProcedureReturn Sprite
EndProcedure

InitSprite()
InitSprite3D()

OpenWindow(0, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)

CreateImage(1, 64, 64, 32|#PB_Image_Transparent)
StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_AllChannels)
Box(16, 16, 32, 32, $80FF8000)
StopDrawing()
SpriteFromImage(1, 1, 0, 0, 64, 64, #PB_Sprite_AlphaBlending|#PB_Sprite_Texture)
CreateSprite3D(1, 1)

Repeat
	
	Repeat
		
		Select WindowEvent()
			Case #PB_Event_CloseWindow
				End
			Case #Null
				Break
		EndSelect
		
	ForEver
	
	ClearScreen(0)
	
	If Start3D()
		ZoomSprite3D(1, 512, 512)
		DisplaySprite3D(1, 0, 0)
		Stop3D()
	EndIf
	
	
	FlipBuffers()
	
Until WindowEvent() = #PB_Event_CloseWindow
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten