Drawing a CatmullRomSpline in libgdx with an endpoint and startpoint - java

So my goal is to draw a spline similar to this one (where the line goes through each point):
But the spline loops around (from the end point 2 back to the start point):
I tried changing the "continuous" boolean in the catmullromspline, but that resulted in only a dot being drawn in the center of the screen.
I also ended the line drawing when it hit the last point, but the result was ugly because the line was still curving at the start and end points.
I looked everywhere in the source code, and could not find a function that could prevent it from looping.
And as far as i know, bezier splines don't go through all the points (they only pass near them).
So what should I do?
Here's my code:
...
public class GameScreen implements Screen {
final game game;
float w=800;
float h=480;
OrthographicCamera camera;
long startTime;
Texture baseTexture=new Texture(Gdx.files.internal("white.png"));
public GameScreen(final game gam) {
this.game = gam;
startTime = TimeUtils.millis();
camera = new OrthographicCamera();
camera.setToOrtho(false, w, h);
setup();
}
//https://github.com/libgdx/libgdx/wiki/Path-interface-&-Splines
int k = 10000; //increase k for more fidelity to the spline
Vector2[] points = new Vector2[k];
Vector2 cp[] = new Vector2[]{
new Vector2(w/2, h), new Vector2(w/2, h/2),new Vector2(50, 50)
};
ShapeRenderer rope=new ShapeRenderer();
public void setup(){
CatmullRomSpline<Vector2> myCatmull = new CatmullRomSpline<Vector2>( cp, true);
for(int i = 0; i < k; ++i)
{
points[i] = new Vector2();
myCatmull.valueAt(points[i], ((float)i)/((float)k-1));
}
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl20.glLineWidth(50);
game.batch.begin();
rope.setAutoShapeType(true);
rope.begin();
for(int i = 0; i < k-1; ++i)
{
//rope.line(points[i], points[i+1]);
//shaper.line(myCatmull.valueAt(points[i], ((float)i)/((float)k-1)), myCatmull.valueAt(points[i+1], ((float)i)/((float)k-1)));
game.batch.draw(baseTexture, points[i].x, points[i].y, 5, 5);
}
rope.end();
for(int i=0;i<cp.length;i++){//draw the location of each point
game.font.draw(game.batch, "point "+i, cp[i].x, cp[i].y);
}
//logging systems
for(int i=0;i<20;i++){
if(Gdx.input.isTouched(i))
game.font.draw(game.batch, "x:"+Gdx.input.getX(i)+" y:"+Gdx.input.getY(i), 0, (game.font.getCapHeight()+10)*(i+1));
}
game.font.draw(game.batch, "fps:"+Gdx.graphics.getFramesPerSecond()+" log:"+log, 0, h-game.font.getCapHeight());
game.batch.end();
}
...

Related

curveVertex() not drawling in Processing?

I'm trying to create a script that drawls a curve through 'n' vertexes equally spaced around the center of an ellipse.
The reason I'm not just drawling an ellipse around the center ellipse is because I eventually want to connect a micro-controller to Processing where the data points acquired from the 'n' amount of sensors will vary the height ('y') of each vertex, creating constantly changing, irregular curves around the center ellipse such as this possible curve:
Essentially, this is supposed to be a data visualizer, but I cannot figure out why this is not working or how to achieve this effect after going through examples and the documentation on https://processing.org/reference/.
Here is my code:
color WHITE = color(255);
color BLACK = color(0);
void setup() {
size(500, 500);
}
void draw() {
background(WHITE);
translate(width/2, height/2); // move origin to center of window
// center ellipse
noStroke();
fill(color(255, 0, 0));
ellipse(0, 0, 10, 10); // center point, red
fill(BLACK);
int n = 10;
int y = 100;
float angle = TWO_PI / n;
beginShape();
for (int i = 0; i < n; i++) {
rotate(angle);
curveVertex(0, y);
}
endShape();
}
The matrix operations like rotate do not transform the single vertices in a shape. The current matrix is applied to the entire shape when it is draw (at endShape). You've to calculate all the vertex coordinates:
Create a ArrayList of PVector, fill it with points and draw it in a loop:
color WHITE = color(255);
color BLACK = color(0);
ArrayList<PVector> points = new ArrayList<PVector>();
void setup() {
size(500, 500);
int n = 10;
int radius = 100;
for (int i = 0; i <= n; i++) {
float angle = TWO_PI * (float)i/n;
points.add(new PVector(cos(angle)*radius, sin(angle)*radius));
}
}
void draw() {
background(WHITE);
translate(width/2, height/2);
noFill();
stroke(255, 0, 0);
beginShape();
PVector last = points.get(points.size()-1);
curveVertex(last.x, last.y);
for (int i = 0; i < points.size(); i++) {
PVector p = points.get(i);
curveVertex(p.x, p.y);
}
PVector first = points.get(0);
curveVertex(first.x, first.y);
endShape();
}

libGDX Strange Rendering Bug

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

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.

Android game freeze for half second

I'm a beginner programmer and I'm trying to make a game for android using LibGDX. I don't understand why it freezees for less than half second all the game (running on desktop) and if I run it on my phone or on the Emulator the freezing time is longer than half a second. This is the code:
#Override
public void show() {
stage = new Stage(physicWidth, physicHeight, true);
gun = new ArrayList<Guns>();
buildingAtlas = new TextureAtlas(Gdx.files.internal("ui/cladiri.pack"));
buildingSkin = new Skin(buildingAtlas);
building1 = new ImageButton(buildingSkin.getDrawable("cladire1"));
building2 = new ImageButton(buildingSkin.getDrawable("cladire2"));
table = new Table();
table.setBounds(0, tileH * 4, tileW * 6, tileH);
table.left();
table.add(building1).width((float) (tileW * 0.8)).height((float) (tileH * 0.7));
table.add(building2).width((float) (tileW * 0.8)).height((float) (tileH * 0.7));
stage.addActor(table);
Gdx.input.setInputProcessor(stage);
building1.addListener(new InputListener(){
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
gun.add(new Guns(selectedTile.x, selectedTile.y));
return true;
}
});
building2.addListener(new InputListener(){
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("Touch on Building 2");
return true;
}
});
}
#Override
public void render(float delta) {
batch.begin();
for(int i = 0; i < gun.size(); i++){
gun.get(i).render(batch, tileW, tileH);
}
batch.end();
}
The Guns class is:
public Guns(float x, float y) {
this.y = y;
this.x = x;
gunTexture = new Texture(Gdx.files.internal("img/gunTest1.png"));
TextureRegion[][] tmp = TextureRegion.split(gunTexture, gunTexture.getWidth() /
COLS, gunTexture.getHeight() / ROWS);
gunFrames = new TextureRegion[COLS * ROWS];
int index = 0;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
cladireFrames[index++] = tmp[i][j];
}
}
gunAnimation = new Animation(0.1f, gunFrames);
stateTime = 0f;
bounds = new Rectangle();
}
public void update(){
stateTime += Gdx.graphics.getDeltaTime();
curGunFrame = gunAnimation.getKeyFrame(stateTime, true);
}
public void render(SpriteBatch batch, float w, float h){
batch.draw(getCurGunFrame(), x, y, w, h);
}
If touched the building2 button who execute the "System.out.println" the game doesn't freeze, but on building1 who adds a new Gun then it does freeze.
The code I posted is simplified, only whats relevant to my problem.
It looks like one of these lines will be causing your problem:
gunTexture = new Texture(Gdx.files.internal("img/gunTest1.png"));
TextureRegion[][] tmp = TextureRegion.split(gunTexture, gunTexture.getWidth() /
COLS, gunTexture.getHeight() / ROWS);
Texture loading is often an expensive operation, you're then operating on it after loading it in and one, or both of these operations is almost certainly going to be causing the lag you are experiencing. I believe a standard mechanism to solve this problem is to share textures between objects and load the texture when the level starts, rather than while it's running.
Rather than having your Gun class creating a new texture on creation, your game should pass the texture in to the constructor along with the x and y variables.
The reason for the different lag times experienced between your desktop and your phone is most likely because your desktop is a lot more powerful.

Categories