[英]How to make one character follow the main character path? LIBGDX / JAVA
我正在使用 Box2d 在 libgdx/java 中的 RPG 2d 中工作。
我有主角和其他 3 個跟隨。 我希望他們像蛇一樣跟隨主角的相同路徑(與 Master System / Phantasy Star 和其他舊 RPG 相同)以避免在發現狹窄入口時搞砸。
在我的 PlayScreen class 中,我單獨調用所有字符。
private static Alis _player;
private static Myau _follower;
private static Odin _follower1;
private static Noah _follower2;
在構造函數播放屏幕上
_player = new Alis(world, this, mapManager);
_follower = new Myau(world, this, mapManager);
_follower1 = new Odin(world, this, mapManager);
_follower2 = new Noah(world, this, mapManager);
HandleInput(float dt) 方法我只移動主角
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT) && _player.b2body.getLinearVelocity().x <= 0.5f) {
_player.b2body.applyLinearImpulse(new Vector2(0.05f, 0), _player.b2body.getWorldCenter(), true);
}else if(Gdx.input.isKeyPressed(Input.Keys.LEFT) && _player.b2body.getLinearVelocity().x >= -0.5f) {
_player.b2body.applyLinearImpulse(new Vector2(-0.05f, 0), _player.b2body.getWorldCenter(), true);
}else if(Gdx.input.isKeyPressed(Input.Keys.RIGHT) == Gdx.input.isKeyPressed(Input.Keys.LEFT)){
_player.b2body.setLinearVelocity(0f, _player.b2body.getLinearVelocity().y);
}
if(Gdx.input.isKeyPressed(Input.Keys.UP) && _player.b2body.getLinearVelocity().y <= 0.5f) {
_player.b2body.applyLinearImpulse(new Vector2(0, 0.05f), _player.b2body.getWorldCenter(), true);
} else if(Gdx.input.isKeyPressed(Input.Keys.DOWN) && _player.b2body.getLinearVelocity().y >= -0.5f) {
_player.b2body.applyLinearImpulse(new Vector2(0, -0.05f), _player.b2body.getWorldCenter(), true);
} else if(Gdx.input.isKeyPressed(Input.Keys.UP) == Gdx.input.isKeyPressed(Input.Keys.DOWN)){ _player.b2body.setLinearVelocity(_player.b2body.getLinearVelocity().x, 0f);
}
更新(浮動dt)方法
handleInput(dt);
_player.update(dt);
_follower.update(dt, _player.b2body.getPosition());
_follower1.update(dt, _follower.b2body.getPosition());
_follower2.update(dt, _follower1.b2body.getPosition());
渲染(浮動增量)方法
game.batch.begin();
_follower2.draw(game.batch);
_follower1.draw(game.batch);
_follower.draw(game.batch);
_player.draw(game.batch);
game.batch.end();
dispose() 方法
_player.dispose();
_follower.dispose();
_follower1.dispose();
_follower2.dispose();
現在,在我的角色 class 中,使用update(float dt, Vector2 position)方法
if ((position.x - b2body.getPosition().x) > (15 /PhantasyStar.PPM)) {
b2body.setLinearVelocity(new Vector2(0.5f, 0));
} else if ((position.x - b2body.getPosition().x) < ( - 15 /PhantasyStar.PPM)) {
b2body.setLinearVelocity(new Vector2(-0.5f, 0));
} else if ((position.y - b2body.getPosition().y) > (15 / PhantasyStar.PPM)) {
b2body.setLinearVelocity(new Vector2(0, 0.5f));
} else if ((position.y - b2body.getPosition().y) < (-15 / PhantasyStar.PPM)) {
b2body.setLinearVelocity(new Vector2(0, -0.5f));
} else if (((position.y - b2body.getPosition().y) <= (15 / PhantasyStar.PPM) && (position.y - b2body.getPosition().y) >= (-15 / PhantasyStar.PPM)) || ((position.x - b2body.getPosition().x) <= (15 /PhantasyStar.PPM) && (position.x - b2body.getPosition().x) >= (-15 /PhantasyStar.PPM)) ) {
b2body.setLinearVelocity(new Vector2(0, 0));
}
setPosition(b2body.getPosition().x - getWidth() / 2, b2body.getPosition().y - getHeight() / 4);
setRegion(getFrame(dt));
這段代碼給了我一個很好的結果,例如,如果我只在 x 軸上或只在 y 軸上行走,玩家們就會完全按照我的需要行走,彼此之間的距離正確並且也正確地返回,但是如果我開始上下移動,他們開始互相跟隨,但每次我發現障礙時,一些追隨者都會卡住。 所以我希望他們完全遵循主角所引導的路徑。
我 100% 認為我所做的是不正確的,但我試圖為此找到一些文獻,但我沒有找到。 我相信如果我找到一種方法來獲得主要玩家的最后一個 position 並將其作為第二個目標。
我試圖在將播放器 position 更新為最后一個 position 后收集並在追隨者的下一次更新中使用,但是,即使我要求追隨者跟隨那個 position,它也太接近了,所以我認為它是不正確的position 收集,或者可能是另一種收集方式。 我是否需要創建一個數組來收集所有位置並將此信息延遲傳遞給其他角色?
在游戲開發方面有更多經驗的人可以幫助我嗎?
在 PlayScreen Class 上創建 2 Arrays 變量。 這兩個 Arrays 將收集主要玩家的位置和狀態。
public class PlayScreen implements Screen {
private Array<Vector2> _playerPath;
private Array<Alis.State> _playerState;
}
在 PlayScreen Constructor 上,我初始化了 Arrays,所以在 .get 和 .set 之后將起作用。
public PlayScreen(PhantasyStar game, MapManager mapManager){
//starting Array for player path and state
_playerPath = new Array<Vector2>(100);
_playerState = new Array<Alis.State>(100);
for(int k=0;k<100;k++) {
_playerPath.add(new Vector2(0f, 0f));
_playerState.add(Alis.State.STANDING_DOWN);
}
//Create Player
_player = new Alis(world, this, mapManager);
_follower = new Myau(world, this, mapManager);
_follower1 = new Odin(world, this, mapManager);
_follower2 = new Noah(world, this, mapManager);
}
依舊在PlayScreen Class,更新方法。 每個 position 和每個 state 都在 Arrays 內更新,為追隨者創建一個路徑。 我更新了每個延遲 20 幀的關注者更新方法。
public void update(float dt){
//start ***Items for the following path***
for (int i = 99; i > 0; i--) {
_playerPath.get(i).set(_playerPath.get(i - 1));
_playerState.set(i,_playerState.get(i - 1));
}
_playerPath.get(0).set(_player.b2body.getPosition());
_playerState.set(0, _player.currentState);
handleInput(dt);
world.step(1/60f, 6, 2);
_player.update(dt);
_follower.update(dt, _playerPath.get(20), _playerState.get(20));
_follower1.update(dt, _playerPath.get(40), _playerState.get(40));
_follower2.update(dt, _playerPath.get(60), _playerState.get(60));
// end ***Items for the following path ***
gamecam.position.x = _player.b2body.getPosition().x;
gamecam.position.y = _player.b2body.getPosition().y;
//removing the blank spaces in the borders stopping the camera
xOffset = (gamecam.position.x - PhantasyStar.V_WIDTH / PhantasyStar.PPM / 2);
xOffsetRight = (mapManager.getMapWidth() / PhantasyStar.PPM) - gamecam.position.x - (PhantasyStar.V_WIDTH / PhantasyStar.PPM / 2);
yOffset = (gamecam.position.y - (PhantasyStar.V_HEIGHT / PhantasyStar.PPM / 2));
yOffsetUp = (mapManager.getMapHeight() / PhantasyStar.PPM) - gamecam.position.y - (PhantasyStar.V_HEIGHT / PhantasyStar.PPM / 2);
if(xOffset < 0)
gamecam.position.x = PhantasyStar.V_WIDTH / PhantasyStar.PPM / 2;
if(xOffsetRight < 0)
gamecam.position.x = (mapManager.getMapWidth() / PhantasyStar.PPM) - (PhantasyStar.V_WIDTH / PhantasyStar.PPM / 2);
if(yOffset < 0)
gamecam.position.y = PhantasyStar.V_HEIGHT / PhantasyStar.PPM / 2;
if(yOffsetUp < 0)
gamecam.position.y = (mapManager.getMapHeight() / PhantasyStar.PPM) - (PhantasyStar.V_HEIGHT / PhantasyStar.PPM / 2);
// end removing blank spaces
//portal contact
if(isCollided) {
updateMap();
}
gamecam.update();
renderer.setView(gamecam);
}
下一個代碼是跟隨者 Class,使用 Arrays 中的 position 和 state。
public TextureRegion getFrame(float dt, Alis.State state) {
currentState = getState(state);
TextureRegion region;
switch (currentState) {
case RUN_UP:
region = myauRun_Up.getKeyFrame(stateTimer, true);
break;
case RUN_DOWN:
region = myauRun_Down.getKeyFrame(stateTimer, true);
break;
case RUN_RIGHT:
region = myauRun_Right.getKeyFrame(stateTimer, true);
break;
case RUN_LEFT:
region = myauRun_Left.getKeyFrame(stateTimer, true);
break;
case STANDING_UP:
region = myauStand_Up;
break;
case STANDING_RIGHT:
region = myauStand_Right;
break;
case STANDING_LEFT:
region = myauStand_Left;
break;
case STANDING_DOWN:
default:
region = myauStand_Down;
break;
}
stateTimer = currentState == previousState ? stateTimer + dt : 0;
previousState = currentState;
return region;
}
public State getState(Alis.State state) {
if (state == Alis.State.RUN_UP)
return State.RUN_UP;
else if (state == Alis.State.RUN_DOWN)
return State.RUN_DOWN;
else if (state == Alis.State.RUN_RIGHT)
return State.RUN_RIGHT;
else if (state == Alis.State.RUN_LEFT)
return State.RUN_LEFT;
else if (state == Alis.State.STANDING_UP)
return State.STANDING_UP;
else if (state == Alis.State.STANDING_LEFT)
return State.STANDING_LEFT;
else if (state == Alis.State.STANDING_DOWN)
return State.STANDING_DOWN;
else
return State.STANDING_DOWN;
}
public void update(float dt, Vector2 position, Alis.State state) {
setPosition(position.x - getWidth() / 2, position.y - getHeight() / 4);
setRegion(getFrame(dt, state));
}
我希望這可以幫助別人
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.