libGDX Strange Rendering Bug - java

I've recently started my first libGDX game, and it is all going well, everything renders fine but after about a minute nothing renders, the rendering calls are still made and the spritebatch works fine, I'm just left with a black screen, I have even changed the 'glClearColor()' to but I'm still left with a black screen. I've have no idea what this could be.
My main class:
#Override
public void create() {
Gdx.graphics.setDisplayMode(Settings.screenWidth, Settings.screenHeight, Settings.fullscreen);
Gdx.graphics.setVSync(Settings.VSync);
Gdx.graphics.setTitle("Trench Warfare");
batch = new SpriteBatch(1000);
previous = System.currentTimeMillis();
currentMap = new Map(this, 0);
currentMap.addObject(new ColourMapObject(this, 0));
}
private void update() {Settings.screenHeight, Settings.fullscreen);
Gdx.graphics.setVSync(Settings.VSync);
batch.setColor(new Color(Settings.brightness, Settings.brightness, Settings.brightness, 1.0f));
float delta = ((float)(System.currentTimeMillis() - previous)) / 1000.0f;
previous = System.currentTimeMillis();
currentMap.update(delta);
}
#Override
public void render() { //Always called
update();
Gdx.gl.glClearColor(1, 0, 0, 1); //Red colour still black screen.
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
currentMap.render(batch); //Basicly list of textures to be rendered, they never stop rendering (Being called) despite black screen.
batch.end();
batch.flush();
}
EDIT:
We've determined that after some time SpriteBatch render a black screen over the red clear colour, It also stops rendering the texture.
I've also determined that the SpriteBatch's tint or colour stays white even during the black screen.
EDIT, this code takes in a texture and then turns into a different texture with different colours:
public class ColourMapObject extends MapObject {
public enum Type {
Dirt,
Water,
Trench,
}
private Texture terrainMap;
private Texture trenchMap;
private Texture soldierMap;
private Texture buildingMap;
private Texture shipMap;
private int levelId;
private Texture finalTexture;
private Type[][] types;
public ColourMapObject(TrenchMain main, int levelId) {
super(main);
this.levelId = levelId;
//finalTexture = new Texture("/map" + String.valueOf(levelId) + "/terrainMap.png");
finalTexture = new Texture("black.png");
finalTexture.getTextureData().prepare();
loadMap(levelId);
}
private void loadMap(int levelId) {
//terrainMap = new Texture("/map" + String.valueOf(levelId) + "/terrainMap.png");
terrainMap = new Texture("terrainMap.png");
types = new Type[terrainMap.getWidth()][terrainMap.getHeight()];
terrainMap.getTextureData().prepare();
Pixmap pixmap = terrainMap.getTextureData().consumePixmap();
for(int x = 0; x < terrainMap.getWidth(); x++) {
for(int y = 0; y < terrainMap.getHeight(); y++) {
types[x][y] = RandomMapColour.getType(new Color(pixmap.getPixel(x, y)));
if(types[x][y] == null) types[x][y] = Type.Dirt;
}
}
// trenchMap = new Texture("/map" + String.valueOf(levelId) + "/trenchMap.png");
//
//
// soldierMap = new Texture("/map" + String.valueOf(levelId) + "/soldierMap.png");
//
//
// buildingMap = new Texture("/map" + String.valueOf(levelId) + "/buildingMap.png");
//
//
// shipMap = new Texture("/map" + String.valueOf(levelId) + "/shipMap.png");
}
#Override
public void update(float delta) {
super.update(delta);
Pixmap draw = new Pixmap(Settings.screenWidth, Settings.screenHeight, Format.RGB888);
float pX = (float)terrainMap.getWidth() / (float)draw.getWidth();
float pY = (float)terrainMap.getHeight() / (float)draw.getHeight();
for(int x = 0; x < draw.getWidth(); x++) {
for(int y = 0; y < draw.getHeight(); y++) {
switch(types[(int)((float)x * pX)][(int)((float)y * pY)]) {
case Dirt:
draw.drawPixel(x, y, RandomMapColour.getDirtColour());
break;
case Trench:
draw.drawPixel(x, y, RandomMapColour.getTrenchColour());
break;
case Water:
draw.drawPixel(x, y, RandomMapColour.getWaterColour());
break;
}
}
}
finalTexture = new Texture(draw);
}
#Override
public void render(SpriteBatch batch) {
super.render(batch);
float sx = ((float)TrenchMain.getScreenWidth()) / ((float)finalTexture.getWidth());
float sy = ((float)TrenchMain.getScreenHeight()) / ((float)finalTexture.getHeight());
batch.draw(finalTexture, 0, 0, 0, 0, finalTexture.getWidth(), finalTexture.getHeight(), sx, sy, 0, 0, 0, finalTexture.getWidth(), finalTexture.getHeight(), false, false);
}

I finally figuired it out, for those who are wonder, what I was doing was creating a new finalTexture every update with disposing of the old one.
Simply dispose of the texture.
finalTexture.dispose();

Related

processing - how to plot a scatter graph with x/y axis bigger than width/height of window

So i have code witch generates a list of the numbers in the recaman sequence and plots them (with 0,0 at bottom left using translate(0,height); scale(1,-1); ).
My problem is it only shows a small part of the graph i want to plot. For example, i want to be able to have 10,000 on the y axis and x axis as well as points using those numbers, but keeping to 500,500 window size.
I want to plot a graph bigger than 500,500, the window size.
how do i do this, if it is possible?
Create a PGraphics object of size (10000, 10000).
Render your points into this (you can call every Processing drawing method on a PGraphics object).
Draw the PGraphics object at different locations within the window to simulate panning within the graph.
The following example shows how you could do the above, with mouse panning functionality and a static graph (instantiated and populated in setup()).
import processing.core.PApplet;
import processing.core.PGraphics;
public class Prototype extends PApplet {
public static void main(String[] args) {
PApplet.main(Prototype.class);
}
int xOffset = 0, yOffset = 0;
int xOffsetP, yOffsetP;
int mouseDownX, mouseDownY;
boolean move = false;
PGraphics graph;
#Override
public void settings() {
size(500, 500);
}
#Override
public void setup() {
graph = createGraphics(2000, 2000); // Create graph 2000x2000px
graph.beginDraw();
graph.background(255);
graph.fill(0);
for (int i = 0; i < 1000; i++) { // Adds 1000 random points to graph
graph.ellipse(random(2000), random(2000), 3, 3);
}
for (int i = 0; i < graph.height; i += 50) { // Adds Y-axis labels
graph.text(i, 5, graph.height - i);
}
graph.line(0, 0, 1999, 0); // Graph edge/border
graph.line(0, 1999, 1999, 1999);
graph.line(0, 0, 0, 1999);
graph.line(1999, 0, 1999, 2000);
graph.endDraw();
}
#Override
public void draw() {
background(255);
if (move) {
xOffset = mouseDownX - mouseX + xOffsetP;
yOffset = mouseY - mouseDownY + yOffsetP;
xOffset = constrain(xOffset, 0, graph.width - width); // Optional
yOffset = constrain(yOffset, 0, graph.height - height); // Optional
}
image(graph, -xOffset, yOffset - graph.height + height);
fill(255, 0, 0);
text("X Offset: " + xOffset, 0, 10);
text("Y Offset: " + yOffset, 0, 25);
}
#Override
public void mousePressed() {
move = true;
mouseDownX = mouseX;
mouseDownY = mouseY;
}
#Override
public void mouseReleased() {
move = false;
xOffsetP = xOffset;
yOffsetP = yOffset;
}
}
Result (in a 500x500 window):

Android draw ball trail

There are balls in my app that just fly through display. They draws as I want. But now I want to draw the trail behind them.
All I could make is just drawing by canvas.drawPath something like following picture:
But it is not what I want. It should have pointed tail and gradient color like this:
I have no idea how to make it. Tried BitmapShader - couldn't make something right. Help, please.
Code:
First of all, there is Point class for position on display:
class Point {
float x, y;
...
}
And trail is stored as queue of Point:
private ConcurrentLinkedQueue<Point> trail;
It doesn't matter how it fills, just know it has size limit:
trail.add(position);
if(trail.size() > TRAIL_MAX_COUNT) {
trail.remove();
}
And drawing happened in DrawTrail method:
private void DrawTrail(Canvas canvas) {
trailPath.reset();
boolean isFirst = true;
for(Point p : trail) {
if(isFirst) {
trailPath.moveTo(p.x, p.y);
isFirst = false;
} else {
trailPath.lineTo(p.x, p.y);
}
}
canvas.drawPath(trailPath, trailPaint);
}
By the way, trailPaint is just really fat paint :)
trailPaint = new Paint();
trailPaint.setStyle(Paint.Style.STROKE);
trailPaint.setColor(color);
trailPaint.setStrokeWidth(radius * 2);
trailPaint.setAlpha(150);
I see you want to see a gradient on the ball path, you could use something like this
int x1 = 0, y1 = 0, x2 = 0, y2 = 40;
Shader shader = new LinearGradient(0, 0, 0, 40, Color.WHITE, Color.BLACK, TileMode.CLAMP);
trailPaint = new Paint();
trailPaint.setShader(shader);
This is what you should change your trailPaint to and see if it works.
provided from here.
I found solution. But still think it is not the best one.
First of all there are my class fields used for that task.
static final int TRAIL_MAX_COUNT = 50; //maximum trail array size
static final int TRAIL_DRAW_POINT = 30; //number of points to split the trail for draw
private ConcurrentLinkedQueue<Point> trail;
private Paint[] trailPaints;
private float[][] trailPoss, trailTans;
private Path trailPath;
Additionally to trailPath object I used PathMeasure object to split path to multiple equal parts.
After filling trail array object added call of trail calculating function.
lastTrailAdd = now;
trail.add(pos.Copy());
if (trail.size() > TRAIL_MAX_COUNT) {
trail.remove();
}
FillTrail();
Then my FillTrail function.
private void FillTrail() {
trailPath.reset();
boolean isFirst = true;
for(Point p : trail) {
if(isFirst) {
trailPath.moveTo(p.x, p.y);
trailPoss[0][0] = p.x;
trailPoss[0][1] = p.y;
isFirst = false;
} else {
trailPath.lineTo(p.x, p.y);
}
}
PathMeasure path = new PathMeasure(trailPath, false);
float step = path.getLength() / TRAIL_DRAW_POINT;
for(int i=0; i<TRAIL_DRAW_POINT; i++) {
path.getPosTan(step * i, trailPoss[i], trailTans[i]);
}
}
It separated from drawing thread. Next code is drawing function.
private void DrawTrail(Canvas canvas) {
if(trail.size() > 1) {
float prevWidthHalfX = 0f, prevWidthHalfY = 0f, prevX = 0f, prevY = 0f;
Path trailStepRect = new Path();
boolean isFirst = true;
for (int i = 0; i < TRAIL_DRAW_POINT; i++) {
float currWidthHalf = (float) (radius) * i / TRAIL_DRAW_POINT / 2f,
currWidthHalfX = currWidthHalf * trailTans[i][1],
currWidthHalfY = currWidthHalf * trailTans[i][0],
currX = trailPoss[i][0], currY = trailPoss[i][1];
if (!isFirst) {
trailStepRect.reset();
trailStepRect.moveTo(prevX - prevWidthHalfX, prevY + prevWidthHalfY);
trailStepRect.lineTo(prevX + prevWidthHalfX, prevY - prevWidthHalfY);
trailStepRect.lineTo(currX + currWidthHalfX, currY - currWidthHalfY);
trailStepRect.lineTo(currX - currWidthHalfX, currY + currWidthHalfY);
canvas.drawPath(trailStepRect, trailPaints[i]);
} else {
isFirst = false;
}
prevX = currX;
prevY = currY;
prevWidthHalfX = currWidthHalfX;
prevWidthHalfY = currWidthHalfY;
}
}
}
Main point of this is drawing trail by parts with different paints. Closer to ball - wider the trail. I think I will optimise it, but it is allready work.
If you want to watch how it looks just install my app from google play.

