libGDX - 如何制作像游戏Fall Down一样的Tiled Map滚动?

时间:2014-05-14 21:57:29

标签: java android libgdx

我试图让我自己的游戏版本倒下。我正在使用TiledMap来显示玩家必须躲闪的行。我随机选择了要放在这些行中的间隙,这一切都运行良好。我坚持的是如何让地图滚动并随着玩家的进展生成新的行。我认为最好删除顶行,并在滚动一定量时添加一行。我只是不知道从哪里开始或我应该做什么。

PlayScreen.java:

package com.divergent.tapdown.screens;

import java.util.Iterator;
import java.util.Random;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTile;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.divergent.tapdown.screens.entities.Player;

public class PlayScreen implements Screen {

    public Stage stage;
    public TextButton pauseButton;
    public TextButtonStyle pauseButtonStyle;
    public BitmapFont font;
    public Skin skin;
    public TextureAtlas buttonAtlas;
    public Table table;

public Stage pauseStage;
public BitmapFont pauseFont;
public Skin pauseSkin;
public Table pauseTable;
public TextButton resumeButton; 
public TextButtonStyle resumeButtonStyle;

private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private OrthographicCamera camera;

Player player;

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);

    camera.position.set(190, player.getY() + player.getHeight() / 2, 0);
    camera.update();

    renderer.setView(camera);
    renderer.render();

    renderer.getSpriteBatch().begin();
    player.draw(renderer.getSpriteBatch());
    renderer.getSpriteBatch().end();

    player.update(delta);

    stage.act();
    stage.draw();

}

@Override
public void resize(int width, int height) {

    camera.viewportHeight = height / 3;
    camera.viewportWidth = width / 3;

}

@Override
public void show() {

    // Create the tiled map and load the player
    map = new TmxMapLoader().load("maps/TapDown.tmx");

    renderer = new OrthogonalTiledMapRenderer(map);

    camera = new OrthographicCamera();
    camera.zoom = 1.65f;

    player = new Player(new Sprite(new Texture("img/player.png")), (TiledMapTileLayer) map.getLayers().get(0));
    player.setPosition(12 * player.getCollisionLayer().getTileWidth(), (player.getCollisionLayer().getHeight() - 1) * player.getCollisionLayer().getTileHeight());

    // Create the main stage

    stage = new Stage();

    Texture backgroundTexture = new Texture(Gdx.files.internal("img/background.png"));
    Image background = new Image(backgroundTexture);
    background.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());


    font = new BitmapFont();
    skin = new Skin();
    table = new Table(skin);
    table.setBounds(500, 850, 10, 10);

    buttonAtlas = new TextureAtlas(Gdx.files.internal("ui/button.pack"));
    skin.addRegions(buttonAtlas);

    pauseButtonStyle = new TextButtonStyle();
    pauseButtonStyle.font = font;
    pauseButtonStyle.fontColor = Color.BLACK;
    pauseButtonStyle.up = skin.getDrawable("button.up");
    pauseButtonStyle.down = skin.getDrawable("button.down");
    pauseButtonStyle.pressedOffsetX = 1;
    pauseButtonStyle.pressedOffsetY = -1;

    pauseButton = new TextButton("Pause Game", pauseButtonStyle);
    pauseButton.pad(20);

    pauseButton.addListener(new ClickListener(){
        @Override
        public void clicked(InputEvent event, float x, float y) {
            pause();

        }
    });

    table.add(pauseButton);
    stage.addActor(background);
    stage.addActor(table);

    // Create a multiplexer to handle both forms of input
    InputProcessor gameProcessor = player;
    InputProcessor stageProcessor = stage;
    InputMultiplexer inputMultiplexer = new InputMultiplexer();

    inputMultiplexer.addProcessor(gameProcessor);
    inputMultiplexer.addProcessor(stageProcessor);
    Gdx.input.setInputProcessor(inputMultiplexer);


    // Generates gaps    
    TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get(0);
    Cell gapCell;

        for(int row = 3; row <= 27; row = row + 4)
        {
            final int gap = GapPicker();

            gapCell = (Cell) layer.getCell(gap, row);
            gapCell.setTile(cellChanger());
            gapCell = (Cell) layer.getCell(gap + 1, row);
            gapCell.setTile(cellChanger());         
        }

    }   


public TiledMapTile cellChanger() {

    Iterator<TiledMapTile> tiles = map.getTileSets().getTileSet("tiles").iterator();
    TiledMapTile newTile = null;

    while(tiles.hasNext()) {
        TiledMapTile tile = tiles.next();

        if(tile.getProperties().containsKey("blank")) {
            newTile = tile;
        }
    }
    return newTile;

}

public int GapPicker() {

    Random randomGap = new Random();

    int gap = randomGap.nextInt(21) + 1; // between 1 and 21(1 less than the max because 1 needs to be added to make gap bigger)
    return gap;
}

@Override
public void hide() {
    dispose();

}

