Пример #1
0
void update_y(int vx, int lx, int rx, int vy, int ly, int ry,
    int x, int y, int new_val) {
  if (ly == ry) {
    if (lx == rx) t[vx][vy] = new_val;
    else t[vx][vy] = t[vx*2][vy] + t[vx*2+1][vy];
  } else {
    int my = (ly + ry) / 2;
    if (y <= my) update_y(vx, lx, rx, vy*2, ly, my, x, y, new_val);
    else update_y(vx, lx, rx, vy*2+1, my+1, ry, x, y, new_val);
    t[vx][vy] = t[vx][vy*2] + t[vx][vy*2+1];
}}
Пример #2
0
void StraightMovement::update() {
	Movement::update();
	
	if(!is_suspended()) {
		uint32_t now = System::now();
		bool current_move_y = move_y != 0 && now >= next_move_date_y;
		bool current_move_x = move_x != 0 && now >= next_move_date_x;

		while(current_move_x || current_move_y) {
			// save current coordinates.
			Rectangle old_xy(get_x(), get_y());

			if(current_move_x) {	// time to move in x direction.
				if(current_move_y) {	// time to move in y direction.
					if(next_move_date_x <= next_move_date_y) {	//	we first move in x direction.
						update_x();
						if(now >= next_move_date_y) {
							update_y();
						}
					} else {
						update_y();								// we first move in y direciton.
						if(now >= next_move_date_x) {
							update_x();
						}
					}
				} else {	// we only move in x direction.
					update_x();
				}
			} else {	// we only move in y direction.
				update_y();
			}

			if(get_entity() != NULL && !finished) {
				// movement is successful old coordinates have changed.
				bool success = (get_x() != old_xy.get_x() || get_y() != old_xy.get_y()
					&& (move_x != 0 || move_y != 0));

				// no movement notify obstacle.
				if(!success) {
					notify_obstacle_reached();
					set_finished();
				}
			}

			// check if we continue wit movement.
			now = System::now();
			current_move_x = move_x != 0 && now >= next_move_date_x;
			current_move_y = move_y != 0 && now >= next_move_date_y;
		}
	}
}
Пример #3
0
void update_x(int vx=1, int lx=0, int rx=n-1, int x, int y, int new_val) {
  if (lx != rx) {
    int mx = (lx + rx) / 2;
    if (x <= mx) update_x(vx*2, lx, mx, x, y, new_val);
    else update_x(vx*2+1, mx+1, rx, x, y, new_val);
  }
  update_y(vx, lx, rx, 1, 0, m-1, x, y, new_val);
}
Пример #4
0
void MainWnd::on_command(WORD wNotifyCode, WORD wID, HWND hwndCtl) {
  if(NULL != hwndCtl) {
    // message is from a control (not menu item nor accelerator)
    switch(wID) {
    case IDC_MEASURE:
      if(BN_CLICKED != wNotifyCode) {
        break;
      }
      if(BST_CHECKED == SendMessage(hwndCtl, BM_GETCHECK, 0, 0)) {
        shield->show();
      } else {
        shield->hide();
      }
      break;
      
    case IDC_XRES:
      if(EN_CHANGE == wNotifyCode) {
        int text_length = GetWindowTextLength(hwndCtl);
        char *text = new char[text_length + 1];
        GetWindowText(hwndCtl, text, text_length + 1);
        double new_res = atof(text);
        delete[] text;
        if(0 == new_res) {
          break;
        }
        x_res = new_res;
        update_x();
        update_area();
      }
      break;
      
    case IDC_YRES:
      if(EN_CHANGE == wNotifyCode) {
        int text_length = GetWindowTextLength(hwndCtl);
        char *text = new char[text_length + 1];
        GetWindowText(hwndCtl, text, text_length + 1);
        double new_res = atof(text);
        delete[] text;
        if(0 == new_res) {
          break;
        }
        y_res = new_res;
        update_y();
        update_area();
      }
      break;
    }
  }
}
Пример #5
0
void StraightMovement::update_x() {
	uint32_t next_move_time_x;
	if(move_x != 0) {	// entity wants to move in x direction.
		next_move_time_x = delay_x;
		if(!test_collision_with_obstacles(move_x, 0) && !test_collision_with_borders(move_x, 0)) {
			translate_x(move_x);	// no collision in x direction 
			if(move_y != 0 && test_collision_with_obstacles(0, move_y)) {
				// if there is also a y move and this move is stopped by an obstacles.
				next_move_time_x = (int) (1000 / get_speed());
				update_y();
			}
		}
	} else {	//entity does not want to move in x direction so we stop the movement.
	    stop();
	}
	next_move_date_x += next_move_time_x;
}
Пример #6
0
void MainWnd::on_mouse_move(int x, int y) {
  x_mouse = x;
  y_mouse = y;
  mouse_valid = true;
  update_x();
  update_y();
  
  // copy 5 * 5 pixels from the mouse position for the "mouse cam"
  HDC hdc_screen = GetDC(shield->getHWnd());
  HDC hdc_main_wnd = GetDC(hWnd);
  StretchBlt(
    hdc_main_wnd, 136, 24, 5*8, 5*8,
    hdc_screen, x - 2, y - 2, 5, 5,
    SRCCOPY
  );
  ReleaseDC(hWnd, hdc_main_wnd);
  ReleaseDC(shield->getHWnd(), hdc_screen);
}
Пример #7
0
/**
 * @brief Updates the position of the object controlled by this movement.
 *
 * This function is called repeatedly.
 */
