Seite 1 von 1

Entity collision

Verfasst: 26.04.2005 20:39
von benpicco
Gibt es eine Möglichkeit, abzufragen, ob ein entity mit einem 2ddrawing object collidiert?
Ich möchte die Roberter anwählen und durch die gegend schicken können.
Hier mein bisheriger code:

Code: Alles auswählen

InitEngine3D()
#CameraSpeed = 20
#max=10
Dim marked.b(#max)
IncludeFile "Screen3DRequester.pb"
DefType.f KeyX, KeyY, MouseX, MouseY
#RobotMesh    = 2
#RobotTexture = 2
Dim movX.b(#max)
Global x.b
Dim movZ.b(#max)
Dim movY.b(#max)
;TransparentSpriteColor(0,0,0,0)

Add3DArchive("3d\", #PB_3DArchive_FileSystem)

LoadImage(1,"grafic\cursor.bmp")

InitSprite()
InitSprite3D()
Sprite3DQuality(1)
InitKeyboard()
InitMouse()
ClearScreen(0,0,0)
If Screen3DRequester()
AmbientColor(RGB(255,255,255))
CreateMaterial  (0, LoadTexture(0, "Terrain_Texture.jpg"))
AddMaterialLayer(0, LoadTexture(1, "Terrain_Detail.jpg"), 1)
CreateTerrain("Terrain.jpg", MaterialID(0), 5, 1, 5, 4)
FOV = 65
CreateCamera(0, 0, 0, 100, 100)
CameraLocate(0, 500, 800, 400)
CreateCamera(1,0,0,25,20)
CameraLocate(1, 500, 800, 400)
RotateCamera(0,0,-90,0)
RotateCamera(1,0,-90,0)
CameraRenderMode(1,#PB_Camera_Wireframe)
CameraFOV(0,65)
SkyDome("sky.jpg",1)
LoadMesh(#RobotMesh, "Robot.mesh")
LoadTexture(#RobotTexture, "r2skin.jpg")
CreateMaterial(1,TextureID(#RobotTexture))
For x=1 To #max/2
CreateEntity(x,MeshID(#RobotMesh),MaterialID(1))
EntityLocate(x,500,10,300+x*50)
AnimateEntity(x, "Walk")
Next
For x=1 To #max/2
  CreateEntity(x+#max/2,MeshID(#RobotMesh),MaterialID(1))
  EntityLocate(x+#max/2,400,10,300+x*50)
  AnimateEntity(x+#max/2, "Walk")
Next
For x=1 To #max
  movX(x)=3
Next
Fog(RGB(220,220,220),1,1000,1500)
FreeCamera(1)
CreateLight(1,RGB(255,0,0),400,0.6,400)
MouseLocate(250,250)
RotateCamera(0,0,30,0)
mov=3
;MessageRequester("info","sceenhight:"+Str(ScreenHeight)+" ScreenWitdh:"+Str(ScreenWidth))
Repeat
  Screen3DEvents() 
  For x=1 To #max
  If EntityX(x)=>800
    RotateEntity(x,180,0,0)    
   movX(x)=-3
ElseIf EntityX(x)<=250
    movX(x)=3
    RotateEntity(x,180,0,0)  
  EndIf
  If TerrainHeight(EntityX(x),EntityZ(x))>EntityY(x)+1
    movY(x)=3
    If movX(x)>0
 movX(x)=2
    ElseIf movX(x)<0
 movX(x)=-2
    EndIf
  ElseIf TerrainHeight(EntityX(x),EntityZ(x))<EntityY(x)+1
    movY(x)=-3
    If movX(x)>0
 movX(x)=4
    ElseIf movX(x)<0
 movX(x)=-4
    EndIf
  Else
    movY(x)=0
  EndIf
  
  MoveEntity(x,movX(x),movY(x),0)
Next
  
  LightColor(1,RGB(Random(255),Random(255),Random(255))) 
  ExamineMouse()
  CameraLocate(0,CameraX(0),800,CameraZ(0)) 
  KeyX=0
  KeyY=0
  If MouseX()=0
    KeyX = -#CameraSpeed 
    ElseIf MouseX()>=(ScreenWidth-2)
      KeyX = #CameraSpeed 
    EndIf
    
    If MouseY()=0 
      KeyY = -#CameraSpeed 
    ElseIf MouseY()>=(ScreenHeight-2) 
      KeyY = #CameraSpeed 
    EndIf
    
    ExamineKeyboard()
    MouseX = 0
    If KeyboardPushed(#PB_Key_Pad4)
      MouseX=-#CameraSpeed/2
  ElseIf KeyboardPushed(#PB_Key_Pad6)
    MouseX=#CameraSpeed/2
  EndIf
  MouseY=0
  If KeyboardPushed(#PB_Key_Pad2)
    MouseY=-#CameraSpeed/2
  ElseIf KeyboardPushed(#PB_Key_Pad8)
    MouseY=#CameraSpeed/2
  EndIf
  
  If KeyboardPushed(#PB_Key_Up)
    KeyY=-#CameraSpeed*2
  ElseIf KeyboardPushed(#PB_Key_Down)
    KeyY=#CameraSpeed*2
  EndIf
  
  If KeyboardPushed(#PB_Key_Left)
    KeyX=-#CameraSpeed*2
  ElseIf KeyboardPushed(#PB_Key_Right)
    KeyX=#CameraSpeed*2
  EndIf
    If KeyboardPushed(#PB_Key_F12)
      GrabSprite(2,0,0,ScreenWidth,ScreenHeight)
      SaveSprite(2,"Screenshot.bmp")
    EndIf

    Height.f = TerrainHeight(CameraX(0), CameraZ(0))
    If MouseWheel()>0
    FOV - 1 : If FOV < 40:FOV=40:EndIf
  CameraFOV(0,FOV):EndIf
  If MouseWheel()<0
    FOV + 1 : If FOV > 120:FOV=120:EndIf
  CameraFOV(0,FOV):EndIf
  RotateCamera(0, MouseX, MouseY, RollZ)
  MoveCamera  (0, KeyX, -KeyY, 0)
  ;RotateCamera(1, MouseX, 0, RollZ)
  ;MoveCamera  (1, KeyX, -KeyY, 0)
  RenderWorld()
  Screen3DStats()
  If MouseButton(1)=1
    If mark=0
      mark=1
      startX=MouseX()
      startY=MouseY()
      For x=1 To #max
        marked(x)=0
      Next
    EndIf
    
    StartDrawing(ScreenOutput())
    DrawingMode(4)
    Box(startX,startY,MouseX()-startX,MouseY()-startY,RGB(0,255,0))
    StopDrawing()
    
    
  Else
    mark=0
  EndIf 
  StartDrawing(ScreenOutput())
  DrawImage(UseImage(1),MouseX(),MouseY())
  DrawingMode(1)
  FrontColor(255,255,255)
  Locate(1,1)
  DrawText("X:"+Str(CameraX(0)))
  Locate(1,20)
  DrawText("Y:"+Str(CameraY(0)))
  Locate(1,40)
  DrawText("Z:"+Str(CameraZ(0)))
  Locate(1,60)
  DrawText("MausX:"+Str(MouseX()))
  Locate(1,80)
  DrawText("MausY:"+Str(MouseY()))
  StopDrawing()
  ;DisplayTransparentSprite(1,MouseX(),MouseY())
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
EndIf 
Die benötigten dateien sind im Beispielordner (ich möchte sie nicht hochladen, ich hab da wohl grad ein kleines Virenproblem...), die datei curor.bmp gibt´s hier:
Bild
Danke schonmal für die Antwort.

Verfasst: 23.03.2007 18:52
von Scarabol
Jo sehr gute Frage sowas such ich auch noch der Code ist leider murks aber die Frage find ich gut.

Hat nicht schon irgendwer von unseren Hobbygrafikenginebastlern sowas versucht oder Ansätze zu einem Versuch gestartet sowas umzusetzen?

Gruß
Scarabol

Verfasst: 24.03.2007 09:09
von Kaeru Gaman
>> ob ein entity mit einem 2ddrawing object collidiert?

> aber die Frage find ich gut.

die Frage fußt auf falschen Annahmen.

eine Entity kann niemals mit einem 2D-Objekt kollidieren,
(egal ob 2DDrawing oder Sprite auch nicht Sprite3D)
weil sich beide nicht im selben Universum befinden!

eine Entity befindet sich im virtuellen 3D Raum, der "World",
wo sich alle Meshes und Partikel und das Terrain aufhalten.

mittels RenderWorld() wird dieser 3D Raum abgebildet auf die
Kameraebene die durch die Cam-Vektoren definiert ist.

das Bild dieser Kameraebene wird so etwas wie ein Hintergrundsprite und
erst jetzt kommt es mit dem 2D-Raum der anderen 2D-Objekte in berührung.

die Einzige Möglichkeit, die man also hat,
um Interaktion zwischen 2D und 3D zu berechnen,
ist eine Rückrechnung von der Kameraebene in die 3D-World.

Damit man sich da nicht nen Wolf rechnet, geht man meistens
nur von einem Punkt aus, der Mausposition auf dem Screen.

von diesem punkt ausgehend kann man nun einen Strahl in die 3D-World hinein senden,
und prüfen, ob dieser strahl irgendeine Entity berührt.

allerdings muss man dabei auch wieder mitdenken beim programmieren,
schließlich will man ja nachher im spiel vielleicht eine Kampfeinheit
anwählen können auch wenn sie unter einem Baum steht.

Verfasst: 24.03.2007 09:25
von Scarabol
Kannst du mal genauer erklären wie das mit dem senden gehen soll?
Vor allem weiß ich nicht welche Startposition ich nehmen soll.

Gruß
Scarabol

Verfasst: 24.03.2007 14:53
von Kaeru Gaman
startposition ist immer die Camera selber,
für die winkel brauchst du wirklich das FOV, da bist du absolut auf der richtigen Spur. :allright:

...dummerweise ist das sehr aufwendig, wenn man es nachträglich extra macht.
eigentlich sollte das eine grundfunktion der Engine sein,
denn die kennt ja alle transformationen für die abbildung der Kameraebene...

wenn man ne Engine selber schreibt codet man so eine OverEntity-Funktion gleich mit rein...
ich wette, OGRE hat das auch, wurde vielleicht nur vergessen zu wrappen....

Verfasst: 24.03.2007 15:44
von Scarabol
Wo muss ich nach der Funktion suchen?

Kann ich die eventuell selber wrappen?

Gruß
Scarabol

PS
Kennt jemand eine andere Engine wo sowas schon gewrappt ist?

Verfasst: 25.03.2007 10:12
von Vermilion
In der Irrlicht ist sone Funktion die gesucht wird schon eingebaut, is voll cool.

Ich empfehle auch die Irrlicht...

Verfasst: 25.03.2007 11:49
von Scarabol
Ja danke ich kenne Irrlicht allerdings stört mich, das ich dann auf deren Befehle zurückgreifen muss was zum Beispiel das Keyboard oder den Screen angeht, oder lieg ich da jetzt total daneben und hab nix gerafft?

Gruß
Scarabol