【问题标题】:libgdx multiplayer - how to handle different screen resolutionslibgdx 多人游戏 - 如何处理不同的屏幕分辨率
【发布时间】:2015-07-22 13:09:26
【问题描述】:

我正在使用 libgdx 在 android 手机之间制作多人空中曲棍球游戏。我已经能够通过 tcp 连接将两部手机连接起来,并且它们交换了对方 mallet 的位置。 这两款手机的分辨率不同,这会导致图形问题,例如: - 当其中一部手机中的木槌与另一部手机中的圆盘在同一条线上时,木槌不在圆盘附近。 )http://en.wikipedia.org/wiki/Air_hockey 你可以在这里看到我所说的槌和冰球的意思,直到读到它我称之为工具和磁盘)

我需要做些什么来解决它,以便不同屏幕尺寸的手机可以毫无问题地玩。 以下是可能有帮助的附加信息:

游戏对象的大小和墙的位置已经由屏幕的百分比决定,例如木槌的半径是屏幕宽度的 7%。此外,我通过 0 -1 之间的浮点数发送两部手机之间的坐标,表示屏幕中的位置,例如中间点(0.5,0.5)。但它并没有解决它。

以下是我的渲染函数中与游戏图形相关的内容:

batch = new SpriteBatch();
camera = new OrthographicCamera();
height = Gdx.graphics.getWidth();
width = Gdx.graphics.getHeight();
camera.setToOrtho(false, height, width);

也许更改此函数中的任何参数可能会有所帮助,但我不知道是否需要在此处更改某些内容。

感谢帮助者。

【问题讨论】:

  • 您正在寻找StretchViewportgithub.com/libgdx/libgdx/wiki/Viewports
  • 我正在尝试寻找一个简单的 StretchViewport 示例,但没有找到,如果您知道,我认为一个示例可能对我有所帮助。
  • 其实,你的问题可能有点复杂。游戏中的元素应该不依赖于屏幕大小,它们应该自己定义(游戏的模型应该决定其对象的大小),并且变换 位于屏幕上的特定位置,触摸输入应进行反变换。我之前解决了这个问题,但我没有使用相机(我有点重新发明轮子......在 2D 中很容易,在 3D 中不会!)

标签: android libgdx render resolution multiplayer


【解决方案1】:

好的,这个解决方案根本没有使用 camera 类,因此在我看来有点低于标准,但这是我大约一年前遇到类似问题时提出的。

public abstract class BaseScreen implements Screen, InputProcessor
{
    protected int windowWidth;
    protected int windowHeight;

    public BaseScreen() 
    {
        windowWidth = Gdx.graphics.getWidth(); //width of screen
        windowHeight = Gdx.graphics.getHeight(); //height of screen
    }

    @Override
    public void resize(int width, int height)
    {
        windowWidth = width;
        windowHeight = height;
    }

    public void show()
    {
        Gdx.input.setInputProcessor(this);
    }

    public int getWindowWidth()
    {
        return windowWidth;
    }

    public int getWindowHeight()
    {
        return windowHeight;
    }

    public void setWindowWidth(int windowWidth)
    {
        this.windowWidth = windowWidth;
    }

    public void setWindowHeight(int windowHeight)
    {
        this.windowHeight = windowHeight;
    }

    ...

    public abstract void onTouchDown(float pointerX, float pointerY);
    public abstract void onTouchUp(float pointerX, float pointerY);

    @Override
    public final boolean touchDown(int screenX, int screenY, int pointer, int button)
    {
        float pointerX = InputTransform.getCursorToModelX(windowWidth, screenX);
        float pointerY = InputTransform.getCursorToModelY(windowHeight, screenY);
        onTouchDown(pointerX, pointerY);
        return false;
    }

    @Override
    public final boolean touchUp(int screenX, int screenY, int pointer, int     button) 
    {
            float pointerX = InputTransform.getCursorToModelX(windowWidth, screenX);
            float pointerY = InputTransform.getCursorToModelY(windowHeight,     screenY);
            onTouchUp(pointerX, pointerY);
            return false;
    }
}

其中使用以下内容(其中appWidth 是模型宽度,appHeight 是模型高度,也就是世界的大小)

public class InputTransform
{
    private static int appWidth = 480;
    private static int appHeight = 320;

