void Player::addRandomPlane(std::string strSrc, bool isVisible) { int i = 0; bool isAdded = false; while(i<10 && !isAdded) { Plane* plane = genRandomPlane(); if(!isPlaneConflicts(plane)) { //添加飞机 addPlane(plane->direction, plane->pos, strSrc, isVisible); isAdded = true; CCLog("addRandomPlane_isAdded x=%f,y=%f", plane->pos.x, plane->pos.y); } i++; } //遍历的方式来保证可以顺利添加 if(!isAdded) { //TODO 写死的数字修改 Direction direction = getRandomDirection(); float posX=0.0f, posY=0.0f; if(direction == NORTH || direction == SOUTH) { posX = 6; posY = 7; } else { posX = 7; posY = 6; } for(int i=0; i<posX; i++) { for(int j=0; j<posY; j++) { if(!isPlaneConflicts(new Plane(ccp(i,j), direction))) { addPlane(direction, ccp(i,j), strSrc, isVisible); //bugfix 在右侧添加了盟军飞机 CCLog("addRandomPlane_isAdded_false x=%f,y=%f", i, j); return; } } } } }
Plane * Player::genRandomPlane() { //随机生成一个方向 Direction direction = getRandomDirection(); //随机生成一个位置 // TODO 写死的数字移走 CCPoint pos; if(direction == NORTH || direction == SOUTH) { pos.x = arc4random() % (int)Constants::NORTH_SOURTH_LIMIT_POSITION_X; pos.y = arc4random() % (int)Constants::NORTH_SOURTH_LIMIT_POSITION_Y; } else { pos.x = arc4random() % (int)Constants::WEST_EAST_LIMIT_POSITION_X; pos.y = arc4random() % (int)Constants::WEST_EAST_LIMIT_POSITION_Y; } return new Plane(pos, direction); }
int moveInhabitants() { for(int iinhabitant = 0; iinhabitant < g_inhabitantCount; iinhabitant++) { inhabitant* cSnake = &g_inhabitants[iinhabitant]; //if the snakes direction is null too, use a random one if(cSnake->direction == 0 && iinhabitant != 0 && (iinhabitant != 1 || !g_confTwoPlayer)) { cSnake->direction = getRandomDirection(); } int nextCollision; int actCollision; point nextPosition = getNextField(cSnake->direction, cSnake->body[cSnake->length-1]); actCollision = collisionDetection(cSnake->body[cSnake->length-1]); nextCollision = collisionDetection(nextPosition); if ((nextCollision == EMPTY || nextCollision == FRUIT)) { // && cSnake->length < MAX_INHABITANT_LENGTH){ cSnake->body[cSnake->length] = nextPosition; } else { // snake dead ! cSnake->alive = false; } if (actCollision != FRUIT) { int count; for(count = 0; count < cSnake->length; count++) { cSnake->body[count] = cSnake->body[count + 1]; } if(cSnake->alive && rand() % POINTS_LEN_ROUNDS == 0) { //for every 10 length -> get one point per round cSnake->points = cSnake->points + (cSnake->length/POINTS_LEN); } } else { reInitFruit(cSnake->body[cSnake->length-1]); if(cSnake->length < MAX_INHABITANT_LENGTH) { cSnake->length++; } //get points for eating fruit! cSnake->points = cSnake->points + POINTS_FRUIT; } if(cSnake->points > g_confWin) { return 0; } } return 1; }
void initWalls(int wallCount) { int count; int innerCount; int wallLength; for(count = 0 ; count < wallCount; count++) { wallLength = getRandomWallLength(); g_walls[count].parts[0] = getRandomCoordinateInField(); g_walls[count].colorpair = COLOR_PAIR_WALL; g_walls[count].length = wallLength; int direction = getRandomDirection(); for (innerCount = 1; innerCount < wallLength; innerCount++) { g_walls[count].parts[innerCount] = getNextField(direction, g_walls[count].parts[innerCount - 1]); } g_wallCount++; } }
/** @def This function move a particle over the mesh */ void MoveParticle(Particle<CMeshO> &info,CMeshO::VertexPointer p,float l,int t,Point3f dir,Point3f g,float a){ if(CheckFallPosition(info.face,g,a)){ p->SetS(); return; } float time=t; if(dir.Norm()==0) dir=getRandomDirection(); Point3f new_pos; Point3f current_pos; Point3f int_pos; CMeshO::FacePointer current_face=info.face; CMeshO::FacePointer new_face; new_face=current_face; current_pos=p->P(); new_pos=StepForward(current_pos,info.v,info.mass,current_face,g+dir,l,time); while(!IsOnFace(new_pos,current_face)){ int edge=ComputeIntersection(current_pos,new_pos,current_face,new_face,int_pos); if(edge!=-1){ Point3f n = new_face->N(); if(CheckFallPosition(new_face,g,a)) p->SetS(); float elapsed_time=GetElapsedTime(current_pos,int_pos,new_pos,time); info.v=GetNewVelocity(info.v,current_face,new_face,g+dir,g,info.mass,elapsed_time); time=time-elapsed_time; current_pos=int_pos; current_face->Q()+=elapsed_time*5; current_face=new_face; new_pos=int_pos; if(time>0){ if(p->IsS()) break; new_pos=StepForward(current_pos,info.v,info.mass,current_face,g+dir,l,time); } current_face->C()=Color4b::Green;//Just Debug!!!! }else{ //We are on a border new_pos=int_pos; current_face=new_face; p->SetS(); break; } } p->P()=new_pos; info.face=current_face; }
void ParticleSystem::spawnParticle() { Particle particle; particle.age = 0; particle.color = color[0]; particle.grow = getRandomValue(grow, growVariance); particle.duration = getRandomValue(particleDuration, particleDurationVariance); particle.speed = getRandomDirection(direction, directionVariance) * getRandomValue(speed, speedVariance); particle.shrink = getRandomValue(shrink, shrinkVariance); particle.size = getRandomValue(size[0], sizeVariance[0]); particle.templateSize[0] = particle.size; particle.templateSize[1] = getRandomValue(size[1], sizeVariance[1]); particle.templateSize[2] = getRandomValue(size[2], sizeVariance[2]); // Shape particle.position = position; particle.vertexOffset = vertexSource->add(); particles.push_back(particle); }
void Pacman::onTick() { // Cambiar dirección deseada de Pacman if(m_input->getKeyPress()->Up.value) { m_player.DesiredDirection = ViewDirection::Up; } else if(m_input->getKeyPress()->Right.value) { m_player.DesiredDirection = ViewDirection::Right; } else if(m_input->getKeyPress()->Left.value) { m_player.DesiredDirection = ViewDirection::Left; } else if(m_input->getKeyPress()->Down.value) { m_player.DesiredDirection = ViewDirection::Down; } if(m_readyTimer.getTicks() > 0) { if(m_readyTimer.getTicks() >= 2000) { m_readyTimer.stop(); m_gameTimer.start(); m_frameTimer.start(); } return; } if(m_pauseTimer.getTicks() > 0) { if(m_pauseTimer.getTicks() >= 500) { m_pauseTimer.stop(); m_gameTimer.resume(); m_frameTimer.resume(); if(m_ghostKillTimer.isPaused()) { m_ghostKillTimer.resume(); } if(m_player.IsDead) { resetGame(); } } return; } // Animar Pacman y Fantasmas (Cambio de Frames) if(m_frameTimer.getTicks() > 50) { if(m_player.Moving) { m_player.CurrentFrame++; if(m_player.CurrentFrame > 3) { m_player.CurrentFrame = 0; } } else { m_player.CurrentFrame = 1; } for(unsigned int x = 0; x < m_ghostCount; ++x) { m_ghost[x].CurrentFrame++; if(m_ghost[x].CurrentFrame > 1) { m_ghost[x].CurrentFrame = 0; } } m_frameTimer.start(); } // Mover Pacman moveEntity(&m_player.CurrentCellIndex, &m_player.PositionOffset, &m_player.Direction, &m_player.DesiredDirection, &m_player.Moving, m_player.MoveSpeed, true); bool ghostForceRefresh = false; sf::Vector2i findCoin = sf::Vector2i(m_player.CurrentCellIndex % m_mapSize.x, floor(m_player.CurrentCellIndex / m_mapSize.x)); // Comer bolas (Pacman) y actualizar mapa for(unsigned int x = 0; x < m_ballPosition.size(); ++x) { if(m_ballPosition[x] == findCoin) { mapSetCell(m_player.CurrentCellIndex, CellType::Nothing); m_ballPosition.erase(m_ballPosition.begin() + x); addScore(10); m_sound.setBuffer(m_ballSound); m_sound.play(); if(m_ballPosition.empty() && m_ballBigPosition.empty()) { resetGame(); return; } } } for(unsigned int x = 0; x < m_ballBigPosition.size(); ++x) { if(m_ballBigPosition[x] == findCoin) { mapSetCell(m_player.CurrentCellIndex, CellType::Nothing); m_ballBigPosition.erase(m_ballBigPosition.begin() + x); m_powerupKillCounter = 0; m_ghostKillTimer.start(); ghostForceRefresh = true; m_sound.setBuffer(m_powerupSound); m_sound.play(); for(unsigned int x = 0; x < m_ghostCount; ++x) { m_ghost[x].Invulnerable = false; } addScore(50); if(m_ballPosition.empty() && m_ballBigPosition.empty()) { resetGame(); return; } } } if(m_ghostKillTimer.getTicks() > 7000) { m_ghostKillTimer.stop(); for(unsigned int x = 0; x < m_ghostCount; ++x) { m_ghost[x].Invulnerable = false; m_ghost[x].LastStateChange = m_gameTimer.getTicks(); m_ghost[x].StateDuration = 3000; m_ghost[x].IsInChase = true; } ghostForceRefresh = true; } // IA Fantasmas for(unsigned int x = 0; x < m_ghostCount; ++x) { if(m_ghost[x].TimeToRelease >= m_gameTimer.getTicks()) { break; } unsigned int ignoreCell; if(m_ghost[x].Direction == ViewDirection::Left) { ignoreCell = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Right); } else if(m_ghost[x].Direction == ViewDirection::Right) { ignoreCell = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Left); } else if(m_ghost[x].Direction == ViewDirection::Up) { ignoreCell = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Down); } else { ignoreCell = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Up); } float ghostMoveSpeed = m_ghostKillTimer.isStarted() && (m_ghost[x].IsDead ? false : !m_ghost[x].Invulnerable) ? (m_ghost[x].MoveSpeed / 2) : (m_ghost[x].IsDead ? m_ghost[x].MoveSpeed * 1.5: m_ghost[x].MoveSpeed); if(m_ghost[x].CurrentCellIndex == m_ghost[x].HomeIndex) { m_ghost[x].IsDead = false; if(m_ghostKillTimer.isStarted()) { m_ghost[x].Invulnerable = true; } m_ghost[x].LastStateChange = m_gameTimer.getTicks(); m_ghost[x].StateDuration = 1000; m_ghost[x].IsInChase = true; } if(m_gameTimer.getTicks() >= (m_ghost[x].LastStateChange + m_ghost[x].StateDuration)) { if(!m_ghostKillTimer.isStarted()) { ghostForceRefresh = true; } m_ghost[x].LastStateChange = m_gameTimer.getTicks(); if(m_ghost[x].IsInChase) { m_ghost[x].IsInChase = false; m_ghost[x].StateDuration = (3000 + (rand() % 3000)); } else { m_ghost[x].IsInChase = true; m_ghost[x].StateDuration = (5000 + (rand() % 3000)); } } if(m_ghost[x].LastCellChecked != m_ghost[x].CurrentCellIndex || ghostForceRefresh) { if(m_ghost[x].IsDead) { m_ghost[x].DesiredDirection = getNextDirection(m_ghost[x].CurrentCellIndex, m_ghost[x].HomeIndex, ignoreCell); } else if(m_ghost[x].IsInChase && (!m_ghostKillTimer.isStarted() || m_ghost[x].Invulnerable)) { if(m_ghost[x].CurrentCellIndex != m_player.CurrentCellIndex) { m_ghost[x].DesiredDirection = getNextDirection(m_ghost[x].CurrentCellIndex, m_player.CurrentCellIndex, ignoreCell); } } else { unsigned int tempIndex; std::vector<unsigned int> possibleCells; if(m_ghost[x].Direction != ViewDirection::Left) { tempIndex = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Left); if(tempIndex != ignoreCell && m_mapInfo[tempIndex] != CellType::Wall) { possibleCells.push_back(tempIndex); } } if(m_ghost[x].Direction != ViewDirection::Right) { tempIndex = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Right); if(tempIndex != ignoreCell && m_mapInfo[tempIndex] != CellType::Wall) { possibleCells.push_back(tempIndex); } } if(m_ghost[x].Direction != ViewDirection::Up) { tempIndex = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Up); if(tempIndex != ignoreCell && m_mapInfo[tempIndex] != CellType::Wall) { possibleCells.push_back(tempIndex); } } if(m_ghost[x].Direction != ViewDirection::Down) { tempIndex = getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Down); if(tempIndex != ignoreCell && m_mapInfo[tempIndex] != CellType::Wall) { possibleCells.push_back(tempIndex); } } // Si hay caminos alternativos a seguir (Que no sea ni a donde se dirige ni la casilla anterior) o es un callejón sin salida... if(possibleCells.size() > 0 || getMapInfo(m_ghost[x].CurrentCellIndex, m_ghost[x].Direction) == CellType::Wall) { m_ghost[x].DesiredDirection = getRandomDirection(m_ghost[x].CurrentCellIndex, ignoreCell); } } m_ghost[x].LastCellChecked = m_ghost[x].CurrentCellIndex; } moveEntity(&m_ghost[x].CurrentCellIndex, &m_ghost[x].PositionOffset, &m_ghost[x].Direction, &m_ghost[x].DesiredDirection, &m_ghost[x].Moving, ghostMoveSpeed, false); if(!m_ghost[x].IsDead) { // Calcular colisión con Pacman if(m_ghost[x].CurrentCellIndex == m_player.CurrentCellIndex) { ghostCollide(x); } else if(getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Left) == m_player.CurrentCellIndex) { if((m_player.PositionOffset.x + (m_tileSize.x / 2)) - (m_ghost[x].PositionOffset.x + (m_tileSize.x / 2)) >= 0) { ghostCollide(x); } } else if(getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Right) == m_player.CurrentCellIndex) { if((m_ghost[x].PositionOffset.x + (m_tileSize.x / 2)) - (m_player.PositionOffset.x + (m_tileSize.x / 2)) >= 0) { ghostCollide(x); } } else if(getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Up) == m_player.CurrentCellIndex) { if((m_player.PositionOffset.y + (m_tileSize.y / 2)) - (m_ghost[x].PositionOffset.y + (m_tileSize.y / 2)) >= 0) { ghostCollide(x); } } else if(getMapIndex(m_ghost[x].CurrentCellIndex, ViewDirection::Down) == m_player.CurrentCellIndex) { if((m_ghost[x].PositionOffset.y + (m_tileSize.y / 2)) - (m_player.PositionOffset.y + (m_tileSize.y / 2)) >= 0) { ghostCollide(x); } } } } }
Pacman::ViewDirection Pacman::getNextDirection(unsigned int startIndex, unsigned int searchIndex, unsigned int ignoreCell) { std::list<Node> OpenNodeList; std::list<Node> ClosedNodeList; // Guardamos en la lista de Nodos Abiertos el Nodo correspondiente a startIndex OpenNodeList.push_back(Node()); OpenNodeList.back().Index = startIndex; OpenNodeList.back().Range = abs((startIndex % m_mapSize.x) - (searchIndex % m_mapSize.x)) + abs(floor(startIndex / m_mapSize.y) - floor(searchIndex / m_mapSize.y)); if(ignoreCell == m_mapNullCell) { // Guardamos en la lista de Nodos Cerrados el Nodo correspondiente a la casilla a ignorar ClosedNodeList.push_back(Node()); ClosedNodeList.back().Index = ignoreCell; } Node* preferentNode = &OpenNodeList.back(); // Hasta que no encuentre el destino o la lista de nodos abiertos se vacíe (no haya caminos posibles)... while (preferentNode->Index != searchIndex && !OpenNodeList.empty()) { // Si el nodo preferente está en la lista de nodos cerrados... for (auto closedNode : ClosedNodeList) { if (closedNode.Index == preferentNode->Index) { preferentNode = &OpenNodeList.back(); // Elegimos el primer nodo más preferente de la lista de nodos abiertos for (auto openNodeIt = OpenNodeList.begin(); openNodeIt != OpenNodeList.end(); ++openNodeIt) //for (auto openNode : OpenNodeList) { if ((preferentNode->Range + preferentNode->Cost) > (openNodeIt->Range + openNodeIt->Cost)) { preferentNode = &*openNodeIt; } } break; } } // Guardamos el nodo preferente en la lista de Nodos cerrados y lo eliminamos de la lista de nodos abiertos for (auto openNodeIt = OpenNodeList.begin(); openNodeIt != OpenNodeList.end(); ++openNodeIt) { if (openNodeIt->Index == preferentNode->Index) { ClosedNodeList.push_back(*preferentNode); // Actualizamos los punteros for (Node openNode : OpenNodeList) { if(openNode.ParentNode == preferentNode) { openNode.ParentNode = &ClosedNodeList.back(); } } preferentNode = &ClosedNodeList.back(); OpenNodeList.erase(openNodeIt); break; } } std::vector<unsigned int> nextIndex; // Añadimos a nextIndex CADA UNA de las 4 direcciones si es posible su tránsito if (!checkCollision(preferentNode->Index, ViewDirection::Left, false)) { nextIndex.push_back(getMapIndex(preferentNode->Index, ViewDirection::Left)); } if (!checkCollision(preferentNode->Index, ViewDirection::Right, false)) { nextIndex.push_back(getMapIndex(preferentNode->Index, ViewDirection::Right)); } if (!checkCollision(preferentNode->Index, ViewDirection::Up, false)) { nextIndex.push_back(getMapIndex(preferentNode->Index, ViewDirection::Up)); } if (!checkCollision(preferentNode->Index, ViewDirection::Down, false)) { nextIndex.push_back(getMapIndex(preferentNode->Index, ViewDirection::Down)); } if (!nextIndex.empty()) { Node* previousNode = preferentNode; for (unsigned int Index : nextIndex) { bool isValid = true; // Miramos si existe en la lista de nodos abiertos for (Node openNode : OpenNodeList) { if (openNode.Index == Index) { isValid = false; break; } } if (!isValid) { continue; } // Miramos si existe en la lista de nodos cerrados for (Node closedNode : ClosedNodeList) { if (closedNode.Index == Index) { isValid = false; break; } } if (!isValid) { continue; } // Si NO existe en ninguna de las listas anteriores, añadimos el nodo a la lista de nodos abiertos OpenNodeList.push_back(Node()); OpenNodeList.back().Index = Index; OpenNodeList.back().ParentNode = previousNode; OpenNodeList.back().Cost = (previousNode->Cost + 1); OpenNodeList.back().Range = abs((int)(Index % m_mapSize.x) - (int)(searchIndex % m_mapSize.x)) + abs(floor(Index / m_mapSize.y) - floor(searchIndex / m_mapSize.y)); // ... y actualizamos preferentNode si así fuera el caso if ((preferentNode->Range + preferentNode->Cost) > (OpenNodeList.back().Range + OpenNodeList.back().Cost)) { preferentNode = &OpenNodeList.back(); } } } } // Si el ultimo nodo preferente encontró el destino... if (preferentNode->Index == searchIndex) { // Localizamos el nodo con la siguiente casilla a desplazarse desde el nodo destino while (preferentNode->ParentNode->Index != startIndex) { preferentNode = preferentNode->ParentNode; } // Nos movemos en una dirección segun el nodo posterior al nodo origen if (preferentNode->Index == (startIndex - 1)) { return ViewDirection::Left; } else if (preferentNode->Index == (startIndex + 1)) { return ViewDirection::Right; } else if (preferentNode->Index == (startIndex + m_mapSize.x)) { return ViewDirection::Down; } else { return ViewDirection::Up; } } else { return getRandomDirection(startIndex, ignoreCell); } }
bool Kleptobot::setProperDirection() { int arr[] = {0,0,0,0}; while(arr[0] == 0 || arr[1] == 0 || arr[2] == 0 || arr[3] == 0) //checks if kleptobot can move in any direction and change its direction if it can { Direction dir = getRandomDirection(); //get a random direction and adjacent position coordinates int x = getWorld()->getXcoordOfNext(getX(), dir); int y = getWorld()->getYcoordOfNext(getY(), dir); switch (dir) { case up: if(arr[0] == 0) //set array value to 1 if robot cannot move in that direction { if(getWorld()->canMove(this, x, y, dir)) { setDirection(dir); return true;} else arr[0] = 1; } break; case down: if(arr[1] == 0) { if(getWorld()->canMove(this, x, y, dir)) { setDirection(dir); return true;} else arr[1] = 1; } break; case left: if(arr[2] == 0) { if(getWorld()->canMove(this, x, y, dir)) { setDirection(dir); return true;} else arr[2] = 1; } break; case right: if(arr[3] == 0) { if(getWorld()->canMove(this, x, y, dir)) { setDirection(dir); return true;} else arr[3] = 1; } break; default: break; } } return false; }