Advertisement
Kitomas

player.cpp as of 2024-06-14

Jun 14th, 2024
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.12 KB | None | 0 0
  1. #include <player.hpp>
  2. #include <tile.hpp>
  3.  
  4. #include <math.h>
  5.  
  6. using namespace kit;
  7.  
  8.  
  9.  
  10.  
  11.  
  12. bool Player::setScale(kit::f32 scale_new){
  13.   kit::f32 scale_old = scale;
  14.   scale = MAX(scale_new, 0.2f); //for a minimum of 2x2 pixels
  15.  
  16.   kit::shape::rect player_rect = getRect();
  17.   kit::shape::point delta;
  18.  
  19.   //player was probably pushed into the floor if the scale increased,
  20.    //so attempt to move the player out of any potential subtiles
  21.   if(subtiles_overlapping(player_rect, &delta))
  22.     player_rect += delta;
  23.  
  24.   //if the previous movement didn't result in the
  25.    //player entering empty space, return false
  26.   if(subtiles_overlapping(player_rect, nullptr)){
  27.     scale = scale_old; //(revert the scale back to what it was originally too)
  28.     return false;
  29.  
  30.   } else { //otherwise, apply those movement changes to pos, and return true
  31.     pos += delta;
  32.     return true;
  33.  
  34.   }
  35.  
  36. }
  37.  
  38.  
  39.  
  40.  
  41.  
  42. #define SPRSHEET_ADJUST(_v) ((_v)*(8+1)) //8px +1 for one pixel of spacing
  43.  
  44. void Player::blit(){
  45.   if(!visible || scale<=0.0f) return;
  46.  
  47.   shape::rect dst = getRect();
  48.  
  49.   shape::rect src(0,0, 8,8);
  50.   if(confused    ) src.y += SPRSHEET_ADJUST(1);
  51.   if(!facingRight) src.y += SPRSHEET_ADJUST(2);
  52.  
  53.  
  54.  
  55.   if(MID_AIR){ //mid-air
  56.     if(fabsf(vel.x) > PLAYER_NEUTRAL){ //going fast horizontally
  57.       if(vel.y<=0) src.x = SPRSHEET_ADJUST(2); //-Y; back leg extended
  58.       else         src.x = SPRSHEET_ADJUST(8); //+Y; front leg extended
  59.     } else { //going slow (or not at all) horizontally
  60.       if(     vel.y <-PLAYER_NEUTRAL) src.x = SPRSHEET_ADJUST(1); //-Y; back leg down
  61.       else if(vel.y > PLAYER_NEUTRAL) src.x = SPRSHEET_ADJUST(4); //+Y; front leg down
  62.       else                            src.x = SPRSHEET_ADJUST(7); //0Y; both legs up
  63.     }
  64.  
  65.   } else { //on the ground
  66.       if(vel.x < 0  &&  acc.x > 0){ //slowing down while moving left
  67.         if(fabsf(vel.x) > PLAYER_NEUTRAL){ //going fast horizontally
  68.           if(facingRight) src.x = SPRSHEET_ADJUST(2); //back leg extended
  69.           else            src.x = SPRSHEET_ADJUST(8); //front leg extended
  70.         } else { //going slow (or not at all) horizontally
  71.           if(facingRight) src.x = SPRSHEET_ADJUST(1); //back leg down
  72.           else            src.x = SPRSHEET_ADJUST(4); //front leg down
  73.         }
  74.  
  75.       } else if(vel.x > 0  &&  acc.x < 0){ //slowing down while moving right
  76.         if(fabsf(vel.x) > PLAYER_NEUTRAL){ //going fast horizontally
  77.           if(facingRight) src.x = SPRSHEET_ADJUST(8); //front leg extended
  78.           else            src.x = SPRSHEET_ADJUST(2); //back leg extended
  79.         } else { //going slow (or not at all) horizontally
  80.           if(facingRight) src.x = SPRSHEET_ADJUST(4); //front leg down
  81.           else            src.x = SPRSHEET_ADJUST(1); //back leg down
  82.         }
  83.  
  84.       } else if(fabsf(vel.x) > PLAYER_NEUTRAL){ //moving forward
  85.         src.x = SPRSHEET_ADJUST(1 + RND(runningState)%6);
  86.  
  87.       } else if(acc.x < 0){ //standing still while accelerating left
  88.         if(facingRight) src.x = SPRSHEET_ADJUST(4); //front leg down
  89.         else            src.x = SPRSHEET_ADJUST(1); //back leg down
  90.  
  91.       } else if(acc.x > 0){ //standing still while accelerating right
  92.         if(facingRight) src.x = SPRSHEET_ADJUST(1); //back leg down
  93.         else            src.x = SPRSHEET_ADJUST(4); //front leg down
  94.  
  95.       } else { //standing still without acceleration
  96.         src.x = SPRSHEET_ADJUST(0); //technically redundant, but left here for clarity
  97.  
  98.       }
  99.  
  100.   }
  101.  
  102.  
  103.  
  104.   //0xff00ff for magenta as the transparency color
  105.   gl_spritesheetPlayer->blitRect(&dst, &src, 0xff00ff);
  106.  
  107. }
  108.  
  109.  
  110.  
  111.  
  112.  
  113. //acc, visible, and confused are not modified here
  114. void Player::update(){
  115.   vel.x += (MID_AIR) ? acc.x*PLAYER_AIR_FRICTION : acc.x;
  116.   vel.y += acc.y;
  117.   if(enforceMaxVel){
  118.     vel.x = CLAMP(vel.x, -VELX_MAX, VELX_MAX);
  119.     vel.y = CLAMP(vel.y, -VELY_MAX, VELY_MAX);
  120.   }
  121.  
  122.  
  123.   {
  124.     //tbd: remove collision_type, CollisionEnum, and by extension move's
  125.      //return if it turns out that it's unnecessary
  126.     //#define collision_type(_type) ((collision&(_type))!=0)
  127.     /*CollisionEnum collision =*/ move(vel.x, vel.y);
  128.     //(maybe even have move return the player's new rect,
  129.      //so getRect() doesn't need to be called below VV)
  130.  
  131.  
  132.     shape::rect collider_ceiling = getRect();
  133.     shape::rect collider_floor   = collider_ceiling;
  134.     shape::rect collider_left    = collider_ceiling;
  135.     shape::rect collider_right   = collider_ceiling;
  136.  
  137.  
  138.     collider_ceiling.y -= 1;
  139.     collider_ceiling.h  = 1;
  140.     collider_floor.y   += collider_floor.h;
  141.     collider_floor.h    = 1;
  142.  
  143.     if(vel.y<0.0f && subtiles_overlapping(collider_ceiling)){
  144.       vel.y = fabsf(vel.y)/2;
  145.       ++ticksInAir;
  146.  
  147.     } else if(vel.y>0.0f && subtiles_overlapping(collider_floor)){
  148.       play_sfx_landing(ticksInAir);
  149.       if(ticksInAir) runningState = 2.5f;
  150.       ticksInAir = 0;
  151.       jumped = false;
  152.       vel.y = 0.0f;
  153.  
  154.     } else {
  155.       ++ticksInAir;
  156.  
  157.     }
  158.  
  159.  
  160.     collider_left.x  -= 1;
  161.     collider_left.w   = 1;
  162.     collider_right.x += collider_right.w;
  163.     collider_right.w  = 1;
  164.  
  165.     if(vel.x<0.0f && subtiles_overlapping(collider_left ) ||
  166.        vel.x>0.0f && subtiles_overlapping(collider_right)  )
  167.     {
  168.       vel.x = 0.0f;
  169.       runningState = 0.0f;
  170.     }
  171.  
  172.  
  173. gl_win->clear(0x7f7f7f); //should be redundant
  174. gl_scene.drawBg();
  175. gl_scene.drawTiles(false);
  176. gl_player.blit();
  177. gl_scene.drawTiles(true);
  178. //gl_win_drawRectEmpty(collider_ceiling, 0x00ffff);
  179. //gl_win_drawRectEmpty(collider_floor,   0xff00ff);
  180. //gl_win_drawRectEmpty(collider_left,    0xffff00);
  181. //gl_win_drawRectEmpty(collider_right,   0xffffff);
  182.  
  183.  
  184.   }
  185.  
  186.  
  187.  
  188.   //manage horizontal velocity
  189.   {
  190.     if(fabsf(vel.x)<0.05f && acc.x==0) vel.x = 0.0f;
  191.  
  192.     //if on ground while moving horizontally
  193.     if(ticksInAir <= 1  &&  vel.x != 0){
  194.       facingRight = vel.x > 0;
  195.       if(ticksInAir <= 1  &&  acc.x == 0){
  196.         vel.x -= (vel.x>0) ?  PLAYER_SPEED*PLAYER_GND_FRICTION
  197.                            : -PLAYER_SPEED*PLAYER_GND_FRICTION;
  198.       }
  199.     }
  200.   }
  201.  
  202.  
  203.  
  204.   //handle incrementing run animations
  205.   {
  206.     f32 prevRunningState = runningState;
  207.  
  208.     if(fabsf(vel.x) > PLAYER_NEUTRAL) runningState += fabsf(vel.x)*PLAYER_RUN_MUL;
  209.     else                              runningState  = 0.0f;
  210.     runningState = fmodf(fabsf(runningState), 6.0f);
  211.  
  212.     //used to indicate that a foot step sound effect should play
  213.      //(1.5 instead of 2, since 1.5 would round up to integer state 2,
  214.      //which is the actual moment that the foot would reach the ground)
  215.     if(prevRunningState < 1.5f  &&  runningState >= 1.5f  &&  !MID_AIR)
  216.       play_sfx_footstep();
  217.   }
  218. }
  219.  
  220.  
  221.  
  222.  
  223.  
  224. CollisionEnum Player::move(f32 deltaX, f32 deltaY){
  225.   rem.x += CLAMP(deltaX, -CANVSIZ_X,CANVSIZ_X);
  226.   rem.y += CLAMP(deltaY, -CANVSIZ_Y,CANVSIZ_Y);
  227.  
  228.   shape::point delta(RND(rem.x), RND(rem.y));
  229.   if(!delta.x && !delta.y) return COLLISION_NONE;
  230.  
  231.   rem.x -= delta.x;
  232.   rem.y -= delta.y;
  233.   shape::rect current = getRect();
  234.   shape::rect end     = current;
  235.   end += delta;
  236.   shape::point newpos(current.x, current.y);
  237.  
  238.  
  239.  
  240.   //do a bresenham line to find the exact point of collision, before setting
  241.    //pos to that (minus 1 step assuming a collision actually occurred)
  242.   s32 d_x =  abs(delta.x);
  243.   s32 d_y = -abs(delta.y);
  244.   s32 s_x = (delta.x >= 0) ? 1 : -1;
  245.   s32 s_y = (delta.y >= 0) ? 1 : -1;
  246.   s32 e_1 = d_x + d_y;
  247.  
  248.   while(true){
  249.     newpos.x = current.x; //(assumes that player isn't colliding
  250.     newpos.y = current.y;  //with any subtiles initially)
  251.  
  252.     if(current.x == end.x  &&  current.y == end.y) break;
  253.  
  254.     s32 e_2 = e_1<<1;
  255.  
  256.     if(e_2 >= d_y){
  257.       if(current.x == end.x) break;
  258.       e_1 += d_y;
  259.       current.x += s_x;
  260.     }
  261.  
  262.     if(e_2 <= d_x){
  263.       if(current.y == end.y) break;
  264.       e_1 += d_x;
  265.       current.y += s_y;
  266.     }
  267.  
  268.     if(subtiles_overlapping(current, &delta)) break;
  269.  
  270.   }
  271.  
  272.  
  273.   pos.x = newpos.x + current.w/2;
  274.   pos.y = newpos.y + current.h/2;
  275.  
  276.   s32 collision_result;
  277.   collision_result  = (delta.x<0) << 3  |  (delta.x!=0) << 2;
  278.   collision_result |= (delta.y<0) << 1  |  (delta.y!=0) << 0;
  279.  
  280.   return (CollisionEnum)collision_result;
  281.  
  282. }
  283.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement