2012-01-29 2 views
0

이제는 별길을 찾는 길잡이를 이해하고 코딩하려고 노력한 지 며칠이 지난 후에야 알 수 있습니다. 마침내 코드를 작성하여 작동 시키십시오.java 캐릭터를 만드는 법 Path Finding

이제는 어떻게하면 영웅이 경로를 따라갈 수 있는지 알고 싶습니다. 코드 스 니펫이나 예제가 도움이 될 것입니다. 나는 그것을하는 방법에 대한 아이디어가 있었지만 불행히도 그것은 미리 감사드립니다.

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionListener; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 


public class GameBoard extends JPanel implements ActionListener,Runnable{ 
private Thread game; 
private volatile boolean running=false; 
Map m; 
Player hero; 
Path path; 
AstarPathfinder p1; 
int targetX,targetY; 
int dir=0; 
public GameBoard() 
{ 
    //setSize(620,720); 
    setBackground(Color.gray); 
    setFocusable(true); 
    requestFocus(); 
    hero=new Player(); 
    hero.setX(3/36); 
    hero.setY(3/36); 

    addMouseListener(new MouseAdapter() 
      { 
     public void mouseClicked(MouseEvent e) { 
      handleMousePressed(e.getX(), e.getY()); 
     } 
    }); 
    addMouseMotionListener(new MouseMotionListener() { 
     public void mouseDragged(MouseEvent e) { 
         // System.out.println("mouse dragged"); 
     } 

     public void mouseMoved(MouseEvent e) { 
      //handleMouseMoved(e.getX(), e.getY()); 
     } 
    }); 

} 

private void handleMousePressed(int x, int y) 
    { 
    targetX=x /= 36; 
    targetY=y/= 36; 
      p1=new AstarPathfinder(); 
      path=p1.PathFinding(hero.getX()/36, hero.getY()/36, targetX,targetY); 
      repaint(); 
    } 




public void startGame() 
{ 
    if(game==null|| !running) 
    {  
       game=new Thread(this); 
       game.start(); 
       running=true;       


    } 
} 
@Override 
    public void run() 
{ 
    while(running) 
    { 

     moveit(); 

     try { 

      Thread.sleep(5); 

     } catch (InterruptedException ex) { 
      Logger.getLogger(GameBoard.class.getName()).log(Level.SEVERE, null, ex); 
     } 

    } 
} 

public void moveit() 
{ 
    for(int x=0; x<14; x++) 
    { 
     for(int y=0;y<14;y++) 
     { 

            if (path != null) 
            { 

       if (path.contains(x,y)) 
             { 
              if(path.getX(x)<hero.getX()){ 
              hero.x-=1; 
              } 
              else if(path.getX(x)> hero.getX()) 
              { 
               hero.x+=1; 
              } 


               if(path.getY(y)< hero.getY()) 
               { 
               hero.y-=1; 
               } 
               else if(path.getY(y)> hero.getY()) 
               { 

               hero.y+=1; 
               } 


       } 
      } 
     } 
     } 

    } 
    @Override 
    public void paint(Graphics g) 
    { 
    m=new Map();  
    m.OpenFile(); 
    m.ReadFile(); 
    m.CloseFile(); 

    for(int y=0; y<14; y++) 
    { 
     for(int x=0; x<14; x++) 
     { 

      if(m.getMap(x, y).equals("g")) 
      { 
       g.drawImage(m.getGrass(), x*36, y*36, this); 
      } 

      if(m.getMap(x, y).equals("b")) 
      { 
       g.drawImage(m.getBlock(), x*36, y*36, this); 
      } 
      if(m.getMap(x, y).equals("d")) 
      { 
       g.drawImage(m.getDirt(), x*36, y*36, this); 
      } 
      if(m.getMap(x, y).equals("t")) 
      { 
       g.drawImage(m.getGOAL(), x*36, y*36, this); 



      } 


          if (path != null) 
          { 

         if (path.contains(x,y)) 
              { 
                g.setColor(Color.YELLOW); 
         g.fillRect(x*36, y*36,19,19); 
              } 

       } 


     } 
    } 

} 
    @Override 
    public void addNotify() 
    {//build in jpanel method 
    super.addNotify(); 
    ///donc quand le jpanel est en marche partir le jeu. 
    startGame(); 



} 

