0
\$\begingroup\$

So I was following this guy's tutorial on how to create the Super Mario Bros game, and I was wondering how it would be possible to change levels (screens), in the tutorial he creates a PlayScreen, I was wondering if when I create a class like "level2" I could make it extend from the playscreen and only change the file that the tmx map loader uses, I thought about doing a whole nem class with all the already created functions and just change the file, but there's other classes that uses the PlayScreen as a reference (B2WorldCreator). I know how I would do to end the level, I would do a object that when in colision would trigger the setScreen method.

(PLAYSCREEN)

public class PlayScreen implements Screen {


private MarioBros game;
private TextureAtlas atlas;

private OrthographicCamera gamecam;
private Viewport gamePort;
private Hud hud;

private TmxMapLoader mapLoader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;

private World world;
private Box2DDebugRenderer b2dr;
private B2WorldCreator creator;

private Mario player;

private Music music;

private Array<Item> items;
private LinkedBlockingQueue<ItemDef> itemsToSpawn;

Controller controller;

public PlayScreen(MarioBros game){
    atlas = new TextureAtlas("Mario_and_Enemies.pack");
    this.game = game;
    gamecam = new OrthographicCamera();
    gamePort = new FitViewport(MarioBros.V_WIDTH / MarioBros.PPM, MarioBros.V_HEIGHT / MarioBros.PPM, gamecam);
    hud = new Hud(game.batch);

    mapLoader = new TmxMapLoader();
    map = mapLoader.load("level1.tmx");

    renderer = new OrthogonalTiledMapRenderer(map, 1 / MarioBros.PPM);
    gamecam.position.set(gamePort.getWorldWidth()/2, gamePort.getWorldHeight()/2, 0);
    world = new World(new Vector2(0,-10), true);
    b2dr = new Box2DDebugRenderer();
    controller = new Controller();
    creator = new B2WorldCreator(this);
    player = new Mario(this);
    world.setContactListener(new WorldContactListener());
    music = MarioBros.manager.get("audio/music/mario_music.ogg", Music.class);
    music.setLooping(true);
    music.play();
    items = new Array<Item>();
    itemsToSpawn = new LinkedBlockingQueue<ItemDef>();
}

/i tried to create a function to change the file but it didn't worked as planned/

public void mudarMapa(String mapa){
    map = mapLoader.load(mapa);
}

public void spawnItem(ItemDef idef){
    itemsToSpawn.add(idef);
}

public void handleSpawningItems(){
    if (!itemsToSpawn.isEmpty()){
        ItemDef idef = itemsToSpawn.poll();
        if(idef.type == Mushroom.class){
            items.add(new Mushroom(this, idef.position.x, idef.position.y));
        }
    }
}


public TextureAtlas getAtlas(){
    return atlas;
}

@Override
public void show() {

}

public void handleInput(float dt){
if (player.currentState != Mario.State.DEAD){
    if(controller.isRightPressed())
        player.b2body.setLinearVelocity(new Vector2(1, 
player.b2body.getLinearVelocity().y));
    else if(controller.isLeftPressed())
        player.b2body.setLinearVelocity(new Vector2(-1, 
player.b2body.getLinearVelocity().y));
    else
        player.b2body.setLinearVelocity(new Vector2(0, 
player.b2body.getLinearVelocity().y));
    if (controller.isUpPressed() && player.b2body.getLinearVelocity().y==0)
        player.b2body.applyLinearImpulse(new Vector2(0, 5f), 
player.b2body.getWorldCenter(), true);

    }
}

public  void  update(float dt){
    handleInput(dt);
    handleSpawningItems();

    world.step(1/60f, 6, 2);

    player.update(dt);
    for (Enemy enemy : creator.getEnemies()){
        enemy.update(dt);
        if (enemy.getX() < player.getX() + 224/ MarioBros.PPM)
            enemy.b2body.setActive(true);
    }

    for (Item item: items)
        item.update(dt);

    hud.update(dt);

    if (player.currentState != Mario.State.DEAD){
    gamecam.position.x = player.b2body.getPosition().x;
    }

    gamecam.update();
    renderer.setView(gamecam);
}

@Override
public void render(float delta) {
    update(delta);

    Gdx.gl.glClearColor(0, 0, 0, 0);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    renderer.render();

    b2dr.render(world, gamecam.combined);

    game.batch.setProjectionMatrix(gamecam.combined);
    game.batch.begin();
    player.draw(game.batch);
    for (Enemy enemy : creator.getEnemies())
        enemy.draw(game.batch);
    for (Item item: items)
        item.draw(game.batch);

    game.batch.end();

    //hud
    game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
    hud.stage.draw();
    //controller
    if (Gdx.app.getType() == Application.ApplicationType.Android)
    controller.draw();

    if (gameOver()){
        game.setScreen(new GameOverScreen(game));
        dispose();
    }
}

public boolean gameOver(){
    if (player.currentState == Mario.State.DEAD && player.getStateTimer() > 3){
        return true;
    }
    return false;
}

@Override
public void resize(int width, int height) {
    gamePort.update(width, height);
    controller.resize(width, height);
}

public TiledMap getMap(){
    return map;
}

public World getWorld(){
    return world;
}

@Override
public void pause() {

}

@Override
public void resume() {

}

@Override
public void hide() {

}

@Override
public void dispose() {
    map.dispose();
    renderer.dispose();
    world.dispose();
    b2dr.dispose();
    hud.dispose();
    controller.dispose();
}

}

