<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[StarGame Kollision fehlt nur noch]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich musste ein StarGame als Aufgabe bauen, in dem man ein Schiff in der Konsole steuert, was zum Punkt E (Erde) fliegen muss und dann eine Ausgabe, des Gewinnens ausgibt.<br />
Das entscheidenste dabei ist, dass ich keine Kollision mit Sternen haben darf, und er dann Game Over ausgeben sollte. Alle Methoden der Klasse sind bereits fertig geschrieben, ausgenommen die der Kollision...</p>
<p>Ich werde euch jetzt nur die <a href="http://Starfield.cc" rel="nofollow">Starfield.cc</a> hierrein kopieren, da es sonst einfach viel zu viel wird.</p>
<p>Ich möchte es am liebsten so lösen, dass er mit C.GetCruiserPos() sich die aktuelle Position des Schiffs holt, dann soll er damit prüfen, ob an dieser Koordinate ein char '*' vorhanden ist, und falls ja entweder direkt in ein GameOver() springen oder aber einen bool true zurückgeben...</p>
<p>Allerdings weiß ich noch nicht, wie ich mir die random generierten '*' Koordinaten auslesen lassen sollte...</p>
<pre><code>#include&quot;Starfield.h&quot;
#include&lt;time.h&gt;
#define _TIMED_ 0

void Starfield::Init(){
  screen = initscr();
  raw();
  keypad(stdscr, TRUE);
  nonl();
  cbreak(); 

  getmaxyx(screen, height, width);

  // initialize the score
  score = width + height;

  // generate asteroids data structure;
  asteroids = new char[width * height];

  // create stars at random positions
  for(unsigned int i = 0; i &lt; width * height; i++) {
    if (rand() % 5 == 0) 
      asteroids[i] = '*';
    else
      asteroids[i] = ' ';
  }  

}

Starfield::Starfield() {
  Init();
  Start = new Coord(1,1);

//#ifdef _WIN32
//  srand((unsigned) time(NULL));
//#else
  srand(time(NULL));
//#endif  

  Goal = new Coord(width-1, rand() % height);
}

Starfield::Starfield(Coord start, Coord goal)
{
  Init();
  Start = new Coord(start);
  Goal = new Coord(goal);
}

/** prints the welcome screen and hands over control to
 * the main game control function 
 */
void Starfield::StartGame()
{
  SplashScreen();
  GameControl();
}

/** deletes allocated memory and calls exit game method
 */
Starfield::~Starfield() {
  delete Start;
  delete Goal;
  delete [] asteroids;
  ExitGame();
}

void Starfield::DrawTrace()
{
  /*
  //  if( !has_colors() )  exit(1);

  start_color();	

    init_pair(1, COLOR_WHITE, COLOR_RED);  
    attron(COLOR_PAIR(1));
    path.push_back( (C.GetCruiserOldPos()).GetY() * width + 
    (C.GetCruiserOldPos()).GetX());

    for( std::vector&lt;int&gt;::iterator it = path.begin(); it != path.end(); it ++ ) {
    move(*it/width, *it % width);
    addch('x');
    }
    attroff(COLOR_PAIR(1));
       */
}

/** prints BASE and EARTH at start and goal positions on the screen 
 */
void Starfield::DrawField() 
{
  for(unsigned int i = 0; i &lt; width * height; i++) {
    move( i / width, i % width);
    addch(asteroids[i]);
  }

  mvaddstr(Start-&gt;GetY()-1, Start-&gt;GetX(), (char *) &quot;SHIP&quot;);
  mvaddstr(Start-&gt;GetY(), Start-&gt;GetX(), (char *) &quot;S&quot;);
  mvaddstr(Goal-&gt;GetY()-1, Goal-&gt;GetX()-4, (char *) &quot;EARTH&quot;);
  mvaddstr(Goal-&gt;GetY(), Goal-&gt;GetX(), (char *) &quot;E&quot;);
  DrawTrace();
  DrawCruiser();
  DrawStatusLine();
  refresh();
}

/** outputs a message at the centre of the screen
 * @param message - the message to be printed
 */
void Starfield::SplashMessage( std::string message, bool waitforkey=true)
{
  std::string decoration;
  for(unsigned int i = 0; i &lt; message.length(); i ++ )
    decoration += &quot;*&quot;;

  mvaddstr(height/2-1, width/2-message.length()/2, decoration.c_str());
  mvaddstr(height/2, width/2-message.length()/2, message.c_str());
  mvaddstr(height/2+1, width/2-message.length()/2, decoration.c_str());

  if( waitforkey ){
    mvaddstr(height-1, width/2-10, &quot;Press SPACE&quot;);
    getch();
    clear(); 
  }
}

