Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Strahlengang im Rotierenden Spiegel

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
08.11.2004, 10:31 Uhr
~Gast
Gast


Hallo,
ich habe folgendes Problem:
Es soll in C ein Grafikprogramm für DOS erstellt werden.
Als Grafiktreiber wird das Borland Graphics Interface BGI verwendet (egavga.bgi).

Es soll der Strahlengang von Licht auf einen rotierenden Spiegel simuliert werden.
Als Spiegel will ich einfach eine Linie rotieren lassen. Der Lichtstrahl soll durch eine weitere Linie dargestellt werden, die sobald Sie auf "den rotierenden Spiegel" trifft, an diesem reflektiert wird.
Habe gehört, dass man mittels paging (Seitenwechseltechnik) das Bild in Bewegung bekommt.
Da ich nicht sehr viel Ahnung von Programmieren habe, ist mein erstes Problem, überhaupt eine Bewegung auf den Bildschirm zu bekommen.
Kann mir dabei jemand helfen?

Habe bisher folgendes programmiert:


C++:
/******************************************************************/
/* Headerdateien                                                                                               */
/******************************************************************/

#include <graphics.h> /* Wird fuer Grafik benoetigt */
#include <stdio.h>    /* Standard Ein Ausgabe       */
#include <conio.h>
#include <stdlib.h>   /* exit                       */

/******************************************************************/
/* Globale Variablen                                                                                            */
/******************************************************************/

int errorcode, graphdriver, graphmode;

/******************************************************************/
/* Funktionen                                                                                                    */
/******************************************************************/

void graphinit(void)
{
int gdriver = 9;   /* Grafiktreiber - 9 = VGA                            */
int gmode   = 1; /* Grafikmodus   - 1 = 640x350 16 color 2             */
int errorcode;    /* Variable fuer Fehlercode                           */

/* Grafikmodus wird initialisiert. (Treiber, Modus, Treiberverzeichnis */
initgraph(&gdriver, &gmode, "");

errorcode = graphresult();  /* Grafik Fehlercode                       */

if (errorcode != grOk)    /* Falls Grafikfehler...                     */
   {
    printf("Grafikfehler: %s\n", grapherrormsg(errorcode));
    printf("Zum Beenden Taste druecken.");
    getch();
    exit(1);               /* Programm Ende mit Errorcode */
   }
}

/******************************************************************/
/* Hauptprogramm                                                                                              */
/******************************************************************/

void main(void)
{
graphinit();

/* Rechteck zeichnen */
rectangle(0,0,getmaxx(),getmaxy());
outtextxy(0,0,"Strahlengang im rotierenden Spiegel");

/* Grafik beenden */
getch();
closegraph();

}



Es wird also erstmal der Treiber geladen und dann ein Rechteck und ein Text gezeichnet.
Habe vor als nächstes den bewegten Spiegel auf den Bildschirm zu bekommen aber wie gesagt keine Ahnung wie man überhaupt etwas bewegt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
08.11.2004, 12:49 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


glaube nicht das das in die rätselecke passt ...


--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
08.11.2004, 14:31 Uhr
Hans
Library Walker
(Operator)



Zitat:
Da ich nicht sehr viel Ahnung von Programmieren habe, ist mein erstes Problem, überhaupt eine Bewegung auf den Bildschirm zu bekommen.

Hi,
der ganz einfache Trick, um eine Bewegung zu erzeugen ist folgender:
* Du zeichnest z.B. ein weisses Rechteck auf schwarzem Hintergrund.
* eine 10-tel sekunde warten (oder solange was anderes berechnen)
* Jetzt mit den selben Koordinaten das Rechteck in der Farbe des Hintergrundes (hier schwarz) neu zeichnen. (Dadurch verschwindet es nämlich).
* Etwas versetzt von den alten Koordinaten das Rechteck in der Farbe neu zeichnen, die es haben soll (hier weiss).

