Browse Source

Unterstützung für circuläre welten hinzugefügt

kolja 5 years ago
parent
commit
4e38af7a43
3 changed files with 126 additions and 10 deletions
  1. 13 1
      Kamera2D.cpp
  2. 104 7
      Welt2D.cpp
  3. 9 2
      Welt2D.h

+ 13 - 1
Kamera2D.cpp

@@ -100,7 +100,19 @@ void Kamera2D::render( Bild &zRObj )
 
 Vertex Kamera2D::getWorldCoordinates( Punkt screenPos )
 {
-    return ( Mat3< float >::translation( wPos ) * Mat3< float >::scaling( 1 / zoom ) * Mat3< float >::rotation( -rotation ) * Mat3< float >::translation( (Vertex)gr / -2 ) ) * (Vertex)screenPos;
+    Vertex wKoord = ( Mat3< float >::translation( wPos ) * Mat3< float >::scaling( 1 / zoom ) * Mat3< float >::rotation( -rotation ) * Mat3< float >::translation( (Vertex)gr / -2 ) ) * (Vertex)screenPos;
+    if( welt->getWorldInfo().circular && welt->getWorldInfo().hasSize && welt->getWorldInfo().size.x && welt->getWorldInfo().size.y )
+    {
+        while( wKoord.x < 0 )
+            wKoord.x += welt->getWorldInfo().size.x;
+        while( wKoord.x > welt->getWorldInfo().size.x )
+            wKoord.x -= welt->getWorldInfo().size.x;
+        while( wKoord.y < 0 )
+            wKoord.y += welt->getWorldInfo().size.y;
+        while( wKoord.y > welt->getWorldInfo().size.y )
+            wKoord.y -= welt->getWorldInfo().size.y;
+    }
+    return wKoord;
 }
 
 Vertex Kamera2D::getWorldDirection( Vertex dir )

+ 104 - 7
Welt2D.cpp

@@ -119,6 +119,17 @@ bool Object2D::tick( const WeltInfo &info, double zeit )
     }
     rSpeed -= ( rSpeed - ( rSpeed / ( 1 + info.airResistance * getLuftWiederstand() ) ) ) * (float)zeit;
     speed -= ( speed - ( speed / ( 1 + info.airResistance * getLuftWiederstand() ) ) ) * (float)zeit;
+    if( info.circular && info.hasSize && info.size.x && info.size.y )
+    {
+        while( position.x > info.size.x )
+            position.x -= (float)info.size.x;
+        while( position.x < 0 )
+            position.x += (float)info.size.x;
+        while( position.y > info.size.y )
+            position.y -= (float)info.size.y;
+        while( position.y < 0 )
+            position.y += (float)info.size.y;
+    }
     return rSpeed != 0 || speed != Vertex( 0, 0 );
 }
 
@@ -238,6 +249,22 @@ void Welt2D::setAirResistance( float resistance )
     info.airResistance = resistance;
 }
 
+void Welt2D::setSize( int width, int height )
+{
+    info.size.x = width;
+    info.size.y = height;
+}
+
+void Welt2D::setSize( bool hasSize )
+{
+    info.hasSize = hasSize;
+}
+
+void Welt2D::setCircular( bool circular )
+{
+    info.circular = circular;
+}
+
 void Welt2D::addObject( Object2D *obj )
 {
     objects->add( obj );
@@ -248,7 +275,33 @@ void Welt2D::explosion( Vertex worldPos, float intensity, float maxRad )
     maxRad = maxRad * maxRad;
     for( auto obj = objects->getArray(); obj.set; obj++ )
     {
-        if( ( obj.var->getPosition() - worldPos ).getLengthSq() < maxRad )
+        if( info.circular && info.hasSize && info.size.x && info.size.y )
+        {
+            Vertex offsets[] = {
+                Vertex( 0, 0 ),
+                Vertex( (float)info.size.x, 0 ),
+                Vertex( 0, (float)info.size.y ),
+                Vertex( (float)info.size.x, (float)info.size.y ),
+                Vertex( (float)-info.size.x, 0 ),
+                Vertex( 0, (float)-info.size.y ),
+                Vertex( (float)-info.size.x, (float)-info.size.y ),
+                Vertex( (float)-info.size.x, (float)info.size.y ),
+                Vertex( (float)info.size.x, (float)-info.size.y ) };
+            Vertex offset;
+            float minDist = INFINITY;
+            for( Vertex p : offsets )
+            {
+                float dist = ( obj.var->getPosition() - (worldPos - p) ).getLengthSq();
+                if( dist < minDist )
+                {
+                    minDist = dist;
+                    offset = p;
+                }
+            }
+            if( ( obj.var->getPosition() - (worldPos - offset) ).getLengthSq() < maxRad )
+                obj.var->explosion( worldPos - offset, intensity );
+        }
+        else if( ( obj.var->getPosition() - worldPos ).getLengthSq() < maxRad )
             obj.var->explosion( worldPos, intensity );
     }
 }
@@ -288,17 +341,18 @@ bool Welt2D::tick( double zeit )
     return ret;
 }
 
