Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > BlitzMax

Ответ
 
Опции темы
Старый 22.11.2011, 13:50   #106
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Сообщение от Greymem Посмотреть сообщение
Сижу, читаю. Неужели всё придется делать через EVENT'ы и HOOK'и ?
Тебе ж сказали как - параметр описываешь как заголовок функции, а внутри вызываешь как обычно.
Function ObjTest:Object()
	Print("Hello")
End Function

Function RunObj( Func:Object() )
    Func()
End Function

RunObj(ObjTest)
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Greymem (22.11.2011)
Старый 22.11.2011, 14:31   #107
Greymem
Нуждающийся
 
Регистрация: 31.05.2010
Сообщений: 63
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Благодарю

Кстати, моё незнание того, что объект можно передать как функцию, и так-же её и вызвать. Вовсе не даёт тебе право мне грубить.
__________________
Мозги... у них есть метод "Storm"

Последний раз редактировалось Greymem, 23.11.2011 в 08:16.
(Offline)
 
Ответить с цитированием
Старый 22.11.2011, 16:30   #108
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)


Сообщение от Greymem Посмотреть сообщение
Благодарю
Кстати, моё незнание того, что объект можно передать как функцию, и так-же её и вызвать. Вовсе не даёт тебе право мне грубить.
Что-что? Грубить? Ты мне напомнил мою тещу, которая в каждом слове в ее адрес видит хамство, забавно так.
ЗЫ
И не объект передать как функцию, а указатель на функцию.

Последний раз редактировалось Платон Александрович, 23.11.2011 в 11:31.
(Offline)
 
Ответить с цитированием
Старый 23.11.2011, 08:15   #109
Greymem
Нуждающийся
 
Регистрация: 31.05.2010
Сообщений: 63
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)


Сообщение от Платон Александрович Посмотреть сообщение
Что-что? Грубить? Ты мне напомнил мою тещу, которая в каждом слове в ее адрес видит хамство, забавно так.
ЗЫ
И не объект передать как функцию, а указатель на функцию.

Не хотел? Ну вот и здорово.
Тёща наверное тоже видит (читает) только тогда когда достают постоянными указанием на кажется (указывающему) элементарные вещи, которые человек просто на просто ещё не практиковал.

Кстати "Тебе ж сказали как" фраза не годится, ибо мне не говорили как вызвать функцию, из функции в которую передан указатель

Так что быстренько помечаем всё оффтопом, дабы публике глаза не мазолить.


А за способ спасибо. Всё заработало.
__________________
Мозги... у них есть метод "Storm"
(Offline)
 
Ответить с цитированием
Старый 25.11.2011, 16:23   #110
Greymem
Нуждающийся
 
Регистрация: 31.05.2010
Сообщений: 63
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Очередной трабл.

Пишу мини-ИИ для "баллистического бота" если можно так сказать
Суть в том, что он должен выстрелить снарядом в объект, но в точку в которой объекта ещё нет.

То есть должен просчитать траекторию движения цели, и выстрелить туда, где объект будет через t итераций (обновления объектов)

Вот что известно на входе:
Начальные координаты цели (X1,Y1)
Скорость цели (V1)
Направление движения цели (угол) (a1)

Начальные координаты бота (X2,Y2)
Скорость снаряда бота (V2)


Вот что нужно найти
Угол выстрела (a2)
Через сколько t они встретятся (t)

За одну итерацию координаты цели обновляются следующим образом
X1 = X1+(V1*Cos(a1))
Y1 = Y1+(V1*Sin(a1))
Выпущенный снаряд выходит из точки X2,Y2, и за одну итерацию обновляет свои координаты похожим образом используя скорость V2 и угол направления движения который мы должны найти a2


Снаряд летит только туда, куда его направили, никакие больше силы на снаряд не действует. А Бот стоит на месте.

Вариант решать перебором (начиная от 1 итерации и просчитывать столкнулись или нет - не подходит, так как сейчас именно так и делается и это не дело =))))

В принципе меня устроит только число t в данном случае. Буду знать t, буду знать угол.

В данный момент уже читаю и книгу по физике для комп. игр и краткий курс тригонометрии.
Но пожалуйста, помогите если кто знает.
__________________
Мозги... у них есть метод "Storm"
(Offline)
 
