#include "VideoSpieler.h" #include #include #include #include // Inhalt der VideoSpieler Klasse aus VideoSpieler.h // Konstruktor VideoSpieler::VideoSpieler( SpielerVideoDaten *vDaten ) { spielerNummer = vDaten->spielerNummer; team = vDaten->team; spielerFarbe = 0; teamFarbe = 0; daten = new Array< VideoSpielerRundeDaten* >(); daten->set( new VideoSpielerRundeDaten( { 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 } ), 0 ); runde = -1; name = new Text(); teamName = new Text(); teamRahmen = new LRahmen(); teamRahmen->setRamenBreite( 1 ); teamRahmen->setSize( 10, 10 ); ref = 1; spielerFarbe = vDaten->spielerFarbe; teamFarbe = vDaten->teamFarbe; name->setText( vDaten->name.getText() ); teamName->setText( vDaten->teamName.getText() ); teamRahmen->setFarbe( vDaten->teamFarbe ); gewonneneRunden = 0; linienLänge = 0; zeitAmLeben = 0; zeitTod = 0; kills = 0; tode = 0; killFarbe = 0; } // Destruktor VideoSpieler::~VideoSpieler() { teamRahmen->release(); name->release(); teamName->release(); int anz = daten->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { if( daten->hat( i ) ) delete daten->get( i ); } daten->release(); } // nicht constant void VideoSpieler::addKill() { kills++; rKills.set( rKills.get( runde ) + 1, runde ); } void VideoSpieler::neuRunde( bool vorwärts, RundeSpielerVideoDaten *vDaten, bool amLeben ) { if( vorwärts ) { if( runde >= 0 ) { if( daten->get( runde )->amLeben ) gewonneneRunden++; } runde++; rLinienLänge.set( 0, runde ); rKills.set( 0, runde ); rTodesZeit.set( 0, runde ); if( daten->hat( runde ) ) delete daten->get( runde ); daten->set( new VideoSpielerRundeDaten( { vDaten->xPos, vDaten->yPos, vDaten->xSpeed, vDaten->ySpeed, vDaten->wendigkeit, 1, amLeben, 0, 0, 1, 0, 0 } ), runde ); } else runde--; } void VideoSpieler::setLinksKurve( bool lKurve ) { daten->get( runde )->lKurve = lKurve; } void VideoSpieler::setRechtsKurve( bool rKurve ) { daten->get( runde )->rKurve = rKurve; } void VideoSpieler::setLinienUnterbrechung( bool unterbrechung ) { daten->get( runde )->linieUnterbrochen = unterbrechung; } void VideoSpieler::prozessKurve( double zeit ) { VideoSpielerRundeDaten *dat = daten->get( runde ); if( dat->amLeben ) { if( dat->lKurve || dat->rKurve ) { double grad = dat->kurve * zeit; if( dat->lKurve ) grad = -grad; double cs = cos( grad ); double sn = sin( grad ); double tmpX = ( dat->xSpeed * cs - dat->ySpeed * sn ); double tmpY = ( dat->xSpeed * sn + dat->ySpeed * cs ); dat->xSpeed = tmpX; dat->ySpeed = tmpY; } } } void VideoSpieler::tick( Bild *zMap, double zeit ) { VideoSpielerRundeDaten *dat = daten->get( runde ); dat->spielZeit += zeit; bool wiederbelebt = 0; bool rückwärts = zeit < 0; if( rückwärts && !dat->amLeben ) { if( dat->todesZeit >= dat->spielZeit ) { dat->amLeben = 1; wiederbelebt = 1; } } if( dat->amLeben ) { zeitAmLeben += zeit; if( !rückwärts ) prozessKurve( zeit ); int dpx = 0; int dpy = 0; int dgx = zMap->getBreite(); int dgy = zMap->getHeight(); int *buff = zMap->getBuffer(); if( zMap && !dat->linieUnterbrochen ) { int x1 = (int)( dat->xPos + 0.5 ); int y1 = (int)( dat->yPos + 0.5 ); int x2 = (int)( dat->xPos + dat->xSpeed * zeit + 0.5 ); int y2 = (int)( dat->yPos + dat->ySpeed * zeit + 0.5 ); int xlän = x2 - x1, axlän = abs( xlän ); int ylän = y2 - y1, 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)x1, y = (double)y1; int maxP = (int)( sqrt( (double)( xlän * xlän + ylän * ylän ) ) + 0.5 ); int count = 0; int lastX = (int)( x + 0.5 ), lastY = (int)( y + 0.5 ); if( !rückwärts ) { while( !( (int)( x + 0.5 ) == x2 && (int)( y + 0.5 ) == y2 ) && count < maxP ) { if( (int)( x + 0.5 ) < dpx || (int)( x + 0.5 ) >= dgx || (int)( y + 0.5 ) < dpy || (int)( y + 0.5 ) >= dgy ) { killFarbe = 0; tode++; dat->todesZeit = dat->spielZeit; rTodesZeit.set( (int)dat->spielZeit, runde ); dat->amLeben = 0; dat->renderVorTod = count; break; } if( buff[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * zMap->getBreite() ] ) { if( buff[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * zMap->getBreite() ] != spielerFarbe ) killFarbe = buff[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * zMap->getBreite() ]; else killFarbe = 0; tode++; dat->todesZeit = dat->spielZeit; rTodesZeit.set( (int)dat->spielZeit, runde ); dat->amLeben = 0; dat->renderVorTod = count; break; } buff[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * zMap->getBreite() ] = spielerFarbe; linienLänge++; rLinienLänge.set( rLinienLänge.get( runde ) + 1, runde ); x += xf, y += yf; if( lastX != (int)( x + 0.5 ) && lastY != (int)( yf + 0.5 ) ) { if( (int)xf ) { if( !( lastX < dpx || lastX >= dgx || (int)( y + 0.5 ) < dpy || (int)( y + 0.5 ) >= dgy ) ) buff[ lastX + (int)( y + 0.5 ) * zMap->getBreite() ] = spielerFarbe; } else { if( !( (int)( x + 0.5 ) < dpx || (int)( x + 0.5 ) >= dgx || lastY < dpy || lastY >= dgy ) ) buff[ (int)( x + 0.5 ) + lastY * zMap->getBreite() ] = spielerFarbe; } } lastX = (int)( x + 0.5 ); lastY = (int)( y + 0.5 ); count++; } } if( rückwärts ) { if( wiederbelebt ) maxP = dat->renderVorTod; while( !( (int)( x ) == x2 && (int)( y + 0.5 ) == y2 ) && count < maxP ) { count++; x += xf, y += yf; if( lastX != (int)( x + 0.5 ) && lastY != (int)( yf + 0.5 ) ) { if( (int)xf ) { if( !( (int)( x + 0.5 ) < dpx || (int)( x + 0.5 ) >= dgx || lastY < dpy || lastY >= dgy ) ) buff[ (int)( x + 0.5 ) + lastY * zMap->getBreite() ] = 0; } else { if( !( lastX < dpx || lastX >= dgx || (int)( y + 0.5 ) < dpy || (int)( y + 0.5 ) >= dgy ) ) buff[ lastX + (int)( y + 0.5 ) * zMap->getBreite() ] = 0; } } lastX = (int)( x + 0.5 ); lastY = (int)( y + 0.5 ); if( !( (int)( x + 0.5 ) < dpx || (int)( x + 0.5 ) >= dgx || (int)( y + 0.5 ) < dpy || (int)( y + 0.5 ) >= dgy ) ) buff[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * zMap->getBreite() ] = 0; } } } dat->xPos += dat->xSpeed * zeit; dat->yPos += dat->ySpeed * zeit; if( rückwärts ) prozessKurve( zeit ); } else zeitTod += zeit; } void VideoSpieler::render( VideoKamera *zKam, Bild &zRObj ) { VideoSpielerRundeDaten *dat = daten->get( runde ); if( dat->amLeben ) { if( zKam->istSichtbar( (int)dat->xPos, (int)dat->yPos ) ) { teamRahmen->setPosition( zKam->getRX( (int)dat->xPos ) - 5, zKam->getRY( (int)dat->yPos ) - 5 ); zRObj.fillRegion( teamRahmen->getX(), teamRahmen->getY(), 10, 10, spielerFarbe ); teamRahmen->render( zRObj ); } } } // constant double VideoSpieler::getX() const { return daten->get( runde )->xPos; } double VideoSpieler::getY() const { return daten->get( runde )->yPos; } int VideoSpieler::getTeam() const { return team; } int VideoSpieler::getTeamFarbe() const { return teamFarbe; } int VideoSpieler::getFarbe() const { return spielerFarbe; } int VideoSpieler::getSpielerNummer() const { return spielerNummer; } bool VideoSpieler::istAmLeben() const { return daten->get( runde )->amLeben; } Text *VideoSpieler::getName() const { return name ? name->getThis() : 0; } Text *VideoSpieler::zName() const { return name; } Text *VideoSpieler::getTeamName() const { return teamName ? teamName->getThis() : 0; } Text *VideoSpieler::zTeamName() const { return teamName; } bool VideoSpieler::istMausIn( int mx, int my ) const { VideoSpielerRundeDaten *dat = daten->get( runde ); return mx >= (int)dat->xPos - 5 && mx <= (int)dat->xPos + 5 && my >= (int)dat->yPos - 5 && my <= (int)dat->yPos + 5; } int VideoSpieler::getGewonneneRunden() const { return gewonneneRunden; } int VideoSpieler::getLinienLänge() const { return linienLänge; } int VideoSpieler::getZeitAmLeben() const { return (int)zeitAmLeben; } int VideoSpieler::getZeitTod() const { return (int)zeitTod; } int VideoSpieler::getKills() const { return kills; } int VideoSpieler::getTode() const { return tode; } int VideoSpieler::getKillFarbe() const { return killFarbe; } int VideoSpieler::getLinienLänge( int r ) const { return rLinienLänge.get( r ); } int VideoSpieler::getKills( int r ) const { return rKills.get( r ); } int VideoSpieler::getTodesZeit( int r ) const { return rTodesZeit.get( r ); } // Reference Counting VideoSpieler *VideoSpieler::getThis() { ref++; return this; } VideoSpieler *VideoSpieler::release() { ref--; if( !ref ) delete this; return 0; }