2013-05-22 6 views
0

십자선이 가리키는 방향으로 어떻게 쏠 수 있습니까?JMonkey - 십자선 방향으로 촬영

JMonkey 엔진을 사용하여 다른 선박을 쏘기 위해 우주선이 필요한 게임을 만들고 있습니다.

그래서 사용자 입력에 따라 화면에서 (위, 아래, 왼쪽, 오른쪽) 이동할 수있는 십자형을 만들었으므로 사용자는 특정 장소를 겨냥 할 수 있습니다.

이제 나는 십자선이 서있는 방향으로 내 우주선에서 대포를 쏴야합니다.

십자선이 가리키는 곳에서 나는 어떻게 쏜다.

directionXYZ=cam.getDirection(); //Vector3f form 

으로부터 위치를 얻을 수 있습니다 :

Ray ray = new Ray(directionXYZ, positionXYZ); 

다음에 대한 데이터를 수집 할 수 있습니다 : 당신은 레이 캐스팅을 가질 수

positionXYZ=cam.getLocation(); //Vector3f 

당신이 카메라 방향을 얻을 수

답변

3

충돌 :

shootables.collideWith(ray, results) 

여기서 shootable은 "노드"입니다.

마지막으로, 당신이 원하는 것을 확인 :

for (int i = 0; i < results.size(); i++) { 
     // For each hit, we know distance, impact point, name of geometry. 
     float dist = results.getCollision(i).getDistance(); 
     Vector3f pt = results.getCollision(i).getContactPoint(); 
     String hit = results.getCollision(i).getGeometry().getName(); 
     System.out.println("* Collision #" + i); 
     System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away."); 
    } 

jmonkey wiki에서 촬영

1

이 질문의 나의 독서 목적은 (카메라가 커서에 직면하지만, 어디 어디하지 촬영되지 않는 것입니다 화면 중앙에 있음)가 가리키고 있습니다.

이 작업은 cam.getWorldCoordinates(screenPosition, zDepth); 명령을 사용하여 수행 할 수 있습니다. 이는 화면의 screenPosition 지점에서 끝날 공간에서 3D 점을 반환합니다. 따라서 zDepth가 0이고 zDepth가 1 인 점을 바깥 쪽을 향하는 커서 위치에서 만들면 커서가 "끝났습니다"라는 것이 선택됩니다. screen 위치는 창 왼쪽 하단의 픽셀 단위입니다.

이 기술을 사용하는 예제 프로그램은 다음과 같습니다. hello picking의 두 번째 부분을 기반으로합니다.

내 예에서

이 커서가 키보드를 사용하여 이동은 (H는, J는, K, U)하지만 마우스 클릭도 사용될 수있다 (그러나 나는 주변을 두리번을 위해 마우스를 사용하고 있습니다)

import com.jme3.app.SimpleApplication; 
import com.jme3.collision.CollisionResults; 
import com.jme3.font.BitmapText; 
import com.jme3.input.KeyInput; 
import com.jme3.material.Material; 
import com.jme3.math.ColorRGBA; 
import com.jme3.math.Ray; 
import com.jme3.math.Vector2f; 
import com.jme3.math.Vector3f; 
import com.jme3.renderer.RenderManager; 
import com.jme3.scene.Geometry; 
import com.jme3.scene.Node; 
import com.jme3.scene.shape.Box; 

public class Main extends SimpleApplication { 

    public static KeyBindings keyBindings; 
    public Vector2f cursorPosition=new Vector2f(100,100); 
    public Node shootables=new Node(); 

    public Node crossHairNode=new Node(); 

    public static void main(String[] args) { 
     Main app = new Main(); 
     app.start(); 
    } 

    @Override 
    public void simpleInitApp() { 
     //bind keys to move cursor 
     keyBindings=new KeyBindings(inputManager); //for managing keystrokes 
     keyBindings.registerKeyBinding(KeyInput.KEY_SPACE, "fire"); 
     keyBindings.registerKeyBinding(KeyInput.KEY_U, "up"); 
     keyBindings.registerKeyBinding(KeyInput.KEY_J, "down"); 
     keyBindings.registerKeyBinding(KeyInput.KEY_H, "left"); 
     keyBindings.registerKeyBinding(KeyInput.KEY_K, "right"); 

     initGui(); 

     Box b = new Box(Vector3f.ZERO, 2, 2, 2); 
     Geometry geom = new Geometry("BigBox", b); 

     Box b2 = new Box(Vector3f.ZERO, 1, 1, 1); 
     Geometry geom2 = new Geometry("SmallBox", b2); 
     geom2.setLocalTranslation(3, 0, 3); 


     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); 
     mat.setColor("Color", ColorRGBA.Blue); 
     geom.setMaterial(mat); 
     geom2.setMaterial(mat); 
     rootNode.attachChild(shootables); 

