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
  • 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, 2017 at 4:21

1 Answer 1

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\$
1
  • \$\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, 2017 at 16:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .