tron.cpp 41.7 KB
Newer Older
1
/****************************************************************************
Stephan Kulow's avatar
Stephan Kulow committed
2 3
  This file is part of the game 'KTron'

4
  Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
Stephan Kulow's avatar
Stephan Kulow committed
5 6 7 8 9

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
10

Stephan Kulow's avatar
Stephan Kulow committed
11 12 13 14
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
15

Stephan Kulow's avatar
Stephan Kulow committed
16 17
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
Dirk Mueller's avatar
Dirk Mueller committed
18
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Stephan Kulow's avatar
Stephan Kulow committed
19

20 21 22 23
  ***************************************************************************/
// Background
#include <kio/netaccess.h>
#include <kmessagebox.h>
Stephan Kulow's avatar
Stephan Kulow committed
24

25
// Normal class
26 27 28
#include <qtimer.h>

#include <kdebug.h>
Stephan Kulow's avatar
Stephan Kulow committed
29
#include <klocale.h>
30
#include <kapplication.h>
Stephan Kulow's avatar
Stephan Kulow committed
31
#include <kconfig.h>
Laurent Montel's avatar
Laurent Montel committed
32
#include <kcolordialog.h>
Andreas Beckermann's avatar
Andreas Beckermann committed
33
#include <kaction.h>
Stephan Kulow's avatar
Stephan Kulow committed
34

35
#include "settings.h"
Stephan Kulow's avatar
Stephan Kulow committed
36 37
#include "tron.h"

38
#define TRON_FRAMESIZE 2
Stephan Kulow's avatar
Stephan Kulow committed
39

40 41 42
/**
 * init-functions
 **/
Stephan Kulow's avatar
Stephan Kulow committed
43

44
Tron::Tron(QWidget *parent,const char *name)
Stephan Kulow's avatar
Stephan Kulow committed
45 46 47 48 49 50 51
  : QWidget(parent,name)
{
  pixmap=0;
  playfield=0;
  beginHint=false;
  lookForward=15;

Waldo Bastian's avatar
Waldo Bastian committed
52
  random.setSeed(0);
Stephan Kulow's avatar
Stephan Kulow committed
53 54 55 56 57

  setFocusPolicy(QWidget::StrongFocus);
  setBackgroundMode(NoBackground);

  gameBlocked=false;
58
  rectSize=10;
Stephan Kulow's avatar
Stephan Kulow committed
59

60 61 62 63 64 65 66
  timer = new QTimer(this,"timer");
  loadSettings();
  connect(timer, SIGNAL(timeout()), SLOT(doMove()));
  QTimer::singleShot(15000, this,SLOT(showBeginHint()));
}

void Tron::loadSettings(){
67
  setPalette(Settings::color_Background());
68 69

  // Size
70
  int newSize = Settings::rectSize();
71 72 73 74 75
  if(newSize!=rectSize){
    rectSize=newSize;
    createNewPlayfield();
  }

76
  reset();
77

78 79
  // Velocity
  setVelocity( Settings::velocity() );
80 81 82 83 84 85

  // Style
  if(pixmap){
    updatePixmap();
    repaint();
  }
86

87
  // Backgroundimage
88
  setBackgroundPix(NULL);
89
  if(Settings::backgroundImageChoice()){
Dirk Mueller's avatar
Dirk Mueller committed
90
    KURL url ( Settings::backgroundImage() );
91 92
    if(!url.isEmpty()){
      QString tmpFile;
93
      KIO::NetAccess::download(url, tmpFile, this);
94 95 96 97 98
      QPixmap pix(tmpFile);
      if(!pix.isNull()){
        setBackgroundPix(pix);
      } else {
  	QString msg=i18n("Wasn't able to load wallpaper\n%1");
99 100
	msg=msg.arg(tmpFile);
	KMessageBox::sorry(this, msg);
101 102
      }
      KIO::NetAccess::removeTempFile(tmpFile);
103
    }
104
    else setBackgroundPix(NULL);
105
  }
106 107
  setComputerplayer(One, Settings::computerplayer1());
  setComputerplayer(Two, Settings::computerplayer2());
Stephan Kulow's avatar
Stephan Kulow committed
108 109 110 111 112 113 114 115 116 117
}

Tron::~Tron()
{
  if(playfield)
    {
      delete []  playfield;
    }
  if(pixmap)
    delete pixmap;
118 119
  delete timer;

Stephan Kulow's avatar
Stephan Kulow committed
120 121 122 123 124
}