Was das Paging betrift: Ich vermute, Du meinst Seitenwechsel damit. Das ist eine verfeinerte Technik von dem, was ich oben beschrieben habe. Es Benötigt doppelt so viel Platz zum Speichern der Grafik, macht optisch aber einen besseren Eindruck. Vor allem, wenn der Rechner nicht sehr schnell ist. Das geht in etwa so:
* Man zeigt erst einen leeren Bildschirm, (erste Seite) und auf der zweiten, nicht sichtbaren Seite zeichnet man seine Figuren.
* Wenn die Zeichnungen fertigt sind, schaltet man zwischen diesen beiden Seiten um. Dadurch wird die ganze Zeichnung mit einem mal sichtbar.
* Auf der jetzt unsichtbaren Seite löscht man alles, was man an bestimmten Positionen nicht mehr haben will, und zeichnet es an anderer Stelle neu.
* Wenn alles neu gezeichnet ist, schaltet man wieder zwischen den beiden Seiten um.

Wenn zwischen den einzelnen Seitenwechseln nicht sehr viel Zeit vergeht, ensteht der Eindruck einer flüssigen Bewegung. Wenn die Zeit zwischen den einzelnen Seiten wechseln zu lange dauert, dann "ruckelt" die Bewegung. Nur weis ich jetzt nicht genau, wie gross die Zeit maximal sein darf. Aber wenn man sich an einen Fernseher orientiert, der 25 Bilder pro Sekunde liefert, dann liegt die Zeit bei 40 Milli- bzw. 4 hundertstel Sekunden.
Soweit ein paar Basics, die aber nur die einfachsten sind.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
08.11.2004, 15:08 Uhr
~Gast
Gast



Zitat von Hans:

der ganz einfache Trick, um eine Bewegung zu erzeugen ist folgender:
* Du zeichnest z.B. ein weisses Rechteck auf schwarzem Hintergrund.
* eine 10-tel sekunde warten (oder solange was anderes berechnen)
* Jetzt mit den selben Koordinaten das Rechteck in der Farbe des Hintergrundes (hier schwarz) neu zeichnen. (Dadurch verschwindet es nämlich).
* Etwas versetzt von den alten Koordinaten das Rechteck in der Farbe neu zeichnen, die es haben soll (hier weiss).



Habe mittlerweile den Spiegel zum drehen bekommen und zwar so:

C++:
void hauptfenster()
{
  rectangle(0,10,getmaxx(),getmaxy());
  outtextxy(0,0,"Strahlengang im rotierenden Spiegel");
}

void spiegel (void)
{
static int StartX, StartY; /* Startposition */
long double a, step;
char ch;
a= 0;
step= 0.05;

while (!kbhit())
  {
    hauptfenster();
    StartX= getmaxx()/2;
    StartY= getmaxy()/2;
    line (StartX - 100*cos(a), StartY - 100*sin(a), StartX + 100*cos(a), StartY + 100*sin(a));
   a= a + step;
   clearviewport();

}
ch= getche();
}



Das ist aber wohl nur die einfache Methode, da clearviewport(); einfach nur den Bildschirminhalt löscht und dann die Linie etwas verschoben neu gezeichnet wird. Bei mir ruckelt diese Methode auch ziemlich obwohl es nur eine Linie ist.


Zitat von Hans:

Was das Paging betrift: Ich vermute, Du meinst Seitenwechsel damit. Das ist eine verfeinerte Technik von dem, was ich oben beschrieben habe. Es Benötigt doppelt so viel Platz zum Speichern der Grafik, macht optisch aber einen besseren Eindruck. Vor allem, wenn der Rechner nicht sehr schnell ist. Das geht in etwa so:
* Man zeigt erst einen leeren Bildschirm, (erste Seite) und auf der zweiten, nicht sichtbaren Seite zeichnet man seine Figuren.
* Wenn die Zeichnungen fertigt sind, schaltet man zwischen diesen beiden Seiten um. Dadurch wird die ganze Zeichnung mit einem mal sichtbar.
* Auf der jetzt unsichtbaren Seite löscht man alles, was man an bestimmten Positionen nicht mehr haben will, und zeichnet es an anderer Stelle neu.
* Wenn alles neu gezeichnet ist, schaltet man wieder zwischen den beiden Seiten um.

