X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fobject%2Fcamera.cpp;h=42dd1aad3044a5c028e9df9ee4b02acd676d9bb5;hb=04a3157ef478169b5a3fc05dae00ed6ee6a1fae2;hp=2f9f4994e12164f2cd6e29bd8e646ceba191f469;hpb=a240b962895aad65e913e8693a260847117b93db;p=supertux.git diff --git a/src/object/camera.cpp b/src/object/camera.cpp index 2f9f4994e..42dd1aad3 100644 --- a/src/object/camera.cpp +++ b/src/object/camera.cpp @@ -42,8 +42,9 @@ class CameraConfig { public: - // 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby, 4 = inverse rubber + // 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby int ymode; + // as above, 4 = super metroid like int xmode; float kirby_rectsize_x; float kirby_rectsize_y; @@ -61,11 +62,15 @@ public: float dirchange_time; // edge_x float edge_x; + // when too change from noscroll mode back to lookahead left/right mode + // set to <= 0 to disable noscroll mode float sensitive_x; float clamp_y; float clamp_x; + float dynamic_speed_sm; + CameraConfig() { xmode = 1; ymode = 1; @@ -81,6 +86,7 @@ public: sensitive_x = 1.f/4.f; dynamic_max_speed_x = 1.0; dirchange_time = 0.2f; + dynamic_speed_sm = 1.0f; } void load(const std::string& filename) @@ -105,11 +111,13 @@ public: camconfig->get("kirby-rectsize-y", kirby_rectsize_y); camconfig->get("edge-x", edge_x); camconfig->get("sensitive-x", sensitive_x); + camconfig->get("dynamic-speed-sm", dynamic_speed_sm); } }; Camera::Camera(Sector* newsector, std::string name) - : mode(NORMAL), sector(newsector), lookahead_mode(LOOKAHEAD_NONE) + : mode(NORMAL), sector(newsector), lookahead_mode(LOOKAHEAD_NONE), + lookahead_pos(0) { this->name = name; config = new CameraConfig(); @@ -300,11 +308,14 @@ Camera::update_scroll_normal(float elapsed_time) return; /****** Vertical Scrolling part ******/ + int xmode = config.xmode; int ymode = config.ymode; if(player->is_dying() || sector->get_height() == 19*32) { ymode = 0; } + if(player->is_dying()) + xmode = 0; if(ymode == 1) { translation.y = player_pos.y - SCREEN_HEIGHT * config.target_y; @@ -338,8 +349,8 @@ Camera::update_scroll_normal(float elapsed_time) if(ymode == 3) { float halfsize = config.kirby_rectsize_y * 0.5f; translation.y = clamp(translation.y, - player_pos.y - SCREEN_HEIGHT * (0.5f - halfsize), - player_pos.y - SCREEN_HEIGHT * (0.5f + halfsize)); + player_pos.y - SCREEN_HEIGHT * (0.5f + halfsize), + player_pos.y - SCREEN_HEIGHT * (0.5f - halfsize)); } if(ymode == 4) { // TODO... @@ -347,16 +358,16 @@ Camera::update_scroll_normal(float elapsed_time) if(ymode != 0 && config.clamp_y > 0) { translation.y = clamp(translation.y, - player_pos.y - SCREEN_HEIGHT * config.clamp_y, - player_pos.y - SCREEN_HEIGHT * (1-config.clamp_y)); + player_pos.y - SCREEN_HEIGHT * (1-config.clamp_y), + player_pos.y - SCREEN_HEIGHT * config.clamp_y); } /****** Horizontal scrolling part *******/ - if(config.xmode == 1) { + if(xmode == 1) { translation.x = player_pos.x - SCREEN_WIDTH * config.target_x; } - if(config.xmode == 2) { + if(xmode == 2) { // our camera is either in leftscrolling, rightscrolling or // nonscrollingmode. // @@ -371,17 +382,30 @@ Camera::update_scroll_normal(float elapsed_time) else if (player->dir == ::LEFT) walkDirection = LOOKAHEAD_LEFT; else walkDirection = LOOKAHEAD_RIGHT; - float LEFTEND = SCREEN_WIDTH * config.sensitive_x; - float RIGHTEND = SCREEN_WIDTH * (1-config.sensitive_x); + float LEFTEND, RIGHTEND; + if(config.sensitive_x > 0) { + LEFTEND = SCREEN_WIDTH * config.sensitive_x; + RIGHTEND = SCREEN_WIDTH * (1-config.sensitive_x); + } else { + LEFTEND = SCREEN_WIDTH; + RIGHTEND = 0; + } - /* if we're undecided then look if we crossed the left or right "sensitive" - * area */ if(lookahead_mode == LOOKAHEAD_NONE) { + /* if we're undecided then look if we crossed the left or right + * "sensitive" area */ if(player_pos.x < translation.x + LEFTEND) { lookahead_mode = LOOKAHEAD_LEFT; } else if(player_pos.x > translation.x + RIGHTEND) { lookahead_mode = LOOKAHEAD_RIGHT; } + /* at the ends of a level it's obvious which way we will go */ + if(player_pos.x < SCREEN_WIDTH*0.5) { + lookahead_mode = LOOKAHEAD_RIGHT; + } else if(player_pos.x >= sector->get_width() - SCREEN_WIDTH*0.5) { + lookahead_mode = LOOKAHEAD_LEFT; + } + changetime = -1; } else if(lookahead_mode != walkDirection) { /* player changed direction while camera was scrolling... @@ -397,7 +421,6 @@ Camera::update_scroll_normal(float elapsed_time) player_pos.x < translation.x + LEFTEND) { lookahead_mode = LOOKAHEAD_LEFT; } else { - printf("abortscroll\n"); lookahead_mode = LOOKAHEAD_NONE; } } @@ -411,9 +434,9 @@ Camera::update_scroll_normal(float elapsed_time) // calculate our scroll target depending on scroll mode float target_x; if(lookahead_mode == LOOKAHEAD_LEFT) - target_x = player->get_bbox().get_middle().x - RIGHTEND; + target_x = player_pos.x - RIGHTEND; else if(lookahead_mode == LOOKAHEAD_RIGHT) - target_x = player->get_bbox().get_middle().x - LEFTEND; + target_x = player_pos.x - LEFTEND; else target_x = translation.x; @@ -438,20 +461,52 @@ Camera::update_scroll_normal(float elapsed_time) // apply scrolling translation.x -= speed_x * elapsed_time; } - if(config.xmode == 3) { + if(xmode == 3) { float halfsize = config.kirby_rectsize_x * 0.5f; translation.x = clamp(translation.x, - player_pos.x - SCREEN_WIDTH * (0.5f - halfsize), - player_pos.x - SCREEN_WIDTH * (0.5f + halfsize)); + player_pos.x - SCREEN_WIDTH * (0.5f + halfsize), + player_pos.x - SCREEN_WIDTH * (0.5f - halfsize)); } - if(config.xmode == 4) { - // TODO... + if(xmode == 4) { + float LEFTEND = SCREEN_WIDTH * config.edge_x; + float RIGHTEND = SCREEN_WIDTH * (1 - config.edge_x); + + if (player_delta.x < -EPSILON) { + // walking left + lookahead_pos -= player_delta.x * config.dynamic_speed_sm; + + if(lookahead_pos > RIGHTEND) { + lookahead_pos = RIGHTEND; + } + } else if (player_delta.x > EPSILON) { + // walking right + lookahead_pos -= player_delta.x * config.dynamic_speed_sm; + if(lookahead_pos < LEFTEND) { + lookahead_pos = LEFTEND; + } + } + + if(player->peeking_direction() == ::LEFT) { + lookahead_pos += config.max_speed_x * elapsed_time * 3.0f; + } else if(player->peeking_direction() == ::RIGHT) { + lookahead_pos -= config.max_speed_x * elapsed_time * 3.0f; + } + + // adjust for level ends + if (player_pos.x < LEFTEND) { + lookahead_pos = LEFTEND; + } + if (player_pos.x > sector->get_width() - LEFTEND) { + lookahead_pos = RIGHTEND; + } + + translation.x = player_pos.x - lookahead_pos; } - if(config.xmode != 0 && config.clamp_x > 0) { + if(xmode != 0 && config.clamp_x > 0) { translation.x = clamp(translation.x, - player_pos.x - SCREEN_WIDTH * config.clamp_x, - player_pos.x - SCREEN_WIDTH * (1-config.clamp_x)); + player_pos.x - SCREEN_WIDTH * (1-config.clamp_x), + player_pos.x - SCREEN_WIDTH * config.clamp_x); } keep_in_bounds(translation);