/** the welcome screen  
*/
void Starfield::SplashScreen() 
{
  clear();
  SplashMessage(&quot;S P A C E - C R U I S E R (TM)&quot;, false);

  char text[] = 
    &quot;In a remote galaxy, our starship troopers &quot; \
    &quot;want to start their way home to celebrate  xmas on planet earth. Of course, &quot; \
    &quot;this mission is very dangerous as they have to fly through the asteroid belt &quot; \
    &quot;to reach planet earth. \n They have only one trial, will they ever make it ... ?&quot;;

  mvaddstr(height/2+5, 0, text);  
  mvaddstr(height-1, width/2-10, &quot;Press SPACE&quot;);
  getch();
  clear(); 
  DrawField();
  if (_TIMED_) halfdelay(1);
}

/** the winning screen 
*/
void Starfield::YouWin()
{
  cbreak();
  SplashMessage(&quot;CONGRATS, YOU FOUND BACK TO EARTH! MERRY XMAS&quot;);
  ExitGame();
}

/** game over screen 
 */
void Starfield::GameOver()
{
  cbreak();
  SplashMessage(&quot;G A M E  O V E R&quot;);
  ExitGame();
}

/** draw the cruiser symbol at the current position
 */
void Starfield::DrawCruiser() const
{
  move(C.GetY(), C.GetX());
  addch(C.GetCruiserSymbol());
}

/** test for collisions of the space ship with asteroids
 */
void Starfield::TestCollision() const
{
  if(C.GetCruiserPos() == '*')
	{
	GameOver();
	}
}

/** checks if the space ship already reached planet earth, i.e.
 * the goal position 
 */
void Starfield::CheckForEarth() 
{
  if( C.GetCruiserPos() == *Goal ) {
    YouWin();
    ExitGame();
  }
}

/** prints the current position and the goal position in the status line,
 * i.e. the last line of the screen 
 */
void Starfield::DrawStatusLine() const
{
  move(height-1, 1);
  std::stringstream ssship;
  std::stringstream ssearth;
  Coord ship(C.GetCruiserPos());
  Coord earth(*Goal);
  ssship &lt;&lt; ship;
  ssearth &lt;&lt; earth;

  printw(&quot;ship pos: %s &quot;, ssship.str().c_str());
  printw(&quot;earth pos: %s &quot;, ssearth.str().c_str());
  printw(&quot;lives: %i &quot;, 3);
  printw(&quot;time: %i &quot;, 120);
  printw(&quot;score: %i &quot;, score);
}

/** the main game control
 * this function reads the next keyboard input and 
 * depending on the arrow key pressed will call the appropriate
 * function for ship movement. At the end, the game field,
 * status line collision test and goal test are performed */
void Starfield::GameControl()
{
  DrawField();

  while (true) {
  //   noecho(); /* don't echo input */
    int c = 0;
     c = getch();

     //     if ( c == -1 ) { exit(1); DrawField(); return;}
     switch(c) {
     case RIGHT:
       C.MoveRight();
       score--;
       break;
     case LEFT:
       C.MoveLeft();
       score--;
       break;
     case UP:
       C.MoveUp();
       score--;
       break;
     case DOWN:
       C.MoveDown();
       score--;
       break;
     case 'q':
       ExitGame();
     default:      
       DrawField();
       //nothing;
       break;
     }
     DrawField();
     DrawStatusLine();
     TestCollision();
     CheckForEarth();
  }
}

/** cleans up and terminates the window and exits the game 
 */
