Floats doch möglich?

Fragen zu "Adventure Game Studio"? Hier rein!
Antworten
Creedy
Süßwasserpirat
Süßwasserpirat
Beiträge: 443
Registriert: 22.09.2002, 12:53

Floats doch möglich?

Beitrag von Creedy »

Hallo Leute,
bin bei meinem Indy-Game auf folgendes Problem gestoßen:

Bin gerade dabei, die typische Indy-Reisemap zu scripten und musste dabei mit Schrecken feststellen, dass AGS keine Dezimalzahlen unterstützt.
Wollte die Steigung der Geraden durch 2 Punkte berechnen, aber bei einem erwarteten Ergebnis von z.B. 0,5 wird auf 0 abgerundet, was mir natürlich überhaupt nichts bringt.
Gibt es dafür eine "geheime" Möglichkeit oder muss ich für jede Reiseverbindung eine seperate Linien-Animation machen (was deutlich mehr Arbeit und Speicherplatz bedeuten würde)?
Danke und ciao!
[ZENSIERT]
Adventure-Gott
Adventure-Gott
Beiträge: 4575
Registriert: 13.07.2004, 14:04
Wohnort: Da wo muss
Kontaktdaten:

Beitrag von [ZENSIERT] »

Stichwort: Gleichsinnige Kommaverschiebung.

Nimm alle Zahlen mal 10. Hoffe aber, ich mache nicht den gleichen Fehler wie Plato...

Bitte mache ein Backup des Scripts, die Lösung könnte falsch sein
Es heißt, Leute mit den originellsten Nicknames schreiben die besten Beiträge

Ausnahmen bestätigen die Regel
_________________
<Problem> Weil du denken kannst.

Zuletzt bearbeitet von [ZENSIERT] am 16.07.1759, 16:19, insgesamt 54743869-mal bearbeitet
a-v-o
Süßwasserpirat
Süßwasserpirat
Beiträge: 258
Registriert: 22.09.2002, 21:28
Kontaktdaten:

Beitrag von a-v-o »

Abgesehen von der Kommaverschiebung gibt es die Möglichkeit, einen Bruch in 2 Variablen zu speichern, bspw. für 0,75:

int mult, div;

mult = 3;
div = 4;

int y = (x * mult) / div;


oder für die Steigung zwischen 2 Punkten:

int dx = x2 - x1;
int dy = y2 - y1;
int y = (((x - x1) * dy) / dx) + y1;

Hinweis: Bitte IMMER Klammern verwenden, weil AGS solche Ausdrücke entgegen der mathematischen Regel von rechts nach links berechnet.
Norman
Logik-Lord
Logik-Lord
Beiträge: 1089
Registriert: 12.08.2002, 11:44
Wohnort: Köln

Beitrag von Norman »

a-v-o hat geschrieben:Abgesehen von der Kommaverschiebung gibt es die Möglichkeit, einen Bruch in 2 Variablen zu speichern, bspw. für 0,75:

int mult, div;

mult = 3;
div = 4;

int y = (x * mult) / div;
Und wieso funktioniert das? Müsste er nicht das Ergebnis von (x*mult) / div dann auch wieder auf Integer runden?
[ZENSIERT]
Adventure-Gott
Adventure-Gott
Beiträge: 4575
Registriert: 13.07.2004, 14:04
Wohnort: Da wo muss
Kontaktdaten:

Beitrag von [ZENSIERT] »

In einem altem Mathebuch, das gerade vor mir liegt steht:
Der Quotient (Ergebnis einer Division) zweier natürlicher Zahlen z unhd n ist gleich der Bruchzahl z/n
5 : 8 = 5/8
Du brauchst nur eine Variable für den Zähler und eine für den Nenner, die du dann teilen musst. blöderweise tut sich dann wieder ein Problem auf, wenn der Zähler kein Teiler des Nenners ist, denn dann ist das Ganze wieder eine Dezimalzahl
Es heißt, Leute mit den originellsten Nicknames schreiben die besten Beiträge