-void Welt2D::render( Mat3< float > &kamMat, Punkt size, Bild &zRObj )
+void Welt2D::render( Mat3< float > &kamMat, Punkt size, Bild &zRObj, int xOffset, int yOffset )
 {
     for( auto obj = objects->getArray(); obj.set; obj++ )
     {
         Rect2< float > bnd = obj.var->getBoundingBox();
         Vertex topRight = Vertex( bnd.topLeft.y, bnd.bottomRight.x );
         Vertex bottomLeft = Vertex( bnd.topLeft.x, bnd.bottomRight.y );
-        bnd.bottomRight = kamMat * bnd.bottomRight;
-        bnd.topLeft = kamMat * bnd.topLeft;
-        topRight = kamMat * topRight;
-        bottomLeft = kamMat * bottomLeft;
+        Mat3< float > km = kamMat * Mat3<float>::translation( Vertex( (float)xOffset, (float)yOffset ) );
+        bnd.bottomRight = km * bnd.bottomRight;
+        bnd.topLeft = km * bnd.topLeft;
+        topRight = km * topRight;
+        bottomLeft = km * bottomLeft;
         if( ( bnd.bottomRight.x >= 0 && bnd.bottomRight.x < size.x ) ||
             ( bnd.bottomRight.y >= 0 && bnd.bottomRight.y < size.y ) ||
             ( bnd.topLeft.x >= 0 && bnd.topLeft.x < size.x ) ||
@@ -307,10 +361,53 @@ void Welt2D::render( Mat3< float > &kamMat, Punkt size, Bild &zRObj )
             ( topRight.y >= 0 && topRight.y < size.y ) ||
             ( bottomLeft.x >= 0 && bottomLeft.x < size.x ) ||
             ( bottomLeft.y >= 0 && bottomLeft.y < size.y ) )
-            obj.var->render( kamMat, zRObj );
+            obj.var->render( km, zRObj );
+    }
+}
+
+void Welt2D::render( Mat3< float > &kamMat, Punkt size, Bild &zRObj )
+{
+    if( !info.hasSize || !info.circular )
+    {
+        for( auto obj = objects->getArray(); obj.set; obj++ )
+        {
+            Rect2< float > bnd = obj.var->getBoundingBox();
+            Vertex topRight = Vertex( bnd.topLeft.y, bnd.bottomRight.x );
+            Vertex bottomLeft = Vertex( bnd.topLeft.x, bnd.bottomRight.y );
+            bnd.bottomRight = kamMat * bnd.bottomRight;
+            bnd.topLeft = kamMat * bnd.topLeft;
+            topRight = kamMat * topRight;
+            bottomLeft = kamMat * bottomLeft;
+            if( ( bnd.bottomRight.x >= 0 && bnd.bottomRight.x < size.x ) ||
+                ( bnd.bottomRight.y >= 0 && bnd.bottomRight.y < size.y ) ||
+                ( bnd.topLeft.x >= 0 && bnd.topLeft.x < size.x ) ||
+                ( bnd.topLeft.y >= 0 && bnd.topLeft.y < size.y ) ||
+                ( topRight.x >= 0 && topRight.x < size.x ) ||
+                ( topRight.y >= 0 && topRight.y < size.y ) ||
+                ( bottomLeft.x >= 0 && bottomLeft.x < size.x ) ||
+                ( bottomLeft.y >= 0 && bottomLeft.y < size.y ) )
+                obj.var->render( kamMat, zRObj );
+        }
+    }
+    else if( info.circular )
+    {
+        render( kamMat, size, zRObj, 0, 0 );
+        render( kamMat, size, zRObj, info.size.x, 0 );
+        render( kamMat, size, zRObj, 0, info.size.y );
+        render( kamMat, size, zRObj, info.size.x, info.size.y );
+        render( kamMat, size, zRObj, -info.size.x, 0 );
+        render( kamMat, size, zRObj, 0, -info.size.y );
+        render( kamMat, size, zRObj, -info.size.x, -info.size.y );
+        render( kamMat, size, zRObj, -info.size.x, +info.size.y );
+        render( kamMat, size, zRObj, +info.size.x, -info.size.y );
     }
 }
 
+const WeltInfo &Welt2D::getWorldInfo() const
+{
+    return info;
+}
+
 Welt2D *Welt2D::getThis()
 {
     ref++;

+ 9 - 2
Welt2D.h

@@ -13,6 +13,9 @@ namespace Framework
     struct WeltInfo
     {
         float airResistance;
+        bool hasSize;
+        bool circular;
+        Punkt size;
     };
 
     class Object2D
@@ -135,20 +138,24 @@ namespace Framework
     {
     private:
         RCArray< Object2D > *objects;
-        Punkt topLeft;
-        Punkt rightBottom;
         WeltInfo info;
         int ref;
 
+        void render( Mat3< float > &kamMat, Punkt size, Bild &zRObj, int xOffset, int yOffset );
+
     public:
         __declspec( dllexport ) Welt2D();
         __declspec( dllexport ) ~Welt2D();
         __declspec( dllexport ) void setAirResistance( float resistance );
+        __declspec( dllexport ) void setSize( int width, int height );
+        __declspec( dllexport ) void setSize( bool hasSize );
+        __declspec( dllexport ) void setCircular( bool circular );
         __declspec( dllexport ) void addObject( Object2D *obj );
         __declspec( dllexport ) void explosion( Vertex worldPos, float intensity, float maxRad );
         __declspec( dllexport ) void impuls( Vertex worldPos, Vertex worldDir );
         __declspec( dllexport ) bool tick( double zeit );
         __declspec( dllexport ) void render( Mat3< float > &kamMat, Punkt size, Bild &zRObj );
+        __declspec( dllexport ) const WeltInfo &getWorldInfo() const;
         __declspec( dllexport ) Welt2D *getThis();
         __declspec( dllexport ) Welt2D *release();
     };