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

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

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

2D-программирование Вопросы, касающиеся двумерного программирования

Ответ
 
Опции темы
Старый 31.05.2014, 13:44   #1
polopok
ПроЭктировщик
 
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений
(для 71 пользователей)
простой ray casting 2d array hit

Думаю и этот код будет полезен ...

Код в Offtop :
ttt = CreateTimer(60)
;SeedRnd(MilliSecs())
Const numT=10 , sizeT = 20
Dim AA(numT*numT,numT*numT)

Graphics 640,480 
SetBuffer BackBuffer() 


x2#=130 :y2#=130
x1 =x2 : y1=y2

For b =0 To numT
	For a =0 To numT
	 AA(a,b) = Rnd (1 ) 
		
	Next
Next
While Not KeyHit(1) 
Cls ; Сначала очищаем экран 
x2 =MouseX() : y2=MouseY()
CamFOV#= (180+ATan2(x1-x2,y1-y2))
If MouseHit(1) Then x1 =MouseX() : y1=MouseY()

 
WaitTimer(ttt)
For angle#= 0 To 360 Step 2
 x3# = 40+200*Sin#(angle)
  y3# = 150+200*Cos#(angle)
 line2(40,150,x3,y3,25,25,125)
Next
For angle#= 30 To -30 Step -0.09
 x2# = x1+200*Sin#(CamFOV-angle)
  y2# = y1+200*Cos#(CamFOV-angle)

 line2(x1,y1,x2,y2,255,25,25)


Next

For b =0 To numT
	For a =0 To numT
		If AA(a,b) = 1 Then Rect a*sizeT ,b*sizeT ,sizeT  ,sizeT  ,0
		If AA(a,b) = 2 Then Rect a*sizeT ,b*sizeT ,sizeT  ,sizeT  ,1
		If AA(a,b) = 2 Then AA(a,b) = 1
	Next
Next

Line x1,y1,x2,y2
Line x1,y1,x1+200*Sin(CamFOV-30),y1+200*Cos(CamFOV-30)
Line x1,y1,x1+200*Sin(CamFOV),y1+200*Cos(CamFOV)
Flip ; Меняем буфер 
Wend 
FreeTimer(tttt)
End



