我试图让我自己的游戏版本倒下。我正在使用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;
}
}