    @Override 
    public void actionPerformed(ActionEvent e) { 
    throw new UnsupportedOperationException("Not supported yet."); 
    } 


} 

끝 내 엔티티 클래스

public class Entity { 

int x, y, dx, dy; 

public Entity() { 
    x = 0; 
    y = 0; 
    dx = 0; 
    dy = 0; 
} 

public Entity(int xe, int ye) { 
    this.x = xe; 
    this.y = ye; 
} 

public int getDx() { 
    return dx; 
} 

public void setDx(int dx) { 
    this.dx = dx; 
} 

public int getDy() { 
    return dy; 
} 

public void setDy(int dy) { 
    this.dy = dy; 
} 

public int getX() { 
    return x; 
} 

public void setX(int x) { 
    this.x = x; 
} 

public int getY() { 
    return y; 
} 

public void setY(int y) { 
    this.y = y; 
} 
} 

클래스 플레이어 여기

import java.awt.Graphics; 
    import java.awt.Image; 
    import javax.swing.ImageIcon; 

public class Player extends Entity { 
private Image p; 
public Player() 
{ 
    super(); 
    p=new ImageIcon("C:/Java/Prj/src/images/player.png").getImage(); 
} 

public Image getPlayer() 
{ 
    return p; 
} 
/* public void move(char d) 
{ 
    if(d=='d') 
    this.x+=this.dx; 
    this.y+=this.dy; 
}*/ 
public void drawPlayer(Graphics g) 
{ 

    g.drawImage(this.p,this.x,this.y,null); 

} 
} 

내 Astarpath 클래스

enter code here 

    import java.util.ArrayList; 
    import java.util.LinkedList; 
    import java.util.List; 

public class AstarPathfinder { 

LinkedList<Node> closed = new LinkedList(); 
LinkedList<Node> open = new LinkedList(); 
int newH, newF, newG, ndlength = 14; 
Node[][] nodes = new Node[ndlength][ndlength]; 
Path path; 

public AstarPathfinder() { 


    for (int i = 0; i < ndlength; i++) { 
     for (int j = 0; j < ndlength; j++) { 
      nodes[i][j] = new Node(i, j); 
     } 
    } 

} 

public Path PathFinding(int sx, int sy, int tx, int ty) { 
    Node start = nodes[sx][sy]; 
    Node target = nodes[tx][ty]; 
    start.g = 0; 
    start.h = estimateCost(start, target); 
    start.f = start.g + start.h; 

    start.parent = null; 
    open.add(start); 



    while (open.size() != 0) { 

     Node current = null; 

     if (open.size() == 0) { 
      System.out.println("aucune route/no possible road"); 
     } 


     current = getCurrent(); 
     if (current == target) { 
      //System.out.println("reach the target: " + target); 
      break; 
     } 
     open.remove(current); 
     closed.add(current); 




     List<Node> neighbors = (List<Node>) createNeighbors(current); 

     for (int k = 0; k < neighbors.size(); k++) { 

      Node neighborNode = neighbors.get(k); 
      if (closed.contains(neighborNode)) { 
       continue; 
      } 
      newG = current.g + 10;// + estimateDistance(current, neighborNode); 
      newH = estimateCost(neighborNode, target); 
      newF = newG + newH; 

      if (newG < neighborNode.g) { 

       neighborNode.parent = current; 
       neighborNode.h = newH; 
       neighborNode.g = newG; 
       neighborNode.f = newF; 

      } 
      if ((!open.contains(neighborNode)) && !(closed.contains(neighborNode))) { 

       open.add(neighborNode); 
       neighborNode.parent = current; 
       neighborNode.h = newH; 
       neighborNode.g = newG; 
       neighborNode.f = newF; 
      } 
     }//endloopfor 

    }//end while 

    path = new Path(); 
    Node target2 = target; 
    while (target2 != start) { 
     path.prependStep(target2.x, target2.y); 
     target2 = target2.parent; 

    } 

    path.prependStep(start.x, start.y); 
    return path; 
} 

public int estimateCost(Node node1, Node node2) { 
    float resultat; 
    float dx = node1.x - node2.x; 
    float dy = node1.y - node2.y; 
    resultat = Math.abs((dx * dx) + (dy + dy)); 
    resultat += resultat * 0.001; 
    return (int) resultat; 
} 

/** 
* cette fonction perment de retourner le noeud courant 
* @return 
*/ 
private Node getCurrent() { 
    Node currentNode = null; 
    int maxintf = open.size(); 
    int minf = 1000000; 
    for (int i = 0; i < maxintf; i++) { 
     Node node = (Node) open.get(i); 
     if (node.f < minf) { 
      currentNode = node; 

     } 
    } 
    return currentNode; 
} 

/** 
* Fontion permettant de trouver les 8 voisins 
*/ 
private List<Node> createNeighbors(Node cnodes) { 
    int i = cnodes.x; 
    int j = cnodes.y; 
    List<Node> neighbors = new ArrayList<Node>(); 
    int indiceup = cnodes.x - 1; 
    int indicedown = cnodes.x + 1; 
    int indiceleft = cnodes.y - 1; 
    int indiceright = cnodes.y + 1; 
    if (indiceup > -1) { 
     neighbors.add(nodes[indiceup][cnodes.y]); 
    } 
    if (indicedown < 14) { 
     neighbors.add(nodes[indicedown][cnodes.y]); 
    } 
    if (indiceleft > -1) { 
     neighbors.add(nodes[cnodes.x][indiceleft]); 
    } 
    if (indiceright < 14) { 
     neighbors.add(nodes[cnodes.x][indiceright]); 
    } 
    return neighbors; 
} 

public class Node { 

