Accessing A Specific Cell's Tile In LibGDX - java

I have started to create a 2D game in LibGDX using a map(32x32 8 pixel tiles) from tiled map editor. In the method generateMushrooms, I want to access the cell(1,2) in layer 1 and set its tile to another tile in my tileset sprites.png with the id of 8. How would I achieve this? Right now I am getting a null pointer exception.
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, 256, 256);
camera.update();
tiledMap = new TmxMapLoader().load("custom.tmx");
tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);
generateMushrooms();
Gdx.input.setInputProcessor(this);
sb = new SpriteBatch();
texture = new Texture(Gdx.files.internal("badlogic.jpg"));
sprite = new Sprite(texture, 50, 50);
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
tiledMapRenderer.setView(camera);
tiledMapRenderer.render();
sb.setProjectionMatrix(camera.combined);
sb.begin();
//sprite.draw(sb);
sb.end();
}
public void generateMushrooms() {
//Get first layer
TiledMapTileLayer layer = (TiledMapTileLayer) tiledMap.getLayers().get(1);
// Get cell at row 1 column 2
TiledMapTileLayer.Cell cell = layer.getCell(1, 2);
// Get Tileset
TiledMapTileSet tileSet = tiledMap.getTileSets().getTileSet("sprites.png");
//Set tile of id 8 for the cell
cell.setTile(tileSet.getTile(8));
//Set the cell back in the layer at their x and y positions
layer.setCell(8, 16, cell);
}

Solved my problem! I have a traversing for loop go through the tiles and replace certain tiles like this (note that cur is a layer in the map).
for(int i=0; i < row; i++)
{
for(int j=0; j < column; j++)
{
cell = cur.getCell(i, j);
cur.setCell(i * 8, j * 8, cell);
cell.setTile(new StaticTiledMapTile("Some type of TextureRegion/Texture");
}
}

Related

LibGdx animation using TextureAtlas

I'm trying to load an explosion animation. The animations consists of 16 frames, all saved in the file Explosion.png. In my game, all the images are stored in a texture atlas pack.
So first i got the region that i needed from the class Assets.java
public class Explosion {
public final AtlasRegion explosion;
public Explosion (TextureAtlas atlas){
explosion = atlas.findRegion(Constants.EXPLOSION);
}
}
Then in my class which will create the explosion, I have the following code:
public Particles(Vector2 position){
this.position = position;
startTime = TimeUtils.nanoTime();
Array<TextureRegion> explosionAnimationTexture = new Array<TextureRegion>();
TextureRegion region = Assets.instance.explosion.explosion;
Texture explosionTexture = region.getTexture();
int ROW = 4; // rows of sprite sheet image
int COLUMN = 4;
TextureRegion[][] tmp = TextureRegion.split(explosionTexture, explosionTexture.getWidth() / COLUMN, explosionTexture.getHeight() / ROW);
TextureRegion[] frames = new TextureRegion[ROW * COLUMN];
int elementIndex = 0;
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COLUMN; j++) {
explosionAnimationTexture.add(tmp[i][j]);
frames[elementIndex++] = tmp[i][j];
}
}
explosion = new Animation(EXPLOSION_FRAME_DURATION,explosionAnimationTexture , Animation.PlayMode.LOOP_PINGPONG);
}
I'm using 4x4 since I have 16 frame. And inside the render method i got the following:
public void render(SpriteBatch batch){
float elapsedTime = MathUtils.nanoToSec * (TimeUtils.nanoTime() - startTime);
TextureRegion walkLoopTexture = explosion.getKeyFrame(elapsedTime);
batch.draw(
walkLoopTexture.getTexture(),
position.x,
position.y,
0,
0,
walkLoopTexture.getRegionWidth(),
walkLoopTexture.getRegionHeight(),
0.3f,
0.3f,
0,
walkLoopTexture.getRegionX(),
walkLoopTexture.getRegionY(),
walkLoopTexture.getRegionWidth(),
walkLoopTexture.getRegionHeight(),
false,
false);
}
The animation is working, however the images are loading from the whole atlas file, and not only Explosion.png as specified in step 1.
Code inside your Particles class :
TextureRegion region = Assets.instance.explosion.explosion;
TextureRegion[][] tmp = TextureRegion.split(explosionTexture, explosionTexture.getWidth() / COLUMN, explosionTexture.getHeight() / ROW);
replace with :
TextureRegion[][] tmp = region.split(region.getRegionWidth()/COLUMN,region.getRegionHeight()/ROW);
And
draw your Animation using textureRegion instead of his texture so choose appropriate method signature of SpriteBatch for drawing textureRegion.

Libgdx/Java ShadowMap and Framebuffer update using Cameras

