реализовать игровые состояния с макетом MVC?

Привет, я создаю базовую игру и пытаюсь реализовать шаблон MVC с помощью своего кода. В настоящее время у меня есть: Модель игровой объект, облака, вода в лодке и т. д.

мир Это связывает все модели вместе и определяет объекты

WorldRenderer Применяет все текстуры к объектам.

GameScreen обрабатывает пользовательский ввод, касание или клавиатуру.

Моя проблема в том, как и где я могу реализовать игровые состояния? Я предполагаю, что он попадет на GameScreen, но я реализовал базовую схему состояний, READY, RUNNING, PAUSED, NEXT_LVL, GAME_OVER,

Но что я обнаружил, когда при представлении состояния READY игра работает в фоновом режиме?

это определено в WorldRenderer, то есть уровень воды поднимается вверх по экрану на заднем плане, но я хочу, чтобы это происходило только тогда, когда состояние игры переключается на бег.

как мне заставить Gamestate инициализировать WorldRenderer только тогда, когда Gamstate переключается в РАБОЧЕЕ СОСТОЯНИЕ. Я применил оператор renderer.render(); к оператору RUNNING, но он все еще работает в состоянии READY.

Любая помощь в этом будет очень признательна.

Ваше здоровье

Даниэль.

Я присоединяю классы WorldRenderer, World и GameScreen.

GameScreen Class


    import com.badlogic.gdx.Gdx;

    import com.badlogic.gdx.Input.Keys;

    import com.badlogic.gdx.Screen;
    import com.badlogic.gdx.graphics.GL10;
    import com.badlogic.gdx.graphics.OrthographicCamera;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.Texture.TextureFilter;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    import com.badlogic.gdx.graphics.g2d.TextureRegion;

    import com.badlogic.gdx.math.Rectangle;
    import com.badlogic.gdx.math.Vector3;




    public class GameScreen implements Screen {

    enum State{
        READY,RUNNING,PAUSED,LEVEL_END,GAME_OVER
    }


    MainThing game;


    OrthographicCamera cam;
    SpriteBatch batch;

    Texture pauseMenu;
    TextureRegion pauseMenuR;

    Texture pauseBtn;

    Texture ready;
    TextureRegion readyR;

    private World world;
    private WorldRenderer renderer;

    public static State state = State.READY;


    public GameScreen(MainThing game){

        this.game = game;
        cam = new OrthographicCamera(800,480);
        cam.position.set(800/2, 480/2, 0);
        batch = new SpriteBatch();
        state = State.READY;

        loadingTexture();

    }





    private void loadingTexture() {

        pauseBtn = Assets.manager.get("pause.png", Texture.class);

        pauseMenu = Assets.manager.get("resume-quit.png", Texture.class);
        pauseMenu.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        pauseMenuR = new TextureRegion(pauseMenu,0,0,375,256);

        ready = Assets.manager.get("ready.png",Texture.class);
        readyR = new TextureRegion(ready,0,0,256,105);
    }


    public static void setState(State newState){
        state = newState;
    }





    private void update(float delta) {

        switch (state) {
        case READY:
            updateReady();
            break;
        case RUNNING:
            updateRunning(delta);
            break;
        case PAUSED:
            updatePaused();
            break;
        case LEVEL_END:
            updateLevelEnd();
            break;
        case GAME_OVER:
            updateGameOver();
            break;
        }

    }



    private void updateReady() {
        if (Gdx.input.justTouched()) {
            state = State.RUNNING;
        }

    }

    private void updateRunning(float delta) {

        if(Gdx.input.isTouched()) {
             Vector3 touchPos = new Vector3();
             touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
             WorldRenderer.cam.unproject(touchPos);
             Boat.position.x = touchPos.x - 1f / 2;
          }



        if(Gdx.input.isKeyPressed(Keys.LEFT)) {

        Boat.velocity.x = -Boat.SPEED * delta;
        }


        else if(Gdx.input.isKeyPressed(Keys.RIGHT)) {

            Boat.velocity.x = Boat.SPEED * delta;
          }
        else if(!Gdx.input.isKeyPressed(Keys.LEFT) && !(Gdx.input.isKeyPressed(Keys.RIGHT)) || (Gdx.input.isKeyPressed(Keys.LEFT) && (Gdx.input.isKeyPressed(Keys.RIGHT)))) {

            Boat.velocity.x = 0;
            }

          Boat.update(delta);

          if(Boat.position.x < 0) Boat.position.x = 0;
          if(Boat.position.x > WorldRenderer.cam.viewportWidth - 1f) Boat.position.x = WorldRenderer.cam.viewportWidth - 1f;


    }




    private void updatePaused() {
        // TODO Auto-generated method stub

    }





    private void updateLevelEnd() {
        // TODO Auto-generated method stub

    }





    private void updateGameOver() {
        // TODO Auto-generated method stub

    }





    private void draw(float deltaTime) {

        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        renderer.render(deltaTime);
        cam.update();
        batch.setProjectionMatrix(cam.combined);
        batch.begin();

        switch (state) {
        case READY:
            presentReady();
            break;
        case RUNNING:
            presentRunning(deltaTime);
            break;
        case PAUSED:
            presentPaused();
            break;
        case LEVEL_END:
            presentLevelEnd();
            break;
        case GAME_OVER:
            presentGameOver();
            break;
        }
        batch.end();
    }




    private void presentReady() {
        batch.draw(readyR, cam.viewportWidth /2 - 375 /2    , cam.viewportHeight /2 - 256 /2,375,256);

    }





    private void presentRunning(float delta) {
        // TODO Auto-generated method stub

    }





    private void presentPaused() {
        // TODO Auto-generated method stub

    }





    private void presentLevelEnd() {
        // TODO Auto-generated method stub

    }





    private void presentGameOver() {
        // TODO Auto-generated method stub

    }




    @Override
    public void render(float delta) {

        update(delta);
        draw(delta);



    }






    @Override
    public void resize(int width, int height) {
        renderer.setSize(width,height);

    }

    @Override
    public void show() {
        world = new World();
        renderer = new WorldRenderer(world, false);


    }

    @Override
    public void hide() {


    }

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

    }

    @Override
    public void resume() {


    }

    @Override
    public void dispose() {
        Assets.unload();


        Boat.dispose();
        Cloud.dispose();
        WorldRenderer.dispose();


    }



}