Ответить с цитированием
Старый 25.11.2011, 18:55   #111
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Сообщение от Greymem Посмотреть сообщение
Снаряд летит только туда, куда его направили, никакие больше силы на снаряд не действует. А Бот стоит на месте.
Это довольно просто
дистанция = | координаты_цели - координаты_бота |
время_полета_снаряда_по_прямой = дистанция / скорость_снаряда
упрежденные_координаты_цели = координаты_цели + скорость_цели * время_полета_снаряда_по_прямой

а если нужен именно угол, используй ATan2 с разностью упрежденных_координат_цели и координат_бота
(Offline)
 
Ответить с цитированием
Старый 27.11.2011, 10:46   #112
Greymem
Нуждающийся
 
Регистрация: 31.05.2010
Сообщений: 63
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Сообщение от Платон Александрович Посмотреть сообщение
Это довольно просто
дистанция = | координаты_цели - координаты_бота |
время_полета_снаряда_по_прямой = дистанция / скорость_снаряда
упрежденные_координаты_цели = координаты_цели + скорость_цели * время_полета_снаряда_по_прямой

а если нужен именно угол, используй ATan2 с разностью упрежденных_координат_цели и координат_бота
Спс, данные операции я итак сейчас проделываю, только если скорость цели=0. Тогда можно смело запускать снаряд туда, где цель сейчас и стоит. Там уже нам t ненужно, ибо все равно они столкнуться когданибудь.

Но если цель подвижна (с постоянной скоростью и углом направления) данный алгоритм уже не годится. Ибо сначала надо расчитать куда стрелять чтобы они столкнулись

Сообщение от Платон Александрович Посмотреть сообщение
упрежденные_координаты_цели = координаты_цели + скорость_цели * время_полета_снаряда_по_прямой
Опять таки время полёта в данном случае это время полета снаряда до той координаты где БЫЛА цель. А цель то перемещается. =(
__________________
Мозги... у них есть метод "Storm"
(Offline)
 
Ответить с цитированием
Старый 27.11.2011, 13:41   #113
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Greymem
вот такой итеративный алгоритм вроде работает:

1) расчетная_позиция = позиция_цели
2) дистанция = |расчетная_позиция - позиция_бота|
3) время_полета = дистанция / скорость_снаряда
4) упрежденная_позиция = позиция_цели + скорость_цели * время_полета

пункты 2,3,4 повторить несколько раз

некогда все грамотно расписывать, поэтому глянь эту говнодемку
при 5 итерациях ~60% попаданий, но это из-за того что цель отскакивает от стен, т.е. меняет направление когда выстрел уже произошел.

SuperStrict

Framework BRL.Blitz
Import BRL.Math
Import BRL.LinkedList
Import BRL.KeyCodes
Import BRL.GLMax2D

Type TBullet
	
	Field Link:TLink
	
	Field Force:Int
	
	Field PositionX:Float
	Field PositionY:Float
	
	Field DirectionX:Float
	Field DirectionY:Float
	
End Type

Const BulletSpeed:Float = 5

Local Bullets:TList = CreateList()

Local TargetPositionX:Float = 100
Local TargetPositionY:Float = 100

Local TargetDirectionX:Float = Sin(45)
Local TargetDirectionY:Float = Cos(45)

Const TargetSpeed:Float = 3

Local BotPositionX:Float = 400
Local BotPositionY:Float = 300

Local TicksCount:Int = 0

Local ShootTick:Int = 0

Local ShotsCount:Int = 0
Local HitsCount:Int = 0

Graphics(800, 600)

Repeat
	
	TicksCount :+ 1
	
	' движение цели
	
	TargetPositionX :+ TargetDirectionX * TargetSpeed
	TargetPositionY :+ TargetDirectionY * TargetSpeed
	
	' отскок от стен
	
	If TargetPositionX < 0 Then
		TargetPositionX = 0
		TargetDirectionX = -TargetDirectionX
	End If
	
	If TargetPositionX >= 800 Then
		TargetPositionX = 800 - 1
		TargetDirectionX = -TargetDirectionX
	End If
	
	If TargetPositionY < 0 Then
		TargetPositionY = 0
		TargetDirectionY = -TargetDirectionY
	End If
	
	If TargetPositionY >= 600 Then
		TargetPositionY = 600 - 1
		TargetDirectionY = -TargetDirectionY
	End If
	
	' стрельба
	
	If TicksCount >= ShootTick Then
		
		ShootTick = TicksCount + 10
		
		ShotsCount :+ 1
		
		' расчет упреждения
		
		Local DeflexionX:Float = TargetPositionX
		Local DeflexionY:Float = TargetPositionY
		
		Local TargetVelocityX:Float = TargetDirectionX * TargetSpeed
		Local TargetVelocityY:Float = TargetDirectionY * TargetSpeed
		
		For Local ComputingPass:Int = 1 To 5
			
			Local DeltaX:Float = DeflexionX - BotPositionX
			Local DeltaY:Float = DeflexionY - BotPositionY
			
			Local Distance:Float = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
			
			Local Time:Float = Distance / BulletSpeed
			
			DeflexionX = TargetPositionX + TargetVelocityX * Time
			DeflexionY = TargetPositionY + TargetVelocityY * Time
			
		Next
		
		' выстрел
		
		Local Bullet:TBullet = New TBullet
		
		Bullet.Link = Bullets.AddLast(Bullet)
		
		Local DeltaX:Float = DeflexionX - BotPositionX
		Local DeltaY:Float = DeflexionY - BotPositionY
		
		Local Distance:Float = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
		
		Bullet.DirectionX = DeltaX / Distance
		Bullet.DirectionY = DeltaY / Distance
		
		Bullet.PositionX = BotPositionX
		Bullet.PositionY = BotPositionY
		
		Bullet.Force = 100
		
	End If
	
	' обновление пуль
	
	For Local Bullet:TBullet = EachIn Bullets
		
		If Bullet.Force <= 0 Then
			
			Bullet.Link.Remove()
			
			Continue
			
		End If
		
		' полет
		
		Bullet.Force :- 1
		
		Bullet.PositionX :+ Bullet.DirectionX * BulletSpeed
		Bullet.PositionY :+ Bullet.DirectionY * BulletSpeed
		
		' проверка на попадание в цель
		
		Local DeltaX:Float = TargetPositionX - Bullet.PositionX
		Local DeltaY:Float = TargetPositionY - Bullet.PositionY
		
		Local Distance:Float = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
		
		If Distance <= 8 Then
			
			HitsCount :+ 1
			
			Bullet.Link.Remove()
			
		End If
		
	Next
	
	' отрисовка
	
	Cls()
	
	SetColor(0, 255, 0)
	
	DrawOval(BotPositionX - 8, BotPositionY - 8, 16, 16)
	
	SetColor(255, 0, 0)
	
	DrawOval(TargetPositionX - 8, TargetPositionY - 8, 16, 16)
	
	SetColor(255, 255, 0)
	
	For Local Bullet:TBullet = EachIn Bullets
		
		DrawOval(Bullet.PositionX - 3, Bullet.PositionY - 3, 6, 6)
		
	Next
	
	SetColor(255, 255, 255)
	
	DrawText(String.FromInt(HitsCount * 100 / ShotsCount) + "%", 10, 10)
	
	Flip()
	
Until KeyDown(KEY_ESCAPE)

End

Последний раз редактировалось Платон Александрович, 27.11.2011 в 14:52. Причина: опечатки
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Greymem (28.11.2011)
Старый 28.11.2011, 07:33   #114
Greymem
Нуждающийся
 
Регистрация: 31.05.2010
Сообщений: 63
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Найс, очень полезно и прикольно.

Не понятно только зачем нужен цикл. =)
For Local ComputingPass:Int = 1 To 5
Но при его отсутствии пули летят не в центр цели =) и иногда пролетают мимо
Мистика =)


К сожалению в данном примере направление X и Y довольно сильно различаются.
Как сделать те-же самые расчеты используя только одну переменную направления?
- Сделано

Как установить угол выстрела на координату я уже знаю
Осталось заранее узнать координату в которой они столкнуться.
- Сделано.

Вот переделал на использование одного поля "Direction" для пули
Правда подлагивает, подёргивает (интересно из-за чего?)
Но вроде работает, ХЗ, может ещё что неправильно, посмотрите плиз.

SuperStrict

Framework BRL.Blitz
Import BRL.Math
Import BRL.LinkedList
Import BRL.KeyCodes
Import brl.GLMax2D

Function GetRange:Int(x1:Int, x2:Int, y1:Int, y2:Int)
Return Sqr(((x1 - x2) ^ 2) + ((y1 - y2) ^ 2)) ;
End Function

Function Strike_Angle:Double(x0:Double, y0:Double, x1:Double, y1:Double)
	Return ATan2(y1 - y0, x1 - x0) ;
