AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Der Klassiker Pong & die Winkel...

Ein Thema von Corelgott · begonnen am 11. Dez 2003 · letzter Beitrag vom 13. Dez 2003
Antwort Antwort
Benutzerbild von Corelgott
Corelgott

Registriert seit: 11. Apr 2003
Ort: Lübeck
213 Beiträge
 
Delphi 2006 Enterprise
 
#1

Der Klassiker Pong & die Winkel...

  Alt 11. Dez 2003, 23:35
Hi Leute,

ich versuche mich gerade ein bisschen mit Pong (falls es einner nicht kennt so ne Art Tennis: Ein Ball zwei Schläger... )

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....

*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
  Mit Zitat antworten Zitat
supermuckl

Registriert seit: 1. Feb 2003
1.340 Beiträge
 
FreePascal / Lazarus
 
#2

Re: Der Klassiker Pong & die Winkel...

  Alt 12. Dez 2003, 01:19
berechnung des winkels von einer koordinate zur anderen
Delphi-Quellcode:

function 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;



//------------------------------------------------------------------------------
vielleicht hilfts ja bissi

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
Das echte Leben ist was für Leute...
... die im Internet keine Freunde finden!
  Mit Zitat antworten Zitat
supermuckl

Registriert seit: 1. Feb 2003
1.340 Beiträge
 
FreePascal / Lazarus
 
#3

Re: Der Klassiker Pong & die Winkel...

  Alt 12. Dez 2003, 01:29
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:

  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;
hier noch bissi code wo ich fürs schiffe begewen mal gehabt habe:
Delphi-Quellcode:

              // 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[] is array mit schiffen
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 ? :>
Das echte Leben ist was für Leute...
... die im Internet keine Freunde finden!
  Mit Zitat antworten Zitat
Benutzerbild von Jens Schumann
Jens Schumann

Registriert seit: 27. Apr 2003
Ort: Bad Honnef
1.644 Beiträge
 
Delphi 2009 Professional
 
#4

Re: Der Klassiker Pong & die Winkel...

  Alt 12. Dez 2003, 08:41
Hallo,
da sich der Ball auf einer zweidimensionalen Fläche auf einer Geraden bewegt kann man die Bewegung auch mit einer Geradegleichung beschreiben:
Zitat:
y=m*x+b
Da gilt:
Zitat:
Einfallswinkel = Ausfallwinkel
muss die Steigung m mit -1 multipliziert werden und der neue Wert b für den Schnittpunkt mit der Y-Achse berechnet werden.
Im Falle eine Kollision ist also folgendes zu tun
Code:
m:=m-1
b:=y-m*x
wobei x und y die aktuelle Position des Ball's ist.

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.
  Mit Zitat antworten Zitat
supermuckl

Registriert seit: 1. Feb 2003
1.340 Beiträge
 
FreePascal / Lazarus
 
#5

Re: Der Klassiker Pong & die Winkel...

  Alt 13. Dez 2003, 04:31
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 )
Das echte Leben ist was für Leute...
... die im Internet keine Freunde finden!
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Der Klassiker Pong & die Winkel...

  Alt 13. Dez 2003, 07:39
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.
Angehängte Dateien
Dateityp: pas u2dmove.pas (18,8 KB, 21x aufgerufen)
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Jens Schumann
Jens Schumann

Registriert seit: 27. Apr 2003
Ort: Bad Honnef
1.644 Beiträge
 
Delphi 2009 Professional
 
#7

Re: Der Klassiker Pong & die Winkel...

  Alt 13. Dez 2003, 09:49
Hallo supermuckel,
Zitat:
is total kacke weil da die geschwindigkeit auch noch verändert wird usw..
Wo ändert sich denn die Geschwindigkeit ?
  Mit Zitat antworten Zitat
Mr.Dollar2k3

Registriert seit: 12. Okt 2003
Ort: KÖLN
29 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: Der Klassiker Pong & die Winkel...

  Alt 13. Dez 2003, 10:10
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 .
  Mit Zitat antworten Zitat
Benutzerbild von Corelgott
Corelgott

Registriert seit: 11. Apr 2003
Ort: Lübeck
213 Beiträge
 
Delphi 2006 Enterprise
 
#9

Re: Der Klassiker Pong & die Winkel...

  Alt 13. Dez 2003, 16:09
Hi Leute,

erst mal vielen Dank 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:
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;
X und Y sind die Kooerdinaten des Punkets wo der Ball hin soll. So zu sagen der Bezugspunkt im Raum.
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:
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;
Ich hole mir nen Pointer auf ein Pixel des Bildes
Code:
pt := Target.ScanLine[Top + Y];
Sehe mir die drei RGB werte an:
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:
MSN Library

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
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:33 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz