java - 为什么当我移动时,游戏中的情况会发生变化? Java处理环境

标签 java processing game-physics 2d-games

我正在处理中创建 2D 游戏。

  • 播放器始终位于屏幕中央
  • 玩家始终面向鼠标
  • 移动是通过相对于玩家移动世界来实现的

每个游戏循环:

  • 玩家速度会添加到该位置
  • 玩家加速度被添加到速度
  • 加速度设置为鼠标方向,与鼠标到屏幕中心的距离成正比。
  • 速度 +=(-速度 * 阻力),这样当您改变方向时,您可以实现平滑过渡。

所以基本上,您总是以与鼠标到玩家(屏幕中心)的距离成正比的速度向鼠标移动。

到目前为止,除了我的世界中对象的绘制方式存在一个错误之外,我的所有机制都工作正常。当我移动时,这些元素会根据方向稍微移动,但它们移动得非常平稳,好像与我的速度有关。它看起来非常像拖动效果。

我添加了一个世界边界,以及世界上的一些随机圆圈。边界似乎停留在正确的位置,但如果我向与墙相反的方向移动,边缘附近的圆圈可能会越过边缘。

有什么想法可能导致这种情况吗?这是相关代码(抱歉,有一点......)

import java.util.ArrayList;

//constants
int ROCKET_WIDTH = 32;
int ROCKET_HEIGHT = 52;
float PLAYER_MAX_ACC = 0.4;
float PLAYER_MAX_VEL = 12;
float MOVEMENT_RESISTANCE = 0.05;

//global variables
Rocket player;
ArrayList<PVector> balls;
float offsetX;
float offsetY;

void setup()
{
  size(800,600);
  frameRate(30);
  background(0);
  player = new Rocket();
  balls = new ArrayList<PVector>();
  offsetX = width/2 - player.pos.x;
  offsetY = height/2 - player.pos.y;
  for (int i = 0;i < 100;i++)
  {
    PVector vec = new PVector(random(-width,width*2),random(-height,height*2));
    balls.add(vec);
  }
}

void draw()
{
  background(0);
  drawWorldEdges();
  updateMechanics();
  for (PVector b:balls)
  {
    ellipseMode(CENTER);
    ellipse(b.x + offsetX,b.y + offsetY,10,10);
  }
  drawPlayer();
}

void drawWorldEdges()
{
  //top,right,bottom,left
  strokeWeight(1);
  stroke(255);
  line(-width + offsetX,-height + offsetY,(width * 2) + offsetX,-height +offsetY);
  line((width*2) + offsetX,-height + offsetY,(width*2)+offsetX,(height*2)+offsetY);
  line(-width+offsetX,(height*2)+offsetY,(width*2)+offsetX,(height*2)+offsetY);
  line(-width+offsetX,-height+offsetY,-width+offsetX,(height*2)+offsetY);
}


void updateMechanics()
{
  offsetX = width/2 -player.pos.x;
  offsetY = height/2 - player.pos.y;
  updateFacing();
  getMoveInput();
  updatePhysics();
}

void updatePhysics()
{
  if (player.pos.x < width*2 && player.pos.x >= -width)
  {
    player.pos.x += player.vel.x;
  }
  if (player.pos.y < height*2 && player.pos.y >= -height)
  {
    player.pos.y += player.vel.y;
  }
  player.vel.x += -player.vel.x * MOVEMENT_RESISTANCE;
  player.vel.y += -player.vel.y * MOVEMENT_RESISTANCE;
}

void getMoveInput()
{
  PVector vel = new PVector(mouseX - width/2,mouseY - height/2);
  float distMult = dist(mouseX,mouseY,width/2,height/2)/(Math.min(width,height) / 2);
  vel = vel.normalize().setMag(PLAYER_MAX_ACC * distMult);
  PVector newVel = new PVector(player.vel.x,player.vel.y);
  newVel.add(vel);
  if (newVel.mag() <= PLAYER_MAX_VEL)
  {
    player.vel.add(vel);
  }
}

void updateFacing()
{
  float x = mouseX;
  if (x == 0)
  {
    x = 0.1;
  }
  player.facing = PI/2 + atan((mouseY-(height/2))/(x-(width/2)));
  if (x < width/2)
  {
    player.facing += PI;
  }
}

void drawPlayer()
{
  pushMatrix();
  translate(width/2,height/2);
  rotate(player.facing);
  stroke(255);
  strokeWeight(2);
  fill(127);
  rect(-ROCKET_WIDTH/4,0-ROCKET_HEIGHT/2,ROCKET_WIDTH/2,ROCKET_HEIGHT*0.75);
  rect(-ROCKET_WIDTH/2,0,ROCKET_WIDTH/4,ROCKET_HEIGHT*0.5);
  rect(ROCKET_WIDTH/4,0,ROCKET_WIDTH/4,ROCKET_HEIGHT*0.5);
  popMatrix();
}

火箭级:

class Rocket
{
  PVector pos;
  PVector vel;
  float facing; //radians
  boolean pressingW,pressingA,pressingS,pressingD,mouseLClicked = false;
  public Rocket()
  {
    pos = new PVector(0,0);
    vel = new PVector(0,0);
    facing = 0;
  }

  public Rocket(int x,int y)
  {
    pos = new PVector(x,y);
    vel = new PVector(0,0);
    facing = 0;
  }
}

最佳答案

以后,请尝试发布MCVE而不是你的整个项目。将其范围缩小到尽可能少的代码行。在您的情况下,您只需显示两个圆圈,并且可以删除任何其他代码,例如显示船舶。

话虽这么说,您的问题是由多种因素引起的:

  • “星星”的位置存储在 PVector 中,它将它们存储为 float 值。
  • 您的 offsetXoffsetY 也是 float 值。
  • 但是,像素始终是 int 值! (半个像素实际上没有意义。)

发生的情况是,您的起始移动间隔略有不同,您的眼睛将其检测为零星移动。这是由于 float 值在不同时间到达下一个 int 值造成的。

假设您有两个位置:一个位于 [0, 10],另一个位于 [.6, 20]。最初,它们具有相同的像素 X 值 0,因为像素始终是 int 值。现在假设您的 xOffset.5,然后将其添加到您的位置中以获得 [.5, 10][ 1.1, 20]。现在,它们具有不同的像素 X 值 01,这使得看起来第二个移动了,但第一个没有!这就是导致您出现问题的原因。

有多种方法可以解决此问题,但最简单的方法可能是将星号位置初始化为 int 值:

PVector vec = new PVector(int(random(-width,width*2)), int(random(-height,height*2)));

这也是您的墙壁看起来不错的原因:这实际上只是您要更新的一个位置。

关于java - 为什么当我移动时,游戏中的情况会发生变化? Java处理环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41292266/

相关文章:

java - 嵌套循环的实现

java - 尝试查找 .bmp 文件的高度和宽度在处理中得到不一致的结果

c++ - 使用固定时间步移动 Sprite

android - 用于处理的游戏 handle 控制 + 用于控制 Arduino 机器人的 Android

java - 是否可以编写逻辑形式 "then if"的条件?

javascript - 如何让verlet集成碰撞更稳定?

java - 为什么我的坐标系没有反射(reflect)我请求的标准坐标轴?(LibGdx)

java - 为什么Thread.isInterrupted()总是返回false?

java - 在 GUI 上重复 controlChanges

java - SocketChannel 是否必须在应用程序关闭时显式关闭?