Arraylist 处理:蛇游戏动作逻辑

Arraylist 处理:蛇游戏动作逻辑,arraylist,processing,Arraylist,Processing,每次我吃苹果时,我的蛇的移动速度都会加倍。我似乎不知道是什么引起的。另外,让我困惑的另一件事是,每当我调用background()然后调用它正下方的drawgrid时,网格在游戏开始时快速出现和消失,然后再也不会被绘制。任何帮助都将不胜感激。代码如下: class Sprite { float x; float y; float [] dx = {0, 0, 20, -20};//up, down, right, left float [] dy = {20, -20, 0,

每次我吃苹果时,我的蛇的移动速度都会加倍。我似乎不知道是什么引起的。另外,让我困惑的另一件事是,每当我调用background()然后调用它正下方的drawgrid时,网格在游戏开始时快速出现和消失,然后再也不会被绘制。任何帮助都将不胜感激。代码如下:

  class Sprite {
  float x;
  float y;
  float [] dx = {0, 0, 20, -20};//up, down, right, left
  float [] dy = {20, -20, 0, 0};//up, down, right, left

  void update() {
    x += dx[dir];
    y += dy[dir];
  }
}

class Body extends Sprite {

  void render() {

    pushMatrix();
    stroke(255);
    fill(0);
    rect(x, y, bSize, bSize);
    popMatrix();
  }

  void update() {
    super.update();
    if (Direction.equals("up")) {
      dir = 1;
    } else if (Direction.equals("down")) {
      dir = 0;
    } else if (Direction.equals("right")) {
      dir = 2;
    } else if (Direction.equals("left")) {
      dir = 3;
    }

    if (dist(x, y, applex*bSize, appley*bSize) < 10) {
      add = true;
      applex = ceil(random(0, 38));
      appley = ceil(random(0, 38));
    }
  }
}
int w = 50;
int h = 50;
float bSize;
color fillColor;
String Direction;
int dir = 2; //starting at the "right" direction
ArrayList<Body> sBody;
float applex;
float appley;
float prevX;
float prevY;

boolean add = false;

void setup() {

  size(801, 801);
  smooth();
  //frameRate(12);
  applex = ceil(random(0, 38));
  appley = ceil(random(0, 38));
  bSize = 20;
  prevX = -5;
  prevY = -5;
  fillColor = color(0);
  Direction = "right";
  sBody = new ArrayList<Body>();
  Body b = new Body();
  sBody.add(b);
}

void draw() {
  if (add) {
    Body b = new Body();
    sBody.add(b);
    add = false;
  }

  if ((frameCount%5)==0) {
    //background(255);
    drawGrid();
    fill(255, 0, 0);
    rect(applex*bSize, appley*bSize, 20, 20);
    for (Body t : sBody) {
      if (prevX > -1 && prevY > -1) {
        t.x = prevX;
        t.y = prevY;
      }
      t.render();
      t.update();
      prevX = t.x;
      prevY = t.y;
    }
  }
}

void keyPressed() {
  if (key == CODED) {

    if (Direction.equals("right") || Direction.equals("left")) {
      if (keyCode == UP) {
        Direction = "up";
      }
      if (keyCode == DOWN) {
        Direction = "down";
      }
    }

    if (Direction.equals("up") || Direction.equals("down")) {
      if (keyCode == RIGHT) {
        Direction = "right";
      }
      if (keyCode == LEFT) {
        Direction = "left";
      }
    }
  }
}

void drawGrid() {

  for (int i =  0; i < height; i += 20) {
    for (int j = 0; j < width; j += 20) {
      pushMatrix();
      fill(200);
      stroke(255);
      rect(i, j, bSize, bSize);
      popMatrix();
    }
  }
}


////end of code////
类精灵{
浮动x;
浮动y;
float[]dx={0,0,20,-20};//上、下、右、左
float[]dy={20,-20,0,0};//上、下、右、左
无效更新(){
x+=dx[dir];
y+=dy[dir];
}
}
类主体扩展了Sprite{
void render(){
pushMatrix();
中风(255);
填充(0);
rect(x,y,bSize,bSize);
popMatrix();
}
无效更新(){
super.update();
如果(方向等于(“向上”)){
dir=1;
}else if(方向等于(“向下”)){
dir=0;
}else if(方向等于(“右”)){
dir=2;
}else if(方向等于(“左”)){
dir=3;
}
if(距离(x,y,applex*bSize,appley*bSize)<10){
加法=真;
applex=ceil(随机(0,38));
appley=ceil(随机(0,38));
}
}
}
int w=50;
int h=50;
浮动大小;
颜色填充颜色;
弦方向;
int dir=2//从“正确”的方向开始
阵列体;
浮动applex;
浮子苹果;
浮动prevX;
浮动汇率;
布尔加法=假;
无效设置(){
尺寸(801801);
光滑的();
//帧率(12);
applex=ceil(随机(0,38));
appley=ceil(随机(0,38));
bSize=20;
prevX=-5;
prevY=-5;
fillColor=color(0);
Direction=“right”;
sBody=newarraylist();
主体b=新主体();
sBody.添加(b);
}
作废提款(){
如果(添加){
主体b=新主体();
sBody.添加(b);
add=false;
}
如果((帧数%5)=0){
//背景(255);
drawGrid();
填充(255,0,0);
rect(applex*bSize,appley*bSize,20,20);
用于(车身t:sBody){
if(prevX>-1&&prevY>-1){
t、 x=prevX;
t、 y=上一个;
}
t、 render();
t、 更新();
prevX=t.x;
prevY=t.y;
}
}
}
按下void键(){
如果(键==编码){
if(方向等于(“右”)| |方向等于(“左”)){
if(keyCode==UP){
方向=“向上”;
}
如果(键代码==向下){
方向=“向下”;
}
}
如果(方向等于(“向上”)|方向等于(“向下”)){
if(keyCode==右){
Direction=“right”;
}
if(keyCode==左){
方向=“左”;
}
}
}
}
void drawGrid(){
对于(int i=0;i
您的逻辑有一些问题

看看这个循环:

for (Body t : sBody) {
      if (prevX > -1 && prevY > -1) {
        t.x = prevX;
        t.y = prevY;
      }
      t.render();
      t.update();
      prevX = t.x;
      prevY = t.y;
 }
注意您是如何对列表中的每个
对象调用
update()
。这会导致蛇在每一段都移动,这就是为什么它越长越快的原因。若要解决该问题,只需在蛇的头部调用
update()
,然后在其余部分循环,使其跟随头部

但这不是你唯一的问题。还请注意,在该循环退出后,
prevX
prevY
将在
sBody
列表中保存最后一个
对象的值。然后,下次循环时,将蛇的头部的位置设置为该位置。这没有任何意义,它会导致你的蛇从最后一段而不是头部“转向”

您的第三个问题是:在更新它们之后,您还设置了
prevX
prevY
的值,这再次导致您的snake行为不正确

因此,要解决所有这些问题,您需要做几件事:

  • 只有
    update()
    蛇头
  • 在每个循环之前设置
    prevX
    prevY
    ,而不是将头部移动到末端
  • 只需在蛇的其余部分中循环,使其跟随头部
  • 使用临时变量,以便将
    prevX
    prevY
    设置为更新前
    t.x
    t.y
    保持的值
最后,您的循环应该如下所示:

    //only move the head
    sBody.get(0).update();

    //set prevX and prevY to the head's position
    prevX =  sBody.get(0).x;
    prevY =  sBody.get(0).y;

    for (Body t : sBody) {

      //render ever piece, including the head
      t.render();

      //but don't move the head again
      if (t == sBody.get(0)) {
        continue;
      }

      //store the position before you change it
      float tempX = t.x;
      float tempY = t.y;

      //change the position
      t.x = prevX;
      t.y = prevY;

      //prevX and prevY hold the t.x and t.y values **before** you updated them
      prevX = tempX;
      prevY = tempY;
    }
另外,值得注意的是,使用2D数组可能更容易实现。哦,您对
pushMatrix()
popMatrix()
的调用是不必要的,因为您实际上并没有修改矩阵。

如果您在设置中放入
frameRate(5)
,您将看到为什么会发生这种情况,而且如果((frameCount%5)==0),您将不需要
If((frameCount%5)=
)。本质上,就像你有很多身体一样,整条蛇跳过了那么多的障碍!这是因为您构建for循环的方式,它基本上以这样一种方式渲染块,即最后一个块是蛇头

如果我可以提出一个更好的解决方案。唯一需要更新的块是蛇头,我建议它是
sBody.get(0)
。其余的块只需要具有上一个位置,但必须注意每个单元格都具有上一个单元格的位置!以下是解决方案:

for (Body t : sBody) {
  if (t == sBody.get(0)) {
    // if its the first element (the head) store its 
    // position in prevX,prevY and update it afterwards
    prevX = t.x;
    prevY = t.y;
    t.update();
  } else {
    // otherwise for other blocks, since we are 
    // using prevX, prevY for the previous block
    // we need to store the current position
    // of this block to give it back to prevX, prevY
    float tpX = t.x;
    float tpY = t.y;
    t.x = prevX;
    t.y = prevY;
    prevX = tpX;
    prevY = tpY;
  }
  t.render();
}

在我的例子中,我没有看到网格问题,这可能是因为您正在使用
if((frameCount%5)==0)
行…

非常感谢!你的回答很有帮助。