Ausnahmen bestätigen die Regel
_________________
<Problem> Weil du denken kannst.

Zuletzt bearbeitet von [ZENSIERT] am 16.07.1759, 16:19, insgesamt 54743869-mal bearbeitet
a-v-o
Süßwasserpirat
Süßwasserpirat
Beiträge: 258
Registriert: 22.09.2002, 21:28
Kontaktdaten:

Beitrag von a-v-o »

Norman hat geschrieben:Und wieso funktioniert das? Müsste er nicht das Ergebnis von (x*mult) / div dann auch wieder auf Integer runden?
Das Ergebnis ist natürlich eine Ganzzahl, da AGS nur mit Ganzzahlen rechnen kann. Letztlich braucht man in AGS auch nur Ganzzahlen, bspw. für Raum- oder Bildschirmkoordinaten, Anzahl Gegenstände im Inventar, Geld, Punktezahl.

Ich habe die Aufgabe so verstanden:
Gegeben sind 2 Punkte einer Strecke.
Gesucht werden die Koordinaten der Punkte auf dieser Strecke.
Die Lösung ist im 2. Beispiel für die Steigung zwischen 2 Punkten dargestellt.
Diese Koordinaten sollen ja Ganzzahlen sein.

Wenn das Ergebnis eine Dezimalzahl sein soll (bspw. ein Geldbetrag), dann ist die Kommaverschiebung die richtige Wahl.
Benutzeravatar
Lebostein
Logik-Lord
Logik-Lord
Beiträge: 1343
Registriert: 24.03.2003, 22:54
Wohnort: Elbflorenz
Kontaktdaten:

Beitrag von Lebostein »

[off] @Creedy: Wieso steht dein dein Indy-Spiel auf der "Eingestellt-Liste" bei den Fanadventures hier im AT? Ist das ein Versehen oder hattest du bereits aufgegeben und machst jetzt doch weiter :D ? [/off]
Creedy
Süßwasserpirat
Süßwasserpirat
Beiträge: 443
Registriert: 22.09.2002, 12:53

Beitrag von Creedy »

@a-v-o:

Oh, da hast du wohl etwas falsch verstanden.
Ich habe auf meiner Indy-Map ja mehrere Orte mit festen Koordinaten (New York usw.)
Ich will jetzt, dass beim Klick auf einen Ort die typische rote Indy-Reise-Linie von Punkt A zu Punkt B gezeichnet wird.
Damit ich nicht für jede Reise-Kombination eine Animation machen muss, wollte ich das ganze mit einer Funktion lösen:
Zuerst wird eine unsichtbare Linie durch die 2 Punkte angenommen, dann diese Steigung ausgerechnet ((y2-y1)/(x2-x1)) und dann kann ich die Linie schrittweise mit DrawRawLine in einer Schleife zeichnen lassen. Bei einer Steigung von z.B. 0.5 wird aber dann mit 0 gerechnet, was logischerweise zur Folge hat, dass meine Linie waagerecht gezeichnet wird.
Da die Steigungen individuell sind, kann ich auch keine Bruchkombination zweier Faktoren aufstellen, da diese ja bei de Laufzeit berechnet werden.
Gleichsinnige Kommaverschiebung ist auch nicht drin, denn eine Steigung von 0.5 ist ja nicht gleich 5.
Zum Mäusemelken! ;)

@Lebostein

Tja, weiss auch nicht, wieso es dort steht ;) Ich war's nicht.
Aber es stimmt, dass ich fast ein Jahr nicht mehr intensiv an dem Projekt gearbeitet habe. Da ich momentan Semesterferien habe und es bei uns dieses Jahr wohl nicht mehr aufhören wird zu regnen, habe ich mich wieder drangesetzt. Ausserdem habe ich erstaunlich viele aufmunternde und motivierende Mails bekommen, die mich angespornt haben, doch wieder die Arbeit aufzunehmen. Fragt sich nur, wie lange die Motivation noch anhält ;)
BTW: Was macht eigentlich dein Monkey-Sequel? :D
Benutzeravatar
Lebostein
Logik-Lord
Logik-Lord
Beiträge: 1343
Registriert: 24.03.2003, 22:54
Wohnort: Elbflorenz
Kontaktdaten:

