public void draw()
{
switch(direction)
{
case UP:
head.setPos_x(head.getPos_x());
head.setPos_y(head.getPos_y()-0.1f);
for (int i = 0; i < bodyArray.size(); i++)
{
if (i == 0)
{
bodyArray.elementAt(i).setPos_x(head.getPos_x());
bodyArray.elementAt(i).setPos_y((head.getPos_y()+10));
}
else
{
bodyArray.elementAt(i).setPos_x(bodyArray.elementAt(i-1).getPos_x());
bodyArray.elementAt(i).setPos_y(bodyArray.elementAt(i-1).getPos_y()+10);
}
}
break;
case LEFT:
head.setPos_x(head.getPos_x()-0.1f);
head.setPos_y(head.getPos_y());
for (int i = 0; i < bodyArray.size(); i++)
{
if (i == 0)
{
bodyArray.elementAt(i).setPos_x(head.getPos_x()+10);
bodyArray.elementAt(i).setPos_y((head.getPos_y()));
}
else
{
bodyArray.elementAt(i).setPos_x(bodyArray.elementAt(i-1).getPos_x()+10);
bodyArray.elementAt(i).setPos_y(bodyArray.elementAt(i-1).getPos_y());
}
}
break;
case DOWN:
head.setPos_x(head.getPos_x());
head.setPos_y(head.getPos_y()+0.1f);
for (int i = 0; i < bodyArray.size(); i++)
{
if (i == 0)
{
bodyArray.elementAt(i).setPos_x(head.getPos_x());
bodyArray.elementAt(i).setPos_y((head.getPos_y()-10));
}
else
{
bodyArray.elementAt(i).setPos_x(bodyArray.elementAt(i-1).getPos_x());
bodyArray.elementAt(i).setPos_y(bodyArray.elementAt(i-1).getPos_y()-10);
}
}
break;
case RIGHT:
head.setPos_x(head.getPos_x()+0.1f);
head.setPos_y(head.getPos_y());
for (int i = 0; i < bodyArray.size(); i++)
{
if (i == 0)
{
bodyArray.elementAt(i).setPos_x(head.getPos_x()-10);
bodyArray.elementAt(i).setPos_y(head.getPos_y());
}
else
{
bodyArray.elementAt(i).setPos_x(bodyArray.elementAt(i-1).getPos_x()-10);
bodyArray.elementAt(i).setPos_y(bodyArray.elementAt(i-1).getPos_y());
}
}
break;
}
head.draw();
for (snakeBody i : bodyArray)
{
i.draw();
}
}
Refactorings
No refactoring yet !
Ants
May 26, 2009, May 26, 2009 01:15, permalink
Give a man a fish, or teach a man to fish?
Splitting the difference: Set a breakpoint on each of your for loops that copy the body array. Notice that by copying forward through your array that you are simply propagating the head value, hence getting the effect you are seeing. What happens if you copy backwards through your array?
Long term, though, you will probably be better served by changing data structures. Consider using a single linked list where you have a pointer to the first and last nodes. As the snake moves forward, simply create a new node with the new position and insert that at the beginning of the linked list. When the snake reaches maximum length, you simply start removing the last node of the list (and make sure that list gets terminated properly) each time the head moves forward.
Carl Manaster
June 8, 2009, June 08, 2009 19:06, permalink
Just a basic first-pass refactoring. Eliminate the duplication.
// to snakeBody class, add:
public void offset(double dx, double dy) {
setPos_x(getPos_x() + dx);
setPos_y(getPos_y() + dy);
}
// and change main function thus:
public void draw() {
switch (direction) {
case UP:
head.offset(0.0, (-0.1));
offsetBody(0, 10);
break;
case LEFT:
head.offset((-0.1), 0.0);
offsetBody(10, 0);
break;
case DOWN:
head.offset(0.0, 0.1);
offsetBody(0, -10);
break;
case RIGHT:
head.offset(0.1, 0.0);
offsetBody(-10, 0);
break;
}
head.draw();
for (SnakeBody i : bodyArray)
i.draw();
}
private void offsetBody(double dx, double dy) {
for (int i = 0; i < bodyArray.size(); i++) {
if (i == 0) {
bodyArray.get(i).setPos_x(head.getPos_x() + dx);
bodyArray.get(i).setPos_y(head.getPos_y() + dy);
} else {
bodyArray.get(i).setPos_x(bodyArray.get(i - 1).getPos_x() + dx);
bodyArray.get(i).setPos_y(bodyArray.get(i - 1).getPos_y() + dy);
}
}
}
I'm having a lot of trouble figuring out how to move each individual body piece at one time so they don't all completely change direction at one time. Instead, I want each body piece to wait its turn to move and follow the next body piece. The code i currently have has each body piece follow the one after it, but instead of turning with its turn, all the body pieces instantly (or very very very quickly) change direction. It would be great if someone can help me figure out how i can do that. Should i use a timer or something?