void Tron::createNewPlayfield()
{
  if(playfield)
125
    delete [] playfield;
Stephan Kulow's avatar
Stephan Kulow committed
126 127 128 129

  if(pixmap)
    delete pixmap;

130
  // field size
131 132
  fieldWidth=(width()-2*TRON_FRAMESIZE)/rectSize;
  fieldHeight=(height()-2*TRON_FRAMESIZE)/rectSize;
Stephan Kulow's avatar
Stephan Kulow committed
133

134
  // start positions
135
  playfield=new QMemArray<int>[fieldWidth];
Stephan Kulow's avatar
Stephan Kulow committed
136 137 138 139
  for(int i=0;i<fieldWidth;i++)
    playfield[i].resize(fieldHeight);

  pixmap=new QPixmap(size());
140
  pixmap->fill(Settings::color_Background());
Stephan Kulow's avatar
Stephan Kulow committed
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

  //int min=(fieldWidth<fieldHeight) ? fieldWidth : fieldHeight;
  //lookForward=min/4;
}

void Tron::newGame()
{
  players[0].score=0;
  players[1].score=0;
  emit gameEnds(Nobody);
  reset();

  QTimer::singleShot(15000,this,SLOT(showBeginHint()));
}

void Tron::reset()
{
  gamePaused=false;
  stopGame();

  players[0].reset();
  players[1].reset();

164 165
  // If playfield exists, then clean it
  // ans set start coordinates
Stephan Kulow's avatar
Stephan Kulow committed
166 167 168 169 170 171
  if(playfield)
  {
      int i;
      for(i=0;i<fieldWidth;i++)
	   	playfield[i].fill(BACKGROUND);

172
      // set start coordinates
Stephan Kulow's avatar
Stephan Kulow committed
173 174 175 176

      players[0].setCoordinates(fieldWidth/3, fieldHeight/2);
      players[1].setCoordinates(2*fieldWidth/3, fieldHeight/2);

177 178 179 180
      playfield[players[0].xCoordinate][players[0].yCoordinate]=
         PLAYER1 | TOP | BOTTOM | LEFT | RIGHT;
      playfield[players[1].xCoordinate][players[1].yCoordinate]=
         PLAYER2 | TOP | BOTTOM | LEFT | RIGHT;
Stephan Kulow's avatar
Stephan Kulow committed
181 182 183 184 185 186 187 188 189 190

      updatePixmap();
      update();
    }

    setFocus();

    emit gameReset();
}

191 192 193 194 195 196 197 198
void Tron::computerStart()
{
   if(isComputer(Both))
   {
      reset();
      startGame();
   }
}
Stephan Kulow's avatar
Stephan Kulow committed
199 200 201 202 203 204 205 206

/* *************************************************************** **
**                   	??? functions										 **
** *************************************************************** */

void Tron::startGame()
{
   gameEnded=false;
207 208
   beginHint=false;
   timer->start(velocity);
Stephan Kulow's avatar
Stephan Kulow committed
209 210 211 212
}

void Tron::stopGame()
{
213 214
   timer->stop();
   gameEnded=true;
215 216
   players[0].last_dir = Directions::None;
   players[1].last_dir = Directions::None;
Stephan Kulow's avatar
Stephan Kulow committed
217 218 219 220 221
}

void Tron::togglePause() // pause or continue game
{
  if(!gameEnded)
222 223 224 225 226 227 228 229 230 231 232 233 234
  {
     if(gamePaused)
     {
        gamePaused=false;
        update();
        timer->start(velocity);
     }
     else
     {
        gamePaused=true;
        timer->stop();
        update();
     }
Stephan Kulow's avatar
Stephan Kulow committed
235 236 237 238 239
  }
}

void Tron::showWinner(Player player)
{
240
   int i,j;
Stephan Kulow's avatar
Stephan Kulow committed
241

242
   if(player != Both && Settings::changeWinnerColor())
243 244
   {
      int winner;
James Greenhalgh's avatar
James Greenhalgh committed
245
      int loser;
246 247 248
      if(player==One)
      {
         winner=PLAYER1;
James Greenhalgh's avatar
James Greenhalgh committed
249
         loser=PLAYER2;
Stephan Kulow's avatar
Stephan Kulow committed
250
      }
251 252 253
      else
      {
         winner=PLAYER2;
James Greenhalgh's avatar
James Greenhalgh committed
254
         loser=PLAYER1;
Stephan Kulow's avatar
Stephan Kulow committed
255 256
      }

257 258
      for(i=0;i<fieldWidth;i++)
         for(j=0;j<fieldHeight;j++)
259
         {
260 261 262 263
            if(playfield[i][j]!=BACKGROUND)
            {
               // change player
               playfield[i][j] |= winner;
James Greenhalgh's avatar
James Greenhalgh committed
264
               playfield[i][j] &= ~loser;
265 266 267 268
            }
         }

      updatePixmap();
Stephan Kulow's avatar
Stephan Kulow committed
269 270
   }

271
   repaint();
Stephan Kulow's avatar
Stephan Kulow committed
272

273
   emit gameEnds(player);
Stephan Kulow's avatar
Stephan Kulow committed
274

275 276 277 278
   if(isComputer(Both))
   {
       QTimer::singleShot(1000,this,SLOT(computerStart()));
   }
Stephan Kulow's avatar
Stephan Kulow committed
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
}