im working on a little rpg game and today i tried to add shadows.
I saw this tutorial here which is good :)
Pixel Perfect Shader
So following problem :
Test example from the tutorial site, works fine. Theres one cam and the shadows are on the right place.
As soon i use Orthographic cameras from my player sprite, the shadow isnt there where it should be and when im moving the shadow moves with me, he is on the same spot on the display screen but in the world the shadow is moving _/ that looks so :
The SpriteSheet should cast shadows ... but they are on the wrong place :/
Here i didnt moved :
It is very dark, because of the day/night cycle ...
And here i moved a little bit to left :
I dont know why it wont work ... im giving the Orthographic camera out of my main class to the shadow class. Or did i miss something ? :/
My code should be fine, but if anyone wanna see it here is some code :
public class LightSystemShader {
private int lightSize = 500;
private float upScale = 1f; //for example; try lightSize=128, upScale=1.5f
SpriteBatch batch;
OrthographicCamera cam;
BitmapFont font;
FPSLogger fps;
TextureRegion shadowMap1D; //1 dimensional shadow map
TextureRegion occluders; //occluder map
FrameBuffer shadowMapFBO;
FrameBuffer occludersFBO;
Texture casterSprites;
Texture enmyAnimation;
Texture light;
ShaderProgram shadowMapShader, shadowRenderShader;
Array<Light> lights = new Array<Light>();
boolean additive = true;
boolean softShadows = true;
float xKoord = 600;
public static ShaderProgram createShader(String vert, String frag) {
ShaderProgram prog = new ShaderProgram(vert, frag);
if (!prog.isCompiled())
throw new GdxRuntimeException("could not compile shader: " + prog.getLog());
if (prog.getLog().length() != 0)
Gdx.app.log("GpuShadows", prog.getLog());
return prog;
}
public LightSystemShader() {
batch = new SpriteBatch();
ShaderProgram.pedantic = false;
//read vertex pass-through shader
final String VERT_SRC = Gdx.files.internal("data/pass.vert").readString();
// renders occluders to 1D shadow map
shadowMapShader = createShader(VERT_SRC, Gdx.files.internal("data/shadowMap.frag").readString());
// samples 1D shadow map to create the blurred soft shadow
shadowRenderShader = createShader(VERT_SRC, Gdx.files.internal("data/shadowRender.frag").readString());
//the occluders
casterSprites = new Texture("data/cat4.png");
//
enmyAnimation = new Texture("EnemyAnimations/BugIdleStand.png");
//the light sprite
light = new Texture("data/light.png");
cam = new OrthographicCamera(0,0);
cam.setToOrtho(false);
updateMaps();
font = new BitmapFont();
Gdx.input.setInputProcessor(new InputAdapter() {
public boolean touchDown(int x, int y, int pointer, int button) {
float mx = x;
float my = Gdx.graphics.getHeight() - y;
lights.add(new Light(mx, my, randomColor()));
return true;
}
public boolean keyDown(int key) {
if (key==Keys.SPACE){
clearLights();
return true;
} else if (key==Keys.A){
additive = !additive;
return true;
} else if (key==Keys.S){
softShadows = !softShadows;
return true;
}
return false;
}
});
clearLights();
}
public void renderLightSystemShader(OrthographicCamera screenCam){
screenCam = new OrthographicCamera(0,0);
screenCam.setToOrtho(false);
Gdx.gl.glClearColor(0,0,0,0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
float mx = Gdx.input.getX();
float my = Gdx.graphics.getHeight() - Gdx.input.getY();
if (additive)
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE);
for (int i=0; i<lights.size; i++) {
Light o = lights.get(i);
if (i==lights.size-1) {
o.x = mx;
o.y = my;
}
renderLight(o, screenCam);
}
if (additive)
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
//STEP 4. render sprites in full colour
batch.setProjectionMatrix(screenCam.combined);
batch.begin();
batch.setShader(null); //default shader
drawShaderBatch(batch);
//DEBUG RENDERING -- show occluder map and 1D shadow map
/*batch.setColor(Color.BLACK);
batch.draw(occluders, Gdx.graphics.getWidth()-lightSize, 0);
batch.setColor(Color.WHITE);
batch.draw(shadowMap1D, Gdx.graphics.getWidth()-lightSize, lightSize+5);
//DEBUG RENDERING -- show light
batch.draw(light, mx-light.getWidth()/2f, my-light.getHeight()/2f); //mouse
batch.draw(light, Gdx.graphics.getWidth()-lightSize/2f-light.getWidth()/2f, lightSize/2f-light.getHeight()/2f);
*/
//draw FPS
batch.end();
System.out.println(Gdx.graphics.getFramesPerSecond());
}
// draw Lights
void renderLight(Light o, OrthographicCamera screenCam) {
float mx = o.x;
float my = o.y;
screenCam = new OrthographicCamera(0,0);
screenCam.setToOrtho(false);
//STEP 1. render light region to occluder FBO
//bind the occluder FBO
occludersFBO.begin();
//clear the FBO
Gdx.gl.glClearColor(0f,0f,0f,0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//set the orthographic camera to the size of our FBO
screenCam.setToOrtho(false, occludersFBO.getWidth(), occludersFBO.getHeight());
//translate camera so that light is in the center
screenCam.translate(mx - lightSize/2f, my - lightSize/2f);
//update camera matrices
screenCam.update();
//set up our batch for the occluder pass
batch.setProjectionMatrix(screenCam.combined);
batch.setShader(null); //use default shader
batch.begin();
// ... draw any sprites that will cast shadows here ... //
batch.draw(casterSprites, 0, 0);
batch.draw(enmyAnimation,xKoord,600,300,100);
//end the batch before unbinding the FBO
batch.end();
//unbind the FBO
occludersFBO.end();
//STEP 2. build a 1D shadow map from occlude FBO
//bind shadow map
shadowMapFBO.begin();
//clear it
Gdx.gl.glClearColor(0f,0f,0f,0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//set our shadow map shader
batch.setShader(shadowMapShader);
batch.begin();
shadowMapShader.setUniformf("resolution", lightSize, lightSize);
shadowMapShader.setUniformf("upScale", upScale);
//reset our projection matrix to the FBO size
screenCam.setToOrtho(false, shadowMapFBO.getWidth(), shadowMapFBO.getHeight());
batch.setProjectionMatrix(screenCam.combined);
//draw the occluders texture to our 1D shadow map FBO
batch.draw(occluders.getTexture(), 0, 0, lightSize, shadowMapFBO.getHeight());
//flush batch
batch.end();
//unbind shadow map FBO
shadowMapFBO.end();
//STEP 3. render the blurred shadows
//reset projection matrix to screen
screenCam.setToOrtho(false);
batch.setProjectionMatrix(screenCam.combined);
//set the shader which actually draws the light/shadow
batch.setShader(shadowRenderShader);
batch.begin();
shadowRenderShader.setUniformf("resolution", lightSize, lightSize);
shadowRenderShader.setUniformf("softShadows", softShadows ? 1f : 0f);
//set color to light
batch.setColor(o.color);
float finalSize = lightSize * upScale;
//draw centered on light position
batch.draw(shadowMap1D.getTexture(), mx-finalSize/2f, my-finalSize/2f, finalSize, finalSize);
//flush the batch before swapping shaders
batch.end();
//reset color
batch.setColor(Color.WHITE);
//xKoord+=1;
}
void clearLights() {
lights.clear();
lights.add(new Light(Gdx.input.getX(), Gdx.graphics.getHeight()-Gdx.input.getY(), Color.WHITE));
}
static Color randomColor() {
float intensity = (float)Math.random() * 0.5f + 0.5f;
return new Color((float)Math.random(), (float)Math.random(), (float)Math.random(), intensity);
}
void drawShaderBatch(SpriteBatch batch){
batch.draw(casterSprites, 0, 0);
batch.draw(enmyAnimation,600,600,300,100);
}
void updateMaps(){
occludersFBO = new FrameBuffer(Format.RGBA8888, lightSize, lightSize, false);
occluders = new TextureRegion(occludersFBO.getColorBufferTexture());
occluders.flip(false, true);
//our 1D shadow map, lightSize x 1 pixels, no depth
shadowMapFBO = new FrameBuffer(Format.RGBA8888, lightSize, 1, false);
Texture shadowMapTex = shadowMapFBO.getColorBufferTexture();
//use linear filtering and repeat wrap mode when sampling
shadowMapTex.setFilter(TextureFilter.Linear, TextureFilter.Linear);
shadowMapTex.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
//for debugging only; in order to render the 1D shadow map FBO to screen
shadowMap1D = new TextureRegion(shadowMapTex);
shadowMap1D.flip(false, true);
}
public void doDispose(){
batch.dispose();
font.dispose();
shadowMapFBO.dispose();
shadowMapShader.dispose();
shadowRenderShader.dispose();
casterSprites.dispose();
enmyAnimation.dispose();
light.dispose();
occludersFBO.dispose();
}
}
Found it out myself ^^ i forgot to add this to void renderLights :
cam.position.set(positionX,positionY, 0);

Update & DoDraw method to spawn multiple of the same sprite

I'm trying to spawn multiple versions of the same sprite. Each spawns with a random speed (using random numbers between minus and positive speeds to determine random direction) and I have created 2 for loops to load an arraylist with new sprites. However, it seems to spawn 5 sprites, but then it seems like they're deleting and creating 5 more over and over. Below are the methods used:
public void update(){
spritesArrayList.clear();
if (gameOver != true)
{
sprite.update();
}
for (int i = 0; i < count; i++)
{
sprite = new Sprite(this);
spritesArrayList.add(sprite);
}
}
/**
* To draw the game to the screen
* This is called from Thread, so synchronisation can be done
*/
public void doDraw(Canvas canvas) {
Paint textPaint = new Paint();
canvas.drawBitmap(mBackgroundImage, 0, 0, null);
//Draw all the objects on the canvas
canvas.drawText("The Game ",5,25, paint);
canvas.drawText("Score: " + hitCount, 5, 50, paint);
canvas.drawText("Time: " +displayTime, 5, 75, paint);
GetArrayListSize();
//Loop for sprite creation
for (int i = 0; i < arraySize; i++)
{
Sprite sprite = spritesArrayList.get(i);
sprite.draw(canvas);
}
if (gameOver == true)
{
canvas.drawText("Final Score: "+finalScore, 5,100, paint);
int width = this.getMeasuredWidth()/2;
int height = this.getMeasuredHeight()/2;
textPaint.setTextAlign(Align.CENTER);
canvas.drawText("GAME OVER - PRESS BACK BUTTON TO RETURN", width, height, textPaint);
}
}

flickering android screen once drawing using a loop libgdx

im drawing a basic grid using a nested for loop (libgdx) but when i test it on android it keeps on flickering i have tried many different ways but still cant get it to stop the flickering.. here is my code
public void create() {
rend = new ShapeRenderer();
screenH = Gdx.graphics.getHeight();
screenH = (int) (screenH*(0.32));
System.out.println(screenH);
screenW = Gdx.graphics.getWidth();
screenW = (int) (screenW*(0.322));
System.out.println(screenW);
batch = new SpriteBatch();
dots = new Rectangle();
storeV();
render method
public void render() {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
//Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
rend.begin(ShapeType.Filled);
batch.setColor(Color.WHITE);
rend.rect(100, 100, 200, 200);
for (int i=0; i<4; i++){
for (int j=0;j<4;j++){
//batch.draw(dot, posx, posy);
rend.setColor(Color.WHITE);
rend.rect(posx, posy, 16, 16);
posx+=screenW;
}
posx=0;
rend.rect(posx, posy, 16, 16);
// batch.draw(dot, posx, posy);
posy+=screenH;
}
rend.end();
batch.begin();
batch.end();
}
as you see i have tried drawing a rectangle and using a texture but both happen to flicker. the rectangle drawn outside the loop dosent flicker.
and here is my storeV()
public void storeV(){
for (int i=0; i<4; i++){
Xpoints[i]+=screenW*i;
}
for (int i=0; i<4; i++){
Ypoints[i]+=screenH*i;
}

How to get a Picture from Array of ModelInstance in Libgdx

i would like to know, how i could get a rendered Picture of an ModelInstance-ArrayList.
public void modelBufferIcon(int i){
for(int j = 0; j < i; j++){
frameBuffer = new FrameBuffer(Format.RGB565, Hangar.WindowWidth , Hangar.WindowHeight, false);
lights = new Lights();
lights.ambientLight.set(ambientLight);
lights.add(new PointLight().set(pointLightBack, 0f, -1f, -5f,pointLightBack_INTENSITY));
lights.add(new PointLight().set(pointLightFront, 0f, -5f, 10f, pointLightFront_INTENSITY));
perspectiveCamera.lookAt(roboterVector);
perspectiveCamera.update();
frameBuffer.begin();
Gdx.graphics.getGL20().glViewport(0, 0, frameBuffer.getWidth(), frameBuffer.getHeight());
Gdx.graphics.getGL20().glClearColor(0f, 0f, 0f, 1);
Gdx.graphics.getGL20().glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.graphics.getGL20().glEnable(GL20.GL_TEXTURE_2D);
modelBatch.begin(perspectiveCamera);
modelBatch.render(physique.reBuildModel(Controller.getUser().getPets().get(j)),lights);
modelBatch.end();
frameBuffer.end();
texture = frameBuffer.getColorBufferTexture();
TextureRegion textureRegion = new TextureRegion(texture);
textureRegion.flip(false, true);
image_pet = new Image(textureRegion);
imageClickHandler(image_pet, j);
window.add(image_pet).row();
window.pack();
perspectiveCamera.lookAt(cameraVector);
perspectiveCamera.update();
}
}
On the left side u see the rendered Model, on the right side the picture:
Picture
With (physique.reBuildModel(Controller.getUser().getPets().get(j)),lights) the render-method get a Modelinstance of five 3d Models (Head, Arms,... ).

Categories

Resources