4

Java を使用して Snake を再作成することにしましたが、行き詰まっています。現時点では、ユーザーが矢印キーを使用して画面上を移動できる正方形があります。LEFT を 1 回押すと、タイマーを使用して正方形が左に移動し始めます。キーを押したままにしたり、押し続けたりする必要はありません。設定されている他のキー(右、上、下)のいずれかを押すと、方向が変わります。私の目標は、ArrayList を使用して、ヘビを構成する正方形を保持することです。現時点では、内部に Snake オブジェクトを 1 つだけ含む ArrayList を作成しました。リストに 2 つ目の Snake オブジェクトを追加してフレームに追加すると (最初のオブジェクトとともに)、1 つの Snake オブジェクトのみが表示され、移動するキーが表示されます。機能しません。このプロジェクトをどのように進めることができるかについて、いくつかのアイデアを探しています。完全な回答はしないでください。自分でそのほとんどを理解したいと思います。方向性が必要なだけです。前もって感謝します-コードは以下です。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Snake extends JPanel implements KeyListener, ActionListener
{
int x = 0, y = 0, velx = 0, vely = 0;
Timer t = new Timer(250, this);


public Snake(int num1, int num2)
{
    t.start();
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(true);
    x = num1;
    y = num2;
}
public void paintComponent(Graphics g)
{   
    super.paintComponent(g);

    g.setColor(Color.blue);
    g.fillRect(x, y, 20, 20);
}
public void actionPerformed(ActionEvent e)
{
    repaint();
    x += velx;
    y += vely;
}
public void up()
{
    vely = -20;
    velx = 0;
}
public void down()
{
    vely = 20;
    velx = 0;
}
public void left()
{
    vely = 0;
    velx = -20;
}
public void right()
{
    vely = 0;
    velx = 20;
}
public void keyPressed(KeyEvent e)
{
    int code = e.getKeyCode();

    if(code == KeyEvent.VK_UP)
        up();
    else if(code == KeyEvent.VK_DOWN)
        down();
    else if(code == KeyEvent.VK_RIGHT)
        right();
    else if(code == KeyEvent.VK_LEFT)
        left();

}
public void keyReleased(KeyEvent e)
{

}
public void keyTyped(KeyEvent e)
{

}
}
//Driver Class
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;

public class UserClass
{
private static JFrame frame = new JFrame("Snake");
private static ArrayList<Snake> mySnake = new ArrayList<Snake>();

public static void main(String[] args)
{
    frame.setSize(500,500);
    frame.setBackground(Color.black);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    mySnake.add(new Snake(20,20));
    frame.add(mySnake.get(0));
}
}

PS Mac の Eclipse にこれとまったく同じコードを配置すると、フレームの背景は黒ですが、Windows では明るい灰色になります...理由は誰にもわかりますか? ありがとう。

4

3 に答える 3

5

あとがきに答えるには、背景色を設定するか、ペイントされた色で他のすべての背後に JPanel を作成します。

プロジェクトを進めるには、MVC フレームワークでの演習にすることを検討してください。今起こっていることは、Model と View が同じクラスでリンクされているということです。これにより、すべての背後にあるロジックをたどることが難しくなります。

ArrayList<Integer[]> segmentLocationsあなたができることは、最初にスネークをビューと関係のあるものから分離することです-定義したボード上の各セグメント位置の(x、y)を表すために、または何かでスネークを作成します-絶対を使用できますまたは、任意のグリッドを作成して、ビューで絶対座標に変更することもできます (これは、MVC の関係をよりよく表しています)。Snake には、ヘビが向いている方向のフィールドも必要enum Direction {N, S, E, W}です。

次に、Snake には自身を更新する方法もあります - move()、最初のセグメントの現在の方向に基づいてすべてのセグメントの位置をシフトし、他のすべてのセグメントをその前のセグメントの動きに追従させます (この数分考えれば簡単です)。

ビューは、Snake インスタンスをポーリングし、その場所にセグメントがあるかどうかを確認し、ある場合はそれを描画するか、その他の多数のオプションを表示する JPanels で構成される GridLayout を持つ JFrame である可能性があります。

コントローラーは、矢印キーが押されたときに更新を Snake に送信する KeyAdapter になります。

生活を楽にするための小さなヒント: 新しいセグメントを追加するときは、Snake の最後のセグメントの場所に配置してください。次に移動するとき、新しいセグメントは同じ場所にあり、それに応じてスネークの残りの部分が移動するはずです。

于 2012-06-09T22:12:01.460 に答える
5

あなたpaintComponent(...)だけが1つの長方形を描きます。代わりに、複数の長方形や楕円形などを描きたい場合は、クラスにList<Point>またはList<Rectangle2D>を指定し、Swing Timer で、リストからテールを削除して新しいヘッドを追加します。次にpaintComponent()、for ループを使用してリストを反復処理し、リストに保持されているすべての四角形を描画します。

また、おそらくKeyListener ではなくキーバインディングを使用して、ユーザーのキー押下を取得することをお勧めします。これは、他のコンポーネントがフォーカスを奪ったときにうまく機能するためです。

于 2012-06-09T22:10:17.947 に答える
4

セグメントのジオメトリを定義するクラスが与えられると、

class Segment {
    private int x, y, d;

    public Segment(int x, int y, int r) {
        this.x = x - r;
        this.y = y - r;
        this.d = 2 * r;
    }
}

セグメントのキューを考えてみましょう。

Queue<Segment> snake = new LinkedList<Segment>();

次に、各反復は単純です

snake.remove();
snake.add(new Segment(...));

そしてpaintComponent()、このループが含まれています

@Override
public void paintComponent(Graphics g) {
    ...
    for (Segment s : snake) {
        g.fillXxxx(s.x, s.y, s.d, s.d);
    }
    ...
}
于 2012-06-09T23:18:19.977 に答える