2013-05-22 9 views
0

Как я могу стрелять в направлении, на котором указывает перекрестье?JMonkey - Стрельба в направлении перекрестия

Используя двигатель JMonkey, я создаю игру, в которой мне нужен корабль, чтобы стрелять в другие корабли.

Итак, я создал перекрестие, которое может перемещаться по экрану (вверх, вниз, влево, вправо) в соответствии с пользовательским вводом, чтобы пользователь мог нацелиться на определенное место.

Теперь мне нужно, чтобы я стрелял из пушки с моего корабля в направлении, в котором стоят перекрестия.

Как я могу стрелять в то место, где указываются перекрестия?

ответ

3

Вы можете получить направление камеры с:

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

и может получить позицию из:

positionXYZ=cam.getLocation(); //Vector3f 

Вы можете иметь отливку лучей:

Ray ray = new Ray(directionXYZ, positionXYZ); 

затем может собирать данные для столкновений:

shootables.collideWith(ray, results) 

где стрельба является «узлом».

Наконец, проверьте, что вы хотите:

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);, это возвращает трехмерную точку в пространстве, которая попадет на экран точки на экране. Поэтому, если мы создадим точку в zDepth из нуля и точку в zDepth одного из них, мы можем создать луч, исходящий из положения курсора, перемещающегося наружу, чтобы было выбрано что-либо, что курсор «перевернут». screenPosition находится в пикселях от левого нижнего угла окна

Пример программы, использующей этот метод, заключается в следующем и основывается на второй части 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

вау Thats здорово! –

 Смежные вопросы

  • Нет связанных вопросов^_^