void FighterFightTask::updateState() {
    if (m_state != State::IDLE && m_targets.empty()) {
        setState(State::IDLE);
    }

    switch (m_state) {
        case State::IDLE:
            if (m_targets.empty()) {
                return;
            } else {
                setState(State::APPROACH);
            }
            break;
        case State::APPROACH:
            if (targetDistance() < componentsInfo().maxBulletRange()) {
                setState(State::ENGAGE);
            }
            break;
        case State::ENGAGE:
            if (targetDistance() < m_minEnemyDistance) {
                setState(State::EVADE);
                m_positionBehindTarget = findRandomEvasionPoint();
            }
            break;
        case State::EVADE:
            if (pointDistance(m_positionBehindTarget) < 20 && targetDistance() < m_minEnemyDistance) {
                m_positionBehindTarget = findRandomEvasionPoint();
            }
            if (pointDistance(m_positionBehindTarget) > 20)
                break;
            if (targetDistance() < m_minEnemyDistance) {
                break;
            }
            if (targetDistance() < componentsInfo().maxBulletRange()) {
                setState(State::ENGAGE);
            } else {
                setState(State::APPROACH);
            }
            break;
        default:
            assert(false);
            return;
    }

    if (m_stateChanged) {
        m_stateChanged = false;
        updateState();
    }
}
void FighterFightTask::update(float deltaSec) {
    updateTargets();
    updateState();

    WorldObject* worldObject = boardComputer()->worldObject();

    switch (m_state) {
        case State::IDLE:
            return;
        case State::APPROACH:
            if (angleToTarget() > 45.0f) {
                boardComputer()->rotateTo(m_primaryTarget->transform().position());
            } else {
                boardComputer()->rotateTo(m_primaryTarget->transform().position());
                boardComputer()->moveTo(m_primaryTarget->transform().position());
            }

            if (targetDistance() < componentsInfo().maxBulletRange()) {
                boardComputer()->shootBullet(m_targets);
            }
            break;
        case State::ENGAGE:
            if (angleToTarget() > 45.0f) {
                boardComputer()->moveTo(worldObject->transform().position() + glm::vec3(0, 0, -1) * worldObject->transform().orientation());
                boardComputer()->rotateTo(m_primaryTarget->transform().position());
            } else {
                boardComputer()->rotateTo(m_primaryTarget->transform().position());
                boardComputer()->moveTo(m_primaryTarget->transform().position());
                if (angleToTarget() < 15.0f && targetDistance() < componentsInfo().maxRocketRange()) {
                    boardComputer()->shootRockets(m_primaryTarget);
                }
            }

            if (targetDistance() < componentsInfo().maxBulletRange()) {
                boardComputer()->shootBullet(m_targets);
            }
            break;
        case State::EVADE:
            boardComputer()->rotateTo(m_positionBehindTarget);
            boardComputer()->moveTo(m_positionBehindTarget);
            break;
    }

}
Exemple #3
0
void moveGhost(Location *ghost,int xtl,int ytl,int boardHeight,int boardWidth,int target[]){
/* Moves all active ghosts */
  int i=ghost->y, j=ghost->x;
  int move[4],movement=0; //array of viable moves (each index applies to different move)
  double distance[4]={1000,1000,1000,1000}; //either set to distance or 1000 (arbitrary high value)
  if(board[i+1][j]!=1 && board[i+1][j]!=8 && (i+1)<rows && (i+1)!=ghost->prevY){  //down
    move[down]=1;
    distance[down]=targetDistance(target[1],target[0],j,i+1);
  } else{ move[down]=0; distance[down]=1000;}
  
  if(board[i-1][j]!=1 && board[i-1][j]!=8 && (i-1)>=0 && (i-1)!=ghost->prevY){  //up
    move[up]=1;
    distance[up]=targetDistance(target[1],target[0],j,i-1);
  } else{ move[up]=0; distance[up]=1000;}

  if(board[i][j+1]!=1 && board[i][j+1]!=8 && (j+1)<columns && (j+1)!=ghost->prevX){  //right
    move[right]=1;
    distance[right]=targetDistance(target[1],target[0],j+1,i);
  } else{ move[right]=0; distance[right]=1000;}
  
  if(board[i][j-1]!=1 && board[i][j-1]!=8 && (j-1)>=0 && (j-1)!=ghost->prevX){  //left
    move[left]=1;
    distance[left]=targetDistance(target[1],target[0],j-1,i);
  } else{ move[left]=0; distance[left]=1000;}

/* Now that we know which moves are viable and the distances from each, 
 * determine which is the closest to target */
  movement=minLocation(distance);
  if (i==7 && j==0 && ghost->prevX==1){//this is for the spot on the left to flip sides of the board
        ghost->prevX=columns;
        ghost->x=columns-1;
        ghost->orientation=left;
  } else if (i==7 && j==columns-1 && ghost->prevX==columns-2){//this is for the spot on the rght to flip sides of the board
        ghost->prevX=-1;
	ghost->x=0;
        ghost->orientation=left;
  } else {
    switch(movement){
      case up:
	ghost->prevY=ghost->y;
	ghost->prevX=ghost->x;
        ghost->y--;                                  //move up
        ghost->orientation=up;                       //set orientation upward
    	break;
      case down:
	ghost->prevY=ghost->y;
	ghost->prevX=ghost->x;
        ghost->y++;                                  //move down
        ghost->orientation=down;                     //set orientation downward
    	break;
      case left:
	ghost->prevX=ghost->x;
	ghost->prevY=ghost->y;
        ghost->x--;                                  //move left
        ghost->orientation=left;                     //set orientation left
	break;
      case right:
	ghost->prevX=ghost->x;
	ghost->prevY=ghost->y;
        ghost->x++;                                  //move right
        ghost->orientation=right;                    //set orientation right
	break;
    }
  }
}
Exemple #4
0
void targetGhosts(Location ghosts[],Location *pacman,int xtl,int ytl,int boardHeight,int boardWidth,int active,int state[]){
  int i,j,k=blinky,move,a;
  static int loop=0;
  double dist[4];
/* This loop will update the locations of each individual ghost */
/* Assumptions: ghosts cannot turn around
 * Each ghost tries to get to its specified target that turn */
  int target[2];//target[0]=ytarget target[1]=xtarget
  for(k=blinky;k<=active;k++){
    if(state[k]==frighten && loop%2){//if a ghost is frightened, they slow down to one space every two loops
	target[0]=ghosts[k].y; 
	target[1]=ghosts[k].x;
	continue;
    }
    switch(state[k]){
      case chase: //this is the chase state, all ghosts go for pacman 
	switch(k){
/* Blinky's movement targets pacman directly. His target is pacman's current position */
	    case blinky:
		target[0]=pacman->y;
		target[1]=pacman->x;
		break;
/* Pinky's target is 3 spaces in front of pacman's current position, toward his orientation */
	    case pinky:
		switch(pacman->orientation){
			case left:
				target[0]=pacman->y;
				target[1]=pacman->x - 3;
				break;
			case right:
				target[0]=pacman->y;
                                target[1]=pacman->x + 3;
                                break;
			case up:
				target[0]=pacman->y - 3;
                                target[1]=pacman->x;
                                break;
			case down:
				target[0]=pacman->y + 3;
                                target[1]=pacman->x;
                                break;
		} break;
/* Inky's movement uses blinky's location and pacman's location. His target is blinky's target +2 in direction of pacman's orientation times two */
	    case inky:
		switch(pacman->orientation){
                        case left:
                                target[0]=2*(pacman->y - ghosts[blinky].y)+ghosts[blinky].y;
                                target[1]=2*(pacman->x - 2 - ghosts[blinky].x)+ghosts[blinky].x;
                                break;
                        case right:
                                target[0]=2*(pacman->y - ghosts[blinky].y)+ghosts[blinky].y;
                                target[1]=2*(pacman->x + 2 - ghosts[blinky].x)+ghosts[blinky].x;
                                break;
                        case up:
                                target[0]=2*(pacman->y - 2 - ghosts[blinky].y)+ghosts[blinky].y;
                                target[1]=2*(pacman->x - ghosts[blinky].x)+ghosts[blinky].x;
                                break;
                        case down:
                                target[0]=2*(pacman->y + 2 - ghosts[blinky].y)+ghosts[blinky].y;
                                target[1]=2*(pacman->x - ghosts[blinky].x)+ghosts[blinky].x;
                                break;
                } break;
/* If distance greater than 5, target pacman, otherwise, target random target on board */
	    case clyde:
		if(targetDistance(ghosts[clyde].x,ghosts[clyde].y,pacman->x,pacman->y)>=5){
			target[0]=pacman->y;
                	target[1]=pacman->x;
		} else {
			target[0]=rows-1;
			target[1]=0;
		} break;
      	}
	break;
      case scatter:	//This is when the ghosts go to their respective target corners
	switch(k){	//each has its own designated corner
	    case blinky://top right
		target[0]=0;
		target[1]=columns-1;
		break;
	    case pinky://top left
		target[0]=0;
		target[1]=0;
		break;
	    case inky://bottom right
		target[0]=rows-1;
		target[1]=columns-1;
		break;
	    case clyde://bottom left
		target[0]=rows-1;
		target[1]=0;
		break;
	}
	break;
      case frighten:	//This is randomized chaotic movement, usually slower
	target[0]=rand()%rows;
	target[1]=rand()%columns;
	break;
      case dead:
	target[0]=6;
	target[1]=7;
	break;
    }
/* This next block makes sure the target is on the board */
    if(target[0]>=rows)		target[0]=rows-1;
    else if(target[0]<0)	target[0]=0;
    if(target[1]>=columns)	target[1]=columns-1;
    else if(target[1]<0)	target[1]=0;
/* This block of code decides where to move the ghost in this loop */
    if(state[k]==dead && ghosts[k].x==target[1] && ghosts[k].y==target[0]){
	//This means they are at their designated target
	/* Put them into the ghost house */
	ghosts[k].y++; //at top of house, move into house and change state
	state[k]=housed;
    } else if(state[k]==housed){
	ghosts[k].y--;
	state[k]=chase;	
    } else {
    	moveGhost(&ghosts[k],xtl,ytl,boardHeight,boardWidth,target);
        
    }
  }
  loop++;
}