我正在尝试将蛇移动到JPanel中,但无法正确移动。这不是JPanel的问题或错误,而是我不能像应该的那样移动蛇。我知道问题出在哪里,但是我无法找到正确的解决方法。
问题:蛇应该相距约10像素,但它们聚集在一起,相距仅约1像素。
这是预期效果。
这是聚集在一起时的效果。
我已经尝试了多种方式,也已经努力了数日。
蛇应该以1像素的速度持续移动,以实现平滑动画。由于头部本来就会移动,因此不需要对头部进行处理。但是一旦循环追上头部,它会找到头部的位置,并将位置传递给身体。
蛇的移动。
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 > 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 > 0){
X[i] = X[i-1] + 10;
}
else if(newLocX < 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 > 0){
Y[i] = Y[i-1] + 10;
}
else if(newLocY < 0){
Y[i] = Y[i-1] - 10;
}
else{
Y[i] = Y[i-1];
}
}
}
}
}
编辑1:
非常感谢您的帮助!如果我需要添加更多细节,请随时让我知道!
编辑2:
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
我正在尝试的是IT技术相关内容。但是随着贪吃蛇越来越长,它必须适应。
编辑3:
这里是整个玩家类。玩家类负责所有移动和对齐自身的工作。
类玩家:
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 <= getSizeWithArmor(); i++){
X[i] = (boardWidth / 2) - (i * blockSize);
Y[i] = boardHeight / 2;
}
}
public void SetDirection(int key){
if(key == KeyEvent.VK_UP && !down){
up = true;
left = false;
down = false;
right = false;
}
else if(key == KeyEvent.VK_DOWN && !up){
up = false;
left = false;
down = true;
right = false;
}
else if(key == KeyEvent.VK_LEFT && !right){
up = false;
left = true;
down = false;
right = false;
}
else if(key == KeyEvent.VK_RIGHT && !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 > 0; i--){
int newLocX = X[i] - X[i-1];
int newLocY = Y[i] - Y[i-1];
//Block going left
if(newLocX > 0){
if(newLocX == -1){
}
else if(newLocX < -1){
X[i] = X[i-1] + 10;
}
}
//Block going right
else if(newLocX < 0){
X[i] = X[i-1] - 10;
}
//Block going up
if(newLocY > 0){
Y[i] = Y[i-1] + 10;
}
//Block going down
else if(newLocY < 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 < getSizeWithArmor(); i++){
if(i == 0){
g.drawImage(Head(), X[0], Y[0], null);
}
else if(getArmor() >= 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());
}
}
}
我的Board类调用了修改该类所需的所有数据。如果这个类非常杂乱无章,我感到抱歉。我还没有回去重新组织它,并减少其中的许多垃圾。此外,我知道很多代码是冗余且不需要的。我正在努力解决所有这些问题。现在我只是想修复贪吃蛇身体的问题。
编辑4:
我已经解决了其中的一部分。我已经让它平滑地向右和向下移动。但是一旦你往左或往上走,它将会崩溃,并再次引起问题。就像我需要检查它以前是怎么移动的,朝哪个方向移动。
public void MovePlayer(){
//Move the snake tail
if(IsMoving()){
//Move the head by its velocity
for(int i = getSizeWithArmor(); i > 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 && newLocY != 0){
}
//Block going left
if(newLocX > 0){
if(newLocX > 0 && newLocX <= 10){
X[i] -= 1;
}
else if(newLocX > 10){
X[i] = X[i-1] - 10;
}
}
//Block going right
else if(newLocX < 0){
if(newLocX < 0 && newLocX >= -10){
X[i] += 1;
}
else if(newLocX < -10){
X[i] = X[i-1] + 10;
}
}
//Block going up
else if(newLocY > 0){
if(newLocY == 1){
Y[i] -= 1;
}
else if(newLocY > 1){
Y[i] = Y[i-1] - 10;
}
}
//Block going down
else if(newLocY < 0){
if(newLocY < 0 && newLocY >= -10){
Y[i] += 1;
}
else if(newLocY < -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;
}
}
}
for(int i = getSizeWithArmor(); i >= 0; i--)
而不是for(int i = getSizeWithArmor(); i > 0; i--)
,因为这将永远不会检查数组的第一个值即array[0]
。 - David KroukampX[i] = X[i-1];
我会有一个IndexOutOfBoundsException
。数组中的0不需要被检查,因为它正在移动。唯一需要检查的是随着头部移动的身体。至少这是我理解的。 - Twister1002