Android libgdx多人游戏-如何处理不同的屏幕分辨率
我正在用libgdx在android手机之间制作一个多人空中曲棍球游戏。我已经能够用tcp连接两部手机,它们交换彼此的位置。 这两款手机的分辨率不同,这会导致图形问题,例如: -当一部手机中的木槌与另一部手机中的冰球在同一条线上时,木槌不在冰球附近。 )你可以在这里看到我所说的槌球和冰球的意思,直到读到为止,我称之为工具和圆盘) 我需要做些什么来解决这个问题,这样不同屏幕大小的手机就可以轻松地玩起来。 以下是可能有帮助的其他信息: 游戏对象和墙壁位置的大小已经由屏幕的百分比决定,例如,木槌的半径是屏幕宽度的7%。此外,我还通过0-1之间的浮点数发送两部手机之间的坐标,表示屏幕中的位置,例如中点(0.5,0.5)。但这并不能解决问题 以下是我的渲染功能中与游戏图形相关的内容:Android libgdx多人游戏-如何处理不同的屏幕分辨率,android,libgdx,render,resolution,multiplayer,Android,Libgdx,Render,Resolution,Multiplayer,我正在用libgdx在android手机之间制作一个多人空中曲棍球游戏。我已经能够用tcp连接两部手机,它们交换彼此的位置。 这两款手机的分辨率不同,这会导致图形问题,例如: -当一部手机中的木槌与另一部手机中的冰球在同一条线上时,木槌不在冰球附近。 )你可以在这里看到我所说的槌球和冰球的意思,直到读到为止,我称之为工具和圆盘) 我需要做些什么来解决这个问题,这样不同屏幕大小的手机就可以轻松地玩起来。 以下是可能有帮助的其他信息: 游戏对象和墙壁位置的大小已经由屏幕的百分比决定,例如,木槌的半径
batch = new SpriteBatch();
camera = new OrthographicCamera();
height = Gdx.graphics.getWidth();
width = Gdx.graphics.getHeight();
camera.setToOrtho(false, height, width);
也许更改此函数中的任何参数都会有所帮助,但我不知道是否需要在此处更改某些内容
多亏了助手。好的,这个解决方案根本没有使用
摄像头
类,因此在我看来有点差强人意,但这是大约一年前我遇到类似问题时提出的
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
是模型高度,也就是世界的大小)
然后,我为屏幕的视口变换设置了适当的参数,并为[0480]x[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
但是如果您使用的是正交摄影机
,那么您只需要将输入转换
替换为摄影机.unproject()
,并将摄影机视口设置为拉伸视口
。考虑到我上面给出的方法有它的局限性,那就是你需要修改它,从[0480]x[0320]网格中移动摄像机
因此,根据页面上的文档
private Viewport viewport;
private Camera camera;
public void create() {
camera = new OrthographicCamera();
viewport = new StretchViewport(480, 320, camera);
}
或wiki上更完整的示例:
或最重要的,使用正交摄影机和视口的示例:
您正在查找
StretchViewport
,我正在尝试查找StretchViewport的一个简单示例,但没有找到,如果您知道一个示例,我认为一个示例可能会对我有所帮助。实际上,您的问题可能会更复杂一些。游戏中的元素不应取决于屏幕大小,它们应自行定义(游戏模型应确定其对象的大小),并转换为屏幕上的特定位置,触摸输入应使用相反的方式进行转换。我以前解决过这个问题,但我没有使用相机(我有点重新发明了轮子…2D容易,3D不会!)
private Viewport viewport;
private Camera camera;
public void create() {
camera = new OrthographicCamera();
viewport = new StretchViewport(480, 320, camera);
}
//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;
}
}