Beitrag von Lebostein »

Creedy hat geschrieben: ...Ausserdem habe ich erstaunlich viele aufmunternde und motivierende Mails bekommen, die mich angespornt haben, doch wieder die Arbeit aufzunehmen...
Das kenne ich. So eine Mail von einem Fan kann einem nen ordentlichen Motivationsschub verpassen... Naja, ist halt ne langwierge Sache so ein Spiel, merk ich selber immer wieder. Und wenn man dann noch alles so perfekt machen will wie ich (ich mag diese Eigenschaft an mir nicht besonders), dann kommt man nur ziemlich langsam voran ... was dann wieder nicht gerade motivierend ist... "Ein Teufelskreis!" [Zitat aus Sierrafan's Signatur :D ]
a-v-o
Süßwasserpirat
Süßwasserpirat
Beiträge: 258
Registriert: 22.09.2002, 21:28
Kontaktdaten:

Beitrag von a-v-o »

[/quote]
Creedy hat geschrieben: Oh, da hast du wohl etwas falsch verstanden.
Ich fürchte, ich habe dich richtig verstanden.
Creedy hat geschrieben:Zuerst wird eine unsichtbare Linie durch die 2 Punkte angenommen, dann diese Steigung ausgerechnet ((y2-y1)/(x2-x1))
Das wird hier berechnet:
int dx = x2 - x1;
int dy = y2 - y1;
Allerdings nur die Differenz-Werte und nicht der Quotient (Steigung m=dy/dx).
Creedy hat geschrieben: und dann kann ich die Linie schrittweise mit DrawRawLine in einer Schleife zeichnen lassen.
int x = x1;
int y;
while (x <= x2)
{
y = (((x - x1) * dy) / dx) + y1;
RawDrawLine (x, y, x, y);
x++;
}

Damit das funktioniert, muss x1 <= x2 sein.
Creedy hat geschrieben:Da die Steigungen individuell sind, kann ich auch keine Bruchkombination zweier Faktoren aufstellen, da diese ja bei de Laufzeit berechnet werden.
Also lautet die komplette Funktion:
function DrawLine (int x1, int y1, int x2, int y2)
{
int dx = x2 - x1;
int dy = y2 - y1;
int x = x1;
int y;
while (x <= x2)
{
y = (((x - x1) * dy) / dx) + y1;
RawDrawLine (x, y, x, y);
x++;
}
}

Diese Funktion ist für eine durchgehende Linie zwischen 2 Punkten. Sie müsste für eine gestrichelte Linie noch abgewandelt werden. Ausserdem ist eine Prüfung nötig, damit sichergestellt ist, dass x1 < x2. Darüber hinaus wird diese Funktion nur bei Linien mit einer Steigung zwischen -0,5 bis 0,5 gut funktionieren. Bei steileren Linien sollte y die Variable in while sein und die entsprechende x-Koordinate berechnet werden.
[ZENSIERT]
Adventure-Gott
Adventure-Gott
Beiträge: 4575
Registriert: 13.07.2004, 14:04
Wohnort: Da wo muss
Kontaktdaten:

Beitrag von [ZENSIERT] »

Es gibt doch einen Befehl, mit dem man den Rest einer Aufgabe zurücksenden kann (zumindest in PureBasic, aber die Scriptsprache ist ziemlich gleich). Vielleicht könnt ihr was damit anfangen...

Der Operator ist %. Also wäre der Wert bei [ int a = 10 % 3 ] eins
Es heißt, Leute mit den originellsten Nicknames schreiben die besten Beiträge

Ausnahmen bestätigen die Regel
_________________
<Problem> Weil du denken kannst.

Zuletzt bearbeitet von [ZENSIERT] am 16.07.1759, 16:19, insgesamt 54743869-mal bearbeitet
Nekyl
Komplettlösungsnutzer
Komplettlösungsnutzer
Beiträge: 20
Registriert: 20.01.2007, 20:42
Kontaktdaten:

Beitrag von Nekyl »

Toll gelöst, a-v-o ! :)
Würds dann allerdings optisch noch etwas ausbessern (mit wait, so daß die linie nicht auf einen schlag kommt, sondern sich wie beim guten alten indy vorwärts arbeitet)
und halt noch die passende farbe und n bissken dicker :)
while (x <= x2)
{
Wait(1);
y = (((x - x1) * dy) / dx) + y1;
RawSetColor(4);
RawDrawLine (x, y, x, y);
RawDrawLine (x, y+1, x, y);
x++;
}
Benutzeravatar
Sinitrena
Tastatursteuerer
Tastatursteuerer
Beiträge: 678
Registriert: 08.05.2004, 01:01
Wohnort: Frankfurt
Kontaktdaten:

Beitrag von Sinitrena »

Dir ist schon aufgefallen, dass der Faden 2 1/2 Jahre alt ist oder?

Wenn du nicht genau das gleiche Problem hast, und die Lösung nich über die Forensuche findest, dann hol keine alten Threads hoch.

Du hast aber offensichtlich nicht dieses Problem und deine Ergänzung ist auch alles andere als weltbewegend.

Mach das also nie wieder!
http://www.sinitrena.de.vu Meine Spiele: "A very special dog", "A magic stone", "James Bond - Who wants to live again?", "Lonely Night", "Death of an Angel", "The Witch, the Wizard and the Blue Cup", "Emerald Eyes"
Nekyl
Komplettlösungsnutzer
Komplettlösungsnutzer
Beiträge: 20
Registriert: 20.01.2007, 20:42
Kontaktdaten:

Beitrag von Nekyl »

Doch, is mir direkt danach aufgefallen (hatte den Thread über die Suchfunktion gefunden, da ich ein ähnliches Problem hatte, wobei mir a-v-os Lösung geholfen hat), wollt mein Beitrag auch löschen, aber geht ja leider nicht. :oops:
Werds nie wieder tun ;)
Großes Indianerehrenwort ;)
Küssken :-*

P.S. hättest mir übrigens auch ne PM schreiben dürfen, um den Thread nicht nochmal unnötigerweise zu bumpen :wink:
papapischu
Hobby-Archäologe
Hobby-Archäologe
Beiträge: 195
Registriert: 05.12.2004, 01:22
Wohnort: Berlin/Hamburg

Beitrag von papapischu »

Jetzt wo der Faden schon mal wieder oben ist kann ich auch etwas Weltbewegendes hinzufügen. Für solche fälle "Wie zeichne ich eine Linie auf einem Raster von a nach b" gibt es den "Bresenham-Algorithmus" der auf jeder Grafikkarte implementiert ist. Der kommt ohne Gleitkommaarithmetik aus und ist daher auch gut für AGS geeignet. Da ich mich mit AGS nicht auskenne hier nur der Pseudocode der entsprechend anzupassen ist.
Vorrausstzung x0<x1!

void drawLine(int x0, int y0, int x1, int y1) {
int dx = x1 - x0;
int dy = y1 - y0;
int d = 2*dy - dx;
int dE = 2 * dy;
int dNE = 2 * (dy - dx);
int x = x0;
int y = y0;

writePixel(x,y);
while(x<x1) {
if(d<=0) {
d += dE; x++;
} else {
d += dNE; x++; y++;
}
writePixel(x,y);
}
}
Edit: Die Steigung der Line ist dabei auch egal.
Antworten