Sprite setTexture not working

I'm new to libgdx and I don't know yet how the Sprite class works, so I run into a bit of a problem with Sprite.setTexture() not woking(I need this for animations). Long story short(as an example):
sprite = new Sprite (imgb); //work flawlessly
sprite2 = new Sprite ();
sprite2.setTexture (imgb); //doesn't do anything
Is there a problem with the way I did things or there is something else?
Original code My Player class:
package com.triodefender.game;
import java.util.Vector;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import jdk.nashorn.internal.runtime.Debug;
public class Player {
SpriteBatch batch = new SpriteBatch ();
Sprite sprite = new Sprite ();
//Animator animator;
float cx, cy;
float hp;
Texture img = new Texture ("bullet.png"), imgp = new Texture("turret.png");
Vector<Bullet> bullets = new Vector<Bullet>();
void Debug () {
Sprite debug = new Sprite (new Texture("debug.png"), 0, 0, 15, 15);
debug.setPosition (sprite.getX(), sprite.getY());
batch.begin ();
debug.draw (batch);
batch.end ();
debug.setPosition (cx, cy);
batch.begin ();
debug.draw (batch);
batch.end();
}
Player (com.badlogic.gdx.graphics.Color color) {
//animator = new Animator(a);
//sprite = new Sprite (imgp); //this works
sprite = new Sprite ();
sprite.setTexture(imgp); //this doesn't work
sprite.setOriginCenter();
sprite.setColor(color);
hp = 100f;
}
void Update (float ox, float oy, float rotation, boolean shoot) {
cx = ox; cy = oy;
sprite.setPosition(ox - sprite.getWidth()/2, oy - sprite.getHeight()/2);
sprite.setRotation(-rotation);
if (shoot) {
AddBullet();
//animator.lockRow(0, 1, 5);
}
UpdateBullets();
}
void AddBullet () {
float l = sprite.getWidth()/2f;
float sn = (float) Math.sin(Math.toRadians(-sprite.getRotation()));
float cs = (float)Math.cos(Math.toRadians( -sprite.getRotation() ));
float newpx = cx + (float)(l+16f)*sn;
float newpy = cy + (float)(l+16f)*cs;
bullets.add(new Bullet(new Sprite(img), newpx, newpy, -sprite.getRotation(), 10f, sprite.getColor()));
}
void UpdateBullets () {
for (int i = 0; i < bullets.size(); i++)
if (bullets.elementAt(i).Update() == false) {
bullets.remove(i);
i--;
}
}
void DrawBullets () {
for (int i = 0; i < bullets.size(); i++)
bullets.elementAt(i).Draw();
}
float getRotation () {
return sprite.getRotation();
}
void Draw () {
//Debug ();
batch.begin();
sprite.draw(batch);
batch.end();
DrawBullets ();
}
}
You should consult the Sprite source code:
/** Creates an uninitialized sprite. The sprite will need a texture region and bounds set before it can be drawn. */
public Sprite () {
setColor(1, 1, 1, 1);
}
/** Creates a sprite with width, height, and texture region equal to the size of the texture. */
public Sprite (Texture texture) {
this(texture, 0, 0, texture.getWidth(), texture.getHeight());
}
As you can see the second constructor initializes the sprite's texture and bounds (by calling another Sprite constructor). The first constructor only sets its color.
To get the first constructor up to speed with the second you need to define the texture region and bounds before drawing. You set the texture but you still need to define the bounds. Try adding sprite2.setBounds(0, 0, imgb.getWidth(), imgb.getHeight());
I thinks you need
sprite.setRegion(..And select you need);

LibGDX TiledMap - don't detect Collisions

first of all, sorry, because of my rusty English. Since i learnt German i forgot the English.
I'm doing tests with libGDX and my code doesn't detect any collisions.
In my Screen:
public Pantalla(SpriteBatch batch_1) {
batch = batch_1;
screenWidth = Gdx.graphics.getWidth();
screenHeight = Gdx.graphics.getHeight();
stage = new Stage(new StretchViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()),batch);
Gdx.input.setInputProcessor(stage);
camera = new OrthographicCamera();
camera.setToOrtho(false, 1000, 840);
camera.update();
mapas = new Mapas(camera);
// ACTORS
indiana_actor = new indiana_Actor();
//Here comes TOUCHPAD with Skin blaBlaBla...
if (touchpad.isTouched()) {
if (touchpad.getKnobX() > 120) {
indiana_actor.moveBy(32,0);
camera.translate(32, 0);
return; }
}
stage.addActor(indiana_actor);
stage.addActor(touchpad);
Gdx.input.setInputProcessor(stage);
}
public void render(float delta) {//TODO RENDER
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
mapas.MapasRender(camera,indiana_actor);
batch.begin();
batch.end();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
indiana_actor Class:
public indiana_Actor() {
W=Gdx.graphics.getWidth(); H=Gdx.graphics.getHeight();
bounds=new Rectangle((int)getX(), (int)getY(), (int)getWidth(), (int)getHeight());
}
Animation anim_temp;
#Override
public void draw(Batch batch, float parentAlpha) {
stateTime += Gdx.graphics.getDeltaTime();
batch.setColor(getColor());
batch.draw(Assets.indiana_stop_arriba, (W/2), (H/2), 110, 160);
bounds=new Rectangle((int)getX(), (int)getY(), (int)getWidth(), (int)getHeight());
}
and Mapas Class.
In these class i get the Objects in the "objetos" TiledLayer, and triying to check collisions with a for(...) in the renderer.
public Mapas(OrthographicCamera camera2){
map = new TmxMapLoader().load("terrain/prueba.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 10);//ESCALA
renderer.setView(camera2);
collisionObjects = map.getLayers().get("objetos").getObjects();
collisionRects = new Array<Rectangle>();
collisionRects_total=collisionObjects.getCount();
int tileWidth = 32; // whatever your tile width is
int tileHeight = 32; // whatever your tile height is
for (int i = 0; i < collisionObjects.getCount(); i++) {
RectangleMapObject obj = (RectangleMapObject) collisionObjects.get(i);
Rectangle rect = obj.getRectangle();
collisionRects.add(new Rectangle(rect.x / tileWidth, rect.y / tileHeight, rect.width / tileWidth, rect.height / tileHeight));
}
}
public void MapasRender(OrthographicCamera camera2,indiana_Actor indi){
camera2.update();
renderer.setView(camera2);
renderer.render();
for (int i = 0; i < collisionRects_total; i++) {
Rectangle rect = collisionRects.get(i);
if (indi.bounds.overlaps(rect)){
Gdx.app.log("EVENTO", "MAPAS RENDER - COLISION!");
}if (rect.overlaps(indi.bounds)){
Gdx.app.log("EVENTO", "MAPAS RENDER - COLISION!");
}
}
}
I know (Through the logcat) that the
" for (int i = 0; i < collisionRects_total; i++) {
Rectangle rect = collisionRects.get(i); "
get always the objectsRectangle , but in the next line find any overlaps.
Is that a problem with the actor bounds-rectangle?A problem when moving actor through the map??....
Thanks in advance!!
Why dont U at first check if your rectangle for collision draw correctly on position. You can do that by calling
shapeRenderer.begin(ShapeType.Line);
shapeRenderer.setColor(Color.NAVY);
shapeRenderer.rect(object.getrect().x,
object.getrect().y,object.getrect().width,
object.getrect().height);
may be you draw collision rectangles at wrong position so collision will never occur.

Java Applet adding thread makes while loop infinite

I am trying to make a program that generates 25 random ovals then draw a ball and make it bounce, I got it somewhat done, I generated the ovals and I got the ball to move but when I added the thread it kept repeating the draw oval loop, I get somewhat why this is happening but I have no idea how to fix it.
Basically my program should:
draw 25 random sized ovals on random locations within the border - completed
draw a ball and make it move - completed
make the ball bounce - not done but I know how to do it
but it keeps repeating step one.
this is my code that I have written, oh and I have to use applets right now its part of the course please don't suggest I use swing or something else:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
public class As4B extends Applet implements Runnable
{
public int x, y;
public int width = 854;
public int height = 480;
public int border = 20;
public Image offscreen;
public Graphics d;
public void init()
{
setSize(width,height);
Thread th = new Thread(this);
th.start();
offscreen = createImage(width,height);
d = offscreen.getGraphics();
}
public void run()
{
x = 100;
y = 100;
while(true)
{
x ++;
y ++;
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void paint(Graphics gfx)
{
d.setColor(java.awt.Color.black);
d.fillRect(0, 0, width, height);
d.setColor(java.awt.Color.green);
d.fillRect(0 + border, 0 + border, (width - (border * 2)), (height - (border* 2)));
genOval(25, d);
d.setColor(Color.gray);
d.fillOval(x, y, 50, 50);
gfx.drawImage(offscreen, 0, 0, this);
}
public int random(int low, int high)
{
int answer =(int)((Math.random()*(high-low))+ low);
return answer;
}
public void genOval(int amount, Graphics f)
{
int ranWidth, ranHeight, ranX, ranY, red, blue, green;
int i = 0;
while(i < 25)
{
green = random(0,255);
blue = random(0,255);
red = random(0,255);
f.setColor(new Color(red,green,blue));
ranWidth = random(30,400);
ranHeight = random(30,200);
ranX = random(0 + border, ((width - border)- (ranWidth)));
ranY = random(0 + border , ((height - border)- (ranHeight)));
f.fillOval(ranX, ranY, ranWidth, ranHeight);
i++;
}
}
public void update(Graphics gfx) {
paint(gfx);
}
}
Your genOval() method has no persistent backing. Every time repaint() is called (by your thread), the paint() method is called, and this generates new locations for the random ovals. You need to create a persistent source for that information, like so:
List<Rectangle> rectangles = new ArrayList<Rectangle>();
List<Color> colors = new ArrayList<Color>();
public void init() {
...
for (int i = 0; i < 25; i++) {
int green = random(0,255);
int blue = random(0,255);
int red = random(0,255);
colors.add(new Color(red,green,blue));
ranWidth = random(30,400);
ranHeight = random(30,200);
ranX = random(0 + border, ((width - border)- (ranWidth)));
ranY = random(0 + border , ((height - border)- (ranHeight)));
rectangles.add(new Rectangle(ranX, ranY, ranWidth, ranHeight));
}
}
public void genOval(Graphics g) {
for (int i = 0; i < 25; i++) {
Color color = colors.get(i);
Rectangle rectangle = rectangle.get(i);
// Draw using color & rectangle
}
}

Categories