#include "Laser.h" #include "../Karte/Karte.h" #include "../Spieler/Spieler.h" #include "../Define.h" // Inhalt der Laser Klasse aus Laser.h // Konstruktor Laser::Laser( int id, Vec2< double > pos, Vec2< double > speed, int sNum, double intensität, int tf ) { this->id = id; this->pos = pos; this->speed = speed; this->sNum = sNum; this->intensität = intensität; this->startIntensität = intensität; this->tf = tf; ref = 1; } // privat char Laser::getOutCode( Punkt& p, Bild &zrObj ) const { char ret = 0; if( p.x < 0 ) ret |= 1; else if( p.x >= zrObj.getBreite() ) ret |= 2; if( p.y < 0 ) ret |= 4; else if( p.y >= zrObj.getHeight() ) ret |= 8; return ret; } // nicht constant void Laser::tick( int tick, Karte *zMap ) { double tickVal = tick * TICK; pos += speed * tickVal; Vec2< int > gr = zMap->getSize(); if( pos.x < 0 ) pos.x += gr.x; if( pos.y < 0 ) pos.y += gr.y; if( pos.x >= gr.x ) pos.x -= gr.x; if( pos.y >= gr.y ) pos.y -= gr.y; intensität -= tickVal * 2; } void Laser::render( Bild &zRObj ) { int fa = (int)( ( intensität / startIntensität ) * 255 ); int f = ( ( fa << 24 ) & 0xFF000000 ) | ( tf & 0xFFFFFF ); Punkt a( pos ); Punkt b( pos - ( speed / speed.getLength() * 10 ) ); a += zRObj.getDrawOff(); b += zRObj.getDrawOff(); char outCode1 = getOutCode( a, zRObj ); char outCode2 = getOutCode( b, zRObj ); bool ok = 0; while( 1 ) { int xMax = zRObj.getDrawGr().x - 1; int yMax = zRObj.getDrawGr().y - 1; if( !( outCode1 | outCode2 ) ) { ok = 1; break; } else if( outCode1 & outCode2 ) break; else { int x, y; char outCodeOut = outCode1 ? outCode1 : outCode2; if( outCodeOut & 8 ) { x = (int)( a.x + ( b.x - a.x ) * ( yMax - a.y ) / ( b.y - a.y ) + 0.5 ); y = yMax; } else if( outCodeOut & 4 ) { x = (int)( a.x + ( b.x - a.x ) * ( zRObj.getDrawPos().y - a.y ) / ( b.y - a.y ) + 0.5 ); y = zRObj.getDrawPos().y; } else if( outCodeOut & 2 ) { y = (int)( a.y + ( b.y - a.y ) * ( xMax - a.x ) / ( b.x - a.x ) + 0.5 ); x = xMax; } else if( outCodeOut & 1 ) { y = (int)( a.y + ( b.y - a.y ) * ( zRObj.getDrawPos().x - a.x ) / ( b.x - a.x ) + 0.5 ); x = zRObj.getDrawPos().x; } if( outCodeOut == outCode1 ) { a.x = x; a.y = y; outCode1 = getOutCode( a, zRObj ); } else { b.x = x; b.y = y; outCode2 = getOutCode( b, zRObj ); } } } if( ok ) { int xlän = b.x - a.x, axlän = abs( xlän ); int ylän = b.y - a.y, aylän = abs( ylän ); double xf = (double)xlän / ( aylän ? aylän : 1 ); double yf = (double)ylän / ( axlän ? axlän : 1 ); if( axlän > aylän ) xf = xf < 0 ? -1 : 1; else yf = yf < 0 ? -1 : 1; double x = (double)a.x, y = (double)a.y; int maxP = (int)( sqrt( xlän * xlän + ylän * ylän ) + 0.5 ); int count = 0; int *buffer = zRObj.getBuffer(); int maxPixel = zRObj.getBreite() * zRObj.getHeight(); while( !( (int)( x + 0.5 ) == b.x && (int)( y + 0.5 ) == b.y ) && count < maxP ) { ++count; if( (int)( (int)( x + 0.5 ) + (int)( y + 0.5 ) * zRObj.getBreite() ) < maxPixel ) buffer[ (int)( (int)( x + 0.5 ) + (int)( y + 0.5 ) * zRObj.getBreite() ) ] = 0xFFFFFFFF; if( (int)( (int)( x - 0.5 ) + (int)( y + 0.5 ) * zRObj.getBreite() ) < maxPixel && buffer[ (int)( (int)( x - 0.5 ) + (int)( y + 0.5 ) * zRObj.getBreite() ) ] != 0xFFFFFFFF ) zRObj.alphaPixel( (int)( x - 0.5 ), (int)( y + 0.5 ), f ); if( (int)( (int)( x + 1.5 ) + (int)( y + 0.5 ) * zRObj.getBreite() ) < maxPixel && buffer[ (int)( (int)( x + 1.5 ) + (int)( y + 0.5 ) * zRObj.getBreite() ) ] != 0xFFFFFFFF ) zRObj.alphaPixel( (int)( x + 1.5 ), (int)( y + 0.5 ), f ); if( (int)( (int)( x + 0.5 ) + (int)( y - 0.5 ) * zRObj.getBreite() ) < maxPixel && buffer[ (int)( (int)( x + 0.5 ) + (int)( y - 0.5 ) * zRObj.getBreite() ) ] != 0xFFFFFFFF ) zRObj.alphaPixel( (int)( x + 0.5 ), (int)( y - 0.5 ), f ); if( (int)( (int)( x + 0.5 ) + (int)( y + 1.5 ) * zRObj.getBreite() ) < maxPixel && buffer[ (int)( (int)( x + 0.5 ) + (int)( y + 1.5 ) * zRObj.getBreite() ) ] != 0xFFFFFFFF ) zRObj.alphaPixel( (int)( x + 0.5 ), (int)( y + 1.5 ), f ); x += xf, y += yf; } } } void Laser::renderMinimap( Bild &zRObj, Karte *zMap ) { int x = (int)( ( pos.x / zMap->getSize().x ) * 250 + 0.5 ); int y = (int)( ( pos.y / zMap->getSize().y ) * 250 + 0.5 ); zRObj.setPixelDP( x + zRObj.getDrawOff().x, y + zRObj.getDrawOff().y, tf ); } // constant int Laser::getId() const { return id; } int Laser::getSpieler() const { return sNum; } double Laser::getIntensität() const { return intensität; } // Reference Counting Laser *Laser::getThis() { ref++; return this; } Laser *Laser::release() { ref--; if( !ref ) delete this; return 0; }