Wenn zwischen den einzelnen Seitenwechseln nicht sehr viel Zeit vergeht, ensteht der Eindruck einer flüssigen Bewegung. Wenn die Zeit zwischen den einzelnen Seiten wechseln zu lange dauert, dann "ruckelt" die Bewegung. Nur weis ich jetzt nicht genau, wie gross die Zeit maximal sein darf. Aber wenn man sich an einen Fernseher orientiert, der 25 Bilder pro Sekunde liefert, dann liegt die Zeit bei 40 Milli- bzw. 4 hundertstel Sekunden.
Soweit ein paar Basics, die aber nur die einfachsten sind.



Genau das meinte ich. Weiß aber nicht wie es funktioniert. Könnte man meine funktion da umschreiben oder müßte ich ganz anders an die Sache ran gehen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
08.11.2004, 19:23 Uhr
~Gast
Gast


Der Spiegel dreht sich jetzt mittels paging.


C++:
void spiegel (void)
{
char  SeitenNr = 0;           /* Nummer der Seite fuer PAGING */
int   posX     = getmaxx()/2; /* X-Position der Spiegelmitte  */
int   posY     = getmaxy()/2; /* Y-Position der Spiegelmitte  */
int   laenge   = 100;         /* Laenge des Spiegel in Pixel  */
float a        = 0;           /* Winkel in Bogenmass          */
float step     = 0.01;        /* Geschwindigkeit der Drehung  */


while (!kbhit())
   {
    setvisualpage(SeitenNr);
    setactivepage((SeitenNr+1)%2);
    rahmen();
    line (posX - laenge*cos(a), posY - laenge*sin(a), posX + laenge*cos(a), posY + laenge*sin(a));
    a= a + step;
    clearviewport();
    rahmen();
    line (posX - laenge*cos(a), posY - laenge*sin(a), posX + laenge*cos(a), posY + laenge*sin(a));
    a= a + step;
    SeitenNr = (SeitenNr+1)%2;
   }
}



Müßte jetzt wissen, wie man eine Kollisionskontrolle einbaut und habe noch eine Frage.
Kann man Variablen im Grafikmodus ausgeben? Ich kann ja mittels textoutxy(); einen Text an eine bestimmte Stelle schreiben. In diesem Text kann ich aber nicht wie bei printf("%d",x); Werte ausgeben. Ist dies irgendwie möglich?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
09.11.2004, 00:47 Uhr
Hans
Library Walker
(Operator)


Hi,

also die Methode mit clearviewport() ist ja nicht so Dolle, wie Du auch selber schon gemerkt hast. Damit eine Figur an einer Stelle verschwindet, muss sie deshalb mit der Hintergrundfarbe neu gezeichnet werden. Die Zeichenfunktionen bieten aber, wenn ich mich nicht irre, noch die Möglichkeit der XOR-Verknüpfung. Damit kannst Du eine Linie (oder was auch immer) in die bestehende Grafik "hinein stempeln", oder aber wieder "heraus radieren". Durch diese Verknüpfung wird der Hintergrund meisstens wieder so hergestellt, wie er vorher aussah. Das ist wichtig, wenn da noch weitere Objekte sind, die nicht verändert werden sollen.

Wenn sich die Bewegung nur auf einen bestimmten Bildschirmbereich beschränkt, kann es auch nützlich sein, sich diesen im "Urzustand" in einer Variablen zu merken. Es gibt da zwei Funktionen, die einen rechteckigen Bildschirmausschnitt in ein Char-Array speichern, bzw. den Inhalt eines solchen wieder in auf den Bildschirm bringen. Ich weis jetzt nur gerade nicht wie die heissen ;-) Aber das dürfte auch noch schneller sein, als clearviewport().


Zitat:

Kann man Variablen im Grafikmodus ausgeben? Ich kann ja mittels textoutxy(); einen Text an eine bestimmte Stelle schreiben. In diesem Text kann ich aber nicht wie bei printf("%d",x); Werte ausgeben. Ist dies irgendwie möglich?


Es gibt noch sprintf. Das funktioniert genau so wie printf, nur das die Ausgabe in ein char-Array (string) erfolgt. Den so erstellten String kann man dann mit outtextxy() ausgeben.

Hab an der Funktion mal ein paar Veränderungen vorgenommen, aber nicht getestet...

