 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
MalteF
Anmeldungsdatum: 04.12.2008 Beiträge: 44
|
Verfasst am: 26.05.2011, 08:33 Titel: Mathe Frage |
|
|
Hallo zusammen!
Heute hab ich mal ein Matheproblem. Vorneweg erstmal:
ich möchte einen Shooter machen, in dem der Spieler die Figur mit den
Tasten steuert und mit der Maus ein Fadenkreuz bewegt (in Vogelperspektive)
Das Problem dabei: Das Fadenkreuz soll nicht komplett über den ganzen
Screen wandern, sondern entlang eines gedachten Kreises, dessen Mittelpunkt der Spieler ist. (Ich probier mal ein Bild anzuhängen, damits klarer wird)
Frage: Ich müsste nun denk ich die Bildschirmkoordinaten des Mauscursors irgendwie in Polarkoordinaten (?) umrechnen, damit ich weiß an welcher Stelle ich mein Fadenkreuz zeichnen muss.
Aber ich hab null Ahnung von Mathe!
Wenn mir als jemand da weiterhelfen könnte, das wäre wunderbar!
Skizze:
[IMG]http://www.bilder-space.de/show_img.php?img=ee6ba5-1306391545.jpg&size=thumb[/IMG] |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 26.05.2011, 13:09 Titel: |
|
|
das kannst du eigentlich sehr simpel mithilfe des "Satz des Pythagoras" und der Prozentsatzrechnung lösen.
Code: | screenres 800, 600, 32
'Spielerparameter
Dim TPlayerPosX as UInteger = 400
Dim TPlayerPosY as UInteger = 300
Dim TCircleRadius as UInteger = 40
'Mausparameter
Dim TMouseR as Integer
Dim TMouseX as Integer
Dim TMouseY as Integer
Dim TMouseB as Integer
'zu berechnender Cursor auf dem Kreis
Dim TCursorX as Integer
Dim TCursorY as Integer
Dim TCursorL as Double
do until InKey() = Chr(27) 'Beim Drücken von "ESC" Schleife verlassen
'Aktuelle Mouseposition abfragen
TMouseR = GetMouse(TMouseX, TMouseY, , TMouseB)
'Wenn Linke Maustate gedrückt, dann Spielerposition neu setzen
If TMouseB = 1 then
TPlayerPosX = TMouseX
TPlayerPosY = TMouseY
End If
'Berechnung ausführen
TCursorL = Sqr(Abs(TMouseX - TPlayerPosX) ^ 2 + Abs(TMouseY - TPlayerPosY) ^ 2) 'Weglänge zwischen Mausposition und Spielerposition
If TCursorL > 0 Then 'SONDERFALL! Wenn die Weglänge 0 ist, dann benötigen wir keine Berechnung, da die Position identisch mit der Maus ist. und sich nciht berechnen lässt
TCursorX = TPlayerPosX + (TMouseX - TPlayerPosX) * TCircleRadius / TCursorL 'Berechnugn für X
TCursorY = TPlayerPosY + (TMouseY - TPlayerPosY) * TCircleRadius / TCursorL 'Berechnung für Y
End If
'Funktionsweise der Berechnung:
'1. Wir berechnen die entfernen von zwischen Maus und dem Spieler.
' Dies machen wir mithilfe des Pythagoras-Satzes. a * a + b * b = c * c -> Wurzel aus c * c -> Weglänge
'2. Wir setzen die Länge zwischen Maus und Spieler in ein Prozentuales Verhältniss zu dem Gewünschten Radius
' Hierbei nutzen wir einen Simplen Prozentsatz.
' Wir kennen die Strecke von SpielerPosition X und der MausPosition X und ziehen beides voneinander ab um einen Abstand (Länge) zu erhalten. (TMouseX - TPlayerPosX)
' Angenommen wir haben SpielerX = 100 und MauseX = 60, dann wäre das ergebniss 40
' Wir möchten den Kreis im Radius von 30 um den Spieler Zeichnen
' Dazu Multiplizieren wir unser ergebniss mit dem gewünschten Radius 40 * 30
' und teilen dies anschliessend durch die Berechnete Länge des Abstandes zwischen Maus und Spielerposition
' damit erhalten wir die neue X Koordinate welche genau auf dem Kreis liegt.
' Anschliessend müssen wir zu diesem Ergebniss von die Aktuelle Position des Spielers hinzu addieren.
'Selbes auch mit Y machen
'Zeichnen
ScreenLock() 'Flimmern verhindern
CLS() 'Bildshirm leeren
Circle (TPlayerPosX, TPlayerPosY), 3, &HFF, , , , F 'Aktuelle Spielerposition Zeichnen (Gefüllter Kreis, ROT)
Circle (TPlayerPosX, TPlayerPosY), TCircleRadius, &H00FF00 'Spielerradius (Kreis, GRÜN)
Circle (TCursorX, TCursorY), 3, &HFFFFFF, , , , F 'Berechneter Cursorpunkt (Gefüllter Kreis, WEIS)
Circle (TMouseX, TMouseY), 3, &HFFFF00, , , , F 'Aktuelle Mausposition Zeichnen (Gefüllter Kreis, GELB)
'Aktuelle Berechnungen anzeigen
Locate 1, 1 'Textposition zurücksetzen
Print "Maus: "; Str(TMouseX); " "; Str(TMouseY) 'Aktuelle Mauskoordinaten
Print "Laenge:"; Str(TCursorL) 'Aktuelle Weglänge
Print "Cursor:"; Str(TCursorX); " "; Str(TCursorY) 'Aktuelle Cursorberechnung
ScreenUnLock() 'Flimmern verhindern
'kurz warten um CPU zu schonen
sleep 1, 1 '0,001 Sekunde Warten
loop
screen 0 'Bildschirm wieder schliessen
end 0 'Programm sauber beenden
|
PS: Ist zwar FB, aber die berechnugn funzt genauso in QB.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
MalteF
Anmeldungsdatum: 04.12.2008 Beiträge: 44
|
Verfasst am: 26.05.2011, 20:45 Titel: |
|
|
Suuuuper geil, vielen Dank!
Ich hab schon schlimmste Mathematik befürchtet, aber das raff ja sogar ich, ich wär nur nie drauf gekommen!  |
|
Nach oben |
|
 |
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 26.05.2011, 21:31 Titel: |
|
|
@ThePuppetMaster
Code: | TCursorL = Sqr(Abs(TMouseX - TPlayerPosX) ^ 2 + Abs(TMouseY - TPlayerPosY) ^2) |
wieso das Abs. Alle quadrate von realen zahlen sind positiv. wieso machst du aber vorher diese zahlen noch positiv, ist das scheller? |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 26.05.2011, 21:40 Titel: |
|
|
hab ich mir angewöhnt, und muss ich mir dringend wieder abgewöhen. Eigentlich genauso das ^2, das ist nämlich ca. 1/2x so langsam wie das einfache *
31125382 berechnungen pro 10sek. mit *
19942850 berechnungen pro 10sek. mit ^ 2
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 27.05.2011, 15:45 Titel: |
|
|
ThePuppetMaster hat Folgendes geschrieben: | hab ich mir angewöhnt, und muss ich mir dringend wieder abgewöhen. Eigentlich genauso das ^2, das ist nämlich ca. 1/2x so langsam wie das einfache *
31125382 berechnungen pro 10sek. mit *
19942850 berechnungen pro 10sek. mit ^ 2 |
Hmm ich mach mir da immer ein Makro alá #define square(u) ((u)*(u)) geht fix und verhindert Coderedundanz |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 27.05.2011, 15:47 Titel: |
|
|
Coderedundanz verhinderst du mit Makros nicht. Du änderst nur die Optik.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 27.05.2011, 15:49 Titel: |
|
|
verhindert quellcode-redundanz, doch nicht ausführbarer-code-redundanz, aber quellcore-redundanz und das ist die wichtigere  _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 27.05.2011, 15:53 Titel: |
|
|
Nö. Die Redundanz ist noch vorhanden. Und steigert sie auch, wenn man animmt, das dieses Makro nur 1x verwendet wird. Bei häufigerer nutzung sinkt zwar die Quellcodegrösse, allerdings ist die Redundanz durch mehrmalige Nutzung wieder vorhanden. ... das ist ein Spiel, das sich nicht gewinnen lässt. Denn, gebraucht wird es so oder so.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 27.05.2011, 18:32 Titel: |
|
|
Wenn in einem Programm eine Aktion 20x ausgeführt werden muss, dann ist das keine Redundanz, sondern Programmlogik. Dagegen kann man nix machen. Wie auch? Es ist ja keine Redundanz, auch wenn du das so nennen magst. Solange man aber von dem, was getan werden soll, abstrahieren kann (z.B. mit inline-Funktionen oder eben Makros unter FB), sollte man das auch tun, denn wenn der redundante Code verändert werden muss, muss das nur an einer Stelle und nicht an 20 getan werden.
Wenn man jetzt z.B. einen noch schnelleren Weg zur Quadrierung als ein x*x-Makro findet, muss man den Code an genau einer Stelle anpassen und eben nicht überall, wo quadriert wurde. Dass dieses Makro vielleicht 20 Mal verwendet wurde, ist aber keine Redundanz. Wenn es Redundanz wäre, hieße das, dass 19 Aufrufe des Makros unnötig gewesen wären. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|