End Function


Type TBullet
	
	Field Link:TLink
	
	Field Force:Int
	
	Field PositionX:Float
	Field PositionY:Float
	
	'= = ОРИГИНАЛЬНЫЙ КОД = =
	'Field DirectionX:Float
	'Field DirectionY:Float
	' = = = = = = = = = = = =
	
	Field Direction:Float;
	
End Type

Const BulletSpeed:Float = 4

Local Bullets:TList = CreateList()

Local TargetPositionX:Float = 100
Local TargetPositionY:Float = 100

Local TargetDirectionX:Float = Sin(45)
Local TargetDirectionY:Float = Cos(45)

Const TargetSpeed:Float = 1

Local BotPositionX:Float = 400
Local BotPositionY:Float = 300

Local TicksCount:Int = 0

Local ShootTick:Int = 0

Local ShotsCount:Int = 0
Local HitsCount:Int = 0

Graphics(800, 600)

Repeat
	
	TicksCount :+ 1
	
	' движение цели
	
	TargetPositionX :+ TargetDirectionX * TargetSpeed
	TargetPositionY :+ TargetDirectionY * TargetSpeed
	
	' отскок от стен
	
	If TargetPositionX < 0 Then
		TargetPositionX = 0
		TargetDirectionX = -TargetDirectionX
	End If
	
	If TargetPositionX >= 800 Then
		TargetPositionX = 800 - 1
		TargetDirectionX = -TargetDirectionX
	End If
	
	If TargetPositionY < 0 Then
		TargetPositionY = 0
		TargetDirectionY = -TargetDirectionY
	End If
	
	If TargetPositionY >= 600 Then
		TargetPositionY = 600 - 1
		TargetDirectionY = -TargetDirectionY
	End If
	
	' стрельба
	
	If TicksCount >= ShootTick Then
		
		ShootTick = TicksCount + 10
		
		ShotsCount :+ 1
		
		' расчет упреждения
		
		Local DeflexionX:Float = TargetPositionX
		Local DeflexionY:Float = TargetPositionY
		
		Local TargetVelocityX:Float = TargetDirectionX * TargetSpeed
		Local TargetVelocityY:Float = TargetDirectionY * TargetSpeed
		
		For Local ComputingPass:Int = 1 To 5
			' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = = =
			'Local DeltaX:Float = (DeflexionX - BotPositionX)
			'Local DeltaY:Float = (DeflexionY - BotPositionY)
			' = = = = =  = = = = = = = = = = = = = = = = = = =
			
			Local Distance:Float = GetRange(BotPositionX, TargetPositionX, BotPositionY, TargetPositionY)
			Local Time:Float = Distance / BulletSpeed
			
			DeflexionX = TargetPositionX + TargetVelocityX * Time
			DeflexionY = TargetPositionY + TargetVelocityY * Time
			
		Next
		
		' выстрел
		
		Local Bullet:TBullet = New TBullet
		
		Bullet.Link = Bullets.AddLast(Bullet)
		
		' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = =  = = = = = = =
		'Local DeltaX:Float = DeflexionX - BotPositionX
		'Local DeltaY:Float = DeflexionY - BotPositionY
		'Local Distance:Float = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
		'Bullet.DirectionX = DeltaX / Distance
		'Bullet.DirectionY = DeltaY / Distance
		' = = = = =  = = = = = = = = = = = = = = = = = =  = = = = = = =
		
		Bullet.Direction = Strike_Angle(BotPositionX, BotPositionY, DeflexionX, DeflexionY)
		Bullet.PositionX = BotPositionX
		Bullet.PositionY = BotPositionY
		
		Bullet.Force = 500
		
	End If
	
	' обновление пуль
	
	For Local Bullet:TBullet = EachIn Bullets
		
		If Bullet.Force <= 0 Then
			
			Bullet.Link.Remove()
			
			Continue
			
		End If
		
		' полет
		
		Bullet.Force :- 1
		
		' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = =  = = = = = = =
		'Bullet.PositionX :+ Bullet.DirectionX * BulletSpeed
		'Bullet.PositionY :+ Bullet.DirectionY * BulletSpeed
		' = = = = =  = = = = = = = = = = = = = = = = = =  = = = = = = =
		
		Bullet.PositionX:+BulletSpeed * Cos(Bullet.Direction) ;
		Bullet.PositionY:+BulletSpeed * Sin(Bullet.Direction) ;
		
		' проверка на попадание в цель
		
		Local DeltaX:Float = TargetPositionX - Bullet.PositionX
		Local DeltaY:Float = TargetPositionY - Bullet.PositionY
		
		Local Distance:Float = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
		
		If Distance <= 8 Then
			
			HitsCount :+ 1
			
			Bullet.Link.Remove()
			
		End If
		
	Next
	
	' отрисовка
	
	Cls()
	
	SetColor(0, 255, 0)
	
	DrawOval(BotPositionX - 8, BotPositionY - 8, 16, 16)
	
	SetColor(255, 0, 0)
	
	DrawOval(TargetPositionX - 8, TargetPositionY - 8, 16, 16)
	
	SetColor(255, 255, 0)
	
	For Local Bullet:TBullet = EachIn Bullets
		
		DrawOval(Bullet.PositionX - 3, Bullet.PositionY - 3, 6, 6)
		
	Next
	
	SetColor(255, 255, 255)
	
	DrawText(String.FromInt(HitsCount * 100 / ShotsCount) + "%", 10, 10)
	
	Flip()
	