void StraightMovement::update() {

  if (!is_suspended()) {
    uint32_t now = System::now();

    bool x_move_now = x_move != 0 && now >= next_move_date_x;
    bool y_move_now = y_move != 0 && now >= next_move_date_y;

    while (x_move_now || y_move_now) { // while it's time to move

      // save the current coordinates
      Rectangle old_xy(get_x(), get_y());

      if (x_move_now) {
        // it's time to make an x move

        if (y_move_now) {
          // but it's also time to make a y move

          if (next_move_date_x <= next_move_date_y) {
            // x move first
            update_x();
            if (now >= next_move_date_y) {
              update_y();
            }
          }
          else {
            // y move first
            update_y();
            if (now >= next_move_date_x) {
              update_x();
            }
          }
        }
        else {
          update_x();
        }
      }
      else {
        update_y();
      }

      if (!is_suspended() && get_entity() != NULL && !finished) {

        // the movement was successful if the entity's coordinates have changed
        // and the movement was not stopped
        bool success = (get_x() != old_xy.get_x() || get_y() != old_xy.get_y())
            && (x_move != 0 || y_move != 0);

        if (!success) {
          notify_obstacle_reached();
        }
      }

      now = System::now();

      if (!finished && max_distance != 0 && Geometry::get_distance(initial_xy.get_x(),
          initial_xy.get_y(), get_x(), get_y()) >= max_distance) {
        set_finished();
      }
      else {
        x_move_now = x_move != 0 && now >= next_move_date_x;
        y_move_now = y_move != 0 && now >= next_move_date_y;
      }
    }
  }

  // Do this at last so that Movement::update() knows whether we are finished.
  Movement::update();
}
Пример #8
0
/**
 * @brief Updates the x position of the entity if it wants to move
 * (smooth version).
 */
void StraightMovement::update_smooth_x() {

  if (x_move != 0) {  // The entity wants to move on x.

    // By default, next_move_date_x will be incremented by x_delay,
    // unless we modify below the movement in such a way that the
    // x speed needs to be fixed.
    uint32_t next_move_date_x_increment = x_delay;

    if (!test_collision_with_obstacles(x_move, 0)) {

      translate_x(x_move);  // Make the move.

      if (y_move != 0 && test_collision_with_obstacles(0, y_move)) {
        // If there is also a y move, and if this y move is illegal,
        // we still allow the x move and we give it all the speed.
        next_move_date_x_increment = (int) (1000.0 / get_speed());
      }
    }
    else {
      if (y_move == 0) {
        // The move on x is not possible and there is no y move:
        // let's try to add a move on y to make a diagonal move,
        // but only if the wall is really diagonal: otherwise, the hero
        // could bypass sensors.

        if (!test_collision_with_obstacles(x_move, 1)    // Can move diagonally and:
            && (test_collision_with_obstacles(0, -1) ||  // the wall is really diagonal
                test_collision_with_obstacles(0, 1))     // or we don't have a choice anyway.
        ) {
          translate_xy(x_move, 1);
          next_move_date_x_increment = (int) (x_delay * Geometry::SQRT_2);  // Fix the speed.
        }
        else if (!test_collision_with_obstacles(x_move, -1)
            && (test_collision_with_obstacles(0, 1) ||
                test_collision_with_obstacles(0, -1))
        ) {
          translate_xy(x_move, -1);
          next_move_date_x_increment = (int) (x_delay * Geometry::SQRT_2);
        }
        else {

          // The diagonal moves didn't work either.
          // So we look for a place (up to 8 pixels up and down)
          // where the required move would be allowed.
          // If we find a such place, then we move towards this place.

          bool moved = false;
          for (int i = 1; i <= 8 && !moved; i++) {

            if (!test_collision_with_obstacles(x_move, i) && !test_collision_with_obstacles(0, 1)) {
              translate_y(1);
              moved = true;
            }
            else if (!test_collision_with_obstacles(x_move, -i) && !test_collision_with_obstacles(0, -1)) {
              translate_y(-1);
              moved = true;
            }
          }
        }
      }
      else {
        // The move on x is not possible, but there is also a vertical move.
        if (!test_collision_with_obstacles(x_move, y_move)) {
          // This case is only necessary in narrow diagonal passages.
          translate_xy(x_move, y_move);
          next_move_date_y += y_delay;  // Delay the next update_smooth_y() since we just replaced it.
        }
        else if (!test_collision_with_obstacles(0, y_move)) {
          // Do the vertical move right now, don't wait uselessly.
          update_y();
        }
      }
    }
    next_move_date_x += next_move_date_x_increment;
  }
}
Пример #9
0
/**
 * @brief Updates the x position of the entity if it wants to move
 * (smooth version).
 */
void StraightMovement::update_smooth_x() {

  if (x_move != 0) { // the entity wants to move on x

    // by default, next_move_date_x will be incremented by x_delay,
    // unless we modify the movement in such a way that the
    // x speed needs to be fixed
    uint32_t next_move_date_x_increment = x_delay;

    if (!test_collision_with_obstacles(x_move, 0)) {

      translate_x(x_move); // make the move

      if (y_move != 0 && test_collision_with_obstacles(0, y_move)) {
        // if there is also a y move, and if this y move is illegal,
        // we still allow the x move and we give it all the speed
        next_move_date_x_increment = (int) (1000.0 / get_speed());
      }
    }
    else {
      if (y_move == 0) {
        // the move on x is not possible: let's try
        // to add a move on y to make a diagonal move

        if (!test_collision_with_obstacles(x_move, 1)
            && test_collision_with_obstacles(0, -1)) {
          translate_xy(x_move, 1);
          next_move_date_x_increment = (int) (x_delay * Geometry::SQRT_2); // fix the speed
        }
        else if (!test_collision_with_obstacles(x_move, -1)
            && test_collision_with_obstacles(0, 1)) {
          translate_xy(x_move, -1);
          next_move_date_x_increment = (int) (x_delay * Geometry::SQRT_2);
        }
        else {

          /* The diagonal moves didn't work either.
           * So we look for a place (up to 8 pixels up and down)
           * where the required move would be allowed.
           * If we find a such place, then we move towards this place.
           */

          bool moved = false;
          for (int i = 1; i <= 8 && !moved; i++) {

            if (!test_collision_with_obstacles(x_move, i) && !test_collision_with_obstacles(0, 1)) {
              translate_y(1);
              moved = true;
            }
            else if (!test_collision_with_obstacles(x_move, -i) && !test_collision_with_obstacles(0, -1)) {
              translate_y(-1);
              moved = true;
            }
          }
        }
      }
      else {
        // no attractive place was found, but there is a vertical move
        if (!test_collision_with_obstacles(0, y_move)) {
          // do the vertical move right now, don't wait uselessly
          update_y();
        }
      }
    }
    next_move_date_x += next_move_date_x_increment;
  }
}