/* *************************************************************** **
**                    paint functions										 **
** *************************************************************** */

void Tron::updatePixmap()
{
  int i,j;

  if(!bgPix.isNull())
  {
     int pw=bgPix.width();
     int ph=bgPix.height();
     for (int x = 0; x <= width(); x+=pw)
294 295
        for (int y = 0; y <= height(); y+=ph)
	    bitBlt(pixmap, x, y, &bgPix);
Stephan Kulow's avatar
Stephan Kulow committed
296 297 298
  }
  else
  {
299
    pixmap->fill(Settings::color_Background());
Stephan Kulow's avatar
Stephan Kulow committed
300 301 302 303 304 305 306
  }

  QPainter p;
  p.begin(pixmap);

  // alle Pixel prfen und evt. zeichnen
  for(i=0;i<fieldWidth;i++)
307 308 309 310 311
     for(j=0;j<fieldHeight;j++)
     {
        if(playfield[i][j]!=BACKGROUND)
        {
           drawRect(p,i,j);
Stephan Kulow's avatar
Stephan Kulow committed
312
	}
313
     }
314

315 316 317 318 319 320
   // draw frame
   QColor light=parentWidget()->colorGroup().midlight();
   QColor dark=parentWidget()->colorGroup().mid();

   p.setPen(NoPen);
   p.setBrush(light);
321 322
      p.drawRect(width()-TRON_FRAMESIZE,0,TRON_FRAMESIZE,height());
   p.drawRect(0,height()-TRON_FRAMESIZE,width(),TRON_FRAMESIZE);
323
   p.setBrush(dark);
324 325
   p.drawRect(0,0,width(),TRON_FRAMESIZE);
   p.drawRect(0,0,TRON_FRAMESIZE,height());
Stephan Kulow's avatar
Stephan Kulow committed
326

327
   p.end();
Stephan Kulow's avatar
Stephan Kulow committed
328 329
}

330
// draw new player rects
Stephan Kulow's avatar
Stephan Kulow committed
331 332
void Tron::paintPlayers()
{
333 334 335 336 337
   QPainter p;
   p.begin(this);
   drawRect(p,players[0].xCoordinate,players[0].yCoordinate);
   drawRect(p,players[1].xCoordinate,players[1].yCoordinate);
   p.end();
Stephan Kulow's avatar
Stephan Kulow committed
338

339 340 341 342
   p.begin(pixmap);
   drawRect(p,players[0].xCoordinate,players[0].yCoordinate);
   drawRect(p,players[1].xCoordinate,players[1].yCoordinate);
   p.end();
Stephan Kulow's avatar
Stephan Kulow committed
343 344 345 346
}

void Tron::drawRect(QPainter & p, int x, int y)
{
347 348
   int xOffset=x*rectSize+(width()-fieldWidth*rectSize)/2;
   int yOffset=y*rectSize+(height()-fieldHeight*rectSize)/2;
Stephan Kulow's avatar
Stephan Kulow committed
349

350
   int type=playfield[x][y];
Stephan Kulow's avatar
Stephan Kulow committed
351 352

   // find out which color to draw
353 354 355 356
   QColor toDraw;
   int player;
   if(type&PLAYER1) // check player bit
   {
357
      toDraw=Settings::color_Player1();
358 359 360 361
      player=0;
   }
   else if(type&PLAYER2)
   {
362
      toDraw=Settings::color_Player2();
363 364
      player=1;
   }
Stephan Kulow's avatar
Stephan Kulow committed
365 366
   else
   {
367
      kdDebug() << "No player defined in Tron::drawRect(...)" << endl;
Stephan Kulow's avatar
Stephan Kulow committed
368 369 370
      return;
   }

371
   switch(Settings::style())
372
   {
373
      case Settings::EnumStyle::Line:
374 375 376 377
         p.setBrush(toDraw);
         p.setPen(toDraw);
         p.drawRect(xOffset,yOffset,rectSize,rectSize);
         break;
378
      case Settings::EnumStyle::OLine:
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
      {
         p.setBrush(toDraw);
         p.setPen(toDraw);
         p.drawRect(xOffset,yOffset,rectSize,rectSize);
         p.setPen(toDraw.light());
         if(type&TOP)
         {
            p.drawLine(xOffset,yOffset,xOffset+rectSize-1,yOffset);
         }
         if(type&LEFT)
         {
            p.drawLine(xOffset,yOffset,xOffset,yOffset+rectSize-1);
         }
         p.setPen(toDraw.dark());
         if(type&RIGHT)
         {
            p.drawLine(xOffset+rectSize-1,yOffset,xOffset+rectSize-1,yOffset+rectSize-1);
         }
         if(type&BOTTOM)
         {
            p.drawLine(xOffset,yOffset+rectSize-1,xOffset+rectSize-1,yOffset+rectSize-1);
         }

         break;
      }
404
      case Settings::EnumStyle::Circle:
405 406 407 408
         p.setBrush(toDraw);
         p.setPen(toDraw);
         p.drawEllipse(xOffset ,yOffset ,rectSize,rectSize);
         break;
409
      case Settings::EnumStyle::ORect:
410 411 412 413 414 415 416 417
         p.setBrush(toDraw);
         p.setPen(toDraw.light());
         p.drawRect(xOffset,yOffset,rectSize,rectSize);
         p.setPen(toDraw.dark());
         p.drawLine(xOffset,yOffset+rectSize-1,xOffset+rectSize-1
             ,yOffset+rectSize-1);
         p.drawLine(xOffset+rectSize-1,yOffset,xOffset+rectSize-1,yOffset+rectSize-1);
         break;
Stephan Kulow's avatar
Stephan Kulow committed
418 419 420 421 422 423 424
    }
}

/* *************************************************************** **
**                    config functions										 **
** *************************************************************** */

Andreas Beckermann's avatar
Andreas Beckermann committed
425
void Tron::setActionCollection(KActionCollection *a)
Stephan Kulow's avatar
Stephan Kulow committed
426
{
Andreas Beckermann's avatar
Andreas Beckermann committed
427
   actionCollection = a;
Stephan Kulow's avatar
Stephan Kulow committed
428 429 430 431 432 433
}

void Tron::setBackgroundPix(QPixmap pix)
{
    bgPix=pix;

434
    if(pixmap!=0){
Stephan Kulow's avatar
Stephan Kulow committed
435
       updatePixmap();
436 437 438
      // most pictures have colors, that you can read white text
      setPalette(QColor("black"));
    }
Stephan Kulow's avatar
Stephan Kulow committed
439 440 441 442 443 444 445 446 447 448
}

void Tron::setVelocity(int newVel)            // set new velocity
{
  velocity=(10-newVel)*15;

  if(!gameEnded && !gamePaused)
    timer->changeInterval(velocity);
}

449
void Tron::setComputerplayer(Player player, bool flag) {
Stephan Kulow's avatar
Stephan Kulow committed
450
  if(player==One)
451
    players[0].setComputer(flag);
Stephan Kulow's avatar
Stephan Kulow committed
452
  else if(player==Two)
453
    players[1].setComputer(flag);
Stephan Kulow's avatar
Stephan Kulow committed
454

455
  if(isComputer(Both))
456
      QTimer::singleShot(1000,this,SLOT(computerStart()));
Stephan Kulow's avatar
Stephan Kulow committed
457 458 459 460 461
}

bool Tron::isComputer(Player player)
{
   if(player==One)
462
     return players[0].computer;
Stephan Kulow's avatar
Stephan Kulow committed
463
   else if(player==Two)
464
     return players[1].computer;
Stephan Kulow's avatar
Stephan Kulow committed
465 466 467
   else if(player==Both)
   {
      if(players[0].computer && players[1].computer)
468
        return true;
Stephan Kulow's avatar
Stephan Kulow committed
469 470
   }

471
   return false;
Stephan Kulow's avatar
Stephan Kulow committed
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
}

/* *************************************************************** **
**                    moving functions										 **
** *************************************************************** */

bool Tron::crashed(int playerNr,int xInc, int yInc) const
{
  bool flag;
  int newX=players[playerNr].xCoordinate+xInc;
  int newY=players[playerNr].yCoordinate+yInc;

  if(newX<0 || newY <0 || newX>=fieldWidth || newY>=fieldHeight)
     flag=true;
  else if(playfield[newX][newY] != BACKGROUND)
    flag=true;
  else flag=false;

  return flag;
}

