예제 #1
0
VOID D1PlayerFighter::update(AEHashedTable<AEPlatform>* platformTable) {
    
    if (!(isKeyPressed(D1Key::KEY_LEFT) && isKeyPressed(D1Key::KEY_RIGHT))) {
        FLOAT xSpeed = 0.0f;
        if (isKeyPressed(D1Key::KEY_LEFT)) {
            xSpeed = -1.0f;
        }
        else if (isKeyPressed(D1Key::KEY_RIGHT)) {
            xSpeed = 1.0f;
        }
        else {
            xSpeed = 0.0f;
        }
        setVx(xSpeed);
    }
    FLOAT ySpeed = (isKeyPressed(D1Key::KEY_UP) ? -1.0f : 0.0f) + (isKeyPressed(D1Key::KEY_DOWN) ? 1.0f : 0.0f);
    setVy(ySpeed);
    
    attackTimer--;
    if (attackTimer == 25 || attackTimer == 15 || attackTimer == 5) {
        shoot(8.0f);
        shoot(-8.0f);
    }

    if (hpValue <= 0 && action < D1PlayerFighter::ACTION_KILLED) {
        changeAction(D1PlayerFighter::ACTION_KILLED);
        AESpriteAttachment* attachedShadow = attachmentTable->getItem(0);
        if (attachedShadow) attachedShadow->getSprite()->remove();
    }
    
    D1Sprite::update(platformTable);

}
예제 #2
0
파일: alien.cpp 프로젝트: cather/High-Flyer
/** Function that takes in the size of the available area to move, and changes the alien's position by its velocity. Then sets velocity to a random number for the next time move is called. lifetime_ is decremented each time the alien moves this way. When lifetime_ = 0, the velocity stays constant and no longer sets randomly. When the alien's position is off-screen, its offScreen flag is set to true. 
    @param windowMaxX the width of the space the Alien can move in and be considered on screen
    @param windowMaxY the height of the space the Alien can move in and be considered on screen
    */
void Alien::move(int windowMaxX, int windowMaxY){
   // updates x, y positions based on velocities
    x_ += velocityX_;
    y_ += velocityY_;
    setPos(x_,y_);

    // check whether offScreen
    if ( (x_+width_)< 0  ||  (y_+height_)< 0 || (x_ > windowMaxX ) || ( y_ > windowMaxY ) )
      offScreen = true;
        
    // checks whether appropriate to change velocity
    if (lifeTime_ != 0 && !dead && !offScreen )
    {
      int mag = rand()%3;
      switch(mag)
      {
        case 0: // move NE
          setVx(rand()%randFactor_);
          setVy(rand()%randFactor_);
          break;
        case 1: // move NW
          setVx(- rand()%randFactor_);
          setVy(rand()%randFactor_);
          break;
        case 2: // move SW
          setVx(- rand()%randFactor_);
          setVy(- rand()%randFactor_);
          break;
        case 3: // move SE
          setVx(rand()%randFactor_);
          setVy(- rand()%randFactor_);
          break;
      }
      lifeTime_--; // decrement amount of times allowed to move randomly
    }
  
}
void OpticalFlowTransitionModel::predict(vector<Sample>& samples, const Mat& image, const optional<Sample>& target) {
	points.clear();
	forwardPoints.clear();
	backwardPoints.clear();
	forwardStatus.clear();
	error.clear();
	squaredDistances.clear();
	correctFlowCount = 0;

	// build pyramid of the current image
	cv::buildOpticalFlowPyramid(makeGrayscale(image), currentPyramid, windowSize, maxLevel, true, BORDER_REPLICATE, BORDER_REPLICATE);
	if (previousPyramid.empty() || !target) { // optical flow cannot be computed if there is no previous pyramid or no current target
		swap(previousPyramid, currentPyramid);
		return fallback->predict(samples, image, target);
	}

	// compute grid of points at target location
	for (auto point = templatePoints.begin(); point != templatePoints.end(); ++point)
		points.push_back(Point2f(target->getWidth() * point->x + target->getX(), target->getHeight() * point->y + target->getY()));
	// compute forward and backward optical flow
	cv::calcOpticalFlowPyrLK(previousPyramid, currentPyramid, points, forwardPoints, forwardStatus, error, windowSize, maxLevel);
	cv::calcOpticalFlowPyrLK(currentPyramid, previousPyramid, forwardPoints, backwardPoints, backwardStatus, error, windowSize, maxLevel);
	swap(previousPyramid, currentPyramid);

	// compute flow and forward-backward-error
	vector<Point2f> flows;
	flows.reserve(points.size());
	squaredDistances.reserve(points.size());
	for (unsigned int i = 0; i < points.size(); ++i) {
		flows.push_back(forwardPoints[i] - points[i]);
		if (forwardStatus[i] && backwardStatus[i]) {
			Point2f difference = backwardPoints[i] - points[i];
			squaredDistances.push_back(make_pair(difference.dot(difference), i));
		}
	}
	if (squaredDistances.size() < points.size() / 2) // the flow for more than half of the points could not be computed
		return fallback->predict(samples, image, target);

	// find the flows with the least forward-backward-error (not more than 1 pixel)
	float maxError = 1 * 0.5f;
	vector<float> xs, ys;
	sort(squaredDistances.begin(), squaredDistances.end(), [](pair<float, int> lhs, pair<float, int> rhs) { return lhs.first < rhs.first; });
	xs.reserve(squaredDistances.size());
	ys.reserve(squaredDistances.size());
	for (correctFlowCount = 0; correctFlowCount < squaredDistances.size(); ++correctFlowCount) {
		if (squaredDistances[correctFlowCount].first > maxError)
			break;
		int index = squaredDistances[correctFlowCount].second;
		xs.push_back(flows[index].x);
		ys.push_back(flows[index].y);
	}
	if (correctFlowCount < points.size() / 2) // to little correct correspondences
		return fallback->predict(samples, image, target);

	// compute median flow (only change in position for now)
	sort(xs.begin(), xs.end());
	sort(ys.begin(), ys.end());
	float medianX = xs[xs.size() / 2];
	float medianY = ys[ys.size() / 2];
	Point2f medianFlow(medianX, medianY);

	// compute ratios of point distances in previous and current image
	vector<float> squaredRatios;
	squaredRatios.reserve(correctFlowCount * (correctFlowCount - 1) / 2);
	for (unsigned int i = 0; i < correctFlowCount; ++i) {
		for (unsigned int j = i + 1; j < correctFlowCount; ++j) {
			Point2f point1 = points[squaredDistances[i].second];
			Point2f forwardPoint1 = forwardPoints[squaredDistances[i].second];
			Point2f point2 = points[squaredDistances[j].second];
			Point2f forwardPoint2 = forwardPoints[squaredDistances[j].second];
			Point2f differenceBefore = point1 - point2;
			Point2f differenceAfter = forwardPoint1 - forwardPoint2;
			float squaredDistanceBefore = differenceBefore.dot(differenceBefore);
			float squaredDistanceAfter = differenceAfter.dot(differenceAfter);
			squaredRatios.push_back(squaredDistanceAfter / squaredDistanceBefore);
		}
	}

	// compute median ratio to complete the median flow
	sort(squaredRatios.begin(), squaredRatios.end());
	float medianRatio = sqrt(squaredRatios[squaredRatios.size() / 2]);

	// predict samples according to median flow and random noise
	for (auto sample = samples.begin(); sample != samples.end(); ++sample) {
		int oldX = sample->getX();
		int oldY = sample->getY();
		float oldSize = sample->getSize();
		// change position according to median flow
		double newX = oldX + medianX;
		double newY = oldY + medianY;
		double newSize = oldSize * medianRatio;
		// add noise to position
		double positionDeviation = scatter * sample->getSize();
		newX += positionDeviation * generator();
		newY += positionDeviation * generator();
		newSize *= pow(2, scatter * generator());
		// round to integer
		sample->setX((int)(newX + 0.5));
		sample->setY((int)(newY + 0.5));
		sample->setSize((int)(newSize + 0.5));
		// compute change
		sample->setVx(sample->getX() - oldX);
		sample->setVy(sample->getY() - oldY);
		sample->setVSize(sample->getSize() / oldSize);
	}
}