そのため、JPanel でスネークを全面的に移動する際に問題が発生しています。これは JPanel の問題でも障害でもありません。Snake を本来のように動かすことができません。問題の場所はわかっていますが、問題なく正しく動作させる方法がわかりません。
問題: スネークは互いに約 10 ピクセル離れているはずですが、互いに約 1 ピクセル離れて凝集しています。
これが本来の姿です。
まとまるとこんな感じ
私は考えられるいくつかの異なる方法を試し、何日もかけて取り組んできました。
Snake は 1px の速度で動き続けるはずなので、滑らかなアニメーションです。とにかく動かされているので、頭は影響を受ける必要はありません。しかし、ループが頭に追いつくと、頭の位置が検出され、体に位置が与えられます。
スネークの移動。
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
私がやろうとしていることです。しかし、ヘビが長くなるにつれて、適応しなければなりません。
編集3:
これが Player のクラス全体です。プレーヤー クラスは、すべての移動と自己調整を処理します。
クラスプレーヤー:
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;
}
}
}