-
Notifications
You must be signed in to change notification settings - Fork 0
player_scene
With the project settings in place, we can start working on the player-controlled character.
The first thing is to create a parent state for the scenes.
In package e.g.dodgethecreeps.screen
create a class 'AbstractScreen' that inherits from BaseAppState
(implement all abstract methods).
package e.g.dodgethecreeps.screen;
...
public abstract class AbstractScreen extends BaseAppState {
...
}
Now that you have your main class, create a new class GameSceneAppState
for the player scene state.
package e.g.dodgethecreeps.screen;
...
public class GameSceneAppState extends AbstractScreen {
private Node rootNode;
@Override
protected void initialize(Application app) {
super.initialize(app);
Dodgethecreeps application = (Dodgethecreeps) app;
rootNode = new Node("MyRootNode");
application.getRootNode().attachChild(rootNode);
}
@Override
protected void onDisable() {
super.onDisable();
rootNode.detachAllChildren();
}
}
Add the following states to the manager, open class Dodgethecreeps
and find method public void simpleInitApp()
.
@Override
public void simpleInitApp() {
...
// scene states; where the game is managed
GameSceneAppState gameAppState = new GameSceneAppState();
stateManager.attach(gameAppState);
....
}
To start, in the e.g.dodgethecreeps.game
package, create a new Player
class for the player character's body and control.
package e.g.dodgethecreeps.game;
...
public final class Player extends KinematicBody2D {
public Player(Dodgethecreeps app) {}
protected void ready() {
}
protected void physicsProcess(float delta) {
}
}
In the Player
class, generate a static method where the character models are configured.
public static Player getNewInstancePlayer(Dodgethecreeps app) {
AssetManager assetManager = app.getAssetManager();
Material mat = MaterialUtilities.getUnshadedMaterialFromClassPath(assetManager, "Textures/playerGrey_walk1.png");
mat.setFloat("AlphaDiscardThreshold", 0.0F);
Sprite sprite = new Sprite(1.5F, 1.5F);
Geometry geom = new Geometry("Player", sprite);
geom.setMaterial(mat);
geom.setQueueBucket(RenderQueue.Bucket.Transparent);
Player player = new Player(app);
geom.addControl(player);
return player;
}
Add 2 animations for the player character.
...
// Add the following animations.
AnimatedSprite2D animatedSprite = new AnimatedSprite2D();
animatedSprite.addAnimation("walk", new Texture[] {
TextureUtilities.getTextureFromClassPath(assetManager, "Textures/playerGrey_walk1.png"),
TextureUtilities.getTextureFromClassPath(assetManager, "Textures/playerGrey_walk2.png")
});
animatedSprite.addAnimation("up", new Texture[] {
TextureUtilities.getTextureFromClassPath(assetManager, "Textures/playerGrey_up1.png"),
TextureUtilities.getTextureFromClassPath(assetManager, "Textures/playerGrey_up2.png")
});
animatedSprite.setAnimationSpeed(0.60F);
geom.addControl(animatedSprite);
...
Dyn4j uses a filter system to apply physical body collisions.
Create a new class in package e.g.dodgethecreeps.game
as follows.
package e.g.dodgethecreeps.game;
...
public final class LayerFilter implements Filter {
private final int layer;
public LayerFilter(int layer) {
this.layer = layer;
}
@Override
public boolean isAllowed(Filter filter) {
if (filter instanceof LayerFilter) {
if (this.layer == ((LayerFilter) filter).layer) {
return false;
}
}
return true;
}
}
This filter applies collisions if the layers are equal, otherwise the physical bodies do not collide.
Finally add a physical shape (Capsule).
....
BodyFixture fixture = new BodyFixture(GeometryUtilities.dyn4jCreateCapsule(0.8, 1.1));
fixture.setFilter(new LayerFilter(0));
player.addFixture(fixture);
player.setMass(MassType.NORMAL);
....
Your player class must have the following.
package e.g.dodgethecreeps.game;
...
public final class Player extends KinematicBody2D {
public Player(Dodgethecreeps app) {
}
protected void ready() {
}
protected void physicsProcess(float delta) {
}
public static Player getNewInstancePlayer(Dodgethecreeps app) {
AssetManager assetManager = app.getAssetManager();
Material mat = MaterialUtilities.getUnshadedMaterialFromClassPath(assetManager, "Textures/playerGrey_walk1.png");
mat.setFloat("AlphaDiscardThreshold", 0.0F);
Sprite sprite = new Sprite(1.5F, 1.5F);
Geometry geom = new Geometry("Player", sprite);
geom.setMaterial(mat);
geom.setQueueBucket(RenderQueue.Bucket.Transparent);
// Add the following animations.
AnimatedSprite2D animatedSprite = new AnimatedSprite2D();
animatedSprite.addAnimation("walk", new Texture[] {
TextureUtilities.getTextureFromClassPath(assetManager, "Textures/playerGrey_walk1.png"),
TextureUtilities.getTextureFromClassPath(assetManager, "Textures/playerGrey_walk2.png")
});
animatedSprite.addAnimation("up", new Texture[] {
TextureUtilities.getTextureFromClassPath(assetManager, "Textures/playerGrey_up1.png"),
TextureUtilities.getTextureFromClassPath(assetManager, "Textures/playerGrey_up2.png")
});
animatedSprite.setAnimationSpeed(0.60F);
BodyFixture fixture = new BodyFixture(GeometryUtilities.dyn4jCreateCapsule(0.8, 1.1));
fixture.setFilter(new LayerFilter(0));
Player player = new Player(app);
player.addFixture(fixture);
player.setMass(MassType.NORMAL);
geom.addControl(player);
geom.addControl(animatedSprite);
return player;
}
}
Setting GameSceneAppState
status
- Create the following properties in this state:
private Dyn4jAppState<PhysicsBody2D> dyn4jAppState;
private TimerAppState timerAppState;
private Player player;
- Initialize the following properties:
@Override
protected void initialize(Application app) {
....
dyn4jAppState = getState(Dyn4jAppState.class);
timerAppState = getState(TimerAppState.class);
...
}
- Show the player
@Override
protected void onEnable() {
super.onEnable();
player = Player.getNewInstancePlayer((Dodgethecreeps) getApplication());
player.translate(0, -1.5);
dyn4jAppState.getPhysicsSpace().addBody(player);
rootNode.attachChild(player.getJmeObject());
}
- Disabling this state releases all physical bodies of the dyn4j engine.
@Override
protected void onDisable() {
...
World<PhysicsBody2D> world = dyn4jAppState.getPhysicsSpace();
if (world != null) {
world.removeAllBodies();
}
...
}
At the moment your code should look similar to the following:
package e.g.dodgethecreeps.screen;
...
public class GameSceneAppState extends AbstractScreen {
private Node rootNode;
private Dyn4jAppState<PhysicsBody2D> dyn4jAppState;
private TimerAppState timerAppState;
private Player player;
@Override
protected void initialize(Application app) {
super.initialize(app);
Dodgethecreeps application = (Dodgethecreeps) app;
rootNode = new Node("MyRootNode");
application.getRootNode().attachChild(rootNode);
dyn4jAppState = getState(Dyn4jAppState.class);
timerAppState = getState(TimerAppState.class);
}
@Override
protected void onEnable() {
super.onEnable();
player = Player.getNewInstancePlayer((Dodgethecreeps) getApplication());
player.translate(0, -1.5);
dyn4jAppState.getPhysicsSpace().addBody(player);
rootNode.attachChild(player.getJmeObject());
}
@Override
protected void onDisable() {
super.onDisable();
World<PhysicsBody2D> world = dyn4jAppState.getPhysicsSpace();
if (world != null) {
world.removeAllBodies();
}
rootNode.detachAllChildren();
}
}