개인 프로젝트 용으로 Jet Set Willy를 기반으로 한 게임을 작성하고 있습니다. 알 수 있듯이, 캐릭터는 방에서 방으로 이동하여 그가가는 동안 아이템을 수집 할 수 있습니다.Java/LibGDX - 수집 된 항목을 방에서 방으로 추적
저는 LibGDX와 Tiled Map 편집기를 사용하고 있습니다.
I 현재 아래에 따라, '항목'라는 레이어에 내지도의 개체 타일을 기반으로 내 항목을로드 다음과 같이
public void loadItems() {
//////////////////////////////////////////////////////////////////////////
//create all Items
for(MapObject object : map.getLayers().get(4).getObjects().getByType(RectangleMapObject.class)){
Rectangle rect = ((RectangleMapObject) object).getRectangle();
//new Item(screen, object);
items.add(new Item(this, object, (rect.getX() + rect.getWidth()/2)/Engine.PPM, (rect.getY() + rect.getHeight()/2)/Engine.PPM));
}
}
항목
내 Playscreen에 배열에 저장된다 :public static Array<Item> items;
항목을 수집 할 때 간단히 화면에서 제거합니다.
방을 바꾸려면 기본적으로 새지도를로드하고 해당 레벨의 항목 등을 가져옵니다. 문제는 원래 방으로 다시 이동하면 항목을 다시 가져와 다시 모두 그려야한다는 것입니다. 다음과 같이
//////////////////////////////////////////////////////////////////////////////
/**
* Load the next Level
*/
public void changeMap(int roomNumber, float x, float y) {
map.dispose();
loadMap(roomNumber);
this.current_level = roomNumber;
renderer.getMap().dispose(); //dispose the old map
renderer.setMap(map); //set the map in your renderer
world = new World(new Vector2(0,-4), true);
world.setContactListener(new WorldContactListener());
creator = new B2WorldCreator(this);
loadItems();
//Reposition Player
player = new Player(world, this, x * Engine.TILE_WIDTH, y * Engine.TILE_HEIGHT);
}
내 항목 클래스는 다음과 같습니다
public class Item extends Sprite {
protected World world;
protected PlayScreen screen;
private float stateTime;
protected TiledMap map;
protected MapObject object;
private Animation animation;
private Array<TextureRegion> frames;
private boolean setToDestroy;
private boolean destroyed;
float angle;
public Body b2body;
FixtureDef fdef;
private Texture tex;
private Texture blank_texture;
private int item_number;
////////////////////////////////////////////////////////////////////////////////////////////
/**
* Constructor
* @param screen
* @param object
* @param x
* @param y
*/
public Item(PlayScreen screen, MapObject object, float x, float y){
this.world = screen.getWorld();
this.screen = screen;
this.map = screen.getMap();
//this.item_number = item_number;
setPosition(x, y);
Random rn = new Random();
int max = 2;
int min = 1;
int random = rn.nextInt(5) + 1;
tex = new Texture(Gdx.files.internal("sprites/item" + random + ".png"));
frames = new Array<TextureRegion>();
for(int i = 0; i < 4; i++) {
frames.add(new TextureRegion(tex, i * 16, 0, 16, 16));
}
animation = new Animation(0.1f, frames);
blank_texture = new Texture(Gdx.files.internal("sprites/blank_item.png"));
setBounds(getX(), getY(), 15/Engine.PPM, 15/Engine.PPM);
setToDestroy = false;
destroyed = false;
angle = 0;
stateTime = 0;
define_item();
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
*Define the Box2D body for the item
*/
public void define_item() {
BodyDef bdef = new BodyDef();
bdef.position.set(getX(), getY());
bdef.type = BodyDef.BodyType.StaticBody;
b2body = world.createBody(bdef);
fdef = new FixtureDef();
fdef.filter.categoryBits = Engine.ITEM_BIT;
fdef.filter.maskBits = Engine.PLAYER_BIT;
PolygonShape shape = new PolygonShape();
shape.setAsBox(7/Engine.PPM, 7/Engine.PPM);
fdef.shape = shape;
b2body.createFixture(fdef).setUserData(this);
b2body.setGravityScale(0);
b2body.setActive(true);
}
public void redefineItem() {
Gdx.app.log("redefineItem", "Item");
Vector2 position = b2body.getPosition();
world.destroyBody(b2body);
BodyDef bdef = new BodyDef();
bdef.position.set(position);
bdef.type = BodyDef.BodyType.StaticBody;
b2body = world.createBody(bdef);
fdef = new FixtureDef();
fdef.filter.categoryBits = Engine.ITEM_BIT;
fdef.filter.maskBits = Engine.PLAYER_BIT;
PolygonShape shape = new PolygonShape();
shape.setAsBox(7/Engine.PPM, 7/Engine.PPM);
fdef.shape = shape;
b2body.createFixture(fdef).setUserData(this);
b2body.setGravityScale(0);
b2body.setActive(true);
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
* Draw Method
* @param batch
*/
@Override
public void draw(Batch batch) {
if(!destroyed) {
super.draw(batch);
}
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
* Update the Items
* @param dt
*/
public void update(float dt){
setRegion(getFrame(dt));
stateTime += dt;
if(setToDestroy && !destroyed){
world.destroyBody(b2body);
destroyed = true;
setRegion(blank_texture);
stateTime = 0;
}
else if(!destroyed) {
setRegion(animation.getKeyFrame(stateTime, true));
setPosition(b2body.getPosition().x - getWidth()/2, b2body.getPosition().y - getHeight()/2);
}
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
* Get the Texture
* @param dt
* @return
*/
public TextureRegion getFrame(float dt){
TextureRegion region;
region = animation.getKeyFrame(stateTime, true);
return region;
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
* Item has been collected
* @param player
*/
public void collected(Player player) {
if(Engine.bPlaySounds) {
Sound sound = Gdx.audio.newSound(Gdx.files.internal("audio/sounds/collect_item.wav"));
sound.play(1.0f);
}
//Change the Category Bit, so that it is no longer collidable
fdef.filter.categoryBits = Engine.COLLECTED_BIT;
this.setToDestroy = true;
Gdx.app.log("Collected Item ", "" + this.item_number + " from room " + screen.getCurrentLevel());
//Increment the counter on the HUD
screen.incrementItemCounter();
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
* Set the category Filter
* @param filterBit
*/
public void setCategoryFilter(short filterBit){
Filter filter = new Filter();
filter.categoryBits = filterBit;
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
* Get the Tilemap cell
* @return
*/
public TiledMapTileLayer.Cell getCell(){
TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get(0);
return layer.getCell((int)(b2body.getPosition().x * Engine.PPM/16), (int)(b2body.getPosition().y * Engine.PPM/16));
}
}
내가 방 번호가 포함 배열의 어떤 종류에서 수집 각 항목을 저장, 그리고하려는 항목의 X/Y 위치. 항목을 다시 그릴 때 수집 된 목록에있는 항목을 건너 뜁니다. 문제는 Java에서이 작업을 수행하는 방법을 잘 모르겠습니다.
누구에게 내가 이것을 어떻게 달성 할 수있는 제안이 있습니까?
감사
제임스
레벨, 항목 및 저장하려는 데이터의 수에 따라 libGDX의 환경 설정이 가장 쉽습니다. "작은 게임 상태 저장"에 대한 정의에 따라 달라 지거나 roomItemStates를 문자열 또는 숫자로 인코딩하는 영리한 방법을 찾을 수 있다면 - https://github.com/libgdx/libgdx/wiki/ Preferences –
고마워, 나는 그것이 단순한 배열 [room_number, item_number] 일 수 있다고 생각했다. 항목을로드 할 때 아마도이 배열과 비교할 수 있으며 수집 된 배열에없는 항목 만 렌더링합니다. 게임을하는 동안에 만 기억할 필요가 있습니다. 게임 저장 등을 할 생각이 없습니다. 어떻게 생각하십니까? –
아, 그래. 나는 오해했다. 나는 네가 끈기를 찾고 있다고 생각했다. 메모리에만 있으면 더 간단합니다. 해시 맵은 키가 방 번호 인 가장 쉬운 방법 일 수 있으며 값은 수집 된 항목 (목록, 배열 등)을 저장하려고 할 수 있습니다. –