Function line2(x1#,y1#,x2#,y2#,red=-1,green=-1,blue=-1)
	Local StopLine = 0
     If red>0 And green=-1
          rgb=red
     Else If red=-1
         rgb = ColorBlue() Or ( ColorGreen() Shl 8) Or ( ColorRed() Shl 16)
     Else 
          rgb=blue Or (green Shl 8) Or (red Shl 16)
     EndIf

     xd#=x2-x1
     yd#=y2-y1
     If Abs(xd)>Abs(yd) steps=Abs(xd) Else steps=Abs(yd)
     x2=xd/Float(steps)
     y2=yd/Float(steps)

 ;   For Stepr=steps To 1 Step -1
	While Not (x1=x2 And y1=y2) Or ( (StopLine = 1)) Or  (Not ( x1 <=( numT*sizeT+sizeT) And y1 <=(numT*sizeT+sizeT) And x1>-2 And y1>-2)) 
         WritePixel x1,y1,rgb
	x =  Floor(x1/sizeT) : y= Floor(y1/sizeT)
	If  ( x   <=numT And y    <=numT  And x   >=0 And y  >=0)
		If AA(x,y) =1 Or AA(x,y) =2 Then 
		AA(x,y) =2 
		StopLine = 1 
		 Exit 
		EndIf
	EndIf
      x1=x1+x2
      y1=y1+y2
  ;   Next
Wend

End Function

Другой вариант :
;
ttt = CreateTimer(120)
;SeedRnd(MilliSecs())
Const numT=10 , sizeT = 20
Dim AA(numT*numT,numT*numT)

Graphics 800,600,32,2
SetBuffer BackBuffer()


x2#=130 :y2#=130
x1# =x2 : y1#=y2

For b =0 To numT
	For a =0 To numT
	 AA(a,b) = Rnd (1 ) 
		
	Next
Next
While Not KeyHit(1)
Cls 
x2 =MouseX() : y2=MouseY()
If MouseDown(1) Then x1 =MouseX() : y1=MouseY()


WaitTimer(ttt)

RayCast2d(x1,y1,x2,y2)

For b =0 To numT
	For a =0 To numT
		If AA(a,b) = 1 Then Rect a*sizeT ,b*sizeT ,sizeT  ,sizeT  ,0
		If AA(a,b) = 2 Then Rect a*sizeT ,b*sizeT ,sizeT  ,sizeT  ,1
		If AA(a,b) = 2 Then AA(a,b) = 1
	Next
Next

Flip 
Wend
FreeTimer(tttt)
End 

Function RayCast2d(x1#,y1#,x2,y2)
	Local count,StopLine,angle#
	dx# = x1-x2
	dy#= y1-y2
	a# = 180+ATan2(dy,dx) ; 

For angle#= 30 To -30 Step -0.5
	vx# = Cos(a+angle)
	vy#= Sin(a+angle)	
	x0#= x1
	y0#=y1
	count=0 : StopLine =0
	While (count<100) Or (StopLine = 1 )
         WritePixel x0,y0,$00ffff
		x =  Floor(x0/sizeT) : y= Floor(y0/sizeT)
		If  ( x   <=numT And y    <=numT  And x   >=0 And y  >=0)
			If AA(x,y) =1 Or AA(x,y) =2 Then 
			AA(x,y) =2 
			StopLine = 1 
			 Exit 
			EndIf
	EndIf
		x0# = (x0#+vx)
		y0# =(y0#+vy)
		 count=count+1
	Wend 
Next
End Function
__________________
Мой проект здесь

Последний раз редактировалось polopok, 31.05.2014 в 15:25. Причина: дополнение
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо polopok за это полезное сообщение:
LLI.T.A.L.K.E.R. (31.05.2014), St_AnGer (02.06.2014)
Старый 31.05.2014, 18:27   #2
LLI.T.A.L.K.E.R.
Мастер
 
Аватар для LLI.T.A.L.K.E.R.
 
Регистрация: 24.06.2009
Адрес: Набережные Челны
Сообщений: 930
Написано 292 полезных сообщений
(для 504 пользователей)
Ответ: простой ray casting 2d array hit

Приложу картинки:
1 пример: синие лучи - обзор 360*, красные лучи - направляющий обзор, белые кубики - попадающие в препятствие перед лучами.


2 пример: лучи - с ограниченной дистанцией дальности обзора
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
moka (02.06.2014)
Старый 02.06.2014, 21:10   #3
polopok
ПроЭктировщик
 
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений
(для 71 пользователей)
Ответ: простой ray casting 2d array hit

Ну типо камера обзора 2д


Const RotateSpeed# = 5 , MoveSpeed# = 1
Global angleViewX# , angleViewY#

ttt = CreateTimer(120)
;SeedRnd(MilliSecs())
Const numT=10 , sizeT = 20
Dim AA(numT*numT,numT*numT)

Graphics 800,600,32,2
SetBuffer BackBuffer()


camPosX#=300
camPosY#=200
angleView#= 180

For b =0 To numT
	For a =0 To numT
	 AA(a,b) = Rnd (1 ) 
		
	Next
Next
While Not KeyHit(1)
Cls 
;x2 =MouseX() : y2=MouseY()

If KeyDown(205) Then angleView#  = angleView# +RotateSpeed  ; RIGHT
If KeyDown(203) Then angleView#  = angleView# -RotateSpeed   ; LEFT
If KeyDown(200) Then camPosX#  = camPosX# +MoveSpeed*angleViewX :  camPosY#  = camPosY# +MoveSpeed*angleViewY  ; DOWN
If KeyDown(208) Then camPosY#  = camPosY# +MoveSpeed* -angleViewY  :  camPosX#  = camPosX# +MoveSpeed* -angleViewX  ; UP

WaitTimer(ttt)

View2D(camPosX#,camPosY#,angleView#,offset=4)

For b =0 To numT
	For a =0 To numT
		If AA(a,b) = 1 Then Rect a*sizeT ,b*sizeT ,sizeT  ,sizeT  ,0
		If AA(a,b) = 2 Then Rect a*sizeT ,b*sizeT ,sizeT  ,sizeT  ,1
		If AA(a,b) = 2 Then AA(a,b) = 1
	Next
Next

text 500,50,"Управляем стрелками клавитуры "

Flip 
Wend
FreeTimer(tttt)
End 


Function View2D#(camPosX#,camPosY#,angleView#,direction = 100)
	IangleView =angleView  Mod 360
	newDirection# =  direction *0.6
	angleViewX# =Cos(angleView )
	angleViewY#= Sin(angleView )
		
	For CV# = 30 To -30 Step -1
	camDirX# =camPosX
	camDirY# =camPosY	
		vd	=0
		While vd < (direction)
				angleViewX1# =Cos(angleView-CV )
				angleViewY1#= Sin(angleView-CV )
				
				x =  Floor(camDirX/sizeT) : y= Floor(camDirY/sizeT)
				If  ( x   <=numT And y    <=numT  And x   >=0 And y  >=0)
					If AA(x,y) =1 Or AA(x,y) =2 Then 
					AA(x,y) =2 
					StopLine = 1 
					 Exit 
					EndIf
				EndIf	
				
				WritePixel camDirX ,camDirY,$666600
				camDirX# =camDirX+offset*angleViewX1
				camDirY# =camDirY+offset*angleViewY1	
			vd = vd +offset			
		Wend 
	Next  
	Line camPosX,camPosY,camPosX+direction*Cos(angleView ),camPosY+direction*Sin(angleView )
	Line camPosX,camPosY,camPosX+direction*Cos(angleView-30 ),camPosY+direction*Sin(angleView-30 )
	Line camPosX,camPosY,camPosX+direction*Cos(angleView- -30 ),camPosY+direction*Sin(angleView- -30 )
End Function
__________________
Мой проект здесь

Последний раз редактировалось polopok, 02.06.2014 в 21:17. Причина: дополнение
(Offline)
 
Ответить с цитированием
Старый 02.06.2014, 21:28   #4
LLI.T.A.L.K.E.R.
Мастер
 
Аватар для LLI.T.A.L.K.E.R.
 
Регистрация: 24.06.2009
Адрес: Набережные Челны
Сообщений: 930
Написано 292 полезных сообщений
(для 504 пользователей)
Ответ: простой ray casting 2d array hit

линии направления не отображаются

попробовал так Line 0,0,camPosX+direction*Cos(angleView ),camPosY+direction*Sin(angleView )
и точка направлена в точку позиции камеры (а не куда должна глядеть камера)

надо вычисления концов линий починить

(я делал на Delphi подобное, но сейчас могу заняться поправкой)

в общем приписал
direction=100
Line camPosX,camPosY,camPosX+direction*Cos(angleView ),camPosY+direction*Sin(angleView )
и норм

для чего тогда newDirection ? и тут же View2D(offset) и View2D(direction)
(Offline)
 
Ответить с цитированием
Старый 02.06.2014, 21:59   #5
polopok
ПроЭктировщик
 
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений
(для 71 пользователей)
Ответ: простой ray casting 2d array hit

newDirection просто не удалил из кода ,а offset - это смещение шага луча
__________________
Мой проект здесь
(Offline)
 
Ответить с цитированием
Старый 02.06.2014, 23:01   #6
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Ответ: простой ray casting 2d array hit

Делал давно, используя тригонометрию а не raycast. Тут 800+ отрезков, никаких оптимизаций.
http://moka.co/shadows/
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо moka за это полезное сообщение:
LLI.T.A.L.K.E.R. (03.06.2014), polopok (02.06.2014)
Старый 02.06.2014, 23:07   #7
polopok
ПроЭктировщик
 
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений
(для 71 пользователей)
Ответ: простой ray casting 2d array hit

что -то вроде пересечения отрезка с отрезком или нормаи? Или проекцией на вектор?
__________________
Мой проект здесь
(Offline)
 
Ответить с цитированием
Старый 02.06.2014, 23:52   #8
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Ответ: простой ray casting 2d array hit

Находим отрезки в радиусе, кастуем два отрезка к концам кастера, продолжаем два отрезка до квадрата который описывает радиус источника света, и добовляем вершин чтобы прилегал массив вершин к прямоугольнику. Для оптимизации можно объединять стрипы от каждого кастера, и проверять если кастер вообще попал в видимость.
Также мягкие тени не сложно сделать с таким подходом.
(Offline)
 
Ответить с цитированием
Старый 03.06.2014, 11:03   #9
LLI.T.A.L.K.E.R.
Мастер
 
Аватар для LLI.T.A.L.K.E.R.
 
Регистрация: 24.06.2009
Адрес: Набережные Челны
Сообщений: 930
Написано 292 полезных сообщений
(для 504 пользователей)
Ответ: простой ray casting 2d array hit

Сообщение от polopok Посмотреть сообщение
newDirection просто не удалил из кода ,а offset - это смещение шага луча
просто хочу сказать-показать, что не отображается желаемое
(Offline)
 
Ответить с цитированием
Старый 03.06.2014, 21:22   #10
polopok
ПроЭктировщик
 
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений
(для 71 пользователей)
Ответ: простой ray casting 2d array hit

Сообщение от moka Посмотреть сообщение
Находим отрезки в радиусе, кастуем два отрезка к концам кастера, продолжаем два отрезка до квадрата который описывает радиус источника света, и добовляем вершин чтобы прилегал массив вершин к прямоугольнику. Для оптимизации можно объединять стрипы от каждого кастера, и проверять если кастер вообще попал в видимость.
Также мягкие тени не сложно сделать с таким подходом.
Нашёл пример 2d light & shadow
__________________
Мой проект здесь
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
LLI.T.A.L.K.E.R. (03.06.2014)
Старый 03.06.2014, 23:03   #11
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Ответ: простой ray casting 2d array hit

Сообщение от polopok Посмотреть сообщение
Нашёл пример 2d light & shadow
Очень похожий подход, эту демку видел тоже, но она поновее будет. Отличие в том что тут нужно отсортировать все вершины по градусу к источнику и бить их поочередно. Как бы тут есть экономия за счет проверки если не попал по отрезку, но и в моем подходе это реализуемо.

Оба подхода очень быстрые и качественные результаты производят.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
LLI.T.A.L.K.E.R. (04.06.2014)
Ответ


Опции темы

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

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


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


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