DizzyAge по-русски
http://dizzyage.flybb.ru/

Карусель
http://dizzyage.flybb.ru/topic227.html
Страница 1 из 1

Автор:  Hippiman [ 21 апр 2017, 23:47 ]
Заголовок сообщения:  Карусель

Сделал набор функций, с которыми можно быстро и удобно реализовать "карусель", типа такой.

https://youtu.be/ynnC-GM9GtE

После кода будет инструкция как пользоваться.

Код:
func atan2f(x,y)
{
   
   
   if((float)x>0.0)
   {
      return gs_atan(y/x);
   }
   if((float)x<0.0 && (float)y>=0.0)
   {
      return (gs_atan(y/x)+PI);
   }
   if((float)x<0.0 && (float)y<0.0)
   {
      return (gs_atan(y/x)-PI);
   }
   if((float)x==0.0)
   {
      if((float)y>0.0)return PI/2.0;
      if((float)y<0.0)return -PI/2.0;
      if((float)y==0.0)return 0.0;
      
   }
}


Код:
func do_karusel(id,ccx,ccy,ang)
{
   idx=ObjFind(id);

   x=(float)ObjGet(idx,O_X);
   y=(float)ObjGet(idx,O_Y);
   w=(float)ObjGet(idx,O_W);
   h=(float)ObjGet(idx,O_H);
   ox=(float)x+w/2.0;
   oy=(float)y+h/2.0;
   delta=ObjGet(idx,O_USER);
   if(delta==0)
   {
      delta=(int)gs_sqrt(((ox-ccx)*(ox-ccx))+((oy-ccy)*(oy-ccy)));
      ObjSet(idx,O_USER,(int)delta);
   }
   afloor=(float)ObjGet(idx,O_USER+1);
   aceil=(float)ObjGet(idx,O_USER+2);
   ang2=afloor+aceil/10.0;
   
   if(ang2==0.0)
   {
      ang2=atan2f(ccx-ox,ccy-oy);
      ang2=180.0/PI*(float)ang2;
      ang2+=180.0;
      afloor=gs_floor((float)ang2);
      aceil=(float)ang2-afloor;
      ObjSet(idx,O_USER+1,(int)afloor);
      ObjSet(idx,O_USER+2,(int)(aceil*10.0));
   }
   
   rad=((float)ang+ang2)/180.0*PI;

   acx=gs_cos(rad);
   acy=gs_sin(rad);
   
   xx=ccx+acx*(float)delta;
   yy=acy*(float)delta+ccy;
   
   xx-=w/2.0;
   yy-=h/2.0;
   ObjSet(idx,O_X,(int)xx);
   ObjSet(idx,O_Y,(int)yy);
   
   if(ObjGet(idx,O_COLLIDER)==2)
   {
      plx=PlayerGet(P_X);
      ply=PlayerGet(P_Y);
      plw=PlayerGet(P_W);
      plh=PlayerGet(P_H);
      if(plx>=(int)x && plx<=(int)x+(int)w && ply<=(int)y&& ply>=(int)y-plh-5)
      {
         dx=(float)plx-x;
         PlayerSet(P_X,(int)((float)dx+xx));
         println(((float)dx+xx));
      }
   }

   id=ObjGet(idx,O_TARGET);
   if(id!=0)do_karusel(id,ccx,ccy,ang);

}
func karusel(id,corner_speed)
{
   odc=ObjFind(id);
   
   afloor=(float)ObjGet(odc,O_USER);
   aceil=(float)ObjGet(odc,O_USER+1);
   ang=afloor+aceil/10.0;
   
   ang+=corner_speed;
        if(ang>=360.0)ang=0.0;
        if(ang<0.0)ang=360.0;
   afloor=gs_floor((float)ang);
   aceil=(float)ang-afloor;
   ObjSet(odc,O_USER,(int)afloor);
   ObjSet(odc,O_USER+1,(int)(aceil*10.0));
   
   cnt=ObjGet(odc,O_USER+2);
   cx=(float)ObjGet(odc,O_X);
   cy=(float)ObjGet(odc,O_Y);
   cw=(float)ObjGet(odc,O_W);
   ch=(float)ObjGet(odc,O_H);
   ccx=(float)cx+cw/2.0;
   ccy=(float)cy+ch/2.0;
   for(a=0;a<cnt;a++)
   {
      do_karusel(ObjGet(odc,O_USER+a+3),ccx,ccy,ang);
   }
   
}


Настройка:
Рисуем на карте объект - центр типа dynamic.
Рисуем вокруг него динамические объекты, которые будем вертеть.

В центральном объекте User+0 и User+1 оставляем пустыми. В User+2 вбиваем количество вращаемых объектов.
Начиная с User+3 вбиваем id вращаемых объектов.
У вращаемых объектов O_USER +0 - O_USER +2 Должен быть = 0. Эти переменные используются в функциях.

т.к. объектов может крутиться реально много, то я сделал что-то типа цепочек.
К любому объекту можно прицепить ведомый. Для этого в O_TARGET вписываем id ведомого. У последнего объекта в цепочке O_TARGET должен быть = 0.
В видео-примере, к центру прицеплены только 4 внутренних шарика, а к ним ещё по одному шарику, а уже к ним - платформы.

После настройки в функциях обновления комнат (н.р. UpdateRoom_47_48()) вызываем karusel(ID,angle_speed);
Скорость вращения - дробная.


PS. Я не знаю насколько тормозной gscript, сколько он отъедает памяти и процессорного времени, и как оно будет работать на слабых компьютерах. У меня стабильно 64fps.

Автор:  Verm-V [ 22 апр 2017, 09:06 ]
Заголовок сообщения:  Re: Карусель

Круто. Только надо бы еще тогда в код прилипание к платформам прикрутить, чтобы Диззи вместе с ними двигался (вправо-влево).
---
Посмотрел, остальные видео - симпатично получается. У самого была подобная идея, вроде попадания Диззи в виртуальную реальность, только не в стилистике "Трон", а ближе к NES.
---
Оффтоп. По какому принципу ты делал двойной прыжок и прилипание к стенам?

Автор:  VK007 [ 22 апр 2017, 17:41 ]
Заголовок сообщения:  Re: Карусель

Verm-V писал(а):
Круто. Только надо бы еще тогда в код прилипание к платформам прикрутить, чтобы Диззи вместе с ними двигался (вправо-влево).

Да, прилипание нужно, без него не то.

Автор:  Hippiman [ 22 апр 2017, 22:00 ]
Заголовок сообщения:  Re: Карусель

Да, прилипание хотел сегодня делать.
Утром придумал пару загадок основанных на каруселях.

Verm-V писал(а):
Оффтоп. По какому принципу ты делал двойной прыжок и прилипание к стенам?


Двойной прыжок очень простой.
Делаем проверку на состояние падения, в ней на возможность двойного прыжка и в ней несколько мелких проверок для определения силы прыжка.
Код:
func dbl_jump()
{
   if( GetKey(KEY_JUMP) )      
   {
      if( PlayerGet(P_TILE)==PlayerGet(P_COSTUME)+PlayerGet(P_TILEJUMP) ||  PlayerGet(P_TILE)==PlayerGet(P_COSTUME)+PlayerGet(P_TILEUP)|| PlayerGet(P_STATUS)== STATUS_FALL)
      {
         if(PlayerGet(ST_DBL_JUMP)==1)//DOUBLE JUMP
         {
            if( PlayerGet(P_STATUS)== STATUS_FALL)
            {
               PlayerSet(P_FRAME, 0);
               PlayerSet(P_TILE, PlayerGet(P_COSTUME)+PlayerGet(P_TILEJUMP));
            }
            PlayerSet(ST_DBL_JUMP,2);

            if(PlayerGet(ST_HIGH_JUMP)==0)
            {
               if(PlayerGet(ST_SMALL)!=2)   pow = CM_DEFPOW;
               else pow = CM_SM_DEFPOW;
            }
            else
            {
               if(PlayerGet(ST_SMALL)!=2)   pow = CM_HIGHDEFPOW;
               else pow = CM_SM_HIGHDEFPOW;
            }

            PlayerSet(P_FRAME_CTR, 0);      // Сбросить счетчик фреймов
            PlayerSet(P_STATUS, STATUS_JUMP);
            PlayerSet(P_POW, pow);
            PlayerSet(P_FPOW, 0);
         }
      }
   }
}



Прилипание тоже очень простое.
Проверка на включенную способность и на нормальный размер, далее проверка на состояние падения или полета и проверка на столкновение с препятствием и на нажатую кнопку в сторону препятствия.
Код:
func check_wall_climb(step,pow,fpow)
{
   dir=PlayerGet(P_DIR);
   if(PlayerGet(ST_CLIMB)==1 && (PlayerGet(ST_SMALL)!=2))
   {
      if( PlayerGet(P_TILE)==PlayerGet(P_COSTUME)+PlayerGet(P_TILEJUMP))
      {
         if (!CM_CheckJumpX())
         {
            if((GetKey(KEY_RIGHT)&&dir>0) || (GetKey(KEY_LEFT)&&dir<0))
            {
               fpow=0;
               pow=0;
               step=0;
               PlayerSet(P_FPOW, fpow);
               PlayerSet(P_POW, pow);
               PlayerSet(P_STATUS,STATUS_CLIMB);
               PlayerSet(P_DIR,PlayerGet(P_DIR)*(-1));
               costume = PlayerGet(P_COSTUME);
               PlayerSet(P_FRAME, 0);
               PlayerSet(P_TILE, costume+PTILE_CLIMB);
            }
         }
      }
   }
   return step;
}
func CM_UpdateClimb()
{
   dir=PlayerGet(P_DIR);
   frame = PlayerGet(P_FRAME_CTR) / 10;      
   PlayerSet(P_FRAME, frame);            
   
   PlayerSet(P_FRAME_CTR, PlayerGet(P_FRAME_CTR)+1);   
   if(GetKey(KEY_JUMP) )      
   {
      if(PlayerGet(P_USER+63)==0)
      {
         pow = CM_DEFPOW;
      }
      else
      {
         pow = CM_HIGHDEFPOW;
      }
      PlayerSet(P_FRAME_CTR, 0);      // Сбросить счетчик фреймов
      if (pow>0) CM_EnterJump(dir,pow);
   }
   if((GetKey(KEY_RIGHT)&&dir>0) || GetKey(KEY_LEFT)&&dir<0)
   {
      CM_EnterJump(dir,0);
   }
}

Автор:  Hippiman [ 23 апр 2017, 00:14 ]
Заголовок сообщения:  Re: Карусель

Обновил код в первом посте. Теперь Диззи не съезжает с платформы.

Автор:  trz [ 23 апр 2017, 02:44 ]
Заголовок сообщения:  Re: Карусель

Круто Валера!

Не поверишь, буквально вчера матчасть вспоминал: https://www.youtube.com/watch?v=-dGi2Ffdiuk А сегодня уже вижу на DizzyAGE.

Страница 1 из 1 Часовой пояс: UTC + 4 часа
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/