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]; }}
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; } } }
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); }
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; } } }
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; }
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); }
/** * @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(); }
/** * @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; } }
/** * @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; } }