示例#1
0
int main() {
	typedef std::deque<Invader> InvaderList;
	typedef std::deque<Shot> ShotList;

	cv::VideoCapture cap( DEFAULT_DEVICE );
	if(!cap.isOpened()) {
		std::cerr << "Error opening VideoCapture!" << std::endl;
		return -1;
	}
	
	cap.set(CV_CAP_PROP_FRAME_WIDTH, 1024);
	cap.set(CV_CAP_PROP_FRAME_HEIGHT, 768);
	
	cv::namedWindow("SpaceInvaders", CV_WINDOW_AUTOSIZE);
	
	cv::Mat cameraImage;
	cap >> cameraImage;
	
	const cv::Size CameraImageSize( cameraImage.size() );
	
	for (int key = -1; ' ' != key; key = cv::waitKey(WAIT_DELAY_MS)) {
		cap >> cameraImage;
		cv::flip(cameraImage, cameraImage, FLIPPING_AROUND_Y_AXIS);
		cv::putText(cameraImage, "Press space to play!", cv::Point(30,80), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar::all(255), 2, 8);
		cv::resize(cameraImage, cameraImage, CameraImageSize * 2);
		cv::imshow("SpaceInvaders", cameraImage);
	}
	
	const GameImage playerImage( PLAYER_PNG );
	const GameImage invaderImage( INVADER_PNG );
	
	const int YPlayerShot = CameraImageSize.height - playerImage.size().height;
	const int YGameOver = YPlayerShot - invaderImage.size().height;
	
	Player player(playerImage, CameraImageSize, SHOT_LINE_PIX);
	PlayerPosition playerPosition(player, HAARCASCADE_XML, CameraImageSize);
	Shot playerShot;
	bool gameOver = false;
	
	InvaderList invaders;
	std::generate_n(std::back_inserter(invaders), MAX_INVADERS, Invader::Factory(invaderImage, CameraImageSize, 5));
	
	ShotList shots;
	
	cv::RNG rng(uint64(std::time(0)));
	
	for (int key = -1; 'q' != key; key = cv::waitKey(WAIT_DELAY_MS)) {
		cap >> cameraImage;
		cv::flip(cameraImage, cameraImage, FLIPPING_AROUND_Y_AXIS);

		if (!gameOver) {
		
		playerPosition.update(cameraImage);
		playerShot.update();
		std::for_each(invaders.begin(), invaders.end(), GraphicUpdate);
		std::for_each(shots.begin(), shots.end(), GraphicUpdate);
		
		if (playerShot.isValid()) {
			const InvaderList::iterator iInvaderEnd = std::remove_if(invaders.begin(),invaders.end(), GraphicColision(playerShot.rect()));
			if (iInvaderEnd != invaders.end()) {
				invaders.erase(iInvaderEnd, invaders.end());
				playerShot = Shot();
			}
		}
		
		if (!shots.empty()) {
			const ShotList::iterator iShotsEnd = std::remove_if(shots.begin(), shots.end(), isInvalidShot);
			if (iShotsEnd != shots.end()) {
				shots.erase(iShotsEnd, shots.end());
			}
		}
		
		for (InvaderList::const_iterator iInvader = invaders.begin(); iInvader != invaders.end() && !gameOver; ++iInvader) {
			const cv::Rect irect( iInvader->rect() );
			if ((rng.uniform(0.0,1.0) < 0.05) && (shots.size() < MAX_INVADERS)) {
				cv::Point shotPos(irect.x + (irect.width / 2), irect.y + irect.height);
				shots.push_back( Shot(shotPos, SHOT_SPEED, cv::Scalar(100,50,100), CameraImageSize) );
			}
			if (irect.y >= YGameOver) {
				gameOver = true;
			}
		}
		
		if (!playerShot.isValid() && player.isShooting()) {
			cv::Point shotPoint( player.facePosition().x, YPlayerShot );
			playerShot = Shot(shotPoint, -SHOT_SPEED, cv::Scalar(100,170,10), CameraImageSize);
		}
		
		for (ShotList::iterator iShot(shots.begin()); iShot != shots.end() && !gameOver; ++iShot) {
			if (iShot->isValid() && checkColision(iShot->rect(),player.rect())) {
				gameOver = true;
			}
		}
		
		}
		
		std::for_each(invaders.begin(), invaders.end(), GraphicPaint(cameraImage));
		std::for_each(shots.begin(), shots.end(), GraphicPaint(cameraImage));
		player.paint(cameraImage);
		playerShot.paint(cameraImage);
		
		if (invaders.empty()) {
			cv::putText(cameraImage, "Winner!", cv::Point(30,80), cv::FONT_HERSHEY_SIMPLEX, 3, cv::Scalar::all(255), 2, 8);
		} else if (gameOver) {
			cv::putText(cameraImage, "Game Over!", cv::Point(30,80), cv::FONT_HERSHEY_SIMPLEX, 3, cv::Scalar::all(255), 2, 8);
		}
		
		cv::resize(cameraImage, cameraImage, CameraImageSize * 2);
		cv::imshow("SpaceInvaders", cameraImage);
	}
	
	return 0;
}
示例#2
0
文件: Game.cpp 项目: fraang/glPortal
void Game::update() {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  float dt = FRAMETIME_SECONDS;
  
  //Get delta mouse movement
  int mousedx, mousedy;
  SDL_GetRelativeMouseState(&mousedx, &mousedy);
  
  // Apply mouse movement to view
  player.rotation->x -= mousedy * sensitivity;
  player.rotation->y -= mousedx * sensitivity;
  
  // Restrict rotation in horizontal axis
  if(player.rotation->x < -1.5f) player.rotation->x = -1.5f;
  if(player.rotation->x >  1.5f) player.rotation->x =  1.5f;
  
  if(!player.isDead() && !player.hasWon()) {
    // Reset x and z speed
    player.velocity->x = 0;
    player.velocity->z = 0;
    
    // Apply gravity to yspeed
    player.velocity->y -= GRAVITY*dt;
    if(player.velocity->y < -MAXSPEED) player.velocity->y = -MAXSPEED;
    if(player.velocity->y > MAXSPEED) player.velocity->y = MAXSPEED;

    // Move forward
    if(keystates['w']) {
      player.velocity->z -= cos(player.rotation->y)*PLAYER_MOVESPEED*dt;
      player.velocity->x -= sin(player.rotation->y)*PLAYER_MOVESPEED*dt;
    }
    // Move backward
    if(keystates['s']) {
      player.velocity->z += cos(player.rotation->y)*PLAYER_MOVESPEED*dt;
      player.velocity->x += sin(player.rotation->y)*PLAYER_MOVESPEED*dt;
    }
    // Strafe left
    if(keystates['a']) {
      player.velocity->x -= cos(player.rotation->y)*PLAYER_MOVESPEED*dt;
      player.velocity->z += sin(player.rotation->y)*PLAYER_MOVESPEED*dt;
    }
    // Strafe right
    if(keystates['d']) {
      player.velocity->x += cos(player.rotation->y)*PLAYER_MOVESPEED*dt;
      player.velocity->z -= sin(player.rotation->y)*PLAYER_MOVESPEED*dt;
    }

    if(keystates[' '] && (player.isOnGround() || gameMap.jetpackIsEnabled())) {
      if(player.isOnGround()) {
        player.velocity->y = JUMPPOWER;
      }
    }

    if(keystates[225]) {
      if(gameMap.jetpackIsEnabled()) {
        player.velocity->y += JETPACK_ACC*dt;
      }
    }
    
    // Disable portals if R is held
    if(keystates['r']) {
      portals[0].disable();
      portals[1].disable();
    }
    
    float newx = player.position->x + player.velocity->x * dt;
    float newy = player.position->y + player.velocity->y * dt;
    float newz = player.position->z + player.velocity->z * dt;

    Box bbox;
    bbox.set(newx-0.5, player.position->y, player.position->z-0.5, newx+0.5, player.position->y+1.8, player.position->z+0.5);
    if(gameMap.collidesWithWall(bbox) == false || portals[0].inPortal(bbox) || portals[1].inPortal(bbox)) {
      player.position->x = newx;
    }
    // Check for collision in y-axis
    bbox.set(player.position->x-0.5, player.position->y, newz-0.5, player.position->x+0.5, player.position->y+1.8, newz+0.5);
    if(gameMap.collidesWithWall(bbox) == false || portals[0].inPortal(bbox) || portals[1].inPortal(bbox)) {
      player.position->z = newz;
    }
    // Check for collision in z-axis
    bbox.set(player.position->x-0.5, newy, player.position->z-0.5, player.position->x+0.5, newy+1.8, player.position->z+0.5);
    player.setOffGround();
    if(gameMap.collidesWithWall(bbox) == false || portals[0].inPortal(bbox) || portals[1].inPortal(bbox)) {
      player.position->y = newy;
    } else {
      // If player was falling it means must have hit the ground
      if(player.velocity->y < 0) {
	      player.setOnGround();
      }
      player.velocity->y = 0;
    }

    // Check if player has fallen into an acid pool
    bbox.set(player.position->x-0.5, player.position->y, player.position->z-0.5, player.position->x+0.5, player.position->y+1.8, player.position->z+0.5);
    if(gameMap.collidesWithAcid(bbox) == true) {
      player.kill();
    }

    // Check if player has fallen into void
    if(player.position->y <= -30) {
      player.kill();
    }

    // Check if player has taken the cake
    if(gameMap.collidesWithCake(bbox) == true) {
      player.setHasWon();
    }

    // Check if player has entered a portal
    if(portalsActive()) {
      for(int i = 0; i < 2; i++) {
	      if(portals[i].throughPortal(player.position->x, player.position->y+0.9f,player.position->z)) {
	        // Calculate rotation between portals
	        float rotation = 0.f;
	        rotation += portals[i].getToRotation()*DEGRAD;
	        rotation += portals[(i+1)%2].getFromRotation()*DEGRAD;
	        player.rotation->y += rotation;
	        // Distance from portal to player
	        float xdist = player.position->x - portals[i].position.x;
	        float zdist = player.position->z - portals[i].position.z;
	        // Calculate this distance when rotated
	        float nxdist = xdist*cos(rotation) + zdist*sin(rotation);
	        float nzdist = zdist*cos(rotation) - xdist*sin(rotation);
	        // Move player to destination portal
	        player.position->x = portals[(i+1)%2].position.x + nxdist;
	        player.position->y = player.position->y + portals[(i+1)%2].position.y - portals[i].position.y;
	        player.position->z = portals[(i+1)%2].position.z + nzdist;
	      }
      }
    }
  }
  // If player is dying
  else if(player.isDead()) {
    player.position->y -= (0.60f*dt);
  }

  // Update shots and check their collision with walls
  for(int i = 0; i < 2; i++) {
    Shot *shot = &shots[i];
    if(shot->active) {
      shot->update(dt);

      Box sbox;
      if(gameMap.pointInWall(shot->position.x, shot->position.y, shot->position.z, &sbox)) {
	      shot->update(-dt); // Reverse time to before collision
	      // Collision really should be interpolated instead
	      if(sbox.type == TID_WALL) {
	        portals[i].placeOnBox(sbox, shot->position.x, shot->position.y, shot->position.z, gameMap);
	      }
	      shot->active = false;
      }
    }
  }
}