2012-01-18 16 views
3

私はJavaで基本的なヘビゲームを作っており、より滑らかなアニメーションを得るためにいくつかの助けが必要です。スネークの各セグメントは20×20の正方形なので、スネークを1ピクセルあたり20ピクセルのステップで作成しました。これは、ヘビが一見グリッド上に移動するようにします。つまり、グリッド上にしか生まれない食べ物と常に整列します。今私の問題は、私が3のステップでそれを試してみると、それはもはや "グリッド"と位置合わせされていないということです。私が持っているさらに深刻なもう一つの問題は、最初の四角形を動かして、配列の次の位置にすべての他のものを設定することです(コード参照)。問題は、3のステップで移動すると、ヘビが縮小し、20の代わりに各起点の間に3の隙間しかないということです。必要に応じてソースコード全体を追加することができます。スネークゲームで滑らかなアニメーション(java)?

import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.BufferStrategy; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.Random; 
import javax.swing.Timer; 

public class player1 extends Canvas implements Runnable { 

private keyevents keyevent; 
private element [] elements; 
private element goal; 
private int numSegments, score, endY, quitX, snakeSize, windowSize; 
private Font scorefont; 

private long cycleTime; 
private final int FRAME_DELAY; 
private BufferStrategy bf; 
private boolean gameOver, isRunning; 

public player1(Frame window) { 
    setSize(new Dimension(window.getWidth(), window.getHeight())); 
    FRAME_DELAY = 20; 
    windowSize = 400; 
    snakeSize = 20; 
    score = 0; 
    isRunning = false; 
    numSegments = 5; 
    scorefont = new Font("Verdana", Font.BOLD, snakeSize); 
    elements = new element [300]; 
    goal = new element(randompos(snakeSize,windowSize-snakeSize),randompos(snakeSize,windowSize-snakeSize), snakeSize, Color.green); 
    keyevent = new keyevents(); 
    keyevent.setP1Keys(2,true); 

    for (int i=0, xPos = round(windowSize/2), yPos = round(windowSize/2); i<numSegments; i++, xPos+=snakeSize) { 
     elements[i] = new element(xPos,yPos, snakeSize, Color.blue); 
    } 

    addKeyListener(new KeyAdapter() { 
     public void keyPressed(KeyEvent evt) { 
      keyevent.moveIt(evt); 
      switch(evt.getKeyCode()){ 
      case KeyEvent.VK_ESCAPE: 
       isRunning = false; 
       screen.newMenu(); 
      } 
     } 
    }); 
} 

public void start(player1 ex){ 
    isRunning = true; 
    Thread gameThread = new Thread(ex); 
    gameThread.setPriority(Thread.MIN_PRIORITY); 
    gameThread.start(); 
} 

public void run(){ 
    cycleTime = System.currentTimeMillis(); 
    while(isRunning){ 
     logic(); 
     render(); 
     sync(); 
    } 
} 

public void render() { 
    if (bf==null){ 
     bf = getBufferStrategy(); 
    } 
    Graphics2D g2 = null; 
    try{ 
     g2 = (Graphics2D) bf.getDrawGraphics(); 
     g2.setColor(Color.black); 
     g2.fillRect(0, 0, windowSize, windowSize); 
     for (int i=0;i<numSegments;i+=1) { 
      elements[i].draw(g2); 
     } 
     g2.setColor(Color.green); 
     goal.draw(g2); 
     g2.setColor(Color.orange); 
     g2.fill3DRect(0, 0, windowSize, snakeSize, true); 
     g2.setColor(Color.red); 
     g2.setFont(scorefont); 
     g2.drawString("Score: "+score, 5, snakeSize-4); 
     FontMetrics fm = g2.getFontMetrics(); 
     g2.setColor(Color.blue); 
     fm = g2.getFontMetrics(); 
     g2.setColor(Color.black); 
     quitX = (windowSize - fm.stringWidth("ESC = quit")-5); 
     g2.drawString("ESC = quit",quitX,snakeSize-snakeSize/5); 
    }finally{ 
     g2.dispose(); 
    } 
    bf.show(); 
    Toolkit.getDefaultToolkit().sync(); 
} 

public void sync(){ 
    cycleTime = cycleTime + FRAME_DELAY; 
    long difference = cycleTime - System.currentTimeMillis(); 
    try { 
     Thread.sleep(Math.max(0, difference)); 
    } 
    catch(InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

public void logic(){ 
    int x = elements[0].getX(); 
    int y = elements[0].getY(); 
    Rectangle elementrect = elements[0].getRect(); 
    keyevent.setP1Pressed(false); 

    //Movement 
    for(int i = numSegments-1; i>0; i--){ 
     elements[i].setX(elements[i-1].getX()); 
     elements[i].setY(elements[i-1].getY()); 
    } 
    if(keyevent.getP1Keys(0)){ 
     elements[0].setY(y+20); 
    } 
    else if(keyevent.getP1Keys(1)){ 
     elements[0].setY(y-20); 
    } 
    else if(keyevent.getP1Keys(2)){ 
     elements[0].setX(x-20); 
    } 
    else if(keyevent.getP1Keys(3)){ 
     elements[0].setX(x+20); 
    } 
    if(elements[0].getX()>windowSize-snakeSize){ 
     elements[0].setX(0); 
    } 
    else if(elements[0].getX()<0){ 
     elements[0].setX(windowSize-snakeSize); 
    } 
    if(elements[0].getY()>windowSize-snakeSize){ 
     elements[0].setY(0); 
    } 
    else if(elements[0].getY()<0+snakeSize){ 
     elements[0].setY(windowSize-snakeSize); 
    } 
    for(int i=0; i<numSegments; i++){ 
     elements[i].updateRect(); 
    }  

    //Collision 
    if(elementrect.intersects(goal.getRect())){ 
     numSegments+=1; 
     elements[numSegments-1] = new element(elements[numSegments-2].getX(),elements[numSegments-2].getY(), snakeSize,Color.blue); 
     goal.setX(randompos(snakeSize,windowSize-snakeSize)); 
     goal.setY(randompos(snakeSize,windowSize-snakeSize)); 
     score+=1; 
    } 
    for(int i=1; i<numSegments; i++){ 
     if(elementrect.intersects(elements[i].getRect())){ 
      gameOver(); 
     } 
    } 
} 

public void gameOver(){ 
    isRunning = false; 
} 

public int randompos(int min,int max){ 
    System.out.println(snakeSize); 
    int range = max-min; 
    Random randompos = new Random(); 
    int pos = randompos.nextInt(range)+min; 
    pos*=2; 
    pos += snakeSize; 
    pos /= snakeSize*2; 
    pos *= snakeSize*2; 
    pos/=2; 
    return pos; 
} 
} 
+1

なぜ20分の1に移動しない(すなわち、 2,5,10)?そして、あなたのヘビはマップ上のすべてのブロックと揃い、あなたの問題を解決するはずです。 3とは異なり、あなたのヘビはすべての3番目のブロックにのみ整列します。 –

答えて

6

1)Javaの命名規則を使用し、正しくplayer1があるべきPlayer1など

2)