Until KeyDown(KEY_ESCAPE)

End
__________________
Мозги... у них есть метод "Storm"

Последний раз редактировалось Greymem, 28.11.2011 в 10:11.
(Offline)
 
Ответить с цитированием
Старый 28.11.2011, 09:50   #115
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Сообщение от Greymem Посмотреть сообщение
Не понятно только зачем нужен цикл. =)
facepalm
ты хоть читаешь что я пишу или сразу код копипастишь?
вот такой итеративный алгоритм вроде работает:
пункты 2,3,4 повторить несколько раз
Каждый цикл увеличивает точность, поэтому нужно несколько раз повторить расчет. Может конечно есть нормальный алгоритм упреждения, но этот работает и пофиг

Сообщение от Greymem Посмотреть сообщение
Как сделать теже самые расчеты используя только одну переменную направления?
Это как? Для двумерного случая вектор направления и должен иметь две компоненты. А если тебе нужна инфа о направлении в одной переменной, то это есть ни что иное как угол А из угла вектор направления извлекается с помощью синуса и косинуса, вот так: X = Sin(Угол), Y = Cos(Угол) (или наоброт, зависит от осей координат)
Иначе говоря в коде расчета, перед циклом, был такой расчет скорости цели:
Local TargetVelocityX:Float = TargetDirectionX * TargetSpeed
Local TargetVelocityY:Float = TargetDirectionY * TargetSpeed
а будет такой
Local TargetVelocityX:Float = Sin(TargetAngle) * TargetSpeed
Local TargetVelocityY:Float = Cos(TargetAngle) * TargetSpeed
где TargetAngle угол направления движения цели

Сообщение от Greymem Посмотреть сообщение
Осталось заранее узнать координату в которой они столкнуться.
Можете помочь?
После цикла расчета переменные DeflexionX и DeflexionY как раз и будут содержать координаты цели где она столкнется с пулей.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Greymem (28.11.2011)
Старый 28.11.2011, 10:11   #116
Greymem
Нуждающийся
 
Регистрация: 31.05.2010
Сообщений: 63
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

А какая гарантия того, что на 5-ом шаге цикла расчеты будут точнее чем на 3-ем?

Код уже готов, вверху.
Можете глянуть, что не так?
__________________
Мозги... у них есть метод "Storm"
(Offline)
 
Ответить с цитированием
Старый 28.11.2011, 10:16   #117
Greymem
Нуждающийся
 
Регистрация: 31.05.2010
Сообщений: 63
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

И еще, при

Const TargetSpeed:Float = 3
и скажем
Const BulletSpeed:Float = 4

Снаряд пулю уже не догонит, хотя мы меняли только скорость цели.
Снаряд должен подстраиваться под цель по-идее
__________________
Мозги... у них есть метод "Storm"
(Offline)
 
Ответить с цитированием
Старый 28.11.2011, 10:22   #118
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Сообщение от Greymem Посмотреть сообщение
А какая гарантия того, что на 5-ом шаге цикла расчеты будут точнее чем на 3-ем?
Ну проверь точность с разной скоростью цели и пуль.
Вообще чем выше скорость пули относительно скорости цели, тем меньше итераций потребуется.
Сообщение от Greymem Посмотреть сообщение
Можете глянуть, что не так?
Вот здесь неверно
GetRange(BotPositionX, TargetPositionX, BotPositionY, TargetPositionY)
Надо не TargetPosition брать, а Deflexion, т.к. я уже говорил что алгоритм итеративный - следующая итерация берет расчет с предыдущей, а у тебя все итерации считают сначала.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Greymem (28.11.2011)
Старый 28.11.2011, 10:39   #119
Greymem
Нуждающийся
 
Регистрация: 31.05.2010
Сообщений: 63
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Сообщение от Платон Александрович Посмотреть сообщение
Надо не TargetPosition брать, а Deflexion, т.к. я уже говорил что алгоритм итеративный - следующая итерация берет расчет с предыдущей, а у тебя все итерации считают сначала.
Готово, так, теперь пули вроде как цель догоняют (разумеется за исключением тех случаев, когда цель вот-вот отскочит или уже отскочила)

Что-то ещё упустили?
__________________
Мозги... у них есть метод "Storm"
(Offline)
 
Ответить с цитированием
Старый 28.11.2011, 12:25   #120
Greymem
Нуждающийся
 
Регистрация: 31.05.2010
Сообщений: 63
Написано 3 полезных сообщений
(для 3 пользователей)
Ответ: Вопрос-Ответ (для новичков BlitzMax)

Вот что получилось, на случай, если кому-нибудь понадобится

SuperStrict

Framework BRL.Blitz
Import brl.Math
Import brl.basic
Import BRL.LinkedList
Import BRL.KeyCodes
Import brl.GLMax2D

Function GetRange:Int(x1:Int, x2:Int, y1:Int, y2:Int)
Return Sqr(((x1 - x2) ^ 2) + ((y1 - y2) ^ 2)) ;
End Function

Function Strike_Angle:Double(x0:Double, y0:Double, x1:Double, y1:Double)
	Return ATan2(y1 - y0, x1 - x0) ;
End Function


Type TBullet
	
	Field Link:TLink
	
	Field PositionX:Float
	Field PositionY:Float
	
	'= = ОРИГИНАЛЬНЫЙ КОД = =
	'Field DirectionX:Float
	'Field DirectionY:Float
	' = = = = = = = = = = = =
	
	Field Direction:Float;
	
End Type

Global BulletSpeed:Float = 1

Local Bullets:TList = CreateList()

Local TargetPositionX:Float = 100
Local TargetPositionY:Float = 100

Local TargetDirectionX:Float = Sin(45)
Local TargetDirectionY:Float = Cos(45)

Global TargetSpeed:Float = 1

Local BotPositionX:Float = 400
Local BotPositionY:Float = 300

Local TicksCount:Int = 0

Local ShootTick:Int = 0

Local ShotsCount:Int = 0
Local HitsCount:Int = 0

Graphics(800, 600)