    int g = 0;//cost 
    int h = 0;//heuristic 
    int f = g;//f+g 
    Node parent; 
    int x, y; 
    boolean visited; 

    public Node(int x, int y) { 
     this.x = x; 
     this.y = y; 
     this.visited = false; 
    } 

    public boolean isVisited() { 
     return visited; 
    } 

    public void setVisited(boolean visited) { 
     this.visited = visited; 
    } 

    public int getF() { 
     return f; 
    } 

    public void setF(int f) { 
     this.f = f; 
    } 

    public int getG() { 
     return g; 
    } 

    public void setG(int g) { 
     this.g = g; 
    } 

    public int getH() { 
     return h; 
    } 

    public void setH(int h) { 
     this.h = h; 
    } 

    public Node getParent() { 
     return parent; 
    } 

    public void setParent(Node parent) { 
     this.parent = parent; 
    } 
    } 
    } 

와 내가 코크스 및 코드 웹 사이트에서 얻은 경로 클래스의 .

: 나는 이해한다 일단 내가 모든 것을 다시 입력합니다 물론 이해하려고 노력하고 처음부터 모든 것을 :

경로 클래스

import java.util.ArrayList; 

    public class Path { 
/** The list of steps building up this path */ 
private ArrayList steps = new ArrayList(); 

/** 
* Create an empty path 
*/ 
public Path() { 

} 

/** 
* Get the length of the path, i.e. the number of steps 
* 
* @return The number of steps in this path 
*/ 
public int getLength() { 
    return steps.size(); 
} 

/** 
* Get the step at a given index in the path 
* 
* @param index The index of the step to retrieve. Note this should 
* be >= 0 and < getLength(); 
* @return The step information, the position on the map. 
*/ 
public Step getStep(int index) { 
    return (Step) steps.get(index); 
} 

/** 
* Get the x coordinate for the step at the given index 
* 
* @param index The index of the step whose x coordinate should be retrieved 
* @return The x coordinate at the step 
*/ 
public int getX(int index) { 
    return getStep(index).x; 
} 

/** 
* Get the y coordinate for the step at the given index 
* 
* @param index The index of the step whose y coordinate should be retrieved 
* @return The y coordinate at the step 
*/ 
public int getY(int index) { 
    return getStep(index).y; 
} 

/** 
* Append a step to the path. 
* 
* @param x The x coordinate of the new step 
* @param y The y coordinate of the new step 
*/ 
public void appendStep(int x, int y) { 
    steps.add(new Step(x,y)); 
} 

/** 
* Prepend a step to the path. 
* 
* @param x The x coordinate of the new step 
* @param y The y coordinate of the new step 
*/ 
public void prependStep(int x, int y) { 
    steps.add(0, new Step(x, y)); 
} 

/** 
* Check if this path contains the given step 
* 
* @param x The x coordinate of the step to check for 
* @param y The y coordinate of the step to check for 
* @return True if the path contains the given step 
*/ 
public boolean contains(int x, int y) { 
    return steps.contains(new Step(x,y)); 
} 

/** 
* A single step within the path 
* 
* @author Kevin Glass 
*/ 
public class Step { 
    /** The x coordinate at the given step */ 
    private int x; 
    /** The y coordinate at the given step */ 
    private int y; 

    /** 
    * Create a new step 
    * 
    * @param x The x coordinate of the new step 
    * @param y The y coordinate of the new step 
    */ 
    public Step(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 

    /** 
    * Get the x coordinate of the new step 
    * 
    * @return The x coodindate of the new step 
    */ 
    public int getX() { 
     return x; 
    } 

    /** 
    * Get the y coordinate of the new step 
    * 
    * @return The y coodindate of the new step 
    */ 
    public int getY() { 
     return y; 
    } 

    /** 
    * @see Object#hashCode() 
    */ 
    public int hashCode() { 
     return x*y; 
    } 

    /** 
    * @see Object#equals(Object) 
    */ 
    public boolean equals(Object other) { 
     if (other instanceof Step) { 
      Step o = (Step) other; 

      return (o.x == x) && (o.y == y); 
     } 

     return false; 
    } 
} 
    } 
+0

만약 당신의 A * 알고리즘이 당신에게 최적의 경로를 제공하거나 심지어 그 최적의 경로를위한 첫 번째 선택을한다면, 그것은 당신의 "영웅"이 사용해야 할 것입니다. A * 구현이나 적용되는 문제에 대한 더 이상의 정보가 없으면 그 이상을 말할 수 없습니다. –

+0

시도한 위치와 관련된 코드를 게시해야하지만 작동하지 않는 것이 좋습니다. –

답변

1

몇 가지 일반적인 의견 엉터리 코드에 대한 유감을 구축 코드를 읽기가 어렵습니다. 나중에 의미있는 변수 이름을 사용하십시오 (또는 적어도 해당 변수에 대한 주석을 달아주십시오). 예 : Dx 란 무엇입니까?

기타 : hero.drawPlayer (g)는 루프와 독립적입니다. 왜 루프에 넣을까요? 플레이어는 필요한 것보다 더 자주 그려집니다. paint()가 호출 될 때마다지도가로드 된 것 같습니다 (파일에서!). 그건 불필요하게 보인다. 문제에 대한

:

당신은 확실이이 라인 : targetX = X/= 36; 맞다? PathFinding 클래스를 포함시키지 않았으므로 올바른 경로를 반환했다고 확신합니다 (인쇄했거나 다른 것으로 인쇄 했음)?

moveit() 루프에서 : path.getX (x) 그냥 제대로 보이지 않습니다. 나는 Path 클래스의 구현을 모른다. 그러나 나는 그것이 일종의리스트라고 생각할 것이다. moveit()을 한 번 호출하면 플레이어를 해당 목록의 다음 요소로 이동하려고합니다. 또는 최소한 그 요소의 방향으로. 하지만 path.getFirst 또는 path.getNext를 호출하지 않으면 경로의 모든 요소를 ​​사용하는 것처럼 보입니다.

하나가 경로에 팝업 방법을 추가 : 그 작업을 수행하는 방법에 관해서 :

// 편집

public Step popStep() { 
    Step temp = steps.get(0); 
    steps.remove(0); 
    return temp; 
} 

그리고를 사용하거나 경우에 (어딘가에 카운터를 추가하면 전체가 필요합니다 나중에 경로).

public void moveit() { 
    Step nextStep = path.popStep(); 
    hero.setX(nextStep.getX()); 
    hero.setY(nextStep.getY()); 
} 

플레이어가 항상 경로의 다음 단계로 이동합니다이 방법을 :

그리고는 당신의 이동 방법을 변경합니다. 또한 이동 호출 사이에 5 밀리 초 이상 기다리고 싶을 수도 있습니다.

+0

Zeychin이 모든 코드를 요청한 것 같지 않습니다 (문제와 관련된 코드 만). 어쨌든, 내가 moveit에서 말했듯이 당신은 플레이어를 경로의 다음 단계로 이동시켜야합니다. 또한 전체 코드를 36 부분으로 나눈 값을 다시 확인합니다. 예 : int 형으로 3/36 캐스팅은 0입니다. – tim

+0

@ 3rdoseye 그 문제가 무엇인지 잘 모르겠습니다. 어쩌면 당신이하려는 일을 오해하고 있습니다. 나는 당신이 원한다고 생각하는 것에 나의 원래 대답을 편집했다. – tim