3)KeyListenerを使用していないFrame ---> JFrameに同じSwing JPanel, JLabel or JComponentを使用し、AWT Canvas pre_historicは使用しないでください、あなたのキャンバスにはFocusが必要なので、最も簡単です。KeyBinding

4)012に問題がありますは、un_responsible滞在AWT/SwingのJ /コ​​ンポーネントは、ブロックEventDispatchTreadなぜなら、およびのThread.sleepの間違ったimplentations()によってyoour GUIがなる凍結OS用Thread.sleep(Math.max(0, difference));を使用することはありません)ではなくRunnable#Tread

5の間違ったimplemntationsよりもjavax.swing.Timerを使用し、スウィングのイベントを解消するためにjavax.swing.Timerを使用してください。ここでは、un_relattedコードの束ではなく、

+0

あなたのポイントごとに+1をしたかったのですが、これは不可能です:-( – Robin

+0

あなたの助けてくれてありがとうございます。まず、これらの問題をすべて解決してから、ここに投稿した問題に戻ってきます私はプログラミング/ Javaのnoobので、私は上に取り組む必要があるものがたくさんあります。 – user1150769

+0

このフォーラムでは、喜んで、このフォーラムで多くのrellated Q&A – mKorbel

1

@ mKorbelの優れたアドバイスに加えて、あなたのヘビセグメントのjava.util.Queueを使用して:

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

そして、単一のアニメーションのステップは、単に最も古いElementを削除し、位置と速度のためのあなたのゲームのルールに従ってオフセットだ新しいものを追加する必要があります。

snake.remove(); 
snake.add(newElement()); 
this.repaint(); 
+0

+1私はペイント対paintComponentを忘れて表示されます参照 – mKorbel

+1

@mKorbel:私はそれがあなたの一部だと言っていますが、関連する見積もりを追加します。 "Swingプログラムは' paint() 'をオーバーライドするのではなく' paintComponent() 'をオーバーライドする必要があります。" - [AWTとペイントのペイント:ペイントメソッド](http://java.sun.com/products/jfc/tsc/articles/painting/index.html#callbacks)を参照してください。 – trashgod

関連する問題