Koordinieren und Essen von Snake - Spiel

Feeder

Bekanntes Mitglied
Hey, ich versuche das Spielo Snake nachzuprogrammieren, leider scheinen meine Algorithmen nicht zu funktionieren.

Wenn meine Schlange isst,verlängert sich die Liste von Positionen um die letztere Position, so dass im Nächsten Schritt sich die Schlange neu "aufrollt"...
Java:
ArrayList<Vector> bodys;
public void addBody() { //wenn sie isst...
        bodys.add(bodys.get(bodys.size()-1));

    }


Dannach stept sie wieder
Java:
ArrayList<Vector> bodys;
public void step(int time) {
        for(int i = 1; bodys.size()-i > 0; ++i ) {
            bodys.get(bodys.size()-i).setLocation(bodys.get(bodys.size()-i-1));
            System.out.println((bodys.size()-i) + " to " + (bodys.size()-i-1) );
        }
        //neue position für den Kopf
        bodys.get(0).add(speed.multiply(time));//speed.multiply time returned neuen Vektor...


}
 

mrBrown

Super-Moderator
Mitarbeiter
Du fügst den letzten Vektor noch Mals hinzu, in der Liste ist also zwei mal der selbe. Veränderst du einen von beide, veränderst du auch den anderen.
 

mrBrown

Super-Moderator
Mitarbeiter
Hiermit fügst du den jeweils letzten Vektor nochmal der Liste hinzu: bodys.add(bodys.get(bodys.size()-1));.
Der hinzugefügte Vektor ist der selbe, wie der schon vorhandenen, er liegt jetzt nur doppelt in der Liste. Da es eben der selbe ist, veränderst immer beide, wenn du einen verändern willst.
Du müsstest eine Kopie des vorhandenen hinzufügen, ohne deine Vector-Klasse zu kennen, kann man da aber nicht mehr zu sagen
 

Feeder

Bekanntes Mitglied
Hiermit fügst du den jeweils letzten Vektor nochmal der Liste hinzu: bodys.add(bodys.get(bodys.size()-1));.
Der hinzugefügte Vektor ist der selbe, wie der schon vorhandenen, er liegt jetzt nur doppelt in der Liste. Da es eben der selbe ist, veränderst immer beide, wenn du einen verändern willst.
Du müsstest eine Kopie des vorhandenen hinzufügen, ohne deine Vector-Klasse zu kennen, kann man da aber nicht mehr zu sagen
ikr

VIELEN DANK, ich probier es später aus...!!!
 

Feeder

Bekanntes Mitglied
Habe jetzt wie folgt abgeändert:

Java:
    public void addBody() { //wenn sie isst... 
        Vector v = new Vector(bodys.get(bodys.size()-1).getX(), bodys.get(bodys.size()-1).getY());
        bodys.add(v);

    }
    public void step(int time) {
        for(int i = 1; bodys.size()-i > 0; ++i ) {
            bodys.get(bodys.size()-i).setLocation(bodys.get(bodys.size()-i-1));
            System.out.println((bodys.size()-i) + " to " + (bodys.size()-i-1) );
        }
        //neue position für den Kopf
        bodys.get(0).add(speed.multiply(time));
     
    }

    public void display(Graphics g) {
        g.setColor(Color.cyan);
        for(int i = 0; i < bodys.size(); ++i) {
        g.fillRect((int)Math.round(bodys.get(i).getX()), (int)Math.round(bodys.get(i).getY()), 20, 20);
        }
    }

