Klasa GameRender:
public class GameRender {
private GameWorld gameWorld;
private Box2DDebugRenderer b2d;
private OrthographicCamera cam;
private SpriteBatch batch;
public GameRender(GameWorld gameWorld, OrthographicCamera cam) {
batch = new SpriteBatch();
this.b2d = new Box2DDebugRenderer();
this.gameWorld = gameWorld;
this.cam = cam;
}
public void render() {
update();
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
b2d.render(gameWorld.getWorld(), cam.combined);
batch.begin();
gameWorld.getHero().getSprite().draw(batch);
batch.end();
}
public void update(){
gameWorld.getHero().update();
gameWorld.update();
cam.update();
}
}
Klasa GameWorld, tutaj jest tworzony "świat" fizyka, obsługa klawiszy i ekranu:
public class GameWorld {
private Hero hero;
private World world;
private OrthographicCamera cam;
private Body bodyplatform; // ruchoma platforma
private float velX = 0.5f; // Prędkość platformy
public GameWorld(OrthographicCamera cam) {
this.cam = cam;
world = new World(new Vector2(0, 10f), true);
hero = new Hero(400,150, 20,20 , world);
createFloor();
}
private void InputHandler(){//obsloga klawiszy
hero.prevRunningRight = hero.runningRight;
if(Gdx.input.isKeyJustPressed(Keys.W) && (hero.getState() != HeroStates.JUMP || hero.getState() != HeroStates.FALL)){
hero.jump();
if(hero.getHeroBody().getLinearVelocity().y < 0){
//pika();
}
}
if(Gdx.input.isKeyPressed(Keys.A)){
hero.moveLeft();
hero.runningRight = false;
hero.actualState = HeroStates.RUN;
}
if(Gdx.input.isKeyPressed(Keys.D)){
hero.moveRight();
hero.runningRight = true;
hero.actualState = HeroStates.RUN;
}
if(Gdx.input.isTouched())
if(Gdx.input.getX() > Gdx.graphics.getWidth()/2){
hero.moveRight();
hero.runningRight = true;
hero.actualState = HeroStates.RUN;
}
else if(Gdx.input.getX() < Gdx.graphics.getWidth()/2){
hero.moveLeft();
hero.runningRight = false;
hero.actualState = HeroStates.RUN;
}
if(Gdx.input.justTouched() && Gdx.input.getY() < Gdx.graphics.getHeight()/2){
hero.jump();
pika();
}
hero.update();
}
public void update() {
InputHandler();
if(bodyplatform.getPosition().x > 7)
velX = -0.5f;
else if(bodyplatform.getPosition().x < 5f)
velX = 0.5f;
bodyplatform.setLinearVelocity(velX, 0f); //platforma jezdzi tam i z powrotem
world.step(1/60f, 6 , 2);
}
public Hero getHero(){
return hero;
}
public World getWorld(){
return world;
}
private void createFloor(){ // tutaj tworzone jest body platform podlogi i jakies piłeczki
BodyDef bdef = new BodyDef();
bdef.type = BodyType.StaticBody;
bdef.position.set(new Vector2(0f, TowerGame.GAME_HEIGHT/ TowerGame.PixPerMeter));
Body body = world.createBody(bdef);
PolygonShape poly = new PolygonShape();
poly.setAsBox(cam.viewportWidth, 10f / TowerGame.PixPerMeter);
body.createFixture(poly, 0.5f);
poly.dispose();
bdef = new BodyDef();
bdef.type = BodyType.StaticBody;
bdef.position.set(new Vector2(1f,170f / TowerGame.PixPerMeter));
body = world.createBody(bdef);
poly = new PolygonShape();
poly.setAsBox(0.3f, 0.3f);
body.createFixture(poly,0.1f);
poly.dispose();
bdef = new BodyDef();
bdef.type = BodyType.DynamicBody;
bdef.position.set(new Vector2(1.8f,110f / TowerGame.PixPerMeter));
body = world.createBody(bdef);
CircleShape circle = new CircleShape();
circle.setRadius(0.1f);
body.createFixture(circle,0.2f);
circle.dispose();
bdef = new BodyDef();
bdef.type = BodyType.DynamicBody;
bdef.position.set(new Vector2(3.5f,110f / TowerGame.PixPerMeter));
body = world.createBody(bdef);
circle = new CircleShape();
circle.setRadius(0.1f);
body.createFixture(circle,0.2f);
circle.dispose();
bdef = new BodyDef();
bdef.type = BodyType.DynamicBody;
bdef.position.set(new Vector2(3.5f,100f / TowerGame.PixPerMeter));
body = world.createBody(bdef);
circle = new CircleShape();
circle.setRadius(0.1f);
body.createFixture(circle,0.2f);
circle.dispose();
bdef = new BodyDef();
bdef.type = BodyType.DynamicBody;
bdef.position.set(new Vector2(3.5f,90f / TowerGame.PixPerMeter));
body = world.createBody(bdef);
circle = new CircleShape();
circle.setRadius(0.1f);
body.createFixture(circle,0.2f);
circle.dispose();
bdef = new BodyDef();
bdef.type = BodyType.DynamicBody;
bdef.position.set(new Vector2(3.5f,80f / TowerGame.PixPerMeter));
body = world.createBody(bdef);
circle = new CircleShape();
circle.setRadius(0.1f);
body.createFixture(circle,0.2f);
circle.dispose();
bdef = new BodyDef();
bdef.type = BodyType.StaticBody;
bdef.position.set(new Vector2(2f,300f / TowerGame.PixPerMeter));
body = world.createBody(bdef);
poly = new PolygonShape();
poly.setAsBox(0.9f, 0.3f);
FixtureDef fixdef = new FixtureDef();
fixdef.friction = 0;
fixdef.restitution = 0.4f;
fixdef.density = 1f;
fixdef.shape = poly;
Fixture fix = body.createFixture(fixdef);
poly.dispose();
bdef = new BodyDef();
bdef.type = BodyType.KinematicBody;
bdef.position.set(new Vector2(5f,300f / TowerGame.PixPerMeter));
bodyplatform = world.createBody(bdef);
poly = new PolygonShape();
poly.setAsBox(0.9f, 0.3f);
bodyplatform.createFixture(poly, 0.1f);
poly.dispose();
}
}
Klasa Hero, tutaj tworzony jest Pikachu, jego body i sprite:
public class Hero{
public static enum HeroStates {JUMP, RUN, STAND, FALL};
public HeroStates actualState;
private HeroStates prevState;
public static final float MAX_VELOCITY = 1.5f;
private float x,y,width,height;
private World world;
private BodyDef bdef;
private Body body;
private FixtureDef fixdef;
private Fixture fixture;
private CircleShape circle;
private Vector2 velocity,position;
private TextureAtlas atlas;
private Animation run;
private TextureRegion stand;
private TextureRegion jump;
private Sprite sprite;
private float timer;
public boolean runningRight, prevRunningRight;
public void dispose(){
world.dispose();
atlas.dispose();
}
public Hero(int posX, int posY, int width, int height, World world){
this.world = world;
this.x = posX;
this.y = posY;
this.width = width;
this.height = height;
actualState = HeroStates.STAND;
prevState = HeroStates.STAND;
this.atlas = new TextureAtlas("pika.pack");
this.timer = 0.0f;
this.runningRight = true;
this.prevRunningRight = true;
heroDef();
createSprite();
}
public void jump(){
if(getState() != HeroStates.JUMP){
if(getState() != HeroStates.FALL)
body.applyLinearImpulse(new Vector2(0,-8f), body.getLocalCenter(), true);
}
}
public void moveLeft(){
velocity = body.getLinearVelocity();
if(velocity.x > -MAX_VELOCITY)
body.applyLinearImpulse(new Vector2(-0.9f,0), body.getLocalCenter(), true);
}
public void moveRight(){
velocity = body.getLinearVelocity();
if(velocity.x < MAX_VELOCITY)
body.applyLinearImpulse(new Vector2(0.9f,0), body.getLocalCenter(), true);
}
public Body getHeroBody(){
return body;
}
public boolean isRunningRight(){
return runningRight;
}
public TextureRegion getFrame(){
TextureRegion region;
actualState = getState();
timer = actualState == prevState ? timer + Gdx.graphics.getDeltaTime() : 0;
switch(getState()){
case JUMP:
region = jump;
break;//*/
case STAND:
region = stand;
break;
case RUN:
region = run.getKeyFrame(timer,true);
break;//*/
default:
region = stand;
}
if((getHeroBody().getLinearVelocity().x < 0 || !runningRight) && !region.isFlipX()){
region.flip(true, false);
runningRight = false;
}
//if mario is running right and the texture isnt facing right... flip it.
else if((getHeroBody().getLinearVelocity().x > 0 || runningRight) && region.isFlipX()){
region.flip(true, false);
runningRight = true;
}
return region;
}
public Sprite getSprite(){
return sprite;
}
public float getX(){
return getHeroBody().getPosition().x*TowerGame.PixPerMeter;
}
public float getY(){
return getHeroBody().getPosition().y*TowerGame.PixPerMeter;
}
public HeroStates getState(){
prevState = actualState;
if(body.getLinearVelocity().y < 0 || (body.getLinearVelocity().y > 0 && prevState == HeroStates.JUMP))
return HeroStates.JUMP;
else if(body.getLinearVelocity().y > 0)
return HeroStates.FALL;
else if(body.getLinearVelocity().x != 0)
return HeroStates.RUN;
else
return HeroStates.STAND;
}
public void update(){
sprite.setRegion(getFrame());
sprite.setPosition(getX()-getFrame().getRegionWidth()/2, TowerGame.GAME_HEIGHT - getY() - getFrame().getRegionHeight()/2+2);
}
private void heroDef(){ //definicja pikachu
bdef = new BodyDef();
bdef.type = BodyType.DynamicBody;
bdef.position.set(new Vector2(x / TowerGame.PixPerMeter,y / TowerGame.PixPerMeter));
body = world.createBody(bdef);
body.setLinearDamping(3);
circle = new CircleShape();
circle.setRadius(10 / TowerGame.PixPerMeter);
fixdef = new FixtureDef();
fixdef.shape = circle;
fixture = body.createFixture(fixdef);
circle.dispose();
}
private void createSprite(){//wygląd pikachu
Array<TextureRegion> frames = new Array<TextureRegion>();
for(int i = 0; i < 3; i++)
frames.add(new TextureRegion(atlas.findRegion("run"), i*32,0,32,31));
run = new Animation(0.2f, frames);
frames.clear();
stand = new TextureRegion(atlas.findRegion("stand"),32,0,32,31);
jump = new TextureRegion(atlas.findRegion("jump"),0,0,32,31);
sprite = new Sprite(jump);
//sprite.setOrigin(jump.getRegionWidth()/2, jump.getRegionHeight()/2);
}
}
importów nie kopiowałem, ale były to głównie biblioteki badlogic.
Zmieniłem tak jak mi poleciłeś. I pikachu biega jakby dobrze, bo nie widać platform itd, ale wskakuje gdzieś coś się dzieje. Ale wszystkie body są rysowane w prawym górnym rogu, jakby były odbite względem punktu jakiegoś. Na załączonym obrazku jest Sprite pokazany w akcji i po drugiej stronie ten okrąg to jego body. Body jest do góry nogami.