C++:
void spiegel (void)
{
  char  SeitenNr = 0;           /* Nummer der Seite fuer PAGING */
  int   posX     = getmaxx()/2; /* X-Position der Spiegelmitte  */
  int   posY     = getmaxy()/2; /* Y-Position der Spiegelmitte  */
  int   laenge   = 100;         /* Laenge des Spiegel in Pixel  */

  float a        = 0;           /* Winkel in Bogenmass          */
  float step     = 0.01;        /* Geschwindigkeit der Drehung  */

  double sinA, cosA;

while (!kbhit())
   {
    setvisualpage(SeitenNr);
    setactivepage(SeitenNr^1); // Logische XOR-Verknüpfung; - spart rechenzeit
    rahmen();
    setcolor(1);   // Zeichenfarbe für line festlegen, Farbe des Objektes, hier der Linie

    sinA=sin(a);   // Winkelfunktionen nur einmal berechnen, spart enorm viel Rechenzeit!
    cosA=cos(a);

    line (posX - laenge*cosA, posY - laenge*sinA, posX + laenge*cosA, posY + laenge*sinA);

    // warten... - d.h. hier was einfügen, das ihn warten lässt.

    setcolor(0);   // Zeichenfarbe für line festlegen, Farbe des Hintergrundes
    line (posX - laenge*cosA, posY - laenge*sinA, posX + laenge*cosA, posY + laenge*sinA);
    a= a + step;
    sinA=sin(a);   // Winkelfunktionen hier neu berechnen
    cosA=cos(a);
    rahmen();
    line (posX - laenge*cosA, posY - laenge*sinA, posX + laenge*cosA, posY + laenge*sinA);
    a= a + step;
    SeitenNr = (SeitenNr^1); // siehe oben
   }



Hans


P.S. Wenn ich hier öfter mal schreibe, das ich nicht mehr ganz sicher bin, liegt das daran, dass ich zur Zeit kein Turbo-C++ installiert habe, und auch die Handbücher nicht in greifbarer Nähe liegen.
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 09.11.2004 um 01:00 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
09.11.2004, 13:17 Uhr
~Gast
Gast



Zitat von Hans:

Damit eine Figur an einer Stelle verschwindet, muss sie deshalb mit der Hintergrundfarbe neu gezeichnet werden. Die Zeichenfunktionen bieten aber, wenn ich mich nicht irre, noch die Möglichkeit der XOR-Verknüpfung. Damit kannst Du eine Linie (oder was auch immer) in die bestehende Grafik "hinein stempeln", oder aber wieder "heraus radieren". Durch diese Verknüpfung wird der Hintergrund meisstens wieder so hergestellt, wie er vorher aussah. Das ist wichtig, wenn da noch weitere Objekte sind, die nicht verändert werden sollen.



Hast Du es so bei Deiner Veränderung gemacht? Weil bei mir läuft das Programm ja auch anders. Das mit dem löschen genau der Zeichnung wäre also nur wichtig, wenn man noch andere Zeichnungen im Hintergrund hat, die nicht gelöscht werden? Deshalb werden bei Dir wohl auch die Farben gesetzt richtig?
Ich verstehe, wenn man die Winkelfunktionen nur einmal berechnet, dass man dann weniger Rechenzeit benötigt, verstehe aber nicht die XOR-Verknüpfung für die SeitenNr.


Zitat von Hans:

Es gibt noch sprintf. Das funktioniert genau so wie printf, nur das die Ausgabe in ein char-Array (string) erfolgt. Den so erstellten String kann man dann mit outtextxy() ausgeben.



Das mit sprintf habe ich hinbekommen. Danke.
Habe da noch eine kleine Veränderung beim Wert a vorgenommen. Er würde sonst irgendwann mal aus seinem Wertebereich rauslaufen und dann gäbe es wohl einen Fehler.

Hier mal die neue Spiegelfunktion wie ich Sie habe:


C++:
void spiegel (void)
{
char   SeitenNr = 0;           /* Nummer der Seite fuer PAGING */
int    posX     = getmaxx()/2; /* X-Position der Spiegelmitte  */
int    posY     = getmaxy()/2; /* Y-Position der Spiegelmitte  */
int    laenge   = 100;         /* Laenge des Spiegel in Pixel  */
float  a        = 0;           /* Winkel in Bogenmass          */
float  step     = 0.01;        /* Geschwindigkeit der Drehung  */
double sinA, cosA;                   /* Variablen fuer Winkelfunktion*/
char msg[80];

while (!kbhit())
   {
    setvisualpage(SeitenNr);
    setactivepage(SeitenNr^1);
    rahmen();
    strahl();
    sinA= sin(a);
    cosA= cos(a);
    line (posX - laenge*cosA, posY - laenge*sinA, posX + laenge*cosA, posY + laenge*sinA);
    if (a <= 6.283)
      {
       a= a + step;
      }
    else
      {
       a= 0;
      }
    sprintf(msg, " (%.2f)",a);
    outtextxy(getmaxx()-70,0, msg);
    clearviewport();
    rahmen();
    strahl();
    sinA= sin(a);
    cosA= cos(a);
    line (posX - laenge*cosA, posY - laenge*sinA, posX + laenge*cosA, posY + laenge*sinA);
    if (a <= 6.283)
      {
       a= a + step;
      }
    else
      {
       a= 0;
      }
    sprintf(msg, " (%.2f)",a);
    outtextxy(getmaxx()-70,0, msg);
    SeitenNr = (SeitenNr^1);
   }
}



Neu dazugekommen ist ein Strahl, der von links nach rechts läuft und wenn er angekommen ist wieder neu beginnt. x1 ist als globale Variable festgelegt.


C++:
void strahl (void)
{
if (x1 <= getmaxx())
   {
    moveto(0,40);
    x1= x1+ 3;
    lineto(x1,40);
   }
else
   {
    x1= 0;
   }
}



Kann ich in der Grafikoberfläche auch Benutzereingaben aufnehmen, so in der Art wie scanf oder so ähnlich? Würde gerne so den Startpunkt und wenn irgendwie möglich den Winkel des Strahls eingeben, so das er jedes mal von einer anderen Stelle starten kann.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
09.11.2004, 14:06 Uhr
Hans
Library Walker
(Operator)



Zitat:
Ich verstehe, wenn man die Winkelfunktionen nur einmal berechnet, dass man dann weniger Rechenzeit benötigt,


Gut.


Zitat:
verstehe aber nicht die XOR-Verknüpfung für die SeitenNr.


Der Wert für die Seite ist doch immer Null oder Eins. Bei der Xor-Verknüpfung mit Eins wird der Wert jedesmal umgekehrt, d.h. aus Null wird Eins, und aus Eins wird Null. Genaues zu Xor findest Du hier.
Die Beschleunigung der Rechenzeit entsteht dadurch, das der Prozessor nur eine einzige Operation durchführen muss. Bei der Rechenmethode, die Du vorher hattest, sind es mindestens zwei. Weitere Antworten geb ich heute Abend.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
10.11.2004, 01:18 Uhr
Hans
Library Walker
(Operator)


Hi,

Zitat:
Kann ich in der Grafikoberfläche auch Benutzereingaben aufnehmen, so in der Art wie scanf oder so ähnlich?

im Prinzip ja, aber da musst Du eine Menge selber machen, vor allem, wenn Du ein "Tastatur-echo" haben willst. Tastatur-echo bedeutet, das man sieht, welche Taste gerade gedrückt wurde.
Du brauchst eine "Cursor-Position", weil Du den nämlich selber Verwalten musst, und einen Eingabe-puffer. Eine Eingabefunktion könnte etwa so aussehen:
* mit outtextxy() den Text ausgeben, der besagt, das eine Eingabe erwartet wird. Die Länge des Textes, d.h. die Anzahl der ausgegebenen Zeichen merken, denn die musst Du zur x-position dazu zählen, wo Dein Tastaturecho erscheinen soll.
* eingabepuffer leeren.
* mit getch() ein Zeichen lesen.
* eventuell auf Gültigkeit prüfen. - Wenn Du z.B. keine Buchstaben haben willst, kannst Du sie hier sofort abblocken.
* Zeichen in den Eingabepuffer schreiben, und mit outtextxy() da ausgeben, wo man es erwartet: Hinter der Aufforderung dazu.
* dies wiederholst Du so lange, bis auf "Enter" gedrückt wird.
* in den Eingabepuffer jetzt ein Null-byte ans Ende hängen.
* jetzt kannst Du den Eingabepuffer noch mal überprüfen, (oder auch nicht) und dann z.B. mit sscanf() oder atoi() in eine Variable übernehmen.

Es bietet sich an, dafür eine eigene Funktion zu schreiben, der man die selben Daten übergibt, die auch outtextxy erwartet, die einem aber als Ergebniss das zurückliefert, was der User eingegeben hat. Dann kann man den Eingabepuffer und die Variablen für die Cursorposition lokal verwalten, was die Sache flexibler machen sollte.


Dann hab ich jetzt mal mein TC++ Referenzhandbuch heraus gekramt, und bin beim Blättern auf die Funktionen gestossen, von denen ich gestern schon geschrieben habe. Die zum kopieren und einfügen eines Bildausschnitts: Die heissen getimage() und putimage(). Dann gibt es da noch eine weitere Namens imagesize() die einem den benötigten Speicherplatz für den Puffer berechnet, den get-/putimage benötigen. Da ist auch ein hübsches Beispiel dabei. Und die Funktion zum setzen des Zeichenmodus hab ich auch gefunden, obwohl Du die wahrscheinlich nicht brauchst. Die heisst setwritemode() und legt fest, wie die Zeichenfunktionen wie line(), usw. arbeiten sollen. Damit erübrigt sich die Farbanpassung, die ich oben noch eingebaut hatte, wenn man den writemode auf XOR_PUT setzt. Einfach die Figuren mit den selben Parametern noch mal zeichen und weg sind sie.

So, ich hoffe, das hilft wieder weiter,

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
10.11.2004, 09:54 Uhr
~Gast
Gast



Zitat von Hans:

Im Prinzip ja, aber da musst Du eine Menge selber machen, vor allem, wenn Du ein "Tastatur-echo" haben willst. Tastatur-echo bedeutet, das man sieht, welche Taste gerade gedrückt wurde.
Du brauchst eine "Cursor-Position", weil Du den nämlich selber Verwalten musst, und einen Eingabe-puffer. Eine Eingabefunktion könnte etwa so aussehen:
* mit outtextxy() den Text ausgeben, der besagt, das eine Eingabe erwartet wird. Die Länge des Textes, d.h. die Anzahl der ausgegebenen Zeichen merken, denn die musst Du zur x-position dazu zählen, wo Dein Tastaturecho erscheinen soll.
* eingabepuffer leeren.
* mit getch() ein Zeichen lesen.
* eventuell auf Gültigkeit prüfen. - Wenn Du z.B. keine Buchstaben haben willst, kannst Du sie hier sofort abblocken.
* Zeichen in den Eingabepuffer schreiben, und mit outtextxy() da ausgeben, wo man es erwartet: Hinter der Aufforderung dazu.
* dies wiederholst Du so lange, bis auf "Enter" gedrückt wird.
* in den Eingabepuffer jetzt ein Null-byte ans Ende hängen.
* jetzt kannst Du den Eingabepuffer noch mal überprüfen, (oder auch nicht) und dann z.B. mit sscanf() oder atoi() in eine Variable übernehmen.

Es bietet sich an, dafür eine eigene Funktion zu schreiben, der man die selben Daten übergibt, die auch outtextxy erwartet, die einem aber als Ergebniss das zurückliefert, was der User eingegeben hat. Dann kann man den Eingabepuffer und die Variablen für die Cursorposition lokal verwalten, was die Sache flexibler machen sollte.



Hallo Hans, Du konntest mir schon helfen, auch die XOR-Verknüpfung hast Du gut erklärt aber ich glaube das ist mir dann vorerst doch etwas zu kompliziert mit dem Einlesen von Zeichen.
Habe gestern den Quelltext etwas umgeschrieben und einiges in die main Funktion verlegt.
Man kann einen Lichtstrahl der von links nach rechts über den Bildschirm geht mit den Tasten 8 und 2 nach oben und unten steuern.


C++:
/******************************************************************/
/* Headerdateien                                                  */
/******************************************************************/

#include <graphics.h> /* Wird fuer Grafik benoetigt */
#include <stdio.h>    /* Standard Ein Ausgabe       */
#include <conio.h>
#include <stdlib.h>   /* exit                       */
#include <math.h>     /* sin, cos                   */
#include <dos.h>      /* delay                      */

/******************************************************************/
/* Globale Variablen                                              */
/******************************************************************/

int errorcode, graphdriver, graphmode, x1= 0, y=0;
float a= 0; /* Winkel fuer Spiegel */

/******************************************************************/
/* Funktionen                                                     */
/******************************************************************/

void graphinit(void)
{
int gdriver = 9; /* Grafiktreiber - 9 = VGA                            */
int gmode   = 1; /* Grafikmodus   - 1 = 640x350 16 color 2             */
int errorcode;   /* Variable fuer Fehlercode                           */

/* Grafikmodus wird initialisiert. (Treiber, Modus, Treiberverzeichnis */
initgraph(&gdriver, &gmode, "");

errorcode = graphresult();  /* Grafik Fehlercode                       */

if (errorcode != grOk)    /* Falls Grafikfehler...                     */
  {
   printf("Grafikfehler: %s\n", grapherrormsg(errorcode));
   printf("Zum Beenden Taste druecken.");
   getch();
   exit(1);               /* Programm Ende mit Errorcode */
  }
}

void rahmen()
{
/* Rahmen */
rectangle(0,10,getmaxx(),getmaxy());
outtextxy(0,0,"Strahlengang im rotierenden Spiegel");
}

void strahl (void)
{
if (x1 <= getmaxx())
  {
   moveto(0,100+y);
   x1= x1+ 3;
   lineto(x1,100+y);
  }
else x1= 0;
}

void spiegel (void)
{

int    posX     = getmaxx()/2; /* X-Position der Spiegelmitte  */
int    posY     = getmaxy()/2; /* Y-Position der Spiegelmitte  */
int    laenge   = 100;         /* Laenge des Spiegel in Pixel  */
float  step     = 0.01;        /* Geschwindigkeit der Drehung  */
double sinA, cosA;             /* Variablen fuer Winkelfunktion*/
char msg[6];

sinA= sin(a);
cosA= cos(a);
line (posX - laenge*cosA, posY - laenge*sinA, posX + laenge*cosA, posY + laenge*sinA);
if (a <= 6.283)
   {
    a= a + step;
   }
else
   {
    a= 0;
   }
sprintf(msg, " (%.2f)",a);
outtextxy(getmaxx()-70,0, msg);
}

/******************************************************************/
/* Hauptprogramm                                                  */
/******************************************************************/

void main(void)
{
char   SeitenNr = 0; /* Nummer der Seite fuer PAGING */

graphinit();         /* Grafikinitialisierung        */

while (1)
   {
    if (kbhit())
      {
       switch(getch())
     {
      case 27:
        {
         closegraph();
         exit(1);
        }
      case 50:
        {
         y++;
         break;
        }
      case 56:
        {
         y--;
         break;
        }
     }
      }

    setvisualpage(SeitenNr);
    setactivepage(SeitenNr^1); /* Umkehrung durch XOR-Verknuepfung */
    rahmen();
    spiegel();
    strahl();
    clearviewport();
    rahmen();
    spiegel();
    strahl();
    SeitenNr = (SeitenNr^1);   /* Umkehrung durch XOR-Verknuepfung */
   }
}


Jetzt müßte ich eine Kollisionsabfrage einbauen, d.h. wenn der Lichtstrahl auf den rotierenden Spiegel trifft, soll er erstmal abbrechen und nicht bis zum rechten Bildschirmrand laufen. Würde der Speigel sich nicht drehen, wäre es ja gar nicht so schwer, sogesehen kollidiert der Strahl ja schon mit dem rechten Bildschirmrand und fängt dann wieder von links neu an. Wie das mit einer sich drehenden Linie funktioniert weiß ich nicht. Habe mir auch schon gedacht, dass man vielleicht wie Du gesagt hast den Spiegel ausschneiden muß und ihn dann als Bild abzuspeichern. Dann dreht man am Ende nur das Bild und könnte vielleicht eine Kollision mit dem Bild erzeugen. Im Internet hatte ich etwas darüber gelesen, das man den Bildschirm in Sektoren aufteilen muß usw, dass wäre für mich als Anfänger aber wohl auch wieder zu kompliziert. Wie gehe ich am besten an die Sache ran?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: