Ok, I'm making a monopoly-like game where in the game-loop activity I have a fragment with a LibGDX inside, which represents the 3D board with pieces. I've been struggling in the last few days figuring out how can I create additional ModelInstances after the activity has loaded and the create() method in the LibGDX class has ended. Here is the Demo3D.java holding the board and pieces:
#Override
public void create() {
pieces = new ArrayList<ModelInstance>();
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 1f, 1f, 1f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.position.set(0f, 1.6f, -4f);
camera.lookAt(0f, 0f, 0f);
camera.near = 0.01f;
camera.far = 12f;
mapTexture = new Texture("monopoly_board.jpg");
mapSprite = new Sprite(mapTexture, 1024, 1024);
modelBatch = new ModelBatch();
modelBuilder= new ModelBuilder();
board = new Board3D(mapSprite, mapSprite);
board.worldTransform.rotate(Vector3.X, 270);
board.worldTransform.rotate(Vector3.Z, 180);
board.worldTransform.translate(0, 0, 0);
createPiece("blue");
createPiece("green");
Gdx.input.setInputProcessor(this);
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
camera.update();
modelBatch.begin(camera);
modelBatch.render(board);
for (ModelInstance piece: pieces) {
modelBatch.render(piece, environment);
}
modelBatch.end();
}
// Some other methods...
public void createPiece(String pieceColor){
// Some logic...
ModelInstance mi = new ModelInstance(modelBuilder.createCone(0.2f, 0.4f, 0.2f, 20,
pieceMat,
VertexAttributes.Usage.Position|VertexAttributes.Usage.Normal), -1.95f, 0.1f, -2.2f);
pieces.add(mi);
render();
}
So I basically need to be able to call a method from the activity/model which would result in invoking
createPiece(String color) in the Demo3D class, resulting in a new piece shown on the board.
I tested calling the createPiece() from the outside and it creates a new piece and shows it but the board disappears. I tried calling render() at the end of createPiece() and in this case the board doesn't disappear but the newly created piece is not present... Couldn't dig anything up so I'd be glad if someone helps..
Cheers
So I decided to make a button "Start" which when pressed gets all the players and creates pieces for every player. This is the Listener:
((Button) findViewById(R.id.populate)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boardFragment.populatePieces(currentGame.getPlayers());
rollDice.setVisibility(View.VISIBLE);
v.setVisibility(View.INVISIBLE);
}
});
Where the boardFragment.populatePieces(Arrl<Players>) is:
for (Player p: players){
instance.createPiece(p.getTokenColor());
}
The odd thing is that yesterday I decided to test this out without any changes and in Genymotion it runs perfectly, adding and removing pieces with no problems at all /Running HTC One X in Geny/. But just few hours ago I decided to test it out on my physical device and there it is the problem again... My device is Huawei Mate 7 with Lolipop 5.1
Update: It turns out the app doesn't work properly on Lollipop devices haven't tested it out on physical devices with Android 4/6, but in Genymotion everything is smooth with 4/6 devices..
I believe you need to make sure that in your drawScene() method, you iterate over the pieces collection and draw/render each component.
Related
I have a camera in my GameStage class and am trying to translate the camera when the left or right arrow keys are pressed. When I press either key and print the camera x position it changes, but nothing moves (actors on screen stay in the same position). What am I doing wrong?
Screen Render Method:
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(255, 255, 255, 255);
gameStage.update();
gameStage.draw();
gameStage.act(delta);
}
Stage Code Involving the Camera:
public GameStage() {
super(new ScalingViewport(Scaling.stretch, Lib.WIDTH, Lib.HEIGHT, new OrthographicCamera(Lib.WIDTH, Lib.HEIGHT)));
initCamera();
Gdx.input.setInputProcessor(this);
}
public void initCamera() {
camera = new OrthographicCamera(Lib.WIDTH, Lib.HEIGHT);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0f);
camera.update();
}
public void updateCamera() {
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
camera.translate(-5, 0);
} else if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
camera.translate(5, 0);
}
camera.update();
}
public void update() {
updateCamera();
}
Thanks :)
From you visible code I would say that the problem is you have two cameras.
One is created when you are calling super constructor. And one created manually. Even if you are translating the camera you created, for rendering batch will use stages camera.
Remove the camera you created and work only with stages camera.
So i am creating a game where i will draw a background but this background doesen't cover the whole screen, even when i lower the window size it doesen't cover the whole window. Here is the code for drawing the background:
Gdx.gl20.glClearColor(0.2F, 0.6F, 1F, 1F);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
cam.update();
sb.setProjectionMatrix(cam.combined);
sb.begin();
sb.draw(Assets.splash_spr_background, 0, 0);
sb.end();
And here is the code for initializing the sprite:
public static Texture splash_tex_background;
public static Sprite splash_spr_background;
public static void init()
{
splash_tex_background = new Texture(Gdx.files.internal("Splash Screen/background.png"));
splash_tex_background.setFilter(TextureFilter.Linear, TextureFilter.Linear);
splash_spr_background = new Sprite(splash_tex_background);
}
And finally here is the code for initializing the camera & spritebatch stuff:
cam = new OrthographicCamera();
cam.setToOrtho(false, 1920, 1080);
sb = new SpriteBatch();
Now here is my question: Why does this not work? What have i done wrong?
Thanks for any help! :)
You don't need 1920x1080 resolution for the game. That's clearly an overkill. Imagine that someone with a lower spec device will play it.
So you can just set the screen to match the background:
cam.setToOrtho(false, 1280, 720);
If you really need the resolution, you can stretch the background like this:
background.setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge);
I'm new in LibGDX.
I've tried to apply some tutorial I've read online to load a model in libGDX.
The problem is that I have a black screen when the app is loaded on my Galaxy Nexus (Android 4.3), no error according to LogCat.
The code is this:
#Override
public void create() {
modelBatch = new ModelBatch();
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(7f, 7f, 7f);
cam.lookAt(0,0,0);
cam.near = 1f;
cam.far = 300f;
cam.update();
assets = new AssetManager();
assets.load("data/skeleton.g3db", Model.class);
loading = true;
camController = new CameraInputController(cam);
Gdx.input.setInputProcessor(camController);
}
private void doneLoading() {
Model I_model = assets.get("data/skeleton.g3db", Model.class);
ModelInstance I_instance = new ModelInstance(I_model);
I_instance.transform.setToTranslation(-5f, 0, -5f);
instances.add(I_instance);
loading = false;
}
#Override
public void render() {
if (loading && assets.update())
doneLoading();
camController.update();
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(cam);
modelBatch.render(instances, environment);
modelBatch.end();
}
#Override
public void dispose() {
modelBatch.dispose();
model.dispose();
assets.dispose();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
The model "skeleton" is taken online as .fbx and converted in .g3db with fbx-conv.
Is a code or model error?
Any help is appreciated, thanks.
I think the problem is the direction of the light, because I think two points of lighting here telling that the model has textures appear.
is possible that the model is getting bad light,
use;
PointLight set (float r, float g, float b, float x, float y, float z, float intensity)
float intensity = 1f;
environment.add(new PointLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.8f, intensity));
and tray change variable intesity in test for example 100;
Hello and sorry for my English, I have not much experience with models, but when you assign
cam.position.set (7f, 7f, 7f);
cam.lookAt (0,0,0);
and then you say
I_instance.transform.setToTranslation (-5F, 0, -5F);
is not far outside the range of vision of the camera? it's just a question maybe this error out there
Edit;
I_instance.transform.setToTranslation(-5f, 0, -5f);
DirectionalLight().set(float r, float g, float b, float dirX, float dirY, float dirZ)
Dirz your not is beyond the scope of the model, -5F changes by aver 1f think if you see that the lighting is not arrived
I had the same problem and my problem was that the model loaded really big, and the camera was in the model. So try either scaling your model down, or moving the camera back a lot.
So basically I'm trying to display a .obj 3D Model with an OrthographicCamera in 2D rather than in 3D with a PerspectiveCamera.
Everything works fine when I render with the PerspectiveCamera, however if I switch it to Orthographic, nothing displays, just the blank background.
Below is the code I'm using with the PerspectiveCamera stuff commented out. I'm not sure if there is a different way that I need to setup the OrthographicCamera, or if I need to use a PerspectiveCamera with some modified to views to achieve this. At this point it really doesn't matter which axis I "eliminate".
Essentially what I want to achieve is being able to use Blender for my 2D animation. I've figured this out on the Blender side and it works very well, however they must be imported as .obj(or .fbx) into LibGDX, these are loaded into LibGDX as Models, and as such must be rendered with a ModelBatch using a ModelInstance and an Environment. I need a way to view this object using a 2D Orthographic projection rather than a 3D Perspective projection.
Anyone got any suggestions for this?
public class Test extends ApplicationAdapter {
//public PerspectiveCamera cam;
public OrthographicCamera cam;
public CameraInputController camController;
public ModelBatch modelBatch;
public ModelInstance ship;
public Environment environment;
#Override
public void create() {
modelBatch = new ModelBatch();
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
/*
cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(10f, 10f, 10f);
cam.lookAt(0, 0, 0);
cam.near = 1f;
cam.far = 10f;
cam.update();
*/
cam = new OrthographicCamera();
cam.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.update();
camController = new CameraInputController(cam);
Gdx.input.setInputProcessor(camController);
ObjLoader loader = new ObjLoader();
Model model = loader.loadModel(Gdx.files.internal("data/invader.obj"));
ship = new ModelInstance(model);
}
#Override
public void render() {
camController.update();
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(cam);
modelBatch.render(ship, environment);
modelBatch.end();
}
#Override
public void dispose() {
modelBatch.dispose();
}
}
I'm trying to create a game with LibGDX. My problem comes when I put the background in the screen that I have. I created a Base Screen (abstract) in order to make easier. In Desktop, the screen fits good, but in Android, trying different devices, the screen doesn't scale to full screen. I solved this situation using the next easy code:
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(texture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.end();
}
That was enough to see my game in full screen on android devices. Now, I want to use Scene2D(which I don't know so much...) So I create a Stage, I'm dealing with the background like an actor. Here's my code.
public class MenuScreen extends BaseScreen {
private FitViewport viewport;
private Stage stage;
private Image imageFondo, imagePrueba;
//private float escala;
public MenuScreen(MissingWords missingwords) {
super(missingwords);
}
#Override
public void show() {
//viewport = new StretchViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
viewport = new FitViewport(800, 480);
stage = new Stage(viewport, missingwords.getSB());
//Gdx.input.setInputProcessor(stage);
/* Crear fondo */
imageFondo = new Image(missingwords.getAM().get("fondo.png", Texture.class));
stage.addActor(imageFondo);
imagePrueba = new Image(missingwords.getAM().get("prueba.png", Texture.class));
imagePrueba.setPosition(50, 50);
stage.addActor(imagePrueba);
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
However, it doesn't work and I don't know if I'm using the Viewports in the correct way. How can I write this line in order to be compatible with Scene 2D and support android devices?
batch.draw(texture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Thanks in advance.
Finally I "solved" it using a ScalingViewport. Like this:
viewport = new ScalingViewport(Scaling.stretch, 800, 480);
Scaling.stretch as javadoc says: the world is scaled to take the whole screen. So, it doesn't keep the aspect ratio but for me is good. Maybe it looks wrong using large screens, but I'm still learning and I don't know if this is the best solution. So, I hope this helps someone.