void Starfield::ExitGame()
{ 
  clear(); 
  endwin(); 
  exit(1);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/329941/stargame-kollision-fehlt-nur-noch</link><generator>RSS for Node</generator><lastBuildDate>Fri, 03 Jul 2026 18:51:41 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/329941.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 15 Dec 2014 12:05:15 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to StarGame Kollision fehlt nur noch on Mon, 15 Dec 2014 12:05:15 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich musste ein StarGame als Aufgabe bauen, in dem man ein Schiff in der Konsole steuert, was zum Punkt E (Erde) fliegen muss und dann eine Ausgabe, des Gewinnens ausgibt.<br />
Das entscheidenste dabei ist, dass ich keine Kollision mit Sternen haben darf, und er dann Game Over ausgeben sollte. Alle Methoden der Klasse sind bereits fertig geschrieben, ausgenommen die der Kollision...</p>
<p>Ich werde euch jetzt nur die <a href="http://Starfield.cc" rel="nofollow">Starfield.cc</a> hierrein kopieren, da es sonst einfach viel zu viel wird.</p>
<p>Ich möchte es am liebsten so lösen, dass er mit C.GetCruiserPos() sich die aktuelle Position des Schiffs holt, dann soll er damit prüfen, ob an dieser Koordinate ein char '*' vorhanden ist, und falls ja entweder direkt in ein GameOver() springen oder aber einen bool true zurückgeben...</p>
<p>Allerdings weiß ich noch nicht, wie ich mir die random generierten '*' Koordinaten auslesen lassen sollte...</p>
<pre><code>#include&quot;Starfield.h&quot;
#include&lt;time.h&gt;
#define _TIMED_ 0

void Starfield::Init(){
  screen = initscr();
  raw();
  keypad(stdscr, TRUE);
  nonl();
  cbreak(); 

  getmaxyx(screen, height, width);

  // initialize the score
  score = width + height;

  // generate asteroids data structure;
  asteroids = new char[width * height];

  // create stars at random positions
  for(unsigned int i = 0; i &lt; width * height; i++) {
    if (rand() % 5 == 0) 
      asteroids[i] = '*';
    else
      asteroids[i] = ' ';
  }  

}

Starfield::Starfield() {
  Init();
  Start = new Coord(1,1);

//#ifdef _WIN32
//  srand((unsigned) time(NULL));
//#else
  srand(time(NULL));
//#endif  

  Goal = new Coord(width-1, rand() % height);
}

Starfield::Starfield(Coord start, Coord goal)
{
  Init();
  Start = new Coord(start);
  Goal = new Coord(goal);
}

/** prints the welcome screen and hands over control to
 * the main game control function 
 */
void Starfield::StartGame()
{
  SplashScreen();
  GameControl();
}

/** deletes allocated memory and calls exit game method
 */
Starfield::~Starfield() {
  delete Start;
  delete Goal;
  delete [] asteroids;
  ExitGame();
}

void Starfield::DrawTrace()
{
  /*
  //  if( !has_colors() )  exit(1);

  start_color();	

    init_pair(1, COLOR_WHITE, COLOR_RED);  
    attron(COLOR_PAIR(1));
    path.push_back( (C.GetCruiserOldPos()).GetY() * width + 
    (C.GetCruiserOldPos()).GetX());

    for( std::vector&lt;int&gt;::iterator it = path.begin(); it != path.end(); it ++ ) {
    move(*it/width, *it % width);
    addch('x');
    }
    attroff(COLOR_PAIR(1));
       */
}

/** prints BASE and EARTH at start and goal positions on the screen 
 */
void Starfield::DrawField() 
{
  for(unsigned int i = 0; i &lt; width * height; i++) {
    move( i / width, i % width);
    addch(asteroids[i]);
  }

  mvaddstr(Start-&gt;GetY()-1, Start-&gt;GetX(), (char *) &quot;SHIP&quot;);
  mvaddstr(Start-&gt;GetY(), Start-&gt;GetX(), (char *) &quot;S&quot;);
  mvaddstr(Goal-&gt;GetY()-1, Goal-&gt;GetX()-4, (char *) &quot;EARTH&quot;);
  mvaddstr(Goal-&gt;GetY(), Goal-&gt;GetX(), (char *) &quot;E&quot;);
  DrawTrace();
  DrawCruiser();
  DrawStatusLine();
  refresh();
}

/** outputs a message at the centre of the screen
 * @param message - the message to be printed
 */
void Starfield::SplashMessage( std::string message, bool waitforkey=true)
{
  std::string decoration;
  for(unsigned int i = 0; i &lt; message.length(); i ++ )
    decoration += &quot;*&quot;;

  mvaddstr(height/2-1, width/2-message.length()/2, decoration.c_str());
  mvaddstr(height/2, width/2-message.length()/2, message.c_str());
  mvaddstr(height/2+1, width/2-message.length()/2, decoration.c_str());

  if( waitforkey ){
    mvaddstr(height-1, width/2-10, &quot;Press SPACE&quot;);
    getch();
    clear(); 
  }
}

/** the welcome screen  
*/
void Starfield::SplashScreen() 
{
  clear();
  SplashMessage(&quot;S P A C E - C R U I S E R (TM)&quot;, false);

  char text[] = 
    &quot;In a remote galaxy, our starship troopers &quot; \
    &quot;want to start their way home to celebrate  xmas on planet earth. Of course, &quot; \
    &quot;this mission is very dangerous as they have to fly through the asteroid belt &quot; \
    &quot;to reach planet earth. \n They have only one trial, will they ever make it ... ?&quot;;

  mvaddstr(height/2+5, 0, text);  
  mvaddstr(height-1, width/2-10, &quot;Press SPACE&quot;);
  getch();
  clear(); 
  DrawField();
  if (_TIMED_) halfdelay(1);
}

/** the winning screen 
*/
void Starfield::YouWin()
{
  cbreak();
  SplashMessage(&quot;CONGRATS, YOU FOUND BACK TO EARTH! MERRY XMAS&quot;);
  ExitGame();
}

/** game over screen 
 */
void Starfield::GameOver()
{
  cbreak();
  SplashMessage(&quot;G A M E  O V E R&quot;);
  ExitGame();
}

/** draw the cruiser symbol at the current position
 */
void Starfield::DrawCruiser() const
{
  move(C.GetY(), C.GetX());
  addch(C.GetCruiserSymbol());
}

/** test for collisions of the space ship with asteroids
 */
void Starfield::TestCollision() const
{
  if(C.GetCruiserPos() == '*')
	{
	GameOver();
	}
}

/** checks if the space ship already reached planet earth, i.e.
 * the goal position 
 */
void Starfield::CheckForEarth() 
{
  if( C.GetCruiserPos() == *Goal ) {
    YouWin();
    ExitGame();
  }
}

/** prints the current position and the goal position in the status line,
 * i.e. the last line of the screen 
 */
void Starfield::DrawStatusLine() const
{
  move(height-1, 1);
  std::stringstream ssship;
  std::stringstream ssearth;
  Coord ship(C.GetCruiserPos());
  Coord earth(*Goal);
  ssship &lt;&lt; ship;
  ssearth &lt;&lt; earth;

  printw(&quot;ship pos: %s &quot;, ssship.str().c_str());
  printw(&quot;earth pos: %s &quot;, ssearth.str().c_str());
  printw(&quot;lives: %i &quot;, 3);
  printw(&quot;time: %i &quot;, 120);
  printw(&quot;score: %i &quot;, score);
}

/** the main game control
 * this function reads the next keyboard input and 
 * depending on the arrow key pressed will call the appropriate
 * function for ship movement. At the end, the game field,
 * status line collision test and goal test are performed */
void Starfield::GameControl()
{
  DrawField();

  while (true) {
  //   noecho(); /* don't echo input */
    int c = 0;
     c = getch();

     //     if ( c == -1 ) { exit(1); DrawField(); return;}
     switch(c) {
     case RIGHT:
       C.MoveRight();
       score--;
       break;
     case LEFT:
       C.MoveLeft();
       score--;
       break;
     case UP:
       C.MoveUp();
       score--;
       break;
     case DOWN:
       C.MoveDown();
       score--;
       break;
     case 'q':
       ExitGame();
     default:      
       DrawField();
       //nothing;
       break;
     }
     DrawField();
     DrawStatusLine();
     TestCollision();
     CheckForEarth();
  }
}

/** cleans up and terminates the window and exits the game 
 */
void Starfield::ExitGame()
{ 
  clear(); 
  endwin(); 
  exit(1);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2432945</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2432945</guid><dc:creator><![CDATA[huwul]]></dc:creator><pubDate>Mon, 15 Dec 2014 12:05:15 GMT</pubDate></item><item><title><![CDATA[Reply to StarGame Kollision fehlt nur noch on Mon, 15 Dec 2014 12:39:00 GMT]]></title><description><![CDATA[<p>Huh?<br />
Du brauchst doch nur eine Funktion</p>
<pre><code class="language-cpp">bool Starfield::is_asteroid_at(Coord c) const
{
  // Angenommen Coord(0,0) ist links oben
  return asteroids[c.GetY() * width + c.GetX()]=='*';
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2432953</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2432953</guid><dc:creator><![CDATA[Furble Wurble]]></dc:creator><pubDate>Mon, 15 Dec 2014 12:39:00 GMT</pubDate></item><item><title><![CDATA[Reply to StarGame Kollision fehlt nur noch on Mon, 15 Dec 2014 13:17:55 GMT]]></title><description><![CDATA[<p>Das müsstest Du mir mal genauer erläutern, was genau ich hier zurückgebe ?</p>
<p>Ja 0,0 ist oben links.</p>
<p>width ist hier die Breite des Screen Windows.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2432960</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2432960</guid><dc:creator><![CDATA[huwul]]></dc:creator><pubDate>Mon, 15 Dec 2014 13:17:55 GMT</pubDate></item><item><title><![CDATA[Reply to StarGame Kollision fehlt nur noch on Mon, 15 Dec 2014 14:17:14 GMT]]></title><description><![CDATA[<p>Hat sich bereits erledigt, aber danke du hast mir trotzdem geholfen..</p>
<pre><code>void Starfield::TestCollision() //const
{
   if(asteroids[C.GetY() * width + C.GetX()]=='*'){GameOver();}
}
</code></pre>
<p>mehr wars nicht..</p>
<p>Jetzt kann ich mir nur noch additional überlegen, ob ich Lebenszähler und Zeitzähler einfüge... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Okay edit:</p>
<p>Problem ist, dass er auf dem E von Earth ebenfalls ins Game Over übergeht obwohl er es ja eigentlich nur für den * machen sollte :o</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2432965</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2432965</guid><dc:creator><![CDATA[huwul]]></dc:creator><pubDate>Mon, 15 Dec 2014 14:17:14 GMT</pubDate></item></channel></rss>