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/ |