@Override
public void pause() {

    Texture pauseBackgroundTexture = new Texture(Gdx.files.internal("img/Pausebackground.png"));
    Image pauseBackground = new Image(pauseBackgroundTexture);
    pauseBackground.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

    pauseFont = new BitmapFont();
    pauseSkin = new Skin();
    pauseTable = new Table(pauseSkin);
    table.setBounds(500, 1280, 10, 10);

    buttonAtlas = new TextureAtlas(Gdx.files.internal("ui/button.pack"));
    skin.addRegions(buttonAtlas);

    resumeButtonStyle = new TextButtonStyle();
    resumeButtonStyle.font = font;
    resumeButtonStyle.fontColor = Color.BLACK;
    resumeButtonStyle.up = skin.getDrawable("button.up");
    resumeButtonStyle.down = skin.getDrawable("button.down");
    resumeButtonStyle.pressedOffsetX = 1;
    resumeButtonStyle.pressedOffsetY = -1;

    resumeButton = new TextButton("Resume Game", resumeButtonStyle);
    resumeButton.pad(20);

    resumeButton.addListener(new ClickListener() {

        @Override
        public void clicked(InputEvent event, float x, float y) {

        }
    }); 

    stage.addActor(pauseBackground);
    stage.addActor(resumeButton);
    stage.addActor(pauseTable);

}

@Override
public void resume() {
    dispose();

}

@Override
public void dispose() {
    map.dispose();
    renderer.dispose();
    player.getTexture().dispose();

}

}

Player.java:

package com.divergent.tapdown.screens.entities;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.math.Vector2;

public class Player extends Sprite implements InputProcessor {
/*** The movement velocity */
private Vector2 velocity = new Vector2();

private float speed = 60 * 2;
private float gravity = 60 * 1.8f;
private TiledMapTileLayer collisionLayer;
private String blockedKey = "blocked";

public Player(Sprite sprite, TiledMapTileLayer collisionLayer) {
    super(sprite);  
    this.collisionLayer = collisionLayer;
}

public void draw(SpriteBatch spriteBatch) {
    update(Gdx.graphics.getDeltaTime());
    super.draw(spriteBatch);
}

public void update(float delta) {
    //apply gravity to player
    velocity.y -= gravity * delta;

    //clamp velocity
    if(velocity.y > speed) 
        velocity.y = speed;
     else if(velocity.y < -speed) 
        velocity.y = -speed;

    float oldX = getX(), oldY = getY(); //save old pos

    boolean collisionX = false, collisionY = false;

    setX(getX() + velocity.x * delta); //move x

    if(velocity.x < 0) {
        //top left
        collisionX = isCellBlocked(getX(), getY() + getHeight());
        //middle left
        if(!collisionX)
        collisionX = isCellBlocked(getX(), getY() + getHeight() / 2);
        //bottom left
        if(!collisionX)
        collisionX = isCellBlocked(getX(), getY());

    } else if(velocity.x > 0) {
        //top right
        collisionX = isCellBlocked(getX() + getWidth(), getY() + getHeight());

        //middle right
        if(!collisionX)
        collisionX = isCellBlocked(getX() + getWidth(), getY() + getHeight() / 2);

        //bottom right
        if(!collisionX)
            collisionX = isCellBlocked(getX() + getWidth(), getY());

    }

    if(collisionX) {
        //react to collision
        setX(oldX);
        velocity.x = 0;
    }

    setY(getY() + velocity.y * delta); //move y

    if(velocity.y < 0) {

        //bottom left
        collisionY = isCellBlocked(getX(), getY());

        //bottom middle
        if(!collisionY)
            collisionY = isCellBlocked(getX() + getWidth() / 2, getY());

        //bottom right
        if(!collisionY)
            collisionY = isCellBlocked(getX() + getWidth(), getY());


    } else if(velocity.y > 0) {
        //top left
        collisionY = isCellBlocked(getX(), getY() + getHeight());

        //top middle
        if(!collisionY)
            collisionY = isCellBlocked(getX() + getWidth() / 2, getY() + getHeight());

        //top right
        if(!collisionY)
            collisionY = isCellBlocked(getX() + getWidth(), getY() + getHeight());

    }

    if(collisionY) {
        //react to collision
        setY(oldY);
        velocity.y = 0;

    }

}

private boolean isCellBlocked(float x, float y) {

    Cell cell = collisionLayer.getCell((int) (x / collisionLayer.getTileWidth()), (int) (y / collisionLayer.getTileHeight()));
    return cell != null && cell.getTile() != null && cell.getTile().getProperties().containsKey(blockedKey);
}



public Vector2 getVelocity() {
    return velocity;
}

public void setVelocity(Vector2 velocity) {
    this.velocity = velocity;
}

public float getSpeed() {
    return speed;
}

public void setSpeed(float speed) {
    this.speed = speed;
}

public float getGravity() {
    return gravity;
}

public void setGravity(float gravity) {
    this.gravity = gravity;
}

public TiledMapTileLayer getCollisionLayer() {
    return collisionLayer;
}

public void setCollisionLayer(TiledMapTileLayer collisionLayer) {
    this.collisionLayer = collisionLayer;
}

@Override
public boolean keyDown(int keycode) {
    switch(keycode) {
    case Keys.SPACE:
        velocity.y = speed;
        break;
    case Keys.A:
        velocity.x = -speed;
        break;
    case Keys.D:
        velocity.x = speed;
        break;
    }   
    return true;
}

@Override
public boolean keyUp(int keycode) {
    switch(keycode){
    case Keys.SPACE:
        velocity.y = 0;
        break;
    case Keys.A:
        velocity.x = 0;
        break;
    case Keys.D:
        velocity.x = 0;
        break;
    }
    return true;
}

@Override
public boolean keyTyped(char character) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean mouseMoved(int screenX, int screenY) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean scrolled(int amount) {
    // TODO Auto-generated method stub
    return false;
}


}

0 个答案:

没有答案