493
void Tron::switchDir(int playerNr,Directions::Direction newDirection)
Stephan Kulow's avatar
Stephan Kulow committed
494 495 496
{
  if(playerNr!=0 && playerNr != 1)
  {
497
     kdDebug() << "wrong playerNr" << endl;
Stephan Kulow's avatar
Stephan Kulow committed
498 499 500
     return;
  }

501
  if (Settings::oppositeDirCrashes()==false)
502
  {
503
    if (newDirection==Directions::Up && players[playerNr].last_dir==Directions::Down)
504
      return;
505
    if (newDirection==Directions::Down && players[playerNr].last_dir==Directions::Up)
506
      return;
507
    if (newDirection==Directions::Left && players[playerNr].last_dir==Directions::Right)
508
      return;
509
    if (newDirection==Directions::Right && players[playerNr].last_dir==Directions::Left)
510 511
      return;
  }
Stephan Kulow's avatar
Stephan Kulow committed
512

513
  players[playerNr].dir=newDirection;
Stephan Kulow's avatar
Stephan Kulow committed
514 515 516 517 518
}

void Tron::updateDirections(int playerNr)
{
   if(playerNr==-1 || playerNr==0)
519
   {
520 521
      int x=players[0].xCoordinate;
      int y=players[0].yCoordinate;
Stephan Kulow's avatar
Stephan Kulow committed
522

523 524 525 526
      // necessary for drawing the 3d-line
      switch(players[0].dir)
      {
         // unset drawing flags in the moving direction
527
         case Directions::Up:
528
         {
529 530 531
            playfield[x][y] &= (~TOP);
            break;
         }
532
         case Directions::Down:
533 534
            playfield[x][y] &= (~BOTTOM);
            break;
535
         case Directions::Right:
536 537
            playfield[x][y] &= (~RIGHT);
            break;
538
         case Directions::Left:
539 540
            playfield[x][y] &= (~LEFT);
            break;
541 542
         default:
            break;
543
      }
544
      players[0].last_dir = players[0].dir;
545 546

   }
Stephan Kulow's avatar
Stephan Kulow committed
547
   if(playerNr==-1 || playerNr==1)
548
   {
549 550
      int x=players[1].xCoordinate;
      int y=players[1].yCoordinate;
551

552 553 554 555
      // necessary for drawing the 3d-line
      switch(players[1].dir)
      {
          // unset drawing flags in the moving direction
556
     	  case Directions::Up:
557 558 559 560
     	  {
             playfield[x][y] &= (~TOP);
             break;
       	  }
561
          case Directions::Down:
562 563
             playfield[x][y] &= (~BOTTOM);
             break;
564
          case Directions::Right:
565 566
             playfield[x][y] &= (~RIGHT);
             break;
567
          case Directions::Left:
568 569
             playfield[x][y] &= (~LEFT);
             break;
570 571
         default:
            break;
572
      }
573
      players[1].last_dir = players[1].dir;
574 575

   }
Stephan Kulow's avatar
Stephan Kulow committed
576

577
   paintPlayers();
Stephan Kulow's avatar
Stephan Kulow committed
578 579 580 581 582 583 584 585
}

/* *************************************************************** **
**                    			Events										 **
** *************************************************************** */

void Tron::paintEvent(QPaintEvent *e)
{
586
   bitBlt(this,e->rect().topLeft(),pixmap,e->rect());
Stephan Kulow's avatar
Stephan Kulow committed
587

588 589 590 591 592 593 594 595 596
   // if game is paused, print message
   if(gamePaused)
   {
      QString message=i18n("Game paused");
      QPainter p(this);
      QFontMetrics fm=p.fontMetrics();
      int w=fm.width(message);
      p.drawText(width()/2-w/2,height()/2,message);
   }
Stephan Kulow's avatar
Stephan Kulow committed
597

598 599 600 601 602 603
   // If game ended, print "Crash!"
   else if(gameEnded)
   {
      QString message=i18n("Crash!");
      QPainter p(this);
      int w=p.fontMetrics().width(message);
604
      int h=p.fontMetrics().height();
605 606 607 608
      for(int i=0;i<2;i++)
      {
         if(!players[i].alive)
     	 {
609 610 611 612 613 614
            int x=players[i].xCoordinate*rectSize;
            int y=players[i].yCoordinate*rectSize;
            while(x<0) x+=rectSize;
            while(x+w>width()) x-=rectSize;
            while(y-h<0) y+=rectSize;
            while(y>height()) y-=rectSize;
615 616 617
            p.drawText(x,y,message);
         }
      }
618

619 620 621 622 623 624 625
      // draw begin hint
      if(beginHint)
      {
         QString hint=i18n("Press any of your direction keys to start!");
         int x=p.fontMetrics().width(hint);
         x=(width()-x)/2;
         int y=height()/2;
626

627 628 629
         p.drawText(x,y,hint);
      }
   }
Stephan Kulow's avatar
Stephan Kulow committed
630 631 632 633 634 635 636 637 638 639
}

void Tron::resizeEvent(QResizeEvent *)
{
    createNewPlayfield();
    reset();
}

void Tron::keyPressEvent(QKeyEvent *e)
{
Andreas Beckermann's avatar
Andreas Beckermann committed
640
  KKey key(e);
Stephan Kulow's avatar
Stephan Kulow committed
641 642
  if(!players[1].computer)
  {
Andreas Beckermann's avatar
Andreas Beckermann committed
643
      if(actionCollection->action("Pl2Up")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
644
		{
645
	  		switchDir(1,Directions::Up);
Stephan Kulow's avatar
Stephan Kulow committed
646 647
	  		players[1].keyPressed=true;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
648
      else if(actionCollection->action("Pl2Left")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
649
	   {
650
	  		switchDir(1,Directions::Left);
Stephan Kulow's avatar
Stephan Kulow committed
651 652
	  		players[1].keyPressed=true;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
653
      else if(actionCollection->action("Pl2Right")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
654
		{
655
	  		switchDir(1,Directions::Right);
Stephan Kulow's avatar
Stephan Kulow committed
656 657
	  		players[1].keyPressed=true;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
658
      else if(actionCollection->action("Pl2Down")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
659
		{
660
	  		switchDir(1,Directions::Down);
Stephan Kulow's avatar
Stephan Kulow committed
661 662
	  		players[1].keyPressed=true;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
663
      else if(actionCollection->action("Pl2Ac")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
664
		{
665
		   if(!Settings::acceleratorBlocked())
Stephan Kulow's avatar
Stephan Kulow committed
666 667
	  			players[1].accelerated=true;

Andreas Beckermann's avatar
Andreas Beckermann committed
668
		}
Stephan Kulow's avatar
Stephan Kulow committed
669 670 671 672
  }

  if(!players[0].computer)
  {
Andreas Beckermann's avatar
Andreas Beckermann committed
673
      if(actionCollection->action("Pl1Left")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
674
		{
675
	  		switchDir(0,Directions::Left);
Stephan Kulow's avatar
Stephan Kulow committed
676 677
	  		players[0].keyPressed=true;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
678
      else if(actionCollection->action("Pl1Right")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
679
		{
680
	  		switchDir(0,Directions::Right);
Stephan Kulow's avatar
Stephan Kulow committed
681 682
	  		players[0].keyPressed=true;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
683
      else if(actionCollection->action("Pl1Up")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
684
		{
685
	  		switchDir(0,Directions::Up);
Stephan Kulow's avatar
Stephan Kulow committed
686 687
	  		players[0].keyPressed=true;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
688
      else if(actionCollection->action("Pl1Down")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
689
		{
690
	 		switchDir(0,Directions::Down);
Stephan Kulow's avatar
Stephan Kulow committed
691 692
	  		players[0].keyPressed=true;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
693
      else if(actionCollection->action("Pl1Ac")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
694
		{
695
		   if(!Settings::acceleratorBlocked())
Stephan Kulow's avatar
Stephan Kulow committed
696 697 698 699 700 701 702
	  			players[0].accelerated=true;
		}
  }

  e->ignore();  // if key is unknown: ignore

  // if both players press keys at the same time, start game...
703 704 705 706 707 708
  if(gameEnded && !gameBlocked)
  {
	if(players[0].keyPressed && players[1].keyPressed)
	{
		reset();
		startGame();
Stephan Kulow's avatar
Stephan Kulow committed
709
	}
710 711 712 713 714 715 716
  }
  // ...or continue
  else if(gamePaused)
  {
	if(players[0].keyPressed && players[1].keyPressed)
	{
	   togglePause();
Stephan Kulow's avatar
Stephan Kulow committed
717
	}
718
  }
Stephan Kulow's avatar
Stephan Kulow committed
719 720 721 722
}

void Tron::keyReleaseEvent(QKeyEvent * e)
{
Andreas Beckermann's avatar
Andreas Beckermann committed
723
  KKey key(e);
Stephan Kulow's avatar
Stephan Kulow committed
724 725 726

  if(!players[1].computer)
  {
Andreas Beckermann's avatar
Andreas Beckermann committed
727 728 729 730
      if(actionCollection->action("Pl2Ac")->shortcut().contains(key))
		{
			players[1].accelerated=false;
			return;
Stephan Kulow's avatar
Stephan Kulow committed
731
  		}
Andreas Beckermann's avatar
Andreas Beckermann committed
732
      else if(actionCollection->action("Pl2Left")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
733
		{
Andreas Beckermann's avatar
Andreas Beckermann committed
734 735
			players[1].keyPressed=false;
			return;
Stephan Kulow's avatar
Stephan Kulow committed
736
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
737
      else if(actionCollection->action("Pl2Right")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
738 739 740 741
		{
	  		players[1].keyPressed=false;
	  		return;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
742
      else if(actionCollection->action("Pl2Up")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
743 744 745 746
		{
	  		players[1].keyPressed=false;
	  		return;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
747
      else if(actionCollection->action("Pl2Down")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
748 749 750 751 752 753
		{
		  players[1].keyPressed=false;
		  return;
		}
  }

Andreas Beckermann's avatar
Andreas Beckermann committed
754
   if(!players[0].computer)
Stephan Kulow's avatar
Stephan Kulow committed
755
   {
Andreas Beckermann's avatar
Andreas Beckermann committed
756 757
      if(actionCollection->action("Pl1Left")->shortcut().contains(key))
		{
Stephan Kulow's avatar
Stephan Kulow committed
758 759
	 		players[0].keyPressed=false;
	 		return;
Andreas Beckermann's avatar
Andreas Beckermann committed
760 761
		}
      else if(actionCollection->action("Pl1Right")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
762 763 764 765
		{
	  		players[0].keyPressed=false;
	  		return;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
766
      else if(actionCollection->action("Pl1Up")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
767 768 769 770
		{
	 		players[0].keyPressed=false;
	  		return;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
771
      else if(actionCollection->action("Pl1Down")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
772 773 774 775
		{
	 		players[0].keyPressed=false;
	 		return;
		}
Andreas Beckermann's avatar
Andreas Beckermann committed
776
      else if(actionCollection->action("Pl1Ac")->shortcut().contains(key))
Stephan Kulow's avatar
Stephan Kulow committed
777 778 779 780 781 782 783 784 785 786
		{
	  		players[0].accelerated=false;
	  		return;
		}
 	}

   e->ignore();  // if pressed key is unknown, ignore it

}

James Greenhalgh's avatar
James Greenhalgh committed
787
// if playingfield loses keyboard focus, pause game
Stephan Kulow's avatar
Stephan Kulow committed
788 789
void Tron::focusOutEvent(QFocusEvent *)
{
790
   if(!gameEnded && !gamePaused)
Stephan Kulow's avatar
Stephan Kulow committed
791
   {
792
      togglePause();
Stephan Kulow's avatar
Stephan Kulow committed
793 794 795 796
   }
}

/* *************************************************************** **
797
**     				slots										 **
Stephan Kulow's avatar
Stephan Kulow committed
798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
** *************************************************************** */

void Tron::unblockGame()
{
  gameBlocked=false;
}

void Tron::showBeginHint()
{
   if(gameEnded)
   {
      // show only at the beginning of a game
      if(players[0].score==0 && players[1].score==0)
      {
         beginHint=true;
         repaint();
      }
   }
}

// doMove() is called from QTimer
void Tron::doMove()
{
   int i;
822 823 824
   for(i=0;i<2;i++)
   {
      // berprfen, ob Acceleratortaste gedrckt wurde...
Stephan Kulow's avatar
Stephan Kulow committed
825
      if(players[i].accelerated)
826 827
      {
         updateDirections(i);
Stephan Kulow's avatar
Stephan Kulow committed
828

829 830 831 832 833 834 835 836 837 838 839
         int newType; // determine type of rect to set
         if(i==0)
         {
            newType=PLAYER1;
         }
         else
         {
            newType=PLAYER2;
         }
         switch(players[i].dir)
         {
840
            case Directions::Up:
841 842 843 844 845 846 847 848
               if(crashed(i,0,-1))
                  players[i].alive=false;
               else
               {
                  players[i].yCoordinate--;
                  newType|=(TOP | LEFT | RIGHT);
               }
            break;
849
            case Directions::Down:
850 851 852 853 854 855 856 857
               if(crashed(i,0,1))
                  players[i].alive=false;
               else
               {
                  players[i].yCoordinate++;
                  newType |= (BOTTOM | LEFT | RIGHT);
               }
            break;
858
            case Directions::Left:
859 860 861 862 863 864 865 866
               if(crashed(i,-1,0))
                  players[i].alive=false;
               else
               {
                  players[i].xCoordinate--;
                  newType |= (LEFT | TOP | BOTTOM);
               }
            break;
867
            case Directions::Right:
868 869 870 871 872 873 874 875
               if(crashed(i,1,0))
                  players[i].alive=false;
               else
               {
                  players[i].xCoordinate++;
                  newType |= (RIGHT | TOP | BOTTOM);
               }
            break;
876 877
            default:
               break;
878 879 880 881 882
         }
         if(players[i].alive)
            playfield[players[i].xCoordinate][players[i].yCoordinate]=newType;
      }
   }
Stephan Kulow's avatar
Stephan Kulow committed
883

884 885 886
   if(players[0].accelerated || players[1].accelerated)
   {
      /* player collision check */
Stephan Kulow's avatar
Stephan Kulow committed
887
      if(!players[1].alive)
888 889 890 891
      {
         int xInc=0,yInc=0;
         switch(players[1].dir)
         {
892
            case Directions::Left:
893 894
              xInc = -1;
            break;
895
            case Directions::Right:
896 897
               xInc = 1;
            break;
898
            case Directions::Up:
899 900
               yInc = -1;
            break;
901
            case Directions::Down:
902 903
               yInc = 1;
            break;
904 905
            default:
            break;
906 907 908 909 910 911 912
         }
         if ((players[1].xCoordinate+xInc) == players[0].xCoordinate)
         if ((players[1].yCoordinate+yInc) == players[0].yCoordinate)
         {
            players[0].alive=false;
         }
      }
Stephan Kulow's avatar
Stephan Kulow committed
913 914 915 916 917

      paintPlayers();

      // crashtest
      if(!players[0].alive && !players[1].alive)
918 919 920 921 922 923
      {
         stopGame();
         players[0].score++;
         players[1].score++;
         showWinner(Both);
      }
Stephan Kulow's avatar
Stephan Kulow committed
924 925
      else
      {
926 927 928 929 930 931 932 933 934 935
         for(i=0;i<2;i++)
         {
            if(!players[i].alive)
            {
               stopGame();
               showWinner((i==0)? Two:One);
               players[i].score++;
            }
         }
      }
Stephan Kulow's avatar
Stephan Kulow committed
936 937 938


      if(gameEnded)
939 940 941 942 943 944 945
      {
         //this is for waiting 0,5s before starting next game
         gameBlocked=true;
         QTimer::singleShot(1000,this,SLOT(unblockGame()));
	 return;
      }
   }
Stephan Kulow's avatar
Stephan Kulow committed
946

947 948
   // neue Spielerstandorte festlegen
   for(i=0;i<2;i++)
Stephan Kulow's avatar
Stephan Kulow committed
949 950
   {
      if(players[i].computer)
951
         think(i);
Stephan Kulow's avatar
Stephan Kulow committed
952 953 954 955 956 957
   }

   updateDirections();

   for(i=0;i<2;i++)
   {
958 959 960 961 962
      int newType;
      if(i==0)
         newType=PLAYER1;
      else
         newType=PLAYER2;
963

Stephan Kulow's avatar
Stephan Kulow committed
964
      switch(players[i].dir)
965
      {
966
         case Directions::Up:
967 968 969 970 971 972 973 974
            if(crashed(i,0,-1))
               players[i].alive=false;
            else
            {
               players[i].yCoordinate--;
               newType |= (TOP | RIGHT | LEFT);
            }
         break;
975
         case Directions::Down:
976 977 978 979 980 981 982 983
            if(crashed(i,0,1))
               players[i].alive=false;
            else
            {
               players[i].yCoordinate++;
               newType |= (BOTTOM | RIGHT | LEFT);
            }
         break;
984
         case Directions::Left:
985 986 987 988 989 990 991 992
            if(crashed(i,-1,0))
               players[i].alive=false;
            else
            {
               players[i].xCoordinate--;
               newType |= (LEFT | TOP | BOTTOM);
            }
         break;
993
         case Directions::Right:
994 995 996 997 998 999 1000 1001
            if(crashed(i,1,0))
               players[i].alive=false;
            else
            {
               players[i].xCoordinate++;
               newType |= (RIGHT | TOP | BOTTOM);
            }
         break;
1002 1003 1004
         default:
         break;

1005 1006 1007 1008
      }
      if(players[i].alive)
         playfield[players[i].xCoordinate][players[i].yCoordinate]=newType;
   }
Stephan Kulow's avatar
Stephan Kulow committed
1009

1010 1011
   /* player collision check */
   if(!players[1].alive)
Stephan Kulow's avatar
Stephan Kulow committed
1012 1013 1014
   {
      int xInc=0,yInc=0;
      switch(players[1].dir)
1015
      {
1016
         case Directions::Left:
1017
            xInc = -1; break;
1018
         case Directions::Right:
1019
            xInc = 1; break;
1020
         case Directions::Up: