super metroid style camera
authorMatthias Braun <matze@braunis.de>
Sat, 3 Mar 2007 22:36:58 +0000 (22:36 +0000)
committerMatthias Braun <matze@braunis.de>
Sat, 3 Mar 2007 22:36:58 +0000 (22:36 +0000)
SVN-Revision: 4925

data/camera.cfg
src/object/camera.cpp
src/object/camera.hpp

index e4d91ca..670ebab 100644 (file)
@@ -4,9 +4,9 @@
   ; 0.3 in x and .66 in y means in left 1/3rd of the screen at the upper 2/3rd
   ; (which is the lower 1/3rd) of the screen...
 
-  ; 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby, 4 = inverse rubberband
-  (xmode 2)
-  ; 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby, 4 = inverse rubberband
+  ; 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby, 4 = Super Metroid like
+  (xmode 4)
+  ; 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby
   (ymode 2)
   
   ; Specify the size of the midle rect of kirby camera mode
@@ -30,7 +30,7 @@
   (clamp-y 0.1666)
 
   ; Keep tux here when he runs in YI mode
-  (edge-x 0.28)
+  (edge-x 0.4)
   ; If YI camera is in no-scrollmode it will go to scrollmode again if tux
   ; reaches this part of the screen, make sure this value is bigger than edge-x
   ; to avoid sudden camera stops
@@ -39,6 +39,8 @@
   ;(sensitive-x 0.35)
   (sensitive-x -1)
 
+  (dynamic-speed-sm 0.8)
+
   (dirchange-time 0.2)
 )
 
index d4feaaf..51d22d2 100644 (file)
@@ -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;
@@ -68,6 +69,8 @@ public:
   float clamp_y;
   float clamp_x;
 
+  float dynamic_speed_sm;
+
   CameraConfig() {
     xmode = 1;
     ymode = 1;
@@ -83,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)
@@ -107,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();
@@ -459,14 +465,40 @@ Camera::update_scroll_normal(float elapsed_time)
     // apply scrolling
     translation.x -= speed_x * elapsed_time;
   }
-  if(mode == 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));
   }
   if(xmode == 4) {
-    // TODO...
+    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;
+      }
+    }
+
+    // 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(xmode != 0 && config.clamp_x > 0) {
index 8a897a5..d5ca2d0 100644 (file)
@@ -108,6 +108,7 @@ private:
   // normal mode
   LookaheadMode lookahead_mode;
   float changetime;
+  float lookahead_pos;
 
   // autoscroll mode
   std::auto_ptr<Path> autoscroll_path;