     shootables.attachChild(geom); 
     shootables.attachChild(geom2); 
    } 

    @Override 
    public void simpleUpdate(float tpf) { 

     updateCrossHairs(); 

     if (keyBindings.getBinding("fire").hasBecomeTrueSinceLastAccess()){ 
      CollisionResults results = new CollisionResults(); 

      Vector3f cursor3dLocation = cam.getWorldCoordinates(
       new Vector2f(cursorPosition.x, cursorPosition.y), 0f).clone(); 
      Vector3f dir = cam.getWorldCoordinates(
       new Vector2f(cursorPosition.x, cursorPosition.y), 1f).subtractLocal(cursor3dLocation).normalizeLocal(); 
      Ray ray = new Ray(cursor3dLocation, dir); 
      shootables.collideWith(ray, results); 

      if (results.size()>0){ 
       resultsText.setText("Hit: " + results.getClosestCollision().getGeometry().getName()); 
       resultsText.setLocalTranslation(settings.getWidth()-resultsText.getLineWidth(),resultsText.getLineHeight(), 0); 
      }else{ 
       resultsText.setText("Missed"); 
       resultsText.setLocalTranslation(settings.getWidth()-resultsText.getLineWidth(),resultsText.getLineHeight(), 0);     
      } 

     } 



    } 

    private void updateCrossHairs(){ 
     if (keyBindings.getBinding("up").getValue()==true){ 
      cursorPosition.y+=1; 
     } 
     if (keyBindings.getBinding("down").getValue()==true){ 
      cursorPosition.y+=-1; 
     } 

     if (keyBindings.getBinding("left").getValue()==true){ 
      cursorPosition.x+=-1; 
     } 
     if (keyBindings.getBinding("right").getValue()==true){ 
      cursorPosition.x+=+1; 
     } 

     crossHairNode.setLocalTranslation(cursorPosition.x - crossHair.getLineWidth()/2,cursorPosition.y + crossHair.getLineHeight()/2, 0); 

    } 

    BitmapText crossHair; 
    BitmapText instructions; 
    BitmapText resultsText; 

    private void initGui() { 
     setDisplayStatView(false); 
     guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); 
     crossHair = new BitmapText(guiFont, false); 
     crossHair.setSize(guiFont.getCharSet().getRenderedSize() * 2); 
     crossHair.setText("+"); // crosshairs 

     crossHairNode.setLocalTranslation(cursorPosition.x - crossHair.getLineWidth()/2,cursorPosition.y + crossHair.getLineHeight()/2, 0); 


     guiNode.attachChild(crossHairNode); 
     crossHairNode.attachChild(crossHair); 

     instructions= new BitmapText(guiFont, false); 
     instructions.setSize(guiFont.getCharSet().getRenderedSize()); 
     instructions.setText("Move cross hairs with U,H,J,K keys, fire with space \n (WSAD moves camera position and look with mouse)"); 
     instructions.setLocalTranslation(0, settings.getHeight(), 0); 

     guiNode.attachChild(instructions); 

     resultsText= new BitmapText(guiFont, false); 
     resultsText.setSize(guiFont.getCharSet().getRenderedSize()); 
     resultsText.setText("Press Space to fire"); 
     resultsText.setLocalTranslation(settings.getWidth()-resultsText.getLineWidth(),resultsText.getLineHeight(), 0); 

     guiNode.attachChild(resultsText); 



    } 

    @Override 
    public void simpleRender(RenderManager rm) { 
     //TODO: add render code 
    } 
} 

키 바인딩은, 커서의 움직임을 제어하는 ​​데에만 사용 :

import com.jme3.input.InputManager; 
import com.jme3.input.KeyInput; 
import com.jme3.input.controls.ActionListener; 
import com.jme3.input.controls.KeyTrigger; 
import com.jme3.input.controls.MouseButtonTrigger; 
import java.util.ArrayList; 
import java.util.Locale; 

public class KeyBindings implements ActionListener{ 

    private InputManager inputManager; 
    private ArrayList<String> bindingString=new ArrayList<String>(100); 
    private ArrayList<KeyBinding> binding=new ArrayList<KeyBinding>(100); 

    public KeyBindings(InputManager inputManager){ 
     this.inputManager=inputManager; 
    } 

    public void registerKeyBinding(int key,String bindingName){ 
     bindingName=preprocess(bindingName); 
     inputManager.addMapping(bindingName, new KeyTrigger(key)); 
     inputManager.addListener(this, bindingName); 

     binding.add(new KeyBinding()); 
     bindingString.add(bindingName); 
    } 

    public void registerMouseBinding(int button,String bindingName){ 
     bindingName=preprocess(bindingName); 
     inputManager.addMapping(bindingName, new MouseButtonTrigger(button)); 
     inputManager.addListener(this, bindingName); 

     binding.add(new KeyBinding()); 
     bindingString.add(bindingName); 
    } 


    public KeyBinding getBinding(String bindingName){ 
     //get which binding we're after 
     bindingName=preprocess(bindingName); 

     int index=bindingString.indexOf(bindingName); 

     if (index!=-1){ 
      return binding.get(index); 
     }else{ 
      return null; 
     } 
    } 

    public void onAction(String bindingName, boolean isPressed, float tpf) { 
     bindingName=preprocess(bindingName); 

     //get which binding we're after 
     int index=bindingString.indexOf(bindingName); 

     if (index!=-1){ 
      binding.get(index).setValue(isPressed); 
     } 
    } 


    private String preprocess(String string){ 
     return string.toUpperCase(); 
    } 

} 


public class KeyBinding { 

    private boolean value; 
    private boolean changedSinceLastAccess; //to avoid multiclicks etc 
    private boolean valueTrueSinceLastAccess; 


    public void setValue(boolean value){ 
     this.value=value; 
     changedSinceLastAccess=true; 

     if (value==true){ 
      valueTrueSinceLastAccess=true; 
     } 
    } 

    public boolean hasChangedSinceLastAccess(){ 
     return changedSinceLastAccess; 
    } 

    public boolean hasBecomeTrueSinceLastAccess(){ 
     //this collects any trues since the last access, is good for things like mouse clicks, 
     //which are instantaneous and you want then recorded on the next tick 
     if (valueTrueSinceLastAccess==true){ 
      valueTrueSinceLastAccess=false; 
      return true; 
     }else{ 
      return false; 
     } 
    } 


    public boolean getValue(){ 
     changedSinceLastAccess=false; 
     valueTrueSinceLastAccess=false; 
     return value; 
    } 

    public boolean getValue_withoutNotifying(){ 
     return value; 
    } 

} 
+0

와우 그게 멋진! –