2015-05-11 4 views
0

Я делаю многопользовательскую игру в воздушном хоккее между мобильными телефонами Android с libgdx. Я уже могу подключить два телефона с tcp-соединением, и они обмениваются местоположениями друг друга. Два телефона имеют разные разрешения, и это вызывает графические проблемы, например: - Когда на одном из телефонов молоток в той же линии с шайбой на другом телефоне, молоток находится не рядом с шайбой. ) http://en.wikipedia.org/wiki/Air_hockey Вы можете увидеть здесь то, что я имею в виду, когда я говорю колотушку и шайбу, пока читать его я назвал его инструментом и диск)libgdx multiplayer - как обрабатывать различные разрешения экрана

Что мне нужно сделать, чтобы решить это так отличается экран размером телефоны могут играть без проблема один на. Дополнительная информация, которая может помочь:

Размеры игровых объектов и настенных мест уже определены процентами экрана, например, радиус молотка составляет 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); 

Возможно изменение каких-либо параметров в этой функции может помочь, но я понятия не имею, если мне нужно что-то изменить здесь.

Благодаря помощникам.

+5

вы ищете 'StretchViewport' и https://github.com/libgdx/libgdx/wiki/Viewports – EpicPandaForce

+0

Я пытаюсь найти простой пример StretchViewport и не найти, если вы знаете, что один пример может мне помочь. – tamirz12345

+0

На самом деле, ваша проблема может быть немного сложнее. Элементы игры должны ** не зависеть от размера экрана **, они должны определяться сами по себе (модель игры должна определять размер ее объектов), а * преобразован *, чтобы находиться в определенном месте на экран и сенсорный ввод должны быть преобразованы с помощью инверсного. Я решил эту проблему раньше, но я не использовал камеру (я как бы изобрел колесо ... легко в 2D, не было бы в 3D!) – EpicPandaForce

ответ

0

Хорошо, это решение не использовало класс 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] х [0320] сетка:

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

Или более полный пример на вики:

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; 
    } 
}