/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.tests;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
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.glutils.ImmediateModeRenderer20;
import com.badlogic.gdx.math.BSpline;
import com.badlogic.gdx.math.Bezier;
import com.badlogic.gdx.math.CatmullRomSpline;
import com.badlogic.gdx.math.Path;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.tests.utils.GdxTest;
import com.badlogic.gdx.utils.Array;
/** @author Xoppa */
public class PathTest extends GdxTest {
int SAMPLE_POINTS = 100;
float SAMPLE_POINT_DISTANCE = 1f / SAMPLE_POINTS;
float ZIGZAG_SCALE;
SpriteBatch spriteBatch;
ImmediateModeRenderer20 renderer;
Sprite obj;
Sprite obj2;
Array<Path<Vector2>> paths = new Array<Path<Vector2>>();
int currentPath = 0;
float t;
float t2;
float zt;
float speed = 0.2f;
float zspeed = 1.0f;
float wait = 0f;
boolean zigzag = false;
@Override
public void create () {
renderer = new ImmediateModeRenderer20(false, false, 0);
spriteBatch = new SpriteBatch();
obj = new Sprite(new Texture(Gdx.files.internal("data/badlogicsmall.jpg")));
obj.setSize(40, 40);
obj.setOriginCenter();
obj2 = new Sprite(new Texture(Gdx.files.internal("data/bobrgb888-32x32.png")));
obj2.setSize(40, 40);
obj2.setOriginCenter();
ZIGZAG_SCALE = Gdx.graphics.getDensity() * 96; // 96DP
float w = Gdx.graphics.getWidth() - obj.getWidth();
float h = Gdx.graphics.getHeight() - obj.getHeight();
paths.add(new Bezier<Vector2>(new Vector2(0, 0), new Vector2(w, h)));
paths.add(new Bezier<Vector2>(new Vector2(0, 0), new Vector2(0, h), new Vector2(w, h)));
paths.add(new Bezier<Vector2>(new Vector2(0, 0), new Vector2(w, 0), new Vector2(0, h), new Vector2(w, h)));
Vector2 cp[] = new Vector2[] {new Vector2(0, 0), new Vector2(w * 0.25f, h * 0.5f), new Vector2(0, h),
new Vector2(w * 0.5f, h * 0.75f), new Vector2(w, h), new Vector2(w * 0.75f, h * 0.5f), new Vector2(w, 0),
new Vector2(w * 0.5f, h * 0.25f)};
paths.add(new BSpline<Vector2>(cp, 3, true));
paths.add(new CatmullRomSpline<Vector2>(cp, true));
pathLength = paths.get(currentPath).approxLength(500);
avg_speed = speed * pathLength;
Gdx.input.setInputProcessor(this);
}
final Vector2 tmpV = new Vector2();
final Vector2 tmpV2 = new Vector2();
final Vector2 tmpV3 = new Vector2();
final Vector2 tmpV4 = new Vector2();
float pathLength;
float avg_speed;
@Override
public void render () {
GL20 gl = Gdx.gl20;
gl.glClearColor(0.7f, 0.7f, 0.7f, 1);
gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (wait > 0)
wait -= Gdx.graphics.getDeltaTime();
else {
t += speed * Gdx.graphics.getDeltaTime();
zt += zspeed * Gdx.graphics.getDeltaTime();
while (t >= 1f) {
currentPath = (currentPath + 1) % paths.size;
pathLength = paths.get(currentPath).approxLength(500);
if (currentPath > 2) {
avg_speed = speed * pathLength / 8.0f;
} else {
avg_speed = speed * pathLength;
}
if (currentPath == 0) {
zigzag = !zigzag;
zt = 0;
}
t -= 1f;
t2 = 0f;
}
paths.get(currentPath).valueAt(tmpV, t);
paths.get(currentPath).derivativeAt(tmpV2, t);
paths.get(currentPath).derivativeAt(tmpV3, t2);
t2 += avg_speed * Gdx.graphics.getDeltaTime() / tmpV3.len();
paths.get(currentPath).valueAt(tmpV4, t2);
// obj.setRotation(tmpV2.angle());
// obj2.setRotation(tmpV3.angle());
if (zigzag) {
tmpV2.nor();
tmpV2.set(-tmpV2.y, tmpV2.x);
tmpV2.scl((float)Math.sin(zt) * ZIGZAG_SCALE);
tmpV.add(tmpV2);
}
obj.setPosition(tmpV.x, tmpV.y);
obj2.setPosition(tmpV4.x, tmpV4.y);
}
renderer.begin(spriteBatch.getProjectionMatrix(), GL20.GL_LINE_STRIP);
float val = 0f;
while (val <= 1f) {
renderer.color(0f, 0f, 0f, 1f);
paths.get(currentPath).valueAt(/* out: */tmpV, val);
renderer.vertex(tmpV.x, tmpV.y, 0);
val += SAMPLE_POINT_DISTANCE;
}
renderer.end();
spriteBatch.begin();
obj.draw(spriteBatch);
obj2.draw(spriteBatch);
spriteBatch.end();
}
private void touch (int x, int y) {
t = paths.get(currentPath).locate(tmpV.set(x, Gdx.graphics.getHeight() - y));
paths.get(currentPath).valueAt(tmpV, t);
obj.setPosition(tmpV.x, tmpV.y);
wait = 0.2f;
}
@Override
public boolean touchUp (int screenX, int screenY, int pointer, int button) {
touch(screenX, screenY);
return super.touchUp(screenX, screenY, pointer, button);
}
@Override
public boolean touchDragged (int screenX, int screenY, int pointer) {
touch(screenX, screenY);
return super.touchDragged(screenX, screenY, pointer);
}
}