Klappt aber immer noch nicht :(
 

Feeder

Bekanntes Mitglied
Und *was* klappt nicht?

War gerade am probieren, habe den Code noch etwas abgeändert:

Java:
public void addBody() { //wenn sie isst...
        Vector v = new Vector(bodys.get(bodys.size()-1).getX(), bodys.get(bodys.size()-1).getY());
        bodys.add(v);

    }
public void step(int time) {
        for(int i = 1; bodys.size()-i > 0; ++i ) {
            Vector v = new Vector(bodys.get(bodys.size()-1-i).getX(), bodys.get(bodys.size()-1-i).getY());
            bodys.set(bodys.size()-i, v);
        }
        double x = bodys.get(0).getX() + speed.getX()*time;
        double y = bodys.get(0).getY() + speed.getY()*time;
        Vector v = new Vector(x, y);
        bodys.set(0, v);

   
    }

public void display(Graphics g) {
        g.setColor(Color.cyan);
        for(int i = 0; i < bodys.size(); ++i) {
        g.fillRect((int)Math.round(bodys.get(i).getX()), (int)Math.round(bodys.get(i).getY()), 20, 20);
        }
    }

Er zeigt stets nur ein Körperteil an, es existieren aber mehrere...
 

Feeder

Bekanntes Mitglied
Eigentlich schon...

Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class SnakeGame {
    JFrame frame;
    GamePanel panel;
    JLabel label;
    Snake s;
    Food f;
    long lasttime;
    public SnakeGame() {
        init();
        while(true) {
            calculate();
            repaint();
           
        }
    }

    private void repaint() {
        label.repaint();
        panel.repaint();
        frame.repaint();
       
    }

    private void calculate() {
        long before = System.currentTimeMillis();
        int delta = (int) (System.currentTimeMillis() - lasttime);
        s.step(delta);
        lasttime = before;
        if(f.isEaten(s)) {
            s.addBody();
            f.step();

        }

    }

    private void init() {
        s = new Snake(new Vector(50, 50));
        f = new  Food();
        lasttime = System.currentTimeMillis();
        frame = new JFrame();
        frame.setBounds(0,0,1000,1000);
        frame.setTitle("Snake");
        frame.setVisible(true);
        frame.setResizable(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(Color.BLACK);
        frame.addComponentListener(new ComponentListener() {
           
            @Override
            public void componentShown(ComponentEvent e) {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            public void componentResized(ComponentEvent e) {
                label.setBounds(0, frame.getHeight()-65, 100, 20);

               
            }
           
            @Override
            public void componentMoved(ComponentEvent e) {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            public void componentHidden(ComponentEvent e) {
                // TODO Auto-generated method stub
               
            }
        });
        panel = new GamePanel();
        panel.setBounds(0, 0, 1000, 1000);
        panel.setVisible(true);
        panel.setLayout(null);
        label = new JLabel();
        label.setBounds(0, frame.getHeight()-65, 250, 20);
        label.setBackground(Color.GREEN);
        label.setForeground(Color.WHITE);
        label.setText("Running...");
        label.setOpaque(false);
        panel.add(label);
        frame.add(panel);
        frame.addKeyListener(s);
   
       
   
       
    }
    private class GamePanel extends JPanel {
        public void paintComponent(Graphics g) {
            f.display(g);
            s.display(g);
           
        }
    }
}


import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

public class Snake implements KeyListener{
    ArrayList<Vector> bodys;
    Vector speed;
    public Snake(Vector pos) {
        bodys = new ArrayList<Vector>();
        bodys.add(pos);
        speed = new Vector(0.1,0);
    }
    public void display(Graphics g) {
        g.setColor(Color.cyan);
        for(int i = 0; i < bodys.size(); ++i) {
        g.fillRect((int)Math.round(bodys.get(i).getX()), (int)Math.round(bodys.get(i).getY()), 20, 20);
        }
    }
    public void step(int time) {
        for(int i = 1; bodys.size()-i > 0; ++i ) {
            Vector v = new Vector(bodys.get(bodys.size()-1-i).getX(), bodys.get(bodys.size()-1-i).getY());
            bodys.set(bodys.size()-i, v);
        }
        double x = bodys.get(0).getX() + speed.getX()*time;
        double y = bodys.get(0).getY() + speed.getY()*time;
        Vector v = new Vector(x, y);
        bodys.set(0, v);

      
    }
    @Override
    public void keyPressed(KeyEvent e) {
        int i = e.getKeyCode();
        if(i == KeyEvent.VK_1) {
            if(speed.getX() == 0) {
                speed.setX(0.1);
                speed.setY(0);
            }
        }
        if(i == KeyEvent.VK_2) {
            if(speed.getY() == 0) {
                speed.setY(0.1);
                speed.setX(0);
            }
        }
        if(i == KeyEvent.VK_3) {
            if(speed.getX() == 0) {
                speed.setX(-0.1);
                speed.setY(0);
            }
        }
        if(i == KeyEvent.VK_4) {
            if(speed.getY() == 0) {
                speed.setY(-0.1);
                speed.setX(0);
            }
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
      
    }
    @Override
    public void keyTyped(KeyEvent e) {
        int i = e.getKeyCode();
        if(i == KeyEvent.VK_1) {
            if(speed.getX() == 0) {
                speed.setX(0.1);
                speed.setY(0);
            }
        }
        if(i == KeyEvent.VK_2) {
            if(speed.getY() == 0) {
                speed.setY(0.1);
                speed.setX(0);
            }
        }
        if(i == KeyEvent.VK_3) {
            if(speed.getX() == 0) {
                speed.setX(-0.1);
                speed.setY(0);
            }
        }
        if(i == KeyEvent.VK_4) {
            if(speed.getY() == 0) {
                speed.setY(-0.1);
                speed.setX(0);
            }
        }
      
    }
    public void addBody() {
        Vector v = new Vector(bodys.get(bodys.size()-1).getX(), bodys.get(bodys.size()-1).getY());
        bodys.add(v);

    }
}
 

mrBrown

Super-Moderator
Mitarbeiter
Der Code ist leider nicht ausführbar.
Spontan: Entweder bewegst du die so schnell, dass sie direkt aus'm Bild ist, oder du rundest irgendwo, sodass der Kopf auf der Stelle steht.
 

Feeder

Bekanntes Mitglied
Der Code ist nicht vollständig.
Ich gebe mal den vorständigen Code:

Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class SnakeGame {
    JFrame frame;
    GamePanel panel;
    JLabel label;
    Snake s;
    Food f;
    long lasttime;
    public SnakeGame() {
        init();
        while(true) {
            calculate();
            repaint();
           
        }
    }

    private void repaint() {
        label.repaint();
        panel.repaint();
        frame.repaint();
       
    }

    private void calculate() {
        long before = System.currentTimeMillis();
        int delta = (int) (System.currentTimeMillis() - lasttime);
        s.step(delta);
        lasttime = before;
        if(f.isEaten(s)) {
            s.addBody();
            f.step();

        }

    }

    private void init() {
        s = new Snake(new Vector(50, 50));
        f = new  Food();
        lasttime = System.currentTimeMillis();
        frame = new JFrame();
        frame.setBounds(0,0,1000,1000);
        frame.setTitle("Snake");
        frame.setVisible(true);
        frame.setResizable(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(Color.BLACK);
        frame.addComponentListener(new ComponentListener() {
           
            @Override
            public void componentShown(ComponentEvent e) {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            public void componentResized(ComponentEvent e) {
                label.setBounds(0, frame.getHeight()-65, 100, 20);

               
            }
           
            @Override
            public void componentMoved(ComponentEvent e) {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            public void componentHidden(ComponentEvent e) {
                // TODO Auto-generated method stub
               
            }
        });
        panel = new GamePanel();
        panel.setBounds(0, 0, 1000, 1000);
        panel.setVisible(true);
        panel.setLayout(null);
        label = new JLabel();
        label.setBounds(0, frame.getHeight()-65, 250, 20);
        label.setBackground(Color.GREEN);
        label.setForeground(Color.WHITE);
        label.setText("Running...");
        label.setOpaque(false);
        panel.add(label);
        frame.add(panel);
        frame.addKeyListener(s);
   
       
   
       
    }
    private class GamePanel extends JPanel {
        public void paintComponent(Graphics g) {
            f.display(g);
            s.display(g);
           
        }
    }
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

public class Snake implements KeyListener{
    ArrayList<Vector> bodys;
    Vector speed;
    public Snake(Vector pos) {
        bodys = new ArrayList<Vector>();
        bodys.add(pos);
        speed = new Vector(0.1,0);
    }
    public void display(Graphics g) {
        g.setColor(Color.cyan);
        for(int i = 0; i < bodys.size(); ++i) {
        g.fillRect((int)Math.round(bodys.get(i).getX()), (int)Math.round(bodys.get(i).getY()), 20, 20);
        }
    }
    public void step(int time) {
        for(int i = 1; bodys.size()-i > 0; ++i ) {
            Vector v = new Vector(bodys.get(bodys.size()-1-i).getX(), bodys.get(bodys.size()-1-i).getY());
            bodys.set(bodys.size()-i, v);
        }
        double x = bodys.get(0).getX() + speed.getX()*time;
        double y = bodys.get(0).getY() + speed.getY()*time;
        Vector v = new Vector(x, y);
        bodys.set(0, v);

       
    }
    @Override
    public void keyPressed(KeyEvent e) {
        int i = e.getKeyCode();
        if(i == KeyEvent.VK_1) {
            if(speed.getX() == 0) {
                speed.setX(0.1);
                speed.setY(0);
            }
        }
        if(i == KeyEvent.VK_2) {
            if(speed.getY() == 0) {
                speed.setY(0.1);
                speed.setX(0);
            }
        }
        if(i == KeyEvent.VK_3) {
            if(speed.getX() == 0) {
                speed.setX(-0.1);
                speed.setY(0);
            }
        }
        if(i == KeyEvent.VK_4) {
            if(speed.getY() == 0) {
                speed.setY(-0.1);
                speed.setX(0);
            }
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
       
    }
    @Override
    public void keyTyped(KeyEvent e) {
        int i = e.getKeyCode();
        if(i == KeyEvent.VK_1) {
            if(speed.getX() == 0) {
                speed.setX(0.1);
                speed.setY(0);
            }
        }
        if(i == KeyEvent.VK_2) {
            if(speed.getY() == 0) {
                speed.setY(0.1);
                speed.setX(0);
            }
        }
        if(i == KeyEvent.VK_3) {
            if(speed.getX() == 0) {
                speed.setX(-0.1);
                speed.setY(0);
            }
        }
        if(i == KeyEvent.VK_4) {
            if(speed.getY() == 0) {
                speed.setY(-0.1);
                speed.setX(0);
            }
        }
       
    }
    public void addBody() {
        Vector v = new Vector(bodys.get(bodys.size()-1).getX(), bodys.get(bodys.size()-1).getY());
        bodys.add(v);

    }
}
import java.awt.Color;
import java.awt.Graphics;

public class Food {
    int x,y;
    public Food() {
        x = 20;
        y = 300;
    }
    public void display(Graphics g) {
        g.setColor(Color.GREEN);
        g.fillOval(x, y, 20, 20);
    }
    public boolean isEaten(Snake s) {
        if(this.x < s.bodys.get(0).x && this.x + 20 > s.bodys.get(0).x) {
            if(this.y < s.bodys.get(0).y && this.y + 20 > s.bodys.get(0).y) {
                return true;
            }
        }
        if(this.x < s.bodys.get(0).x+20 && this.x + 20 > s.bodys.get(0).x+20) {
            if(this.y < s.bodys.get(0).y+20 && this.y + 20 > s.bodys.get(0).y+20) {
                return true;
            }
        }
        return false;
    }
    public void step() {
        x = (int) Math.round(500*Math.random());
        y = (int) Math.round(500*Math.random());
       
    }
}


public class Vector {
    double x,y;
    public Vector(double x, double y) {
        this.x = x;
        this.y = y;
    }
    public void setX(double x) {
        this.x = x;
    }
    public void setY(double y) {
        this.y = y;
    }

    public double getX() {
        // TODO Auto-generated method stub
        return x;
    }

    public double getY() {
        // TODO Auto-generated method stub
        return y;
    }

    public void setLocation(double x, double y) {
        this.x = x;
        this.y = y;
       
    }
    public void rotate(double angle) {
            double rx = (this.x * Math.cos(angle)) - (this.y * Math.sin(angle));
            double ry = (this.x * Math.sin(angle)) + (this.y * Math.cos(angle));
            x = rx;
            y = ry;   
    }
    public void add(Vector v) {
        y = this.y + v.getY();
        x = this.x + v.getX();
   
    }
    public void sub(Vector v) {
        y = this.y - v.getY();
        x = this.x - v.getX();
   
    }
    public void multiply(double d) {
        x = x*d;
        y = y*d;
    }
    public void div(double d) {
        x = x/d;
        y = y/d;
    }
    public double mag() {
          return Math.pow((x*x + y*y), 0.5);
        }
    public void normalize() {
        double m = mag();
        div(m);
    }
   
   

}


public class Vector {
    double x,y;
    public Vector(double x, double y) {
        this.x = x;
        this.y = y;
    }
    public void setX(double x) {
        this.x = x;
    }
    public void setY(double y) {
        this.y = y;
    }

    public double getX() {
        // TODO Auto-generated method stub
        return x;
    }

    public double getY() {
        // TODO Auto-generated method stub
        return y;
    }

    public void setLocation(double x, double y) {
        this.x = x;
        this.y = y;
       
    }
    public void rotate(double angle) {
           double rx = (this.x * Math.cos(angle)) - (this.y * Math.sin(angle));
           double ry = (this.x * Math.sin(angle)) + (this.y * Math.cos(angle));
           x = rx;
           y = ry;   
    }
    public void add(Vector v) {
        y = this.y + v.getY();
        x = this.x + v.getX();
   
    }
    public void sub(Vector v) {
        y = this.y - v.getY();
        x = this.x - v.getX();
   
    }
    public void multiply(double d) {
        x = x*d;
        y = y*d;
    }
    public void div(double d) {
        x = x/d;
        y = y/d;
    }
    public double mag() {
         return Math.pow((x*x + y*y), 0.5);
        }
    public void normalize() {
        double m = mag();
        div(m);
    }
   
   

}

public class Game {

    public static void main(String[] args) {
        new SnakeGame();

    }

}
 

Meniskusschaden

Top Contributor
Ich glaube die Zeitpunkte zwischen zwei Kopfpositions-Berechnungen liegen so dicht beieinander, dass sich die neue Position kaum oder gar nicht von der vorherigen unterscheidet. Dadurch überlappt der Kopf mit dem Folgeelement (also der vorherigen Kopfposition) teilweise oder vollständig. Ich habe testweise mal Wartephasen eingebaut, um das zu überprüfen. Bei 20ms sieht man, dass die Schlange etwas länger wird. Bei 50ms sieht man es deutlicher und sie bewegt sich noch flüssig. Bei 100ms springt sie schon ziemlich stark.
 

Feeder

Bekanntes Mitglied
Ich glaube die Zeitpunkte zwischen zwei Kopfpositions-Berechnungen liegen so dicht beieinander, dass sich die neue Position kaum oder gar nicht von der vorherigen unterscheidet. Dadurch überlappt der Kopf mit dem Folgeelement (also der vorherigen Kopfposition) teilweise oder vollständig. Ich habe testweise mal Wartephasen eingebaut, um das zu überprüfen. Bei 20ms sieht man, dass die Schlange etwas länger wird. Bei 50ms sieht man es deutlicher und sie bewegt sich noch flüssig. Bei 100ms springt sie schon ziemlich stark.
ikr

Danke, ich probiere es sofort mal aus!!!

Edit: Hey, ich sehe das Problem, werde es denke ich mit einem Modulo Operator, fixen. Ower wie würdet ihr das fixen?

Danke an ALLE!
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
J SNAKE-GAME-LOOP / (Applet zu Application) Spiele- und Multimedia-Programmierung 4
P Snake Game Verbessern Spiele- und Multimedia-Programmierung 15
P Snake Java Hilfe Spiele- und Multimedia-Programmierung 4
B "Snake"-Game Logikfehler Spiele- und Multimedia-Programmierung 1
B noch ein snake klon Spiele- und Multimedia-Programmierung 2
Viktim Snake - Schlange wächst nicht Spiele- und Multimedia-Programmierung 3
M Hilfe bei Snake Spiele- und Multimedia-Programmierung 4
J LWJGL Update Schleife (Snake) Spiele- und Multimedia-Programmierung 6
N Schulprogramm "Snake" Spiele- und Multimedia-Programmierung 4
R Hilfe bei Snake-Programmierung Spiele- und Multimedia-Programmierung 6
C Hinterteil von Snake programmieren Spiele- und Multimedia-Programmierung 11
S Snake versuch Spiele- und Multimedia-Programmierung 14
J Snake Programmierung Spiele- und Multimedia-Programmierung 18
V Snake Spiel Spiele- und Multimedia-Programmierung 7
D Snake n+1-Thread Spiele- und Multimedia-Programmierung 2
N Hilfe bei snake Spiele- und Multimedia-Programmierung 37
N Snake (Programmier Stil) Spiele- und Multimedia-Programmierung 8
G SNAKE HILFEEE! Spiele- und Multimedia-Programmierung 15
G Snake Alphaversion Spiele- und Multimedia-Programmierung 18
B Snake-Game fürs Handy Spiele- und Multimedia-Programmierung 3

Ähnliche Java Themen

Neue Themen


Oben