//level 2 screen

public class TESTE_TROCA_FASES extends PlayScreen{

public TESTE_TROCA_FASES(MarioBros game) {
    super(game);
}

@Override
public void mudarMapa(String mapa) {
    mudarMapa("level2.tmx");
}

@Override
public void spawnItem(ItemDef idef) {
    super.spawnItem(idef);
}

@Override
public void handleSpawningItems() {
    super.handleSpawningItems();
}

@Override
public TextureAtlas getAtlas() {
    return super.getAtlas();
}

@Override
public void show() {
    super.show();
}

@Override
public void handleInput(float dt) {
    super.handleInput(dt);
}

@Override
public void update(float dt) {
    super.update(dt);
}

@Override
public void render(float delta) {
    super.render(delta);
}

@Override
public boolean gameOver() {
    return super.gameOver();
}

@Override
public void resize(int width, int height) {
    super.resize(width, height);
}

@Override
public TiledMap getMap() {
    return super.getMap();
}

@Override
public World getWorld() {
    return super.getWorld();
}

@Override
public void pause() {
    super.pause();
}

@Override
public void resume() {
    super.resume();
}

@Override
public void hide() {
    super.hide();
}

@Override
public void dispose() {
    super.dispose();
}

}

\$\endgroup\$
  • 1
    \$\begingroup\$ 1) Why didn't it work? What happened? What did you want to happen? 2) You probably shouldn't have one class per level anyways. \$\endgroup\$ – Charanor May 18 '17 at 4:21
0
\$\begingroup\$

What you're doing here has no sense:

@Override
public void mudarMapa(String mapa) {
    mudarMapa("level2.tmx");
}

Firstly, you're calling the same method from the TESTE_TROCA_FASES class over and over again instead of calling the PlayScreen method, so you must add super in order to call the super method.

Anyway, if you want to load a different map, you need to change the map variable before creating OrthogonalTiledMapRenderer and everything else (box2d, etc), so what I would do is pass the map name in the class constructor:

public PlayScreen(MarioBros game, String mapName){
    atlas = new TextureAtlas("Mario_and_Enemies.pack");
    this.game = game;

    [...]

    mapLoader = new TmxMapLoader();
    map = mapLoader.load(mapName); //<--Here, the map is loaded whith the name

    renderer = new OrthogonalTiledMapRenderer(map, 1 / MarioBros.PPM);

    [...]

So anytime you want to load any map you just need to pass it as a parameter:

new PlayScreen(game, "level2.tmx");
\$\endgroup\$
  • \$\begingroup\$ The way you showed makes a lot more sense. Thanks for the help man! The way I did to solve it wasn't the better in terms of perfomance but it also worked, I made a public static variable in the main game class, in the line where I create in the playscreen class the map loader "map = mapLoader.load("level1.tmx")", now I use "map = mapLoader.load(GLOBALVAR)", and whenever I finish a level a make the GLOBALVAR value to the name of the tmx file I will use. \$\endgroup\$ – J. Carlos Jun 14 '17 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.