Мировой уровень

  package com.inspirednotion.thing;

import com.badlogic.gdx.math.MathUtils;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;



public class World {

Boat boat;
Water water;
Cloud cloud;
long lastDropTime;
Array<Rain> raindrops = new Array<Rain>();


public Array<Rain> getRain(){
     return raindrops;

}

 Boat getBoat(){
    return boat;
}
public Water getWater(){
    return water;
}

public Cloud getCloud(){
    return cloud;
}


public World(){

    createWorld();
    spawnRaindrop();
    lastDropTime = TimeUtils.nanoTime();
}

private void createWorld() {
    boat = new Boat(new Vector2(WorldRenderer.CAMERA_WIDTH / 2 - Boat.BOAT_WIDTH / 2, Water.position.y +11.3f ));
    cloud = new Cloud(new Vector2(WorldRenderer.CAMERA_WIDTH / 2 - Cloud.CLOUD_WIDTH /2, 8));
    water = new Water(new Vector2(WorldRenderer.CAMERA_WIDTH /2 - Water.WATER_WIDTH/2, -11.3f));




}
void spawnRaindrop(){
raindrops.add( new Rain(new Vector2(MathUtils.random(cloud.position.x, cloud.position.x + Cloud.CLOUD_WIDTH ),cloud.position.y)));
lastDropTime = TimeUtils.nanoTime();
}

public static void dispose() {


}
}

Класс WorldRenderer

public class WorldRenderer {

    private static World world;
    public static OrthographicCamera cam;

    ShapeRenderer debugRenderer = new ShapeRenderer();

     static final float CAMERA_WIDTH = 20f;
    static final float CAMERA_HEIGHT = 12f;

    static Texture cloudTexture;
    private TextureRegion cR;
    static Texture boatAniTex;
    TextureRegion[]                 boatFrames;
    Animation                       boatAnimation;
    TextureRegion                   boatCurrentFrame;
    static TextureRegion                   currentFrameBoat;
    TextureRegion[][]               tmpBoat;

    static Texture cloudBg;
    private TextureRegion cloudBgR;


    static Texture rainDrop;
    long lastDropTime;
    float lastDropT;


    private static Texture water;
    TextureRegion[]                 waveFrames;
    Animation                       waveAnimation;
    TextureRegion                   currentFrame;
    TextureRegion                   currentFrameWav;
    TextureRegion[][]               tmp;

    float stateTime = 0f; 

    private static SpriteBatch batch;

    static int width;
     static int height;

    public void setSize(int w, int h){
        WorldRenderer.width= w;
        WorldRenderer.height = h;
    }



    public WorldRenderer(World world, boolean debug){

        WorldRenderer.world = world;
        WorldRenderer.cam = new OrthographicCamera(CAMERA_WIDTH ,CAMERA_HEIGHT);
        WorldRenderer.cam.position.set(CAMERA_WIDTH /2f, CAMERA_HEIGHT /2f, 0);
        WorldRenderer.cam.update();
        batch = new SpriteBatch();
        loadTextures();
        loadAnimations();




    }





    public void loadTextures(){
        boatAniTex = Assets.manager.get("bin.png", Texture.class);
        boatAniTex.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        cloudTexture = Assets.manager.get("cloud.png", Texture.class);
        cloudTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        cR = new TextureRegion(cloudTexture,0,0,256,140);
        cloudBg = Assets.manager.get("cloudbg.png", Texture.class);
        cloudBg.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        cloudBgR = new TextureRegion(cloudBg,0,0,800,480);
        water = Assets.manager.get("wavey.png", Texture.class);
        water.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        rainDrop = new Texture(Gdx.files.internal("RainDrop_sml.png"));
    }


    private void loadAnimations() {

        water.setFilter(TextureFilter.Linear, TextureFilter.Linear);

        tmp = new TextureRegion(water).split(800,480);                                
        waveFrames = new TextureRegion[14];
        for (int x = 0, index = 0; x < 7; x++) {
            for (int y = 0; y < 2; y++, index++) {
               waveFrames[index] = tmp[x][y];
            }
         }

        waveAnimation = new Animation(0.14f, waveFrames); 

        //************************

boatAniTex.setFilter(TextureFilter.Linear, TextureFilter.Linear);

        tmpBoat = new TextureRegion(boatAniTex).split(64,64);                                
        boatFrames = new TextureRegion[7];
        for (int x = 0, indexed = 0; x < 1; x++) {
            for (int y = 0; y < 7; y++, indexed++) {
               boatFrames[indexed] = tmpBoat[x][y];
            }
         }

        boatAnimation = new Animation(0.2f, boatFrames); 

    }


    public void render(float delta){
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        batch.setProjectionMatrix(cam.combined);
        stateTime += Gdx.graphics.getDeltaTime();  
        currentFrameWav = waveAnimation.getKeyFrame(stateTime += delta, true);
        currentFrameBoat = boatAnimation.getKeyFrame(stateTime += delta, true);
        batch.begin();


        batch.disableBlending();
        drawBackGround();
        batch.enableBlending();
        drawBoat();

        drawWater(delta);
        drawCloud();


        batch.end();
        drawRain();
    }





    private void drawRain() {
        batch.begin();
        for(  Rain bounds: world.raindrops) {
             batch.draw(rainDrop, bounds.position.x ,  bounds.position.y,.2f,.2f);

        }
        batch.end();
        if(TimeUtils.nanoTime() - world.lastDropTime >  500000000) world.spawnRaindrop();




        Iterator<Rain> iter = world.raindrops.iterator();
          while(iter.hasNext()) {
             Rain raindrop = iter.next();
             raindrop.position.y -=2f * Gdx.graphics.getDeltaTime();
            if(raindrop.position.y < Water.position.y  ) {
                System.out.println("water is hit");
                iter.remove();
            }
          }
    }



    private void drawWater(float delta) {
        batch.draw(currentFrameWav, Water.position.x , Water.position.y ,Water.WATER_WIDTH , Water.WATER_HEIGHT );
        if (Water.position.y < -4f){
            Water.position.y += .1 * Gdx.graphics.getDeltaTime();
            Boat.position.y += .1 * Gdx.graphics.getDeltaTime();
        }
    }



    private void drawBackGround() {

        batch.draw(cloudBgR, 0,0,CAMERA_WIDTH,CAMERA_HEIGHT);

    }



    private void drawCloud(){
        Cloud cloud = world.getCloud();
         batch.draw(cR,cloud.position.x ,cloud.position.y ,Cloud.CLOUD_WIDTH , Cloud.CLOUD_HEIGHT );
    }


    private void drawBoat(){
        world.getBoat();
         batch.draw(currentFrameBoat, Boat.position.x , Water.position.y +11.3f,Boat.BOAT_WIDTH , Boat.BOAT_HEIGHT );
    }








    private void drawDebug(){
        debugRenderer.setProjectionMatrix(cam.combined);
        debugRenderer.begin(ShapeType.Rectangle);

        Cloud cloud = world.getCloud();
        Rectangle rect =  cloud.bounds;
        float x1 = cloud.position.x + rect.x;
        float y1 = cloud.position.y + rect.y;
        debugRenderer.setColor(new Color(1,0,0,1));
        debugRenderer.rect(x1, y1, rect.width, rect.height);

        Boat boat = world.getBoat();
        Rectangle rec =  boat.bounds;
        float xx1 = Boat.position.x + rec.x;
        float yx1 = Boat.position.y + rec.y;
        debugRenderer.setColor(new Color(1,1,0,1));
        debugRenderer.rect(xx1, yx1, rec.width, rec.height);

        debugRenderer.end();
    }




public static   void dispose(){
    cloudTexture.dispose();
    water.dispose();
    boatAniTex.dispose();
    rainDrop.dispose();
    cloudBg.dispose();
    batch.dispose();

}
}

пожалуйста, извините за беспорядочный код .. в процессе очистки и устранения проблем ..


person Djgriff    schedule 01.08.2012    source источник


Ответы (1)


Итог: ваш GameScreen находится в состоянии READY, но ваш WorldRenderer не знает об этом и продолжает свою веселую жизнь. Вы должны убедиться, что у вашего WorldRenderer есть состояния, которые сопоставляются с GameScreen состояниями.

Виной всему ваш звонок renderer.render(deltaTime) в GameScreen.draw(). Он постоянно обновляет положение вещей, независимо от состояния в GameScreen.

Предполагая, что желаемый эффект состоит в том, чтобы игра рисовалась в фоновом режиме, но игра не запускалась -

  1. Добавьте перечисление состояния в WorldRenderer, которое имеет как минимум WAITING и PLAYING, с полем этого типа перечисления. Убедитесь, что в WorldRenderer создан общедоступный метод, который позволит GameScreen установить это значение.
  2. Когда GameScreen создаст WorldRenderer, обязательно вызовите и установите состояние WorldRenderer в WAITING.
  3. Когда GameScreen переходит в состояние воспроизведения, вызовите и установите состояние WorldRenderer в PLAYING.
  4. В WorldRenderer тщательно определите, что нужно сделать в WAITING состоянии, PLAYING состоянии и в обоих случаях. В этом случае вы не хотите, чтобы вода поднималась, поэтому не меняйте воду и высоту лодки, если вы находитесь в состоянии WAITING.
person Jeremy Scoggins    schedule 06.09.2013