Prechádzať zdrojové kódy

Asteroiden hinzugefügt

Kolja Strohm 6 rokov pred
rodič
commit
705f56e0a8

+ 4 - 0
Asteroids Linux/Asteroids Linux.vcxproj

@@ -51,10 +51,12 @@
     <IntDir>$(ProjectDir)obj\$(Platform)\release\</IntDir>
   </PropertyGroup>
   <ItemGroup>
+    <ClCompile Include="..\Asteroids\Asteroid.cpp" />
     <ClCompile Include="..\Asteroids\Editor.cpp" />
     <ClCompile Include="..\Asteroids\KartenLeser.cpp" />
     <ClCompile Include="..\Asteroids\Klient.cpp" />
     <ClCompile Include="..\Asteroids\Karte.cpp" />
+    <ClCompile Include="..\Asteroids\Pixel.cpp" />
     <ClCompile Include="..\Asteroids\Strukturen.cpp" />
     <ClCompile Include="..\Asteroids\SpielObjekt.cpp" />
     <ClCompile Include="..\Asteroids\Laser.cpp" />
@@ -68,6 +70,8 @@
     <ClCompile Include="..\Asteroids\TeamStatistik.cpp" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="..\Asteroids\Asteroid.h" />
+    <ClInclude Include="..\Asteroids\Pixel.h" />
     <ClInclude Include="..\Asteroids\SSDatenbankV.h" />
     <ClInclude Include="..\Asteroids\Editor.h" />
     <ClInclude Include="..\Asteroids\ESEditorV.h" />

+ 15 - 0
Asteroids Linux/Asteroids Linux.vcxproj.filters

@@ -43,6 +43,9 @@
     <Filter Include="Spiel\Team">
       <UniqueIdentifier>{7af58e2f-8a20-454a-a056-1e169883dc89}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Spiel\Asteroid">
+      <UniqueIdentifier>{ce5d6af0-1b38-4f8c-8303-65676c647e93}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\Asteroids\Editor.cpp">
@@ -90,6 +93,12 @@
     <ClCompile Include="..\Asteroids\STS.cpp">
       <Filter>Spiel</Filter>
     </ClCompile>
+    <ClCompile Include="..\Asteroids\Asteroid.cpp">
+      <Filter>Spiel\Asteroid</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Asteroids\Pixel.cpp">
+      <Filter>Spiel\Asteroid</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\Asteroids\SSDatenbankV.h">
@@ -152,5 +161,11 @@
     <ClInclude Include="..\Asteroids\Team.h">
       <Filter>Spiel\Team</Filter>
     </ClInclude>
+    <ClInclude Include="..\Asteroids\Asteroid.h">
+      <Filter>Spiel\Asteroid</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Asteroids\Pixel.h">
+      <Filter>Spiel\Asteroid</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>

+ 65 - 0
Asteroids/Asteroid.cpp

@@ -0,0 +1,65 @@
+#include "Asteroid.h"
+
+Asteroid::Asteroid( int id, Vertex pos, Vertex speed, float rot, float rotS, Model2DData *data )
+    : Model2DObject()
+{
+    this->id = id;
+    setPosition( pos );
+    setSpeed( speed );
+    setDrehung( rot );
+    setDrehungSpeed( rotS );
+    setModel( data );
+}
+
+bool Asteroid::tick( const WeltInfo &info, double zeit )
+{
+    wInfo = info;
+    return Model2DObject::tick( info, zeit );
+}
+
+Asteroid *Asteroid::istTreffer( Laser *zL, RandomGenerator *zRandG, int &asteroidId, Vertex &pos )
+{
+    Vertex hp;
+    for( int i = 0; i < 3; i++ )
+    {
+        for( int j = 0; j < 3; j++ )
+        {
+            pos = zL->getPosition() + Punkt( ( i - 1 ) * wInfo.size.x, ( j - 1 ) * wInfo.size.y );
+            if( istPunktInnen( pos ) && calcHitPoint( pos - zL->getSpeed(), zL->getSpeed(), hp ) )
+            {
+                Polygon2D a, b;
+                Punkt pa, pb;
+                if( zModel()->split( getObjectPos( hp ), getObjectDir( zL->getSpeed() ) * 0.1f, ( char* )"", a, b, pa, pb, [ zRandG ]() -> double
+                {
+                    return zRandG->rand();
+                } ) )
+                {
+                    impuls( pos - zL->getSpeed(), zL->getSpeed() * 0.05f );
+                    hp = ( hp * getSize() ).rotation( getDrehung() ) + getPosition();
+                    Vertex pav = ( (Vertex)pa ).rotation( getDrehung() ) + getPosition();
+                    Vertex pbv = ( (Vertex)pb ).rotation( getDrehung() ) + getPosition();
+                    Array< Polygon2D > *npaA = new Array< Polygon2D >();
+                    npaA->add( a );
+                    Model2DData *npdA = new Model2DData();
+                    npdA->erstelleModell( npaA );
+                    Array< Polygon2D > *npaB = new Array< Polygon2D >();
+                    npaB->add( b );
+                    Model2DData *npdB = new Model2DData();
+                    npdB->erstelleModell( npaB );
+                    Asteroid *astr = new Asteroid( asteroidId++, pav, getSpeed() * (float)zRandG->rand(), getDrehung(), getDrehungSpeed() * (float)zRandG->rand(), npdA );
+                    setSpeed( getSpeed() * (float)zRandG->rand() );
+                    setDrehungSpeed( getDrehungSpeed() * (float)zRandG->rand() );
+                    setModel( npdB );
+                    setPosition( pbv );
+                    return astr;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+int Asteroid::getId() const
+{
+    return id;
+}

+ 19 - 0
Asteroids/Asteroid.h

@@ -0,0 +1,19 @@
+#pragma once
+#include <Model2D.h>
+#include "Laser.h"
+#include <Random.h>
+
+using namespace Framework;
+
+class Asteroid : public Model2DObject
+{
+private:
+    int id;
+    WeltInfo wInfo;
+
+public:
+    Asteroid( int id, Vertex pos, Vertex speed, float rot, float rotS, Model2DData *data );
+    bool tick( const WeltInfo &info, double zeit ) override;
+    Asteroid *istTreffer( Laser *zL, RandomGenerator *zRandG, int &asteroidId, Vertex &pos );
+    int getId() const;
+};

+ 68 - 8
Asteroids/Klient.cpp

@@ -73,21 +73,15 @@ void Klient::sendeStart( int spielZeit )
 	delete[] bytes;
 }
 
-void Klient::sendeTastaturStatus( int spielerId, TastaturStatus ts, bool aktiv, int spielZeit, Vertex pos, Vertex speed, float rot, float rotS )
+void Klient::sendeTastaturStatus( int spielerId, TastaturStatus ts, bool aktiv, int spielZeit )
 {
 	if( !klient )
 		return;
-	short len = 33;
+	short len = 9;
 	char *bytes = new char[ len ];
 	*(int*)bytes = spielZeit;
 	*(char*)( bytes + 4 ) = (char)( (char)ts * 2 + (char)!aktiv );
 	*(int*)( bytes + 5 ) = spielerId;
-    *(float*)( bytes + 9 ) = pos.x;
-    *(float*)( bytes + 13 ) = pos.y;
-    *(float*)( bytes + 17 ) = speed.x;
-    *(float*)( bytes + 21 ) = speed.y;
-    *(float*)( bytes + 25 ) = rot;
-    *(float*)( bytes + 29 ) = rotS;
 	klient->spielNachricht( len, bytes );
 	delete[] bytes;
 }
@@ -106,6 +100,26 @@ void Klient::sendeSkillNachricht( int sNum, char art, int spielZeit )
 	delete[] bytes;
 }
 
+void Klient::sendeAsteroid( int id, Vertex pos, Vertex speed, float rot, float rotS, int index, int spielZeit )
+{
+    if( !klient )
+        return;
+    short len = 37;
+    char *bytes = new char[ len ];
+    *(int*)bytes = spielZeit;
+    *(char*)( bytes + 4 ) = 0x11;
+    *(int*)( bytes + 5 ) = id;
+    *(float*)( bytes + 9 ) = pos.x;
+    *(float*)( bytes + 13 ) = pos.y;
+    *(float*)( bytes + 17 ) = speed.x;
+    *(float*)( bytes + 21 ) = speed.y;
+    *(float*)( bytes + 25 ) = rot;
+    *(float*)( bytes + 29 ) = rotS;
+    *(int*)( bytes + 33 ) = index;
+    klient->spielNachricht( len, bytes );
+    delete[] bytes;
+}
+
 void Klient::sendeSchuss( int id, int sNum, Vertex pos, Vertex speed, double intensity, int spielZeit )
 {
 	if( !klient )
@@ -125,6 +139,34 @@ void Klient::sendeSchuss( int id, int sNum, Vertex pos, Vertex speed, double int
 	delete[] bytes;
 }
 
+void Klient::sendePixel( int asteroid, int pixelId, int spielZeit )
+{
+    if( !klient )
+        return;
+    short len = 13;
+    char *bytes = new char[ len ];
+    *(int*)bytes = spielZeit;
+    *(char*)( bytes + 4 ) = 0x13;
+    *(int*)( bytes + 5 ) = asteroid;
+    *(int*)( bytes + 9 ) = pixelId;
+    klient->spielNachricht( len, bytes );
+    delete[] bytes;
+}
+
+void Klient::sendeEp( int pixelId, int spielerId, int spielZeit )
+{
+    if( !klient )
+        return;
+    short len = 13;
+    char *bytes = new char[ len ];
+    *(int*)bytes = spielZeit;
+    *(char*)( bytes + 4 ) = 0x14;
+    *(int*)( bytes + 5 ) = pixelId;
+    *(int*)( bytes + 9 ) = spielerId;
+    klient->spielNachricht( len, bytes );
+    delete[] bytes;
+}
+
 void Klient::sendeTreffer( int id, int sNum, int spielZeit )
 {
 	if( !klient )
@@ -139,6 +181,24 @@ void Klient::sendeTreffer( int id, int sNum, int spielZeit )
 	delete[] bytes;
 }
 
+void Klient::sendeAsteroidTreffer( int asteroidId, int newAsteroidId, int schussId, Vertex pos, __int64 seed, int spielZeit )
+{
+    if( !klient )
+        return;
+    short len = 33;
+    char *bytes = new char[ len ];
+    *(int*)bytes = spielZeit;
+    *(char*)( bytes + 4 ) = 0x12;
+    *(int*)( bytes + 5 ) = schussId;
+    *(int*)( bytes + 9 ) = asteroidId;
+    *(float*)( bytes + 13 ) = pos.x;
+    *(float*)( bytes + 17 ) = pos.y;
+    *(__int64*)( bytes + 21 ) = seed;
+    *(int*)( bytes + 29 ) = newAsteroidId;
+    klient->spielNachricht( len, bytes );
+    delete[] bytes;
+}
+
 void Klient::sendeWiederbelebung( int sNum, int spielZeit )
 {
 	if( !klient )

+ 42 - 0
Asteroids/Pixel.cpp

@@ -0,0 +1,42 @@
+#include "Pixel.h"
+
+Pixel::Pixel( Vertex pos, Vertex speed, float ep, int id )
+    : Object2D()
+{
+    setPosition( pos );
+    setSpeed( speed );
+    this->ep = ep;
+    pixelId = id;
+    collision = false;
+}
+
+bool Pixel::tick( const WeltInfo &info, double zeit )
+{
+    ep -= (float)zeit;
+    return Object2D::tick( info, zeit );
+}
+
+void Pixel::render( Mat3< float > &kamMat, Bild &zRObj, const char *kamName )
+{}
+
+Rect2< float > Pixel::getBoundingBox() const
+{
+    Rect2< float > r = Rect2< float >();
+    r.topLeft.x = -( ep / 5 + 1 );
+    r.topLeft.y = -( ep / 5 + 1 );
+    r.bottomRight.x = ep / 5 + 1;
+    r.bottomRight.y = ep / 5 + 1;
+    r.topLeft = getWorldPos( r.topLeft );
+    r.bottomRight = getWorldPos( r.bottomRight );
+    return r;
+}
+
+float Pixel::getEp() const
+{
+    return ep;
+}
+
+int Pixel::getId() const
+{
+    return pixelId;
+}

+ 20 - 0
Asteroids/Pixel.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#include <Welt2D.h>
+
+using namespace Framework;
+
+class Pixel : public Object2D
+{
+private:
+    float ep;
+    int pixelId;
+
+public:
+    Pixel( Vertex pos, Vertex speed, float ep, int id );
+    bool tick( const WeltInfo &info, double zeit ) override;
+    void render( Mat3< float > &kamMat, Bild &zRObj, const char *kamName ) override;
+    Rect2< float > getBoundingBox() const override;
+    float getEp() const;
+    int getId() const;
+};

+ 5 - 1
Asteroids/SSKlient.h

@@ -29,10 +29,14 @@ public:
 	void sendeInit( RCArray< Spieler > *zSpieler, int spielZeit );
 	void sendeSpielerNummer( int sNum, int spielZeit );
 	void sendeStart( int spielZeit );
-	void sendeTastaturStatus( int spielerId, TastaturStatus ts, bool aktiv, int spielZeit, Vertex pos, Vertex speed, float rot, float rotS );
+	void sendeTastaturStatus( int spielerId, TastaturStatus ts, bool aktiv, int spielZeit );
 	void sendeSkillNachricht( int sNum, char art, int spielZeit );
+    void sendeAsteroid( int id, Vertex pos, Vertex speed, float rot, float rotS, int index, int spielZeit );
 	void sendeSchuss( int id, int sNum, Vertex pos, Vertex speed, double intensity, int spielZeit );
+    void sendePixel( int asteroid, int pixelId, int spielZeit );
+    void sendeEp( int pixelId, int spielerId, int spielZeit );
 	void sendeTreffer( int id, int sNum, int spielZeit );
+    void sendeAsteroidTreffer( int asteroidId, int newAsteroidId, int schussId, Vertex pos, __int64 seed, int spielZeit );
 	void sendeWiederbelebung( int sNum, int spielZeit );
 	void sendeTod( int sNum, int killSNum, int spielZeit );
 	void sendeSpielEnde( char gewonnen, int spielZeit );

+ 583 - 448
Asteroids/Spiel.cpp

@@ -7,6 +7,8 @@
 #include "Statistik.h"
 #include "Team.h"
 #include "Laser.h"
+#include <M2Datei.h>
+#include <iostream>
 #ifdef WIN32
 #include <random>
 #else
@@ -20,80 +22,89 @@
 // Konstruktor
 Spiel::Spiel()
 {
-	zAccounts = 0;
-	zKlients = 0;
-	stat = new Statistik();
-	teams = new RCArray< Team >();
-	teamAnzahl = 0;
-	spieler = new RCArray< Spieler >();
-	shots = new RCArray< Laser >();
-	objekte = new RCArray< SpielObjekt >();
+    zAccounts = 0;
+    zKlients = 0;
+    asteroids = new RCArray< Asteroid >();
+    asteroidModels = new RCArray< Model2DData >();
+    stat = new Statistik();
+    teams = new RCArray< Team >();
+    teamAnzahl = 0;
+    spieler = new RCArray< Spieler >();
+    shots = new RCArray< Laser >();
+    objekte = new RCArray< SpielObjekt >();
     welt = new Welt2D();
+    pixel = new RCArray< Pixel >();
     welt->setCircular( 1 );
     welt->setAirResistance( 0.001f );
-	psqldb = 0;
-	spielId = 0;
-	karteId = 0;
-	spielerAnzahl = 0;
-	karte = 0;
-	InitializeCriticalSection( &cs );
-	sts = 0;
-	log = 0;
-	isRunning = 0;
-	spielZeit = 0;
-	ende = 1;
-	nextSchussId = 1;
-	ref = 1;
+    psqldb = 0;
+    spielId = 0;
+    karteId = 0;
+    spielerAnzahl = 0;
+    karte = 0;
+    InitializeCriticalSection( &cs );
+    sts = 0;
+    log = 0;
+    isRunning = 0;
+    spielZeit = 0;
+    ende = 1;
+    nextSchussId = 1;
+    nextAsteroid = 30;
+    asteroidId = 0;
+    pixelId = 0;
+    ref = 1;
 }
 
 // Destruktor
 Spiel::~Spiel()
 {
-	teams->release();
-	stat->release();
-	spieler->release();
-	objekte->release();
+    teams->release();
+    stat->release();
+    spieler->release();
+    objekte->release();
     welt->release();
-	if( psqldb )
-		psqldb->release();
-	if( karte )
-		karte->release();
-	if( sts )
-		sts->release();
-	DeleteCriticalSection( &cs );
+    asteroids->release();
+    asteroidModels->release();
+    if( psqldb )
+        psqldb->release();
+    if( karte )
+        karte->release();
+    if( sts )
+        sts->release();
+    pixel->release();
+    DeleteCriticalSection( &cs );
 }
 
 // privat
 int Spiel::getTeamVonSpieler( int sNum )
 {
-	for( int i = 0; i < spielerAnzahl; i++ )
-	{
-		Spieler *tmp = spieler->z( i );
-		if( tmp && tmp->getSpielerNummer() == sNum )
-			return tmp->zTeam() ? tmp->zTeam()->id : 0;
-	}
-	return 0;
+    for( int i = 0; i < spielerAnzahl; i++ )
+    {
+        Spieler *tmp = spieler->z( i );
+        if( tmp && tmp->getSpielerNummer() == sNum )
+            return tmp->zTeam() ? tmp->zTeam()->id : 0;
+    }
+    return 0;
 }
 
 // nicht constant
 void Spiel::setPSQLK( SSDatenbankV *psqldb )
 {
-	if( this->psqldb )
-		this->psqldb->release();
-	this->psqldb = psqldb;
-	stat->setPSQLDB( psqldb->getThis() );
+    if( this->psqldb )
+        this->psqldb->release();
+    this->psqldb = psqldb;
+    stat->setPSQLDB( psqldb->getThis() );
 }
 
 void Spiel::setSpielId( int id )
 {
-	spielId = id;
-	stat->setSpielId( id );
+    spielId = id;
+    stat->setSpielId( id );
 }
 
 void Spiel::setKarteId( int karteId )
 {
-	this->karteId = karteId;
-	stat->setKarteId( karteId );
+    this->karteId = karteId;
+    stat->setKarteId( karteId );
 }
 
 void Spiel::setTempPfad( char *pfad )
@@ -104,30 +115,30 @@ void Spiel::setTempPfad( char *pfad )
 
 void Spiel::setAccounts( int anzahl, Array< int > *zAccounts )
 {
-	this->zAccounts = zAccounts->getThis();
-	spielerAnzahl = anzahl;
+    this->zAccounts = zAccounts->getThis();
+    spielerAnzahl = anzahl;
 }
 
 void Spiel::setKlients( int anzahl, RCArray< SSKlientV > *zKlients )
 {
-	this->zKlients = zKlients->getThis();
+    this->zKlients = zKlients->getThis();
 }
 
 void Spiel::setSpielerNummern( int anzahl, Array< int > *spielerNummern )
 {
-	if( !sts )
-	{
-		sts = new SpielerTeamStruktur();
-		KartenLeser *reader = new KartenLeser( karteId, psqldb->getThis(), mapPfad );
-		reader->ladeSpielerTeamStruktur( sts );
-		if( karte )
-			karte->release();
-		karte = reader->ladeKarte( sts );
-		reader->release();
-		for( int i = 0; i < sts->teamAnzahl; i++ )
-			teams->set( karte->createTeam( i ), i );
-		stat->setTeamNamen( sts->teamName->getThis() );
-		int objektAnzahl = karte->getObjektAnzahl();
+    if( !sts )
+    {
+        sts = new SpielerTeamStruktur();
+        KartenLeser *reader = new KartenLeser( karteId, psqldb->getThis(), mapPfad );
+        reader->ladeSpielerTeamStruktur( sts );
+        if( karte )
+            karte->release();
+        karte = reader->ladeKarte( sts );
+        reader->release();
+        for( int i = 0; i < sts->teamAnzahl; i++ )
+            teams->set( karte->createTeam( i ), i );
+        stat->setTeamNamen( sts->teamName->getThis() );
+        int objektAnzahl = karte->getObjektAnzahl();
         for( int i = 0; i < objektAnzahl; i++ )
         {
             SpielObjekt *obj = karte->createObjekt( i );
@@ -136,435 +147,559 @@ void Spiel::setSpielerNummern( int anzahl, Array< int > *spielerNummern )
         }
         welt->setSize( karte->getSize().x, karte->getSize().y );
         welt->setSize( 1 );
-	}
-	for( int i = 0; i < anzahl; i++ )
-	{
-		Spieler *tmp = karte->createSpieler( spielerNummern->get( i ) );
-		if( tmp )
-		{
-			int team = 0;
-			int von = 0;
-			int bis = 0;
-			for( int j = 0; j < sts->teamAnzahl; j++ )
-			{
-				bis = von + ( sts->teamSize->hat( j ) ? sts->teamSize->get( j ) : 0 );
-				if( tmp->getSpielerNummer() >= von && tmp->getSpielerNummer() < bis )
-				{
-					team = j;
-					break;
-				}
-				von = bis;
-			}
-			tmp->setTeam( teams->get( team ) );
-			teams->z( team )->spieler->add( tmp );
-		}
+    }
+    for( int i = 0; i < anzahl; i++ )
+    {
+        Spieler *tmp = karte->createSpieler( spielerNummern->get( i ) );
+        if( tmp )
+        {
+            int team = 0;
+            int von = 0;
+            int bis = 0;
+            for( int j = 0; j < sts->teamAnzahl; j++ )
+            {
+                bis = von + ( sts->teamSize->hat( j ) ? sts->teamSize->get( j ) : 0 );
+                if( tmp->getSpielerNummer() >= von && tmp->getSpielerNummer() < bis )
+                {
+                    team = j;
+                    break;
+                }
+                von = bis;
+            }
+            tmp->setTeam( teams->get( team ) );
+            teams->z( team )->spieler->add( tmp );
+        }
         welt->addObject( tmp->getThis() );
-		spieler->set( tmp, i );
-	}
-	for( int i = 0; i < anzahl; i++ )
-		spieler->z( i )->setAccountId( zAccounts->hat( i ) ? zAccounts->get( i ) : 0 );
-	for( int i = 0; i < anzahl; i++ )
-		spieler->z( i )->setKlient( new Klient( zKlients->get( i ) ) );
-	stat->setSpieler( spielerAnzahl, spieler );
-	zAccounts = zAccounts->release();
-	zKlients = zKlients->release();
-	teamAnzahl = 0;
-	for( int i = 0; i < sts->teamAnzahl; i++ )
-		if( teams->z( i )->spieler->getEintragAnzahl() )
-			teamAnzahl++;
+        spieler->set( tmp, i );
+    }
+    for( int i = 0; i < anzahl; i++ )
+        spieler->z( i )->setAccountId( zAccounts->hat( i ) ? zAccounts->get( i ) : 0 );
+    for( int i = 0; i < anzahl; i++ )
+        spieler->z( i )->setKlient( new Klient( zKlients->get( i ) ) );
+    stat->setSpieler( spielerAnzahl, spieler );
+    zAccounts = zAccounts->release();
+    zKlients = zKlients->release();
+    teamAnzahl = 0;
+    for( int i = 0; i < sts->teamAnzahl; i++ )
+        if( teams->z( i )->spieler->getEintragAnzahl() )
+            teamAnzahl++;
 }
 
 void Spiel::klientOffline( int accountId )
 {
-	for( int i = 0; i < spielerAnzahl; i++ )
-	{
-		if( spieler->z( i )->getAccountId() == accountId )
-			spieler->z( i )->offline();
-	}
+    for( int i = 0; i < spielerAnzahl; i++ )
+    {
+        if( spieler->z( i )->getAccountId() == accountId )
+            spieler->z( i )->offline();
+    }
 }
 
 void Spiel::klientOnline( int accountId, SSKlientV *zKlient )
 {
-	for( int i = 0; i < spielerAnzahl; i++ )
-	{
-		if( spieler->z( i )->getAccountId() == accountId )
-		{
-			EnterCriticalSection( &cs );
-			Spieler *s = spieler->z( i );
-			s->online( zKlient );
-			Klient *tmp = spieler->z( i )->zKlient();
-			tmp->sendeSpielerNummer( s->getSpielerNummer(), 0 );
-			//--------------------------
-			LeaveCriticalSection( &cs );
-		}
-	}
+    for( int i = 0; i < spielerAnzahl; i++ )
+    {
+        if( spieler->z( i )->getAccountId() == accountId )
+        {
+            EnterCriticalSection( &cs );
+            Spieler *s = spieler->z( i );
+            s->online( zKlient );
+            Klient *tmp = spieler->z( i )->zKlient();
+            tmp->sendeSpielerNummer( s->getSpielerNummer(), 0 );
+            //--------------------------
+            LeaveCriticalSection( &cs );
+        }
+    }
 }
 
 void Spiel::nachricht( int accountId, int len, char *bytes )
 {
-	if( !isRunning || ende )
-		return;
-	EnterCriticalSection( &cs );
-	if( ende )
-	{
-		LeaveCriticalSection( &cs );
-		return;
-	}
-	char *msgBeg = bytes;
-	int msgLen = len;
-	int msgAccount = accountId;
-	bool saveMSG = 1;
-	len--;
-	switch( *bytes )
-	{
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-	case 4:
-	case 5:
-	case 6:
-	case 7:
-		for( int i = 0; i < spielerAnzahl; i++ )
-		{
-			Spieler *tmp = spieler->z( i );
-			if( tmp && tmp->getAccountId() == accountId )
-			{
-				if( !tmp->istAmLeben() )
-					break;
-				if( !tmp->setTastataturStatus( (TastaturStatus)( (int)( *bytes ) / 2 ), ( (int)( *bytes ) % 2 ) == 0 ) )
-				{
-					saveMSG = 0;
-					break;
-				}
-				if( *bytes != 6 && *bytes != 7 )
-				{
-					for( int j = 0; j < spielerAnzahl; j++ )
-					{
-						Spieler *s = spieler->z( j );
-						if( s && s->zKlient() )
-							s->zKlient()->sendeTastaturStatus( tmp->getSpielerNummer(), (TastaturStatus)( (int)( *bytes ) / 2 ), ( (int)( *bytes ) % 2 ) == 0, spielZeit, tmp->getPosition(), tmp->getSpeed(), tmp->getDrehung(), tmp->getDrehungSpeed() );
-					}
-				}
-				break;
-			}
-		}
-		break;
-	case 8: // chat Nachricht
-		if( 1 )
-		{
-			bytes++;
-			Text *txt = psqldb->getAccountRufName( accountId );
-			txt->append( ": " );
-			txt->append( bytes, len );
-			for( int i = 0; i < spielerAnzahl; i++ )
-			{
-				Spieler *tmp = spieler->z( i );
-				if( tmp && tmp->zKlient() )
-					tmp->zKlient()->sendeChatNachricht( txt->getText(), spielZeit );
-			}
-			txt->release();
-			len = 0;
-		}
-		break;
-	case 9: // Skill verwendung
-		if( 1 )
-		{
-			bytes++;
-			char art = *bytes;
-			len--;
-			for( int i = 0; i < spielerAnzahl; i++ )
-			{
-				Spieler *tmp = spieler->z( i );
-				if( tmp && tmp->getAccountId() == accountId )
-				{
-					if( !tmp->istAmLeben() )
-						break;
-					if( !tmp->setSkill( art ) )
-					{
-						saveMSG = 0;
-						break;
-					}
-					for( int j = 0; j < spielerAnzahl; j++ )
-					{
-						Spieler *s = spieler->z( j );
-						if( s && s->zKlient() )
-							s->zKlient()->sendeSkillNachricht( tmp->getSpielerNummer(), art, spielZeit );
-					}
-					break;
-				}
-			}
-			break;
-		}
-		break;
-	default:
-		saveMSG = 0;
-	}
-	if( len )
-	{
-		// error
-	}
-	if( log && log->istOffen() && saveMSG )
-	{
-		char c = 1;
-		log->schreibe( &c, 1 );
-		int spielerNum = 0;
-		for( int i = 0; i < spielerAnzahl; i++ )
-		{
-			Spieler *tmp = spieler->z( i );
-			if( tmp && tmp->getAccountId() == msgAccount )
-			{
-				spielerNum = tmp->getSpielerNummer();
-				break;
-			}
-		}
-		log->schreibe( (char*)&spielerNum, 4 );
-		short l = (short)msgLen;
-		log->schreibe( (char*)&l, 2 );
-		log->schreibe( msgBeg, l );
-	}
-	LeaveCriticalSection( &cs );
+    if( !isRunning || ende )
+        return;
+    EnterCriticalSection( &cs );
+    if( ende )
+    {
+        LeaveCriticalSection( &cs );
+        return;
+    }
+    char *msgBeg = bytes;
+    int msgLen = len;
+    int msgAccount = accountId;
+    bool saveMSG = 1;
+    len--;
+    switch( *bytes )
+    {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+        for( int i = 0; i < spielerAnzahl; i++ )
+        {
+            Spieler *tmp = spieler->z( i );
+            if( tmp && tmp->getAccountId() == accountId )
+            {
+                if( !tmp->istAmLeben() )
+                    break;
+                if( !tmp->setTastataturStatus( (TastaturStatus)( (int)( *bytes ) / 2 ), ( (int)( *bytes ) % 2 ) == 0 ) )
+                {
+                    saveMSG = 0;
+                    break;
+                }
+                if( *bytes != 6 && *bytes != 7 )
+                {
+                    for( int j = 0; j < spielerAnzahl; j++ )
+                    {
+                        Spieler *s = spieler->z( j );
+                        if( s && s->zKlient() )
+                            s->zKlient()->sendeTastaturStatus( tmp->getSpielerNummer(), (TastaturStatus)( (int)( *bytes ) / 2 ), ( (int)( *bytes ) % 2 ) == 0, spielZeit );
+                    }
+                }
+                break;
+            }
+        }
+        break;
+    case 8: // chat Nachricht
+        if( 1 )
+        {
+            bytes++;
+            Text *txt = psqldb->getAccountRufName( accountId );
+            txt->append( ": " );
+            txt->append( bytes, len );
+            for( int i = 0; i < spielerAnzahl; i++ )
+            {
+                Spieler *tmp = spieler->z( i );
+                if( tmp && tmp->zKlient() )
+                    tmp->zKlient()->sendeChatNachricht( txt->getText(), spielZeit );
+            }
+            txt->release();
+            len = 0;
+        }
+        break;
+    case 9: // Skill verwendung
+        if( 1 )
+        {
+            bytes++;
+            char art = *bytes;
+            len--;
+            for( int i = 0; i < spielerAnzahl; i++ )
+            {
+                Spieler *tmp = spieler->z( i );
+                if( tmp && tmp->getAccountId() == accountId )
+                {
+                    if( !tmp->istAmLeben() )
+                        break;
+                    if( !tmp->setSkill( art ) )
+                    {
+                        saveMSG = 0;
+                        break;
+                    }
+                    for( int j = 0; j < spielerAnzahl; j++ )
+                    {
+                        Spieler *s = spieler->z( j );
+                        if( s && s->zKlient() )
+                            s->zKlient()->sendeSkillNachricht( tmp->getSpielerNummer(), art, spielZeit );
+                    }
+                    break;
+                }
+            }
+            break;
+        }
+        break;
+    default:
+        saveMSG = 0;
+    }
+    if( len )
+    {
+        // error
+    }
+    if( log && log->istOffen() && saveMSG )
+    {
+        char c = 1;
+        log->schreibe( &c, 1 );
+        int spielerNum = 0;
+        for( int i = 0; i < spielerAnzahl; i++ )
+        {
+            Spieler *tmp = spieler->z( i );
+            if( tmp && tmp->getAccountId() == msgAccount )
+            {
+                spielerNum = tmp->getSpielerNummer();
+                break;
+            }
+        }
+        log->schreibe( (char*)&spielerNum, 4 );
+        short l = (short)msgLen;
+        log->schreibe( (char*)&l, 2 );
+        log->schreibe( msgBeg, l );
+    }
+    LeaveCriticalSection( &cs );
 }
 
 void Spiel::tick( double zeit )
 {
     // Objekte updaten
     welt->tick( zeit );
-	// Spieler Updaten
-	for( int i = 0; i < spielerAnzahl; i++ )
-	{
-		Spieler *tmp = spieler->z( i );
-		if( tmp )
-		{
-			if( tmp->doNeedWiederbelebung() )
-			{ // Wiederbelebung
+    // Spieler Updaten
+    for( int i = 0; i < spielerAnzahl; i++ )
+    {
+        Spieler *tmp = spieler->z( i );
+        if( tmp )
+        {
+            if( tmp->doNeedWiederbelebung() )
+            { // Wiederbelebung
                 tmp->wiederbeleben();
-				for( int j = 0; j < spielerAnzahl; j++ )
-				{
-					Spieler *s = spieler->z( j );
-					if( s )
-						s->zKlient()->sendeWiederbelebung( tmp->getSpielerNummer(), spielZeit );
-				}
-			}
-		}
-	}
-	// Schüsse Collision
+                for( int j = 0; j < spielerAnzahl; j++ )
+                {
+                    Spieler *s = spieler->z( j );
+                    if( s )
+                        s->zKlient()->sendeWiederbelebung( tmp->getSpielerNummer(), spielZeit );
+                }
+            }
+        }
+    }
+    // Schüsse Collision
     int anz = shots->getEintragAnzahl();
-	for( int i = 0; i < anz; i++ )
-	{
-		Laser *tmp = shots->z( i );
-		if( tmp )
-		{
-			if( tmp->getIntensity() <= 0 )
-			{ // Schuss existiert nicht mehr
-				for( int j = 0; j < spielerAnzahl; j++ )
-				{
-					Spieler *s = spieler->z( j );
-					if( s )
-						s->zKlient()->sendeTreffer( tmp->getId(), -1, spielZeit );
-				}
+    for( int i = 0; i < anz; i++ )
+    {
+        Laser *tmp = shots->z( i );
+        if( tmp )
+        {
+            if( tmp->getIntensity() <= 0 )
+            { // Schuss existiert nicht mehr
+                for( int j = 0; j < spielerAnzahl; j++ )
+                {
+                    Spieler *s = spieler->z( j );
+                    if( s )
+                        s->zKlient()->sendeTreffer( tmp->getId(), -1, spielZeit );
+                }
                 welt->removeObject( tmp );
-				shots->remove( i );
-				anz--;
-				i--;
-			}
-			else
-			{ // Schuss existiert noch
-				int team = getTeamVonSpieler( tmp->getSpieler() );
-				for( int j = 0; j < spielerAnzahl; j++ )
-				{
-					Spieler *s = spieler->z( j );
-					if( s && s->zTeam() && s->zTeam()->id != team && ( s->istTreffer( tmp->getPosition() ) ||
-						s->istTreffer( tmp->getPosition() + karte->getSize() ) || s->istTreffer( tmp->getPosition() - karte->getSize() ) ) )
-					{ // Treffer
+                shots->remove( i );
+                anz--;
+                i--;
+            }
+            else
+            { // Schuss existiert noch
+                int team = getTeamVonSpieler( tmp->getSpieler() );
+                for( int j = 0; j < spielerAnzahl; j++ )
+                {
+                    Spieler *s = spieler->z( j );
+                    if( s && s->zTeam() && s->zTeam()->id != team && s->istTreffer( tmp->getPosition() ) )
+                    { // Treffer
                         double intens = tmp->getIntensity() * ( ( tmp->getSpeed() - s->getSpeed() ).getLength() / 200 );
-						bool kill = s->nimmSchaden( intens );
+                        bool kill = s->nimmSchaden( intens );
                         if( tmp->getSpeed().getLengthSq() > 0 )
                             s->impuls( tmp->getPosition() - tmp->getSpeed(), tmp->getSpeed() * 0.3f );
-						for( int k = 0; k < spielerAnzahl; k++ )
-						{
-							Spieler *sp = spieler->z( k );
-							if( sp )
-								sp->zKlient()->sendeTreffer( tmp->getId(), s->getSpielerNummer(), spielZeit );
-							if( sp && sp->getSpielerNummer() == tmp->getSpieler() )
-								sp->machSchaden( intens, kill );
-							if( kill && sp )
-								sp->zKlient()->sendeTod( s->getSpielerNummer(), tmp->getSpieler(), spielZeit );
-						}
-						if( kill )
-						{
-							if( teams->z( team - 1 ) )
-								teams->z( team - 1 )->punkte++;
-							if( teams->z( team - 1 )->punkte == teams->z( team - 1 )->maxPunkte )
-								ende = 1;
-						}
+                        for( int k = 0; k < spielerAnzahl; k++ )
+                        {
+                            Spieler *sp = spieler->z( k );
+                            if( sp )
+                                sp->zKlient()->sendeTreffer( tmp->getId(), s->getSpielerNummer(), spielZeit );
+                            if( sp && sp->getSpielerNummer() == tmp->getSpieler() )
+                                sp->machSchaden( intens, kill );
+                            if( kill && sp )
+                                sp->zKlient()->sendeTod( s->getSpielerNummer(), tmp->getSpieler(), spielZeit );
+                        }
+                        if( kill )
+                        {
+                            if( teams->z( team - 1 ) )
+                                teams->z( team - 1 )->punkte++;
+                            if( teams->z( team - 1 )->punkte == teams->z( team - 1 )->maxPunkte )
+                                ende = 1;
+                        }
                         welt->removeObject( tmp );
-						shots->remove( i );
-						anz--;
-						i--;
-						break;
-					}
-				}
-			}
-		}
-	}
-	// Neue Schüsse hinzufügen
-	for( int i = 0; i < spielerAnzahl; i++ )
-	{
-		Spieler *tmp = spieler->z( i );
-		if( tmp )
-		{
-			Laser *nL = tmp->getLaser( nextSchussId );
-			if( nL )
-			{
+                        shots->remove( i );
+                        anz--;
+                        i--;
+                        break;
+                    }
+                }
+                int aAnz = asteroids->getEintragAnzahl();
+                for( int j = 0; j < aAnz; j++ )
+                {
+                    Asteroid *a = asteroids->z( j );
+                    Vertex pos;
+                    __int64 seed = randG.getSeed();
+                    double intens = tmp->getIntensity() * ( ( tmp->getSpeed() - a->getSpeed() ).getLength() / 200 );
+                    Asteroid *b = a->istTreffer( tmp, &randG, asteroidId, pos );
+                    if( b )
+                    {
+                        for( int k = 0; k < spielerAnzahl; k++ )
+                        {
+                            Spieler *s = spieler->z( k );
+                            if( s )
+                                s->zKlient()->sendeAsteroidTreffer( a->getId(), b->getId(), tmp->getId(), pos, seed, spielZeit );
+                            if( s && s->getSpielerNummer() == tmp->getSpieler() )
+                                s->addTreffer();
+                        }
+                        welt->removeObject( tmp );
+                        shots->remove( i );
+                        if( b->getMasse() > intens * 50 )
+                        {
+                            asteroids->add( (Asteroid*)b->getThis() );
+                            welt->addObject( b );
+                        }
+                        else
+                        {
+                            Pixel *p = new Pixel( b->getPosition(), b->getSpeed(), b->getMasse() / 50, pixelId++ );
+                            welt->addObject( p->getThis() );
+                            pixel->add( p );
+                            for( int k = 0; k < spielerAnzahl; k++ )
+                            {
+                                Spieler *s = spieler->z( k );
+                                if( s )
+                                    s->zKlient()->sendePixel( b->getId(), p->getId(), spielZeit );
+                            }
+                            b->release();
+                        }
+                        if( a->getMasse() < intens * 50 )
+                        {
+                            Pixel *p = new Pixel( a->getPosition(), a->getSpeed(), a->getMasse() / 50, pixelId++ );
+                            welt->addObject( p->getThis() );
+                            pixel->add( p );
+                            for( int k = 0; k < spielerAnzahl; k++ )
+                            {
+                                Spieler *s = spieler->z( k );
+                                if( s )
+                                    s->zKlient()->sendePixel( a->getId(), p->getId(), spielZeit );
+                            }
+                            welt->removeObject( a );
+                            asteroids->remove( j-- );
+                            aAnz--;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    // Neue Schüsse hinzufügen
+    for( int i = 0; i < spielerAnzahl; i++ )
+    {
+        Spieler *tmp = spieler->z( i );
+        if( tmp )
+        {
+            Laser *nL = tmp->getLaser( nextSchussId );
+            if( nL )
+            {
                 nextSchussId++;
                 welt->addObject( nL->getThis() );
-				shots->add( nL );
-				for( int j = 0; j < spielerAnzahl; j++ )
-				{
-					if( spieler->z( j ) && spieler->z( j )->zKlient() )
-						spieler->z( j )->zKlient()->sendeSchuss( nL->getId(), nL->getSpieler(), nL->getPosition(), nL->getSpeed(), nL->getIntensity(), spielZeit );
-				}
-			}
-		}
-	}
+                shots->add( nL );
+                for( int j = 0; j < spielerAnzahl; j++ )
+                {
+                    if( spieler->z( j ) && spieler->z( j )->zKlient() )
+                        spieler->z( j )->zKlient()->sendeSchuss( nL->getId(), nL->getSpieler(), nL->getPosition(), nL->getSpeed(), nL->getIntensity(), spielZeit );
+                }
+            }
+        }
+    }
+    // Asteroiden
+    nextAsteroid -= zeit;
+    if( nextAsteroid <= 0 )
+    {
+        nextAsteroid += 30 + (float)randG.rand() * 30;
+        Vertex pos = Vertex( (float)randG.rand() * (float)welt->getWorldInfo().size.x, (float)randG.rand() * (float)welt->getWorldInfo().size.y );
+        Vertex speed = Vertex( (float)randG.rand() * 100, (float)randG.rand() * 100 );
+        float rot = 2 * (float)PI * (float)randG.rand();
+        float rotS = (float)randG.rand();
+        int index = (int)( (float)asteroidModels->getEintragAnzahl() * (float)randG.rand() );
+        Asteroid *astr = new Asteroid( asteroidId++, pos, speed, rot, rotS, asteroidModels->get( index ) );
+        asteroids->add( astr );
+        welt->addObject( astr->getThis() );
+        for( int j = 0; j < spielerAnzahl; j++ )
+        {
+            if( spieler->z( j ) && spieler->z( j )->zKlient() )
+                spieler->z( j )->zKlient()->sendeAsteroid( astr->getId(), pos, speed, rot, rotS, index, spielZeit );
+        }
+    }
+    // Pixel
+    int pixelAnz = pixel->getEintragAnzahl();
+    for( int i = 0; i < pixelAnz; i++ )
+    {
+        Pixel *p = pixel->z( i );
+        if( p->getEp() <= 0 )
+        {
+            for( int j = 0; j < spielerAnzahl; j++ )
+            {
+                if( spieler->z( j ) && spieler->z( j )->zKlient() )
+                    spieler->z( j )->zKlient()->sendeEp( p->getId(), -1, spielZeit );
+            }
+            pixel->remove( i-- );
+            welt->removeObject( p );
+            pixelAnz--;
+        }
+        else
+        {
+            for( auto s = spieler->getIterator(); s; s++ )
+            {
+                if( s->istTreffer( p->getPosition() ) )
+                {
+                    s->addEp( p->getEp() );
+                    for( int j = 0; j < spielerAnzahl; j++ )
+                    {
+                        if( spieler->z( j ) && spieler->z( j )->zKlient() )
+                            spieler->z( j )->zKlient()->sendeEp( p->getId(), s->getSpielerNummer(), spielZeit );
+                    }
+                    pixel->remove( i-- );
+                    welt->removeObject( p );
+                    pixelAnz--;
+                    break;
+                }
+            }
+        }
+    }
 }
 
 void Spiel::run()
 {
-	log = new Datei();
-	Text *pfad = new Text( "../spiel log/" );
-	pfad->append( spielId );
-	pfad->append( "/verlauf.ksggl" );
-	log->setDatei( pfad );
-	log->remove();
-	log->erstellen();
-	log->open( Datei::Style::schreiben );
-	time_t t;
-	time( &t );
-	srand( (unsigned int)t );
-	log->schreibe( (char*)&spielerAnzahl, 4 );
-	for( int i = 0; i < spielerAnzahl; i++ )
-	{
-		Spieler *tmp = spieler->z( i );
-		if( tmp && tmp->zKlient() )
-		{
-			tmp->zKlient()->sendeInit( spieler, -1 );
-			log->schreibe( (char*)&i, 4 );
-			int sNum = tmp->getSpielerNummer();
-			log->schreibe( (char*)&sNum, 4 );
-			tmp->zKlient()->sendeSpielerNummer( sNum, -1 );
-			int team = tmp->zTeam()->id;
-			log->schreibe( (char*)&team, 4 );
-			int farbe = tmp->getSpielerFarbe();
-			log->schreibe( (char*)&farbe, 4 );
-			farbe = tmp->zTeam()->farbe;
-			log->schreibe( (char*)&farbe, 4 );
-			Text *name = psqldb->getAccountRufName( tmp->getAccountId() );
-			char len = (char)( name ? name->getLength() : 0 );
-			log->schreibe( &len, 1 );
-			if( len )
-				log->schreibe( name->getText(), len );
-			if( name )
-				name->release();
-			name = sts->teamName->z( team );
-			len = (char)( name ? name->getLength() : 0 );
-			log->schreibe( &len, 1 );
-			if( len )
-				log->schreibe( name->getText(), len );
-		}
-	}
-	Array< char > spielerStatus;
-	ZeitMesser *zeit = new ZeitMesser();
-	zeit->messungStart();
-	isRunning = 1;
-	ende = 0;
-	double ausgleich = 0;
-	double sZ = 0;
-	spielZeit = -1;
-	for( int i = 0; i < spielerAnzahl; i++ )
-	{
-		Spieler *tmp = spieler->z( i );
-		if( tmp && tmp->zKlient() )
-			tmp->zKlient()->sendeStart( spielZeit );
-	}
-	double rZeit = 0;
-	while( !ende )
-	{
-		zeit->messungEnde();
-		zeit->messungStart();
-		double z = zeit->getSekunden();
-		ausgleich += 1.0 / 25 - z;
-		if( ausgleich > 0 )
-			Sleep( (int)( ausgleich * 1000 ) );
-		rZeit += z;
-		while( sZ + TICK < rZeit && !ende )
-		{
-			EnterCriticalSection( &cs );
-			sZ += TICK;
-			spielZeit++;
-			char c = 0;
-			log->schreibe( &c, 1 );
-			tick( TICK );
-			LeaveCriticalSection( &cs );
-		}
-	}
-	zeit->messungEnde();
-	zeit->release();
-	for( int i = 0; i < spielerAnzahl; i++ )
-	{
-		if( spieler->z( i ) && spieler->z( i )->zKlient() )
-		{
-			if( spieler->z( i )->zTeam()->punkte < spieler->z( i )->zTeam()->maxPunkte )
-			{
-				spielerStatus.set( 1, i ); // Datenbank Verloren
-				spieler->z( i )->zKlient()->sendeSpielEnde( 0, 0 );
-			}
-			else
-			{
-				spielerStatus.set( 2, i ); // Datenbank Gewonnen
-				spieler->z( i )->zKlient()->sendeSpielEnde( 1, 0 );
-			}
-		}
-		if( spieler->z( i ) && ( !spieler->z( i )->zKlient() || !spieler->z( i )->istOnline() ) )
-			spielerStatus.set( 3, i );
-	}
-	if( teamAnzahl == 1 )
-		psqldb->setSpielStatusBeendet( spielId, 6 );
-	else
-		psqldb->setSpielStatusBeendet( spielId, 5 );
-	for( int i = 0; i < spielerAnzahl; i++ )
-	{
-		Spieler *tmp = spieler->z( i );
-		if( tmp )
-		{
-			psqldb->setSpielSpielerStatus( spielId, tmp->getAccountId(), tmp->getPunkte(), spielerStatus.get( i ) );
-			if( teamAnzahl > 1 )
-				psqldb->addSpielerStatistik( tmp->getAccountId(), spielId );
-		}
-	}
-	log->close();
-	log = log->release();
-	isRunning = 0;
+    Text *pfad = psqldb->getSpielPfad( karteId );
+    if( pfad )
+        pfad->append( "/" );
+    pfad->append( "models/asteroids.m2" );
+    M2Datei *aDat = new M2Datei();
+    aDat->setPfadZ( pfad );
+    aDat->leseDaten();
+    int anz = aDat->getModelAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        asteroidModels->add( aDat->ladeModel( aDat->zModelName( i )->getText() ) );
+    }
+    log = new Datei();
+    pfad = new Text( "../spiel log/" );
+    pfad->append( spielId );
+    pfad->append( "/verlauf.ksggl" );
+    log->setDatei( pfad );
+    log->remove();
+    log->erstellen();
+    log->open( Datei::Style::schreiben );
+    time_t t;
+    time( &t );
+    srand( (unsigned int)t );
+    log->schreibe( (char*)&spielerAnzahl, 4 );
+    for( int i = 0; i < spielerAnzahl; i++ )
+    {
+        Spieler *tmp = spieler->z( i );
+        if( tmp && tmp->zKlient() )
+        {
+            tmp->zKlient()->sendeInit( spieler, -1 );
+            log->schreibe( (char*)&i, 4 );
+            int sNum = tmp->getSpielerNummer();
+            log->schreibe( (char*)&sNum, 4 );
+            tmp->zKlient()->sendeSpielerNummer( sNum, -1 );
+            int team = tmp->zTeam()->id;
+            log->schreibe( (char*)&team, 4 );
+            int farbe = tmp->getSpielerFarbe();
+            log->schreibe( (char*)&farbe, 4 );
+            farbe = tmp->zTeam()->farbe;
+            log->schreibe( (char*)&farbe, 4 );
+            Text *name = psqldb->getAccountRufName( tmp->getAccountId() );
+            char len = (char)( name ? name->getLength() : 0 );
+            log->schreibe( &len, 1 );
+            if( len )
+                log->schreibe( name->getText(), len );
+            if( name )
+                name->release();
+            name = sts->teamName->z( team );
+            len = (char)( name ? name->getLength() : 0 );
+            log->schreibe( &len, 1 );
+            if( len )
+                log->schreibe( name->getText(), len );
+        }
+    }
+    __int64 randSeed = randG.getSeed();
+    log->schreibe( (char*)&randSeed, 8 );
+    Array< char > spielerStatus;
+    ZeitMesser *zeit = new ZeitMesser();
+    zeit->messungStart();
+    isRunning = 1;
+    ende = 0;
+    double ausgleich = 0;
+    double sZ = 0;
+    spielZeit = -1;
+    for( int i = 0; i < spielerAnzahl; i++ )
+    {
+        Spieler *tmp = spieler->z( i );
+        if( tmp && tmp->zKlient() )
+            tmp->zKlient()->sendeStart( spielZeit );
+    }
+    double rZeit = 0;
+    while( !ende )
+    {
+        zeit->messungEnde();
+        zeit->messungStart();
+        double z = zeit->getSekunden();
+        ausgleich += TICK - z;
+        if( ausgleich > 0 )
+            Sleep( (int)( ausgleich * 1000 ) );
+        std::cout << "tick: " << z << " sleep: " << (int)( ausgleich * 1000 ) << "\n";
+        rZeit += z;
+        while( sZ + TICK < rZeit && !ende )
+        {
+            EnterCriticalSection( &cs );
+            sZ += TICK;
+            spielZeit++;
+            char c = 0;
+            log->schreibe( &c, 1 );
+            tick( TICK );
+            LeaveCriticalSection( &cs );
+        }
+    }
+    zeit->messungEnde();
+    zeit->release();
+    for( int i = 0; i < spielerAnzahl; i++ )
+    {
+        if( spieler->z( i ) && spieler->z( i )->zKlient() )
+        {
+            if( spieler->z( i )->zTeam()->punkte < spieler->z( i )->zTeam()->maxPunkte )
+            {
+                spielerStatus.set( 1, i ); // Datenbank Verloren
+                spieler->z( i )->zKlient()->sendeSpielEnde( 0, 0 );
+            }
+            else
+            {
+                spielerStatus.set( 2, i ); // Datenbank Gewonnen
+                spieler->z( i )->zKlient()->sendeSpielEnde( 1, 0 );
+            }
+        }
+        if( spieler->z( i ) && ( !spieler->z( i )->zKlient() || !spieler->z( i )->istOnline() ) )
+            spielerStatus.set( 3, i );
+    }
+    if( teamAnzahl == 1 )
+        psqldb->setSpielStatusBeendet( spielId, 6 );
+    else
+        psqldb->setSpielStatusBeendet( spielId, 5 );
+    for( int i = 0; i < spielerAnzahl; i++ )
+    {
+        Spieler *tmp = spieler->z( i );
+        if( tmp )
+        {
+            psqldb->setSpielSpielerStatus( spielId, tmp->getAccountId(), tmp->getPunkte(), spielerStatus.get( i ) );
+            if( teamAnzahl > 1 )
+                psqldb->addSpielerStatistik( tmp->getAccountId(), spielId );
+        }
+    }
+    log->close();
+    log = log->release();
+    isRunning = 0;
 }
 
 // constant
 StatistikV *Spiel::getStatistik() const
 {
-	return stat->getThis();
+    return stat->getThis();
 }
 
 // Reference Counting 
 SpielKlasse *Spiel::getThis()
 {
-	ref++;
-	return this;
+    ref++;
+    return this;
 }
 
 SpielKlasse *Spiel::release()
 {
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
 }

+ 10 - 0
Asteroids/Spiel.h

@@ -7,7 +7,10 @@
 #include "Spieler.h"
 #include "Karte.h"
 #include "SpielObjekt.h"
+#include "Asteroid.h"
 #include <Welt2D.h>
+#include <Random.h>
+#include "Pixel.h"
 
 class Statistik;
 class StatistikV;
@@ -15,6 +18,9 @@ class StatistikV;
 class Spiel : public SpielKlasse
 {
 private:
+    RandomGenerator randG;
+    RCArray< Asteroid > *asteroids;
+    RCArray< Model2DData > *asteroidModels;
 	Statistik *stat;
 	RCArray< Team > *teams;
 	int teamAnzahl;
@@ -23,6 +29,7 @@ private:
 	RCArray< Spieler > *spieler;
 	RCArray< Laser > *shots;
 	RCArray< SpielObjekt > *objekte;
+    RCArray< Pixel > *pixel;
     Welt2D *welt;
 	SSDatenbankV *psqldb;
 	int spielId;
@@ -37,6 +44,9 @@ private:
 	int spielZeit;
 	bool ende;
 	int nextSchussId;
+    double nextAsteroid;
+    int asteroidId;
+    int pixelId;
 	int ref;
 	// privat
 	int getTeamVonSpieler( int sNum );

+ 27 - 9
Asteroids/Spieler.cpp

@@ -28,20 +28,17 @@ Spieler::Spieler( SpielerStr *zStr )
     setPosition( startPos );
     setDrehung( (float)zStr->rot );
     beschleunigung = zStr->beschleunigung;
-    beschleunigungStart = zStr->beschleunigung;
     energie = zStr->maxEnergie;
     stability = zStr->maxStability;
     reparatur = zStr->reparatur;
     laserIntensity = zStr->laserIntensity;
     laserEffizienz = zStr->laserEffizienz;
     akkuLeistung = zStr->akkuLeistung;
-    akkuLeistungStart = zStr->akkuLeistung;
     maxEnergie = zStr->maxEnergie;
     maxStability = zStr->maxStability;
     laserTempo = zStr->laserTempo;
     netzwerk = zStr->netzwerk;
     wendigkeit = zStr->wendigkeit;
-    wendigkeitStart = zStr->wendigkeit;
     antriebEffizienz = zStr->antriebEffizienz;
     energieSchild = zStr->energieSchild;
     energieSchildEffizienz = zStr->energieSchildEffizienz;
@@ -56,6 +53,8 @@ Spieler::Spieler( SpielerStr *zStr )
     tode = 0;
     zeitAmLeben = 0;
     zeitTod = 0;
+    ep = 0;
+    nextSkillEp = 100;
     needWiederbelebung = 0;
 }
 
@@ -172,6 +171,7 @@ bool Spieler::setTastataturStatus( TastaturStatus ts, bool aktiv )
 
 bool Spieler::tick( const WeltInfo& info, double zeit )
 {
+    wInfo = info;
     if( !team )
         return 0;
     reinkAbk -= zeit;
@@ -195,7 +195,7 @@ bool Spieler::tick( const WeltInfo& info, double zeit )
             repAbk = 0;
         if( tastatur[ T_GAS ] )
         {
-            double treibstoff = 0.5 * ( ( beschleunigung + team->beschleunigung ) / 5 )
+            double treibstoff = 0.5 * ( ( beschleunigung + team->beschleunigung ) / 15 )
                 * zeit * ( 100 / ( antriebEffizienz + team->antriebEffizienz ) );
             treibstoffVerbraucht += treibstoff;
             float factor = 1;
@@ -207,7 +207,7 @@ bool Spieler::tick( const WeltInfo& info, double zeit )
         }
         if( tastatur[ T_ROT_R ] )
         {
-            double treibstoff = 0.25 * ( ( wendigkeit + team->wendigkeit ) / 5 )
+            double treibstoff = 0.25 * ( ( wendigkeit + team->wendigkeit ) / 15 )
                 * zeit * ( 100 / ( antriebEffizienz + team->antriebEffizienz ) );
             treibstoffVerbraucht += treibstoff;
             float factor = 1;
@@ -219,7 +219,7 @@ bool Spieler::tick( const WeltInfo& info, double zeit )
         }
         if( tastatur[ T_ROT_L ] )
         {
-            double treibstoff = 0.25 * ( ( wendigkeit + team->wendigkeit ) / 5 )
+            double treibstoff = 0.25 * ( ( wendigkeit + team->wendigkeit ) / 15 )
                 * zeit * ( 100 / ( antriebEffizienz + team->antriebEffizienz ) );
             treibstoffVerbraucht += treibstoff;
             float factor = 1;
@@ -270,11 +270,11 @@ bool Spieler::setSkill( int art )
         team->reparatur = team->getReperaturBonus();
         break;
     case 3: // Laser Intensität
-        laserIntensity += 3;
+        laserIntensity += 4;
         team->laserIntensity = team->getLaserIntensityBonus();
         break;
     case 4: // Laser Effizienz
-        laserEffizienz += 1;
+        laserEffizienz += 1.5;
         team->laserEffizienz = team->getLaserEffizienzBonus();
         break;
     case 5: // Laser Tempo
@@ -387,6 +387,11 @@ void Spieler::machSchaden( double intensity, bool kill )
     }
 }
 
+void Spieler::addTreffer()
+{
+    treffer++;
+}
+
 void Spieler::wiederbeleben()
 {
     needWiederbelebung = 0;
@@ -406,6 +411,17 @@ void Spieler::wiederbeleben()
     setCollision( 1 );
 }
 
+void Spieler::addEp( float ep )
+{
+    this->ep += ep;
+    while( this->ep >= nextSkillEp )
+    {
+        skillPunkte++;
+        this->ep -= nextSkillEp;
+        nextSkillEp *= 1.1f;
+    }
+}
+
 // constant
 int Spieler::getAccountId() const
 {
@@ -426,7 +442,9 @@ bool Spieler::istTreffer( Vec2< float > pos ) const
 {
     if( !amLeben )
         return 0;
-    return istPunktInnen( pos );
+    return istPunktInnen( pos ) || istPunktInnen( pos + wInfo.size ) || istPunktInnen( pos + Punkt( wInfo.size.x, 0 ) ) || istPunktInnen( pos + Punkt( 0, wInfo.size.y ) ) ||
+        istPunktInnen( pos + -wInfo.size ) || istPunktInnen( pos + Punkt( -wInfo.size.x, 0 ) ) || istPunktInnen( pos + Punkt( 0, -wInfo.size.y ) ) ||
+        istPunktInnen( pos + Punkt( -wInfo.size.x, wInfo.size.y ) ) || istPunktInnen( pos + Punkt( wInfo.size.x, -wInfo.size.y ) );
 }
 
 // Raumschiff Eigenschaften

+ 5 - 3
Asteroids/Spieler.h

@@ -32,6 +32,7 @@ private:
     Vertex kR;
     Vertex stM;
     Vertex kM;
+    WeltInfo wInfo;
 
 	int accountId;
 	int sNum;
@@ -48,20 +49,17 @@ private:
 	// Raumschiff Eigenschaftend
 	Vertex startPos;
 	double beschleunigung;
-    double beschleunigungStart;
 	double energie;
 	double stability;
 	double reparatur;
 	double laserIntensity;
 	double laserEffizienz;
 	double akkuLeistung;
-    double akkuLeistungStart;
 	double maxEnergie;
 	double maxStability;
 	double laserTempo;
 	double netzwerk;
 	double wendigkeit;
-    double wendigkeitStart;
     double antriebEffizienz;
     double energieSchild;
     double energieSchildEffizienz;
@@ -77,6 +75,8 @@ private:
 	int tode;
 	double zeitAmLeben;
 	double zeitTod;
+    float ep;
+    float nextSkillEp;
     bool needWiederbelebung;
 
 public:
@@ -98,7 +98,9 @@ public:
 	Laser *getLaser( int sId );
 	bool nimmSchaden( double &intensity );
 	void machSchaden( double intensity, bool kill );
+    void addTreffer();
     void wiederbeleben();
+    void addEp( float ep );
 	// constant
 	int getAccountId() const;
 	bool istOnline() const;