    public static float getCursorToModelX(int screenX, int cursorX) 
    {
        return (((float)cursorX) * appWidth) / ((float)screenX); 
    }

    public static float getCursorToModelY(int screenY, int cursorY) 
    {
        return ((float)(screenY - cursorY)) * appHeight / ((float)screenY) ; 
    }
}

然后我为屏幕的视口变换设置适当的参数,以及在 [0,480]x[0,320] 网格内绘制对象的投影变换:

    Gdx.gl.glViewport(0,  0,  Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); //init screen to [0,ScreenWidth]x[0,ScreenHeight]
    Resources.batch = new SpriteBatch();
    Resources.normalProjection = new Matrix4().setToOrtho2D(0, 0, 480, 320); //create transform to [0,480]x[0,320] world grid
    Resources.batch.setProjectionMatrix(Resources.normalProjection); //initialize drawing with transform
    Resources.shapeRenderer.setProjectionMatrix(Resources.normalProjection); //initialize drawing with transform

但如果您正在使用OrthographicCamera,那么您真的只需要将InputTransform 替换为camera.unproject(),并将相机视口设置为StretchViewport。考虑到我上面给出的方法有其局限性,即您需要修改它才能真正移动相机从 [0,480]x[0,320] 网格中。

所以根据页面上的文档,

private Viewport viewport;
private Camera camera;

public void create() {
    camera = new OrthographicCamera();
    viewport = new StretchViewport(480, 320, camera);
}

或者 wiki 上更完整的示例:

https://github.com/libgdx/libgdx/wiki/Orthographic-camera

或者最重要的,一个使用带视口的正交相机的例子:

http://www.gamefromscratch.com/post/2014/12/09/LibGDX-Tutorial-Part-17-Viewports.aspx

//copy paste from GameFromScratch:
package com.gamefromscratch;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.viewport.StretchViewport;
import com.badlogic.gdx.utils.viewport.Viewport;

public class mouseproject extends ApplicationAdapter implements InputProcessor {
   SpriteBatch batch;
   Sprite aspectRatios;
   OrthographicCamera camera; //the camera 
   Viewport viewport; //the viewport

   @Override
   public void create () {
      batch = new SpriteBatch();
      aspectRatios = new Sprite(new Texture(Gdx.files.internal("Aspect.jpg")));
      aspectRatios.setPosition(0,0);
      aspectRatios.setSize(100,100);

      camera = new OrthographicCamera();
      viewport = new StretchViewport(100,100,camera); //stretch screen to [0,100]x[0,100] grid
      viewport.apply();

      camera.position.set(camera.viewportWidth/2,camera.viewportHeight/2,0); //set camera to look at center of viewport
      Gdx.input.setInputProcessor(this);
   }

   @Override
   public void render () {

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

      batch.setProjectionMatrix(camera.combined); //make batch draw to location defined by camera
      batch.begin();
      aspectRatios.draw(batch);
      batch.end();
   }

   @Override
   public void dispose(){
      aspectRatios.getTexture().dispose();
   }

   @Override
   public void resize(int width, int height){
      viewport.update(width, height);
      camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
   }

   @Override
   public boolean keyDown(int keycode) {
      return false;
   }

   @Override
   public boolean keyUp(int keycode) {
      return false;
   }

   @Override
   public boolean keyTyped(char character) {
      return false;
   }

   @Override
   public boolean touchDown(int screenX, int screenY, int pointer, int button) {

      Gdx.app.log("Mouse Event","Click at " + screenX + "," + screenY);
      Vector3 worldCoordinates = camera.unproject(new Vector3(screenX,screenY,0)); //obtain the touch in world coordinates: similar to InputTransform used above
      Gdx.app.log("Mouse Event","Projected at " + worldCoordinates.x + "," + worldCoordinates.y);
      return false;
   }

   @Override
   public boolean touchUp(int screenX, int screenY, int pointer, int button) {
      return false;
   }

   @Override
   public boolean touchDragged(int screenX, int screenY, int pointer) {
      return false;
   }

   @Override
   public boolean mouseMoved(int screenX, int screenY) {
      return false;
   }

   @Override
   public boolean scrolled(int amount) {
      return false;
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    相关资源
    最近更新 更多