用MVC布局实现游戏状态?

时间:2012-08-01 19:53:18

标签: java model-view-controller libgdx states

您好我正在创建一个基本游戏并尝试使用我的代码实现MVC模式。我目前有: 的模型 游戏对象,云,船水等。

世界 这将所有模型联系在一起并定义对象

WorldRenderer 这将所有纹理应用于对象

GameScreen 这可以处理用户输入,触摸或键盘。

我的问题是如何以及在何处实施游戏状态? 我假设它将进入GameScreen,但我实现了状态的基本布局,READY,RUNNING,PAUSED,NEXT_LVL,GAME_OVER,

但是我发现当状态READY出现时游戏正在后台运行?

这是在WorldRenderer中定义的,即水lvl在后面的屏幕上升,但我希望这只发生在游戏状态切换到运行时。

当Gamstate切换到RUNNING STATE时,如何让Gamestate仅初始化WorldRenderer。我已将语句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 Class

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();

}
}

请原谅凌乱的代码..在清理和调试问题的过程中..

1 个答案:

答案 0 :(得分:2)

前面的底线:您的GameScreen处于READY状态,但您的WorldRenderer不知道并且继续它的快乐方式。您需要确保WorldRenderer具有映射到GameScreen州的状态。

您对renderer.render(deltaTime)GameScreen.draw()的致电是罪魁祸首。无论GameScreen中的状态如何,它都在不断更新事物的位置。

假设所需的效果是让游戏在后台绘制,但游戏未开始 -

  1. 使用此枚举类型的字段向至少WorldRendererWAITING的{​​{1}}添加状态枚举。确保在PLAYING中创建了一个公共方法,允许WorldRenderer设置此值。
  2. GameScreen创建GameScreen时,请务必致电并将WorldRenderer州设置为WorldRenderer
  3. WAITING转换为播放状态时,请致电并将GameScreen状态设置为WorldRenderer
  4. PLAYING中,仔细定义在WorldRenderer州,WAITING州以及两者中需要完成的工作。在这种情况下,你不希望水涨,所以如果你处于PLAYING状态,不要改变水和船的高度。