![]() |
Der Klassiker Pong & die Winkel...
Hi Leute,
ich versuche mich gerade ein bisschen mit Pong (falls es einner nicht kennt so ne Art Tennis: Ein Ball zwei Schläger... :wall: ) Ist auch eigentlich nicht weiter schwierig aber, ich würde gerne das orginal Pong nachbauen und bei dem war der Schläger in acht Sengmente unterteilt. Je nach Segment prallte der Winkel in einem anderen Winkel ab (45 am Rand und 180 in der Mitte). Das heist aber ich muss mich mal wieder mit Trigonometrie herrum schlagen.... :kotz: *würg* Das ist für mich eins der Themen, die ich noch nie verstanden habe und es vermutlich auch nicht mehr werde... Also mein Ball kommt an, und soll dann vom Schläger abprallen. Der neue winkel soll aber nicht der einfallswinke sein, sonder so, als wäre der Schläger kein rechteck sondern eher eine art Ellipse (so glaube ich ist das mit den verschienden Winkel deutlicher...) kann da mal vielleicht jemand in seiner "Code Kiste" kramen und nachsehen, ob er da so was rumliegen hat... Falls ja kann man mir das mit Strg + C und Strg + V zukommen lassen? THX CU Corelgott :dp: |
Re: Der Klassiker Pong & die Winkel...
berechnung des winkels von einer koordinate zur anderen
Delphi-Quellcode:
vielleicht hilfts ja bissifunction cortowink(x,y,x2,y2:single):single ; // winkelfunktion umkehrung ( xy ---winkel?--> x2y2 ) //------------------------------------------------------------------------------ // x/y = anfangspunkt 0 // x2/y2 = endpunkt zu dem der winkel berechnet werden soll function cortowink(x,y,x2,y2:single ):single ; // funktion zum berechnen des winkels für x y -> x2 y2 var wurzel: single; begin result := 0.1; // falls garnix von dem da unten funzt //rechts oben kreishälfte - winkel berechnen ( 360 - arcsin ) if ( (x2 > x) AND (y2 < y) ) then result := 360-radtodeg(arcsin((y-y2) / sqrt( ((x2-x)*(x2-x))+((y-y2)*(y-y2)) ))); // links unten kreishälfte if ( (x2 < x) AND (y2 > y) ) then result := 180-radtodeg(arccos((x-x2) / sqrt( (x-x2)*(x-x2)+(y2-y)*(y2-y) ) )); // links oben kreishälfte ( 180 + arccos ) if ( (x2 < x) AND (y2 < y) ) then result := 180+radtodeg(arccos((x-x2) / sqrt( (x-x2)*(x-x2)+(y-y2)*(y-y2) ) )); // rechts unten kreishälfte if ( (x2 > x) AND (y2 > y) ) then result := radtodeg(arcsin((y2-y) / sqrt( ((x2-x)*(x2-x))+((y2-y)*(y2-y)) ))); // gerade werte ( komma werte adden damit die flieger nicht haargenau geradeaus fliegen können ) // hoch if ( (x2 = x) AND (y2 < y) ) then result := 270.1; //runter if ( (x2 = x) AND (y2 > y) ) then result := 90.1; //links if ( (x2 < x) AND (y2 = y) ) then result := 180.1; //rechts if ( (x2 > x) AND (y2 = y) ) then result := 0.1; // punkt auf punkt if ( (x2 = x) AND (y2 = y) ) then result := 0.1; end; //------------------------------------------------------------------------------ zu deinem problem noch: ball fliegt in einem winkel zum schläger ball trifft schläger ( berechnen wieviel % am rand oder zur mitte hin ) winkel vom ball je nach flugrichtung nun verändern um 90° ( austrittswinkel ) und dazu noch x% - oder + damit der "ellypsenschläger" auch seine wirkung zeigt -> ball mit neuem winkel weiterfliegen lassen bis er wieder irgendwo abprallt usw |
Re: Der Klassiker Pong & die Winkel...
achja für die funktionen wo man braucht um ball flugwinkel + geschwindigkeit = neue position von ball ( sin / cos )
hab ich auch den code.. aber der müsste eigentlich auch noch zu schaffen sein ;) hier noch n paar funktionen: vorberechnung der cos/sin ergebnisse:
Delphi-Quellcode:
hier noch bissi code wo ich fürs schiffe begewen mal gehabt habe:sina: array[0..360] of real; // vorberechnete werte für sin cosa: array[0..360] of real; // vorberechnete werte für cos procedure initfunc; var i: integer; begin for i := 0 to 360 do begin sina[i] := Sin(cycletorad( i / 360)); cosa[i] := Cos(cycletorad( i / 360)); end; end;
Delphi-Quellcode:
sh[] is array mit schiffen// BEWEGEN ( x/y verschieben ) if (sh[i].mode >= 1) then begin // fliegt er ? if (sh[i].typ = 1) then begin // jäger sh[i].x := ( cosa[round(sh[i].a)] * (sh[i].v*1.1) ) + sh[i].x; sh[i].y := ( sina[round(sh[i].a)] * (sh[i].v*1.1) ) + sh[i].y; end; if (sh[i].typ = 2) then begin // advjäger sh[i].x := ( cosa[round(sh[i].a)] * (sh[i].v*1.8) ) + sh[i].x; sh[i].y := ( sina[round(sh[i].a)] * (sh[i].v*1.8) ) + sh[i].y; end; if (sh[i].typ = 3) then begin // bomber sh[i].x := ( cosa[round(sh[i].a)] * (sh[i].v*1.4) ) + sh[i].x; sh[i].y := ( sina[round(sh[i].a)] * (sh[i].v*1.4) ) + sh[i].y; end; if (sh[i].typ = 4) then begin // trans sh[i].x := ( cosa[round(sh[i].a)] * sh[i].v ) + sh[i].x; sh[i].y := ( sina[round(sh[i].a)] * sh[i].v ) + sh[i].y; end; sh[].x is x position sh[].y is y position sh[].a ist winkel in ° ( 0 -360 ) sh[].v ist geschwindigkeit ( pixel pro bild ) alles klar ? :> |
Re: Der Klassiker Pong & die Winkel...
Hallo,
da sich der Ball auf einer zweidimensionalen Fläche auf einer Geraden bewegt kann man die Bewegung auch mit einer Geradegleichung beschreiben: Zitat:
Zitat:
Im Falle eine Kollision ist also folgendes zu tun
Code:
wobei x und y die aktuelle Position des Ball's ist.
m:=m-1
b:=y-m*x Habe gerade gelesen, dass der Schläger kein Rechteck sein soll. Kein Problem. Dann multiplizierst Du die Steigung m nicht mit -1 sondern mit einem anderen aber negativen Wert. Den Multiplikator kannst Du in abhängig der Y-Koordinate des Auftreffpunktes des Ball's auf den Schläger berechnen. |
Re: Der Klassiker Pong & die Winkel...
genau so mit der steigung ( x oder y dazu zählen ) hab ich schon ein pong programmiert ( sogar netzwerkfähig )
aber das is total kacke weil da die geschwindigkeit auch noch verändert wird usw.. also bissi heikel mit winkelberechnung wars dann besser ( in meinem 2. spieleversuch (weltraum ballerspiel wir das bekannte "USI") mit directx in 2D ) |
Re: Der Klassiker Pong & die Winkel...
Liste der Anhänge anzeigen (Anzahl: 1)
hab mal ne unit in den anhang gepackt mit der Klasse T2DMove. Da braucht man dann nur noch sagen Drehen um 2 Grad und dann vorwärts1 und der gibt einem die neue koordinate aus.
|
Re: Der Klassiker Pong & die Winkel...
Hallo supermuckel,
Zitat:
|
Re: Der Klassiker Pong & die Winkel...
hi hab auch ne frage zu diesen thema wie machst du das mit der grafik in delphi???
gibs da so was wie opengl für delphi oder wie proggst du dass , würd mich mal interessieren da ich bis jetzt nur an programmen mich ausgetobt hab . :thuimb: |
Re: Der Klassiker Pong & die Winkel...
Hi Leute,
erst mal vielen Dank :thuimb: für die vielen tollen Antworten und Ideen :!: Das hat echt geholfen... (Ich komm blos leider nur schleppend hinter her die einzelden Antworten aus zu probieren .... Zeitprobleme) :!: Das mit dem Winkel bekomme ich so langsam in Griff... Es fehlen mir anscheidnen bei ein paar Rechnungen nur noch ein paar Faktoren :? Wenn der Ball jetzt abprallt, fliegt er immer mit dem Winkel von 0 bzw. 180 Grad weg, aber das bekomme ich schon noch hin... Wen 's interessiert hier der Code:
Code:
X und Y sind die Kooerdinaten des Punkets wo der Ball hin soll. So zu sagen der Bezugspunkt im Raum.
procedure TBall.ReverseX(X, Y, Degrees : Integer);
var arc : Real; begin arc := 0.1; // Backup //rechts oben kreishälfte - winkel berechnen ( 360 - arcsin ) if ( (X > MyX) AND (Y < MyY) ) then arc := 360-radtodeg(arcsin((MyY-Y) / sqrt( ((X-MyX)*(X-MyX))+((MyY-Y)*(MyY-Y)) ))); // links unten kreishälfte if ( (X < MyX) AND (Y > MyY) ) then arc := 180-radtodeg(arccos((MyX-X) / sqrt( (MyX-X)*(MyX-X)+(Y-MyY)*(Y-MyY) ) )); // links oben kreishälfte ( 180 + arccos ) if ( (X < MyX) AND (Y < MyY) ) then arc := 180+radtodeg(arccos((MyX-X) / sqrt( (MyX-X)*(MyX-X)+(MyY-Y)*(MyY-Y) ) )); // rechts unten kreishälfte if ( (X > MyX) AND (Y > MyY) ) then arc := radtodeg(arcsin((Y-MyY) / sqrt( ((X-MyX)*(X-MyX))+((Y-MyY)*(Y-MyY)) ))); // gerade werte vermeiden if ( (X = MyX) AND (Y < MyY) ) then arc := 270.1;// hoch if ( (X = MyX) AND (Y > MyY) ) then arc := 90.1; //runter if ( (X < MyX) AND (Y = MyY) ) then arc := 180.1; //links if ( (X > MyX) AND (Y = MyY) ) then arc := 0.1; //rechts if ( (X = MyX) AND (Y = MyY) ) then arc := 0.1; // punkt auf punkt Arc := Arc + sign(StepY) * (90 + Degrees); StepX := ( cosa[round(arc)] * StepX); StepY := ( sina[round(arc)] * StepY); end; MyX und MyY sind Kooerdinaten des Balls StepX und StepY ist die Geschwindigkeit in Pixel in X bzw. Y Richtung. Na ja werde da noch ein bisschen weiterbasteln... Ach ja an dieser Stelle ein ganz großes Dankeschön an Supermuckl bei dem ich den Code "klauen" und abwandel durfte!!! So!! Nun zu deiner Frage Mr.Dollar2k3: mit dem Zeichen bin ich zwar auch noch nicht so ganz zu frieden aber ich mache das zur Zeit noch "per Hand". Ich schnappe mir das Bild und gehe es, im interessanten Bereich, in den das bilds des Balls, nachher rein soll, Pixel für Pixel durch und kombiniere den Ball mit dem Hintergrundbild. das Sieht dann so auch:
Code:
Ich hole mir nen Pointer auf ein Pixel des Bildes
procedure TDraw.Merge(Target : TBitmap; Source : TBitmap; Strength : Byte; Left, Top : Integer);
var X, Y : integer; pt, ps: ^PixArray; begin Target.PixelFormat := pf24bit; for Y := 0 to Source.height - 1 do begin pt := Target.ScanLine[Top + Y]; //Get the Targetpicture's Line of Pixels inc(pt, Left); //Move focus to the interessting Area ps := Source.ScanLine[Y]; //Get the Sourcepicture's Line of Pixel for X := 0 to Source.width - 1 do begin if ((ps^[2] <> 255) or (ps^[0] <> 0) or (ps^[1] <> 0)) then //Dont add if Color is red begin pt^[2] := Round(ps^[2] * (Strength / 255 ) + pt^[2] * (1 - (Strength / 255))); //Red pt^[0] := Round(ps^[0] * (Strength / 255 ) + pt^[0] * (1 - (Strength / 255))); //Green pt^[1] := Round(ps^[1] * (Strength / 255 ) + pt^[1] * (1 - (Strength / 255))); //Blue end; inc(pt); //Next Pixel of the Target Picture inc(ps); //Next Pixel of the Source Picture end; end; end;
Code:
Sehe mir die drei RGB werte an:
pt := Target.ScanLine[Top + Y];
pt^[2] für Rot pt^[0] für Grün pt^[1] für Blau und verändere sie entsprechend. Strenght gibt dabei den Alpha werde des zu zeichnenden Bildes an. falls du das genauer nachleden willst: ![]() Aber das wird je nach der Menge der Objekte die ich zeichne auch ein bisschen langsam.... Ich bin auf der Suche nach was schnelleren... OpenGL, Direct Draw? Bin noch nicht so ganz sicher.. Ein bisschen schwierig oder? Kennt da jemand was flinkes angenehmeres? Erst mal thx so weit cya Corelgott |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz