Вложений: 2
Квази-интеллект
Немного усложним поведение ботов - чтобы игра не была такой "пресной". Сделаем из бота агр-моба (см LA2). Сценарий следующий: Цитата:
Код:
Type bot Код:
b\point=CreatePivot() Код:
Function update_bot() Рассмотрим подробнее: Код:
If EntityDistance(user,a\entity)<Rdist# Код:
PointEntity a\entity,user Если же игрока рядом нет, то Код:
If EntityDistance(a\entity,a\point)<2 Код:
PositionEntity a\point,EntityX(a\point)+Rnd(-40,40),EntityY(a\point),EntityZ(a\point)+Rnd(-40,40) Код:
PointEntity a\entity,a\point |
Квази-интеллект2
Слегка погонял ботов и понял, что чего-то не хватает. Подправим алгоритм поведения: Цитата:
Код:
Function update_shot() Цитата:
И ещё кое-что: пусть бот становится красным, если он "навёлся" на игрока. Код:
Function update_bot() |
Очень крутая статья все просто и ясно, лучше нигде не втречал, спасибо!
|
Всегда пожалуйста. Будут вопросы - обращайтесь =)
|
Re: Создаём свой FPS (first person shooter)
MANIAK_dobrii первёл данную работу на английский язык:
english-version |
Re: Создаём свой FPS (first person shooter)
Благодаря GoodWin (http://www.boolean.name/showthread.php?p=15571) нарыл баг в коде, который сказывается при использовании уровня с ра3личными высотами. Короче говоря, код создания выстрела должен быть такой:
Код:
Function create_Shot(x#,y#,z#,pitch#,yaw#,roll#) команда позиционирования объекта Код:
PositionEntity s\entity,x#,y#,z#,1 Код:
EntityType s\entity,SHOTT Глюк обидный и вызван только моим недосмотром =( |
Re: Создаём свой FPS (first person shooter)
А как сделать здоровье персонажу и отнятие здоровья при прикосновении бота к игроку?
|
Re: Создаём свой FPS (first person shooter)
Завтра (имеется в виду - т.н. "логическое завтра") отвечу - сегодня спать хочется.
|
Re: Создаём свой FPS (first person shooter)
Цитата:
1) это моя тема 2) выложить просто переправленный аттач моджет каждый - для этого есть рубрики по 2д и 3д. ФАК подразумевает объяснения, тем более что 3)в коде много изменений без которых можно обойтись imper ладно, а так пойдет: назначим еще одну переменную отвечающую за кол-во жизни у игрока Global user, live добавим в функцию создания игрока следующую строку live=100 user=CreateSphere() k#=3 ScaleEntity user,k#,k#,k# теперь необходимо обработать прикосновение бота к игроку изменим функцию update_bot() добавим следующие строки кода: a\time=new_time ;= If EntityCollided (a\entity,USERT); проверякм есть ли колизия между ботои и игроком live=live-1; если есть то уменьшаем кол-во жизни If live<=0; если кол-во жизни игрока 0 или меньше FreeEntity user_h; удаляем игрока и снова его create_user(0,100,0);создаем EndIf ElseIf EntityDistance(user,a\entity)<Rdist# PointEntity a\entity,user Else If EntityDistance(a\entity,a\point)<2 PositionEntity a\point,EntityX(a\point)+Rnd(-40,40),EntityY(a\point),EntityZ(a\point)+Rnd(-40,40) EndIf PointEntity a\entity,a\point EndIf красным новые строки которые необходимо добавить... и конечно-же... идея реализации полность принадлежит Имперсоналису, за что ему огромное спасибо... P.S. извини, что отнял у тебя возможность помочь людям |
Re: Создаём свой FPS (first person shooter)
Смертный герой
Сегодня прикрутим показатель жизни игроку. Как всегда код будет максимально простым - чтобы показать прицип работы. Конечная реализация зависит от вас. В глобал: [highlight=blitzbasic] Global user_H [/highlight] в функцию create_user(x#=0,y#=10,z#=0) [highlight=blitzbasic] user_H=100 [/highlight] в MAIN LOOP: [highlight=blitzbasic] Text 10,40,"H="+user_H [/highlight] Теперь опишем систему нанесения урона пользователю. В функции update_bot() пишем: [highlight=blitzbasic] Function update_bot() Rdist#=15 v#=0.01 For a.bot=Each bot ;= If a\time=0 a\time=MilliSecs() new_time=MilliSecs() delta_t=new_time-a\time a\time=new_time ;= If EntityDistance(user,a\entity)<Rdist# PointEntity a\entity,user EntityColor a\entity,255,0,0 Else EntityColor a\entity,255,255,255 If EntityDistance(a\entity,a\point)<2 PositionEntity a\point,EntityX(a\point)+Rnd(-40,40),EntityY(a\point),EntityZ(a\point)+Rnd(-40,40) EndIf PointEntity a\entity,a\point EndIf ;===========новое player=EntityCollided(a\entity,USERT) If player<>0 user_H=user_H-1 EndIf ;======конец нового MoveEntity a\entity,0,0,v#*delta_t TranslateEntity user,0,-G#*delta_t,0 Next End Function [/highlight] Если бот столкнулся с объектом, у которого стоит тип коллизии USERT, то убавить игроку жизнь на единицу. Запустите и убедитесь в недостаточности этой конструкции. Жизнь уменьшается при каждом вызове функции, т.е. если у вас 60 ФПС, то за секунду прикосновения к вам бота у вас онимется 60 единиц здоровья. Приступим. [highlight=blitzbasic] Type bot Field entity Field time Field Survivability Field point Field last_damage_time End Type [/highlight] Здесь будем хранить время последнего "удара". Подправим функцию обеновления бота: [highlight=blitzbasic] ;=========== player=EntityCollided(a\entity,USERT) If player<>0 user_H=user_H-1 Else a\ last_damage_time=0 EndIf ;====== [/highlight] и далее в блоке If player<>0 [highlight=blitzbasic] If a\last_damage_time=-1 a\last_damage_time=MilliSecs() EndIf [/highlight] Если мы фиксируем акт соприкосновения первый раз (так сказать "локально" - т.е. в прошлом обновлении коллизии не было, а перед этим соприкосновений могло быть лююбое кол-во), то сохраняем в поле время, прошедшее с начала соприкосновения (а далее - время, с последнего обновления события, влекующего сосприкосновение - т.е. время прошлого "удара"). Вообще говоря, факт коллизии будет зафиксирован при вызове UpdateWorld(), т.е. время, прошедешее с акта коллизии до обработки этого факта в функции обновления бота весьма мало. Но всё же, не "пренебрежимо мало", особенно если частота UpdateWorld и функций обновления бота сильно разняться. Но для данного примера это не критично (в описанном выше случае надо или логику вызвать вместе с UpdateWorld или искать иные пути - зависит от конкретики реализации стабилизации и логики мира) [highlight=blitzbasic] If MilliSecs()-a\last_damage_time>1000 user_H=user_H-1 a\last_damage_time=MilliSecs() EndIf [/highlight] Ну и как завершающий штрих - сделаем силу урона произвольной (из диапазона): [highlight=blitzbasic] Function update_bot() Rdist#=15 v#=0.01 For a.bot=Each bot ;= If a\time=0 a\time=MilliSecs() new_time=MilliSecs() delta_t=new_time-a\time a\time=new_time ;= If EntityDistance(user,a\entity)<Rdist# PointEntity a\entity,user EntityColor a\entity,255,0,0 Else EntityColor a\entity,255,255,255 If EntityDistance(a\entity,a\point)<2 PositionEntity a\point,EntityX(a\point)+Rnd(-40,40),EntityY(a\point),EntityZ(a\point)+Rnd(-40,40) EndIf PointEntity a\entity,a\point EndIf ;=========== player=EntityCollided(a\entity,USERT) If player<>0 If a\last_damage_time=-1 a\last_damage_time=MilliSecs() EndIf If MilliSecs()-a\last_damage_time>1000 user_H=user_H-Rand(1,7) a\last_damage_time=MilliSecs() EndIf Else a\ last_damage_time=-1 EndIf ;====== MoveEntity a\entity,0,0,v#*delta_t TranslateEntity user,0,-G#*delta_t,0 Next End Function [/highlight] |
Re: Создаём свой FPS (first person shooter)
Вложений: 2
Вот - код и все ресурсы к нему. В коде GoodWin (спс. за старание) я не нашёл временной паузы между нанесением поврежденй игроку - весьма обидное упущение. В моей заметке это есть :@
ATTENTION! Если вы скачивали сегодня уже этот архив, то перекачайте - в коде была допущена некритичная (но всё же!) неточность. |
Re: Создаём свой FPS (first person shooter)
Думаю следующий урок будет "научим Бота стрелять!"
всем это будет интересно и мне тоже.... ждемс.... Цитата:
Цитата:
|
Re: Создаём свой FPS (first person shooter)
Боевая система
Сделаем несколько типов оружия. Модифицируем систему. [highlight=blitzbasic] Type shot Field entity Field dist# Field time Field class_id%;здесь будет хранится инфа о классе снаряда(патрона) End Type [/highlight] Визуализация снаряда зависит от его класса [highlight=blitzbasic] Function create_Shot(x#,y#,z#,pitch#,yaw#,roll#,class%=1) s.shot=New shot s\class_id=class Local shot_sprite_handle=shot_spriteS(s\class_id) s\entity=CopyEntity(shot_sprite_handle) PositionEntity s\entity,x#,y#,z#,1 EntityType s\entity,SHOTT RotateEntity s\entity,pitch#,yaw#,roll#,1 Return True End Function [/highlight] shot_spriteS - это будет наш массив с образцами спрайтов [highlight=blitzbasic] Global pricel=LoadImage("pricel.bmp") Dim shot_spriteS(2);инициализация For i=0 To 1;загрузка shot_spriteS(i)=LoadSprite("sprite"+i+".bmp") Next Global orient_sprite=LoadSprite("orient.bmp") [/highlight] А вот это - нафик [highlight=blitzbasic] Function create_world() light=CreateLight() RotateEntity light,90,0,0 HideEntity shot_sprite; уже не катит :) [/highlight] Скрывать будем сразу после загрузки: [highlight=blitzbasic] For i=0 To 1 shot_spriteS(i)=LoadSprite("sprite"+i+".bmp") HideEntity shot_spriteS(i) Next [/highlight] Так теперь переименуйте файл со спрайтом выстрела в sprite0 и найдите ещё один (отличный от имеющегося) спрайт - назовите его sprite1. Подправим функцию обновления игрока: [highlight=blitzbasic] If MouseHit(2) And MilliSecs()-last_shot_time>shot_delay user_gun=FindChild(GUN,"END") create_shot(EntityX(user_gun,1),EntityY(user_gun,1 ),EntityZ(user_gun,1),EntityPitch(camera),EntityYa w(user),0) last_shot_time=MilliSecs() EndIf If MouseHit(1) user_gun=FindChild(GUN,"END") create_shot(EntityX(user_gun,1),EntityY(user_gun,1 ),EntityZ(user_gun,1),EntityPitch(camera),EntityYa w(user),0,1) EndIf [/highlight] В зависимости от того что нажато (ЛКМ или ПКМ), производится выстрел из 1ого или 2ого оружия. Уже можно псмотреть результаты работы. Далее. И вот тут начинаешь задумываться: у различного оружия - разлиные характеристики (глубокая мысль). Надо как-то оценивать дальность стрельбы, урон, особенности траектории и прочее... Эх - создаём ещё один информационный тип: [highlight=blitzbasic] Type SHOT_TYPE Field sprite Field damage Field max_dist Field v# End Type [/highlight] Самое мерзкое (так делать не надо!) описываем в коде характеристики оружия. В реальных играх это должно хранится в конфигурационных файлах и загружаться специальной функцией. [highlight=blitzbasic] Dim shot_S.SHOT_TYPE(2) For i=0 To 1 shot_S(i)=New SHOT_TYPE Next shot_S(0)\sprite=LoadSprite("sprite0.bmp") HideEntity shot_S(0)\sprite shot_S(0)\damage=95 shot_S(0)\max_dist=100 shot_S(0)\v=0.3 shot_S(1)\sprite=LoadSprite("sprite1.bmp") HideEntity shot_S(1)\sprite shot_S(1)\damage=10 shot_S(1)\max_dist=1000 shot_S(1)\v=0.1 [/highlight] Характеристики зависят от конкретики игры ( можно хоть мат.дисперсию величины повреждения записать). Не забудьте удалить старый код - с массивом под спрайты. [highlight=blitzbasic] Function create_Shot(x#,y#,z#,pitch#,yaw#,roll#,class%=1) s.shot=New shot s\class_id=class s\entity=CopyEntity(shot_S(s\class_id)\sprite) PositionEntity s\entity,x#,y#,z#,1 EntityType s\entity,SHOTT RotateEntity s\entity,pitch#,yaw#,roll#,1 Return True End Function [/highlight] ну и правим обновление снарядов: [highlight=blitzbasic] Function update_shot() For a.shot=Each shot ;= If a\time=0 a\time=MilliSecs() new_time=MilliSecs() delta_t=new_time-a\time a\time=new_time vs#=shot_S(a\class_id)\v*delta_t ;= MoveEntity a\entity,0,0,vs# a\dist#=a\dist#+vs# Local copy_a_class_id=a\class_id bot_h=EntityCollided(a\entity,BOTT) If a\dist#>shot_S(a\class_id)\max_dist FreeEntity a\entity Delete a ElseIf EntityCollided(a\entity,TERRT)<>0 FreeEntity a\entity Delete a ElseIf bot_h<>0 FreeEntity a\entity Delete a bhandle=EntityName(bot_h) bc.bot=Object.bot(bhandle) bc\Survivability=bc\Survivability-shot_S(copy_a_class_id)\damage ;= PositionEntity bc\point,EntityX(user,1),EntityY(bc\point,1),Entit yZ(user,1) ;= If bc\Survivability<=0 Delete bc FreeEntity bot_h create_bot(EntityX(user)+Rnd(-100,100),2,EntityZ(user)+Rnd(-100,100)) EndIf EndIf Next End Function [/highlight] Запускаем - играем. ГГ... Теперь даже тактика есть: заманить противника на себя из слабого быстроперезаряжаемого оружия а потом, вблизи, замочить из СуперПушки с одного залпа =) |
Re: Создаём свой FPS (first person shooter)
Вложений: 4
Я так смотрю - архив качают :-)
А значит мои коды не лишены смысла - это приятно. В архиве - модифицированный код со всеми ресурсами B) |
Re: Создаём свой FPS (first person shooter)
Для полноценности надо сделать HUD.
|
Часовой пояс GMT +4, время: 08:26. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot