Note that there are some explanatory texts on larger screens.

plurals
  1. POMoving Snake's body across the board is causing clumping of the body
    primarykey
    data
    text
    <p>So I am having some issues with moving my Snake across the board in a JPanel. Now it's not the JPanel's issue or fault, I'm just not able to move the Snake like it should. I know where the issue is, but I just can't figure out a way to make it work correctly without issues.</p> <p>Issue: The Snake is supposed to be about 10 px away from each other, however it is clumping up to be about 1 px away from each other.</p> <p>This is how it is supposed to look.</p> <p><img src="https://i.stack.imgur.com/sfImi.png" alt="This is how it is supposed to look."></p> <p>This is how it looks when it clumps up</p> <p><img src="https://i.stack.imgur.com/L0i7g.png" alt="This is how it looks when it clumps up"></p> <p>I have tried several different ways that I can think of, and I have worked on it for days. </p> <p>The Snake is supposed to keep moving at 1px for its velocity, so it is smooth animation. The head doesn't need to be affected since it is being moved anyways. But once the loop catches up to the head, it finds the position of the head, and gives the location to the body.</p> <p>Moving of the Snake.</p> <pre><code>int playerVel = 1; public void MovePlayer(){ //Move the snake tail if(IsMoving()){ //Move the head by its velocity if(left){ X[0] -= playerVel; } else if(right){ X[0] += playerVel; } else if(up){ Y[0] -= playerVel; } else if(down){ Y[0] += playerVel; } for(int i = getSizeWithArmor(); i &gt; 0; i--){ //Issue is when the for loop finishes counting down it located the Head's position that is 1 px away, and the rest of the body clumps up to it. int newLocX = X[i] - X[i-1]; int newLocY = Y[i] - Y[i-1]; if(newLocX != 0){ if(newLocX == 10 || newLocX == -10){ X[i] = X[i-1]; } else if(newLocX &gt; 0){ X[i] = X[i-1] + 10; } else if(newLocX &lt; 0){ X[i] = X[i-1] - 10; } else{ X[i] = X[i-1]; } } if(newLocY != 0){ if(newLocY == 10 || newLocY == -10){ Y[i] = Y[i-1]; } else if(newLocY &gt; 0){ Y[i] = Y[i-1] + 10; } else if(newLocY &lt; 0){ Y[i] = Y[i-1] - 10; } else{ Y[i] = Y[i-1]; } } } } } </code></pre> <p>Edit 1:</p> <p>Any help would be greatly appreciated! If I need to add more detail, please feel free to let me know!</p> <p>Edit 2:</p> <pre><code> Move X[0] X[1] X[2] X[3] X[4] X[5] ----------------------------------------------------- 1 60 50 40 30 20 10 2 61 51 41 31 21 11 3 62 52 42 32 22 12 4 63 53 43 33 23 13 5 64 54 44 34 24 14 6 65 55 45 35 25 15 7 66 56 46 36 26 16 8 67 57 47 37 27 17 </code></pre> <p>is what I'm looking at trying to do. But as the Snake grows longer, it must adapt.</p> <p>Edit 3:</p> <p>Here is the whole class of Player. The player class takes care of all the moving, and aligning its self. </p> <p>Class Player: </p> <pre><code>public class Player implements Runnable{ //Info about the Player private int[] X; private int[] Y; private int[] size; private int blockPickup; private int points; private int armor; private int blockSize = 10; //Speeds private int playerVel = 1; private int speedDelay = 100; //Direction the player is moving private boolean up = false; private boolean down = false; private boolean right = false; private boolean left = false; private boolean inGame = false; private boolean gamePaused = false; private int boardWidth; private int boardHeight; private int allSpaces; public void AddBlock(){ size = new int[getSizeWithArmor() + 1]; points++; blockPickup++; } private void AddBlock(int increase){ size = new int[getSizeWithArmor() + increase]; points++; } public void AddArmor(){ armor++; AddBlock(1); } public void RemoveArmor(){ armor--; size = new int[getSizeWithArmor() - 1]; } public int getArmor(){ return armor; } public int getSizeWithArmor(){ return size.length; } public int getSizeWithoutArmor(){ return size.length - armor; } public void ResetSize(){ size = new int[1 + getArmor()]; } public int getPoints(){ return points; } public void IsGamePlaying(boolean playing){ inGame = playing; } public void IsGamePaused(boolean pause){ gamePaused = pause; } public void Reset(){ points = 0; armor = 0; blockPickup = 0; ResetSize(); InitPlayer(); } public Image Head(){ if(up){ return headUp; } else if(down){ return headDown; } else if(right){ return headRight; } else if(left){ return headLeft; } else{ return headRight; } } public void InitPlayer(){ for(int i = 0; i &lt;= getSizeWithArmor(); i++){ X[i] = (boardWidth / 2) - (i * blockSize); Y[i] = boardHeight / 2; } } public void SetDirection(int key){ if(key == KeyEvent.VK_UP &amp;&amp; !down){ up = true; left = false; down = false; right = false; } else if(key == KeyEvent.VK_DOWN &amp;&amp; !up){ up = false; left = false; down = true; right = false; } else if(key == KeyEvent.VK_LEFT &amp;&amp; !right){ up = false; left = true; down = false; right = false; } else if(key == KeyEvent.VK_RIGHT &amp;&amp; !left){ up = false; left = false; down = false; right = true; } } public void MovePlayer(){ //Move the snake tail if(IsMoving()){ //Move the head by its velocity for(int i = getSizeWithArmor(); i &gt; 0; i--){ int newLocX = X[i] - X[i-1]; int newLocY = Y[i] - Y[i-1]; //Block going left if(newLocX &gt; 0){ if(newLocX == -1){ } else if(newLocX &lt; -1){ X[i] = X[i-1] + 10; } } //Block going right else if(newLocX &lt; 0){ X[i] = X[i-1] - 10; } //Block going up if(newLocY &gt; 0){ Y[i] = Y[i-1] + 10; } //Block going down else if(newLocY &lt; 0){ Y[i] = Y[i-1] - 10; } } if(left){ X[0] -= playerVel; } else if(right){ X[0] += playerVel; } else if(up){ Y[0] -= playerVel; } else if(down){ Y[0] += playerVel; } } } public boolean IsMoving(){ if(up || down || left || right){ return true; } else{ return false; } } public int getX(int i){ return X[i]; } public int getY(int i){ return Y[i]; } public void paint(Graphics2D g){ for(int i = 0; i &lt; getSizeWithArmor(); i++){ if(i == 0){ g.drawImage(Head(), X[0], Y[0], null); } else if(getArmor() &gt;= i){ g.drawImage(armorImage, X[i], Y[i], null); } else{ g.setColor(Color.YELLOW); g.fillRect(X[i], Y[i], blockSize, blockSize); } } } @Override public void run() { try{ while(inGame){ if(!gamePaused){ MovePlayer(); Thread.sleep(20); } } } catch(Exception e){ System.err.println("Player has encoundered an error: "+e.getMessage()); } } } </code></pre> <p>My Board class calls all of the data needed to make changes to this class. I apologize if this class is very unorganized. I haven't went back to reorganize it and reduce a lot of the crap in it. Also I know a lot of the code is redundant and not needed. I am working on fixing all of that. Right now I'm just trying to fix the snake's body issue.</p> <p>Edit 4:</p> <p>I've figured out part of it. I've got it to smoothly animate to the right and down. However once you go left or up, it will collpase, and start cauing issues again. Its like I need to check to see if it was moving before and in which direction.</p> <pre><code>public void MovePlayer(){ //Move the snake tail if(IsMoving()){ //Move the head by its velocity for(int i = getSizeWithArmor(); i &gt; 0; i--){ int newLocX = X[i] - X[i-1]; int newLocY = Y[i] - Y[i-1]; //Figure out the last direction it was going in if(newLocX != 0 &amp;&amp; newLocY != 0){ } //Block going left if(newLocX &gt; 0){ if(newLocX &gt; 0 &amp;&amp; newLocX &lt;= 10){ X[i] -= 1; } else if(newLocX &gt; 10){ X[i] = X[i-1] - 10; } } //Block going right else if(newLocX &lt; 0){ if(newLocX &lt; 0 &amp;&amp; newLocX &gt;= -10){ X[i] += 1; } else if(newLocX &lt; -10){ X[i] = X[i-1] + 10; } } //Block going up else if(newLocY &gt; 0){ if(newLocY == 1){ Y[i] -= 1; } else if(newLocY &gt; 1){ Y[i] = Y[i-1] - 10; } } //Block going down else if(newLocY &lt; 0){ if(newLocY &lt; 0 &amp;&amp; newLocY &gt;= -10){ Y[i] += 1; } else if(newLocY &lt; -10){ Y[i] = Y[i-1] + 10; } } if(left){ X[0] -= playerVel; } else if(right){ X[0] += playerVel; } else if(up){ Y[0] -= playerVel; } else if(down){ Y[0] += playerVel; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload