Показать сообщение отдельно
Старый 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)
 
Ответить с цитированием