Repeat
	
	TicksCount :+ 1
	If KeyDown(KEY_UP) Then
		BulletSpeed:+0.1
	ElseIf KeyDown(KEY_DOWN) And BulletSpeed > 0 Then
		BulletSpeed:-0.1
	ElseIf KeyDown(KEY_LEFT) And TargetSpeed > 0 Then
		TargetSpeed:-0.1
	ElseIf KeyDown(KEY_RIGHT)
		TargetSpeed:+0.1
	End If
	
	
	' движение цели
	
	TargetPositionX :+ TargetDirectionX * TargetSpeed
	TargetPositionY :+ TargetDirectionY * TargetSpeed
	
	' отскок от стен
	
	If TargetPositionX < 0 Then
		TargetPositionX = 0
		TargetDirectionX = -TargetDirectionX
	End If
	
	If TargetPositionX >= 800 Then
		TargetPositionX = 800 - 1
		TargetDirectionX = -TargetDirectionX
	End If
	
	If TargetPositionY < 0 Then
		TargetPositionY = 0
		TargetDirectionY = -TargetDirectionY
	End If
	
	If TargetPositionY >= 600 Then
		TargetPositionY = 600 - 1
		TargetDirectionY = -TargetDirectionY
	End If
	
	' стрельба
	
	If Bullets.Count() = 0 And TicksCount >= ShootTick Then
		
		ShootTick = TicksCount + 10
		
		ShotsCount :+ 1
		
		' расчет упреждения
		
		Local DeflexionX:Float = TargetPositionX
		Local DeflexionY:Float = TargetPositionY
		
		Local TargetVelocityX:Float = TargetDirectionX * TargetSpeed
		Local TargetVelocityY:Float = TargetDirectionY * TargetSpeed
		
		For Local ComputingPass:Int = 1 To 5
			' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = = =
			'Local DeltaX:Float = (DeflexionX - BotPositionX)
			'Local DeltaY:Float = (DeflexionY - BotPositionY)
			' = = = = =  = = = = = = = = = = = = = = = = = = =
			
			Local Distance:Float = GetRange(BotPositionX, DeflexionX, BotPositionY, DeflexionY)
			Local Time:Float = Distance / BulletSpeed
			
			DeflexionX = TargetPositionX + TargetVelocityX * Time
			DeflexionY = TargetPositionY + TargetVelocityY * Time
			
		Next
		
		' выстрел
		
		Local Bullet:TBullet = New TBullet
		
		Bullet.Link = Bullets.AddLast(Bullet)
		
		' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = =  = = = = = = =
		'Local DeltaX:Float = DeflexionX - BotPositionX
		'Local DeltaY:Float = DeflexionY - BotPositionY
		'Local Distance:Float = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
		'Bullet.DirectionX = DeltaX / Distance
		'Bullet.DirectionY = DeltaY / Distance
		' = = = = =  = = = = = = = = = = = = = = = = = =  = = = = = = =
		
		Bullet.Direction = Strike_Angle(BotPositionX, BotPositionY, DeflexionX, DeflexionY)
		Bullet.PositionX = BotPositionX
		Bullet.PositionY = BotPositionY
		
	End If
	
	' обновление пуль
	
	For Local Bullet:TBullet = EachIn Bullets
		
		
		'If Bullet.Force <= 0 Or Bullet.PositionX + 8 > GraphicsWidth() Or Bullet.PositionX + 8 < 0 Or Bullet.PositionY + 8 > GraphicsHeight() Or Bullet.PositionY + 8 < 0
		If Bullet.PositionX + 8 > GraphicsWidth() Or Bullet.PositionX + 8 < 0 Or Bullet.PositionY + 8 > GraphicsHeight() Or Bullet.PositionY + 8 < 0
	
			Bullet.Link.Remove()
			Continue
			
		End If
		
		' полет
		
		' = = = = = = = = = = ОРИГИНАЛЬНЫЙ КОД = = = = =  = = = = = = =
		'Bullet.PositionX :+ Bullet.DirectionX * BulletSpeed
		'Bullet.PositionY :+ Bullet.DirectionY * BulletSpeed
		' = = = = =  = = = = = = = = = = = = = = = = = =  = = = = = = =
		
		Bullet.PositionX:+BulletSpeed * Cos(Bullet.Direction) ;
		Bullet.PositionY:+BulletSpeed * Sin(Bullet.Direction) ;
		
		' проверка на попадание в цель
		
		Local DeltaX:Float = TargetPositionX - Bullet.PositionX
		Local DeltaY:Float = TargetPositionY - Bullet.PositionY
		
		Local Distance:Float = Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
		
		If Distance <= 8 Then
			
			HitsCount :+ 1
			
			Bullet.Link.Remove()
			
		End If
		
	Next
	
	' отрисовка
	
	Cls()
	
	SetColor(111, 111, 111) ;
	DrawText("[UP] - Increase bullet speed, [DOWN] - Decrease bullet speed", 40, 5) ;
	DrawText("Bullet speed: " + BulletSpeed, 600, 5) ;
	DrawText("[left] - Increase target speed, [right] - Decrease target speed", 40, 20) ;
	DrawText("Target speed: " + TargetSpeed, 600, 20) ;
	SetColor(0, 255, 0)
	
	DrawOval(BotPositionX - 8, BotPositionY - 8, 16, 16)
	
	SetColor(255, 0, 0)
	
	DrawOval(TargetPositionX - 8, TargetPositionY - 8, 16, 16)
	
	SetColor(255, 255, 0)
	
	For Local Bullet:TBullet = EachIn Bullets
		
		DrawOval(Bullet.PositionX - 3, Bullet.PositionY - 3, 6, 6)
		
	Next
	
	SetColor(255, 255, 255)
	
	DrawText(String.FromInt(HitsCount * 100 / ShotsCount) + "%", 10, 10)
	
	Flip()
	
Until KeyDown(KEY_ESCAPE)

End
__________________
Мозги... у них есть метод "Storm"
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 14:16.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com