jMonkeyEngine - rotate with mouse like in first-person games - java

can someone give me sample of code that will rotate my player please? I want achieve same control like in classical fps (w,a,s,d + mouse). Something with FlyByCamera but i don't know how to add it. Code is without errors. Thanks.
here are methods that are related to control
public class Main extends SimpleApplication
implements ActionListener {
private Spatial platforms[];
private Spatial trees[];
private Node sceneNode;
private Node playerNode;
private Node platformNode;
private Node treeNode;
private CameraNode camNode;
private BulletAppState bullet;
private RigidBodyControl scenePhysics;
private BetterCharacterControl player;
private Vector3f walkDir = new Vector3f(0, 0, 0);
private Vector3f viewDir = new Vector3f(0, 0, 1);
private boolean rotateLeft = false, rotateRight = false, forward = false,
backward = false, strafeLeft = false, strafeRight = false;
private float moveSpeed = 70;
public static void main(String[] args) {
Main app = new Main();
AppSettings settings = new AppSettings(true);
app.setSettings(settings);
settings.setTitle(“RUSHY”);
settings.setSettingsDialogImage(“Interface/intro.png”);
app.start();
}
public void simpleInitApp() {
bullet = new BulletAppState();
stateManager.attach(bullet);
setUpKeys();
scenePhysics = new RigidBodyControl(0f);
sceneNode.addControl(scenePhysics);
bullet.getPhysicsSpace().add(sceneNode);
rootNode.attachChild(sceneNode);
bullet.getPhysicsSpace().setGravity(new Vector3f(0, -50.0f, 0));
bullet.getPhysicsSpace().setAccuracy(0.016f);
playerNode = new Node(“player”);
playerNode.setLocalTranslation(new Vector3f(0, 10, 0)); //spawn position
rootNode.attachChild(playerNode);
player = new BetterCharacterControl(1.5f, 7f, 30f);
player.setJumpForce(new Vector3f(0, 1200f, 0));
player.setGravity(new Vector3f(0.0f, -10.0f, 0.0f));
playerNode.addControl(player);
bullet.getPhysicsSpace().add(player);
}
private void setUpKeys() {
inputManager.addMapping(“Forward”,
new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping(“Backward”,
new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping(“Rotate Left”,
new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping(“Rotate Right”,
new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping(“Strafe Right”,
new KeyTrigger(KeyInput.KEY_E));
inputManager.addMapping(“Strafe Left”,
new KeyTrigger(KeyInput.KEY_Q));
inputManager.addMapping(“Jump”,
new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, “Rotate Left”, “Rotate Right”,
“Strafe Right”, “Strafe Left”, “Forward”, “Backward”, “Jump”);
}
public void onAction(String binding, boolean isPressed, float tpf) {
if (binding.equals(“Rotate Left”)) {
rotateLeft = isPressed;
} else if (binding.equals(“Rotate Right”)) {
rotateRight = isPressed;
} else if (binding.equals(“Strafe Left”)) {
strafeLeft = isPressed;
} else if (binding.equals(“Strafe Right”)) {
strafeRight = isPressed;
} else if (binding.equals(“Forward”)) {
forward = isPressed;
} else if (binding.equals(“Backward”)) {
backward = isPressed;
} else if (binding.equals(“Jump”)) {
player.jump();
}
}
#Override
public void simpleUpdate(float tpf) {
camNode = new CameraNode(“CamNode”, cam);
camNode.setControlDir(CameraControl.ControlDirection.SpatialToCamera);
camNode.setLocalTranslation(new Vector3f(0, 6, 0));
Quaternion quat = new Quaternion();
quat.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y);
camNode.setLocalRotation(quat);
playerNode.attachChild(camNode);
camNode.setEnabled(true);
Vector3f modelForwardDir = playerNode.getWorldRotation().mult(Vector3f.UNIT_Z);
Vector3f modelLeftDir = playerNode.getWorldRotation().mult(Vector3f.UNIT_X);
walkDir.set(0, 0, 0);
if (forward) {
walkDir.addLocal(modelForwardDir.mult(moveSpeed));
} else if (backward) {
walkDir.addLocal(modelForwardDir.mult(moveSpeed).
negate());
} else if (strafeLeft) {
walkDir.addLocal(modelLeftDir.mult(moveSpeed));
} else if (strafeRight) {
walkDir.addLocal(modelLeftDir.mult(moveSpeed).negate());
}
player.setWalkDirection(walkDir); // walk
if (rotateLeft) {
Quaternion rotateL = new Quaternion().
fromAngleAxis(FastMath.PI * tpf, Vector3f.UNIT_Y);
rotateL.multLocal(viewDir);
} else if (rotateRight) {
Quaternion rotateR = new Quaternion().
fromAngleAxis(-FastMath.PI * tpf, Vector3f.UNIT_Y);
rotateR.multLocal(viewDir);
}
player.setViewDirection(viewDir); // turn
}
}

Can you try something like the methods from an example:
private BulletAppState bulletAppState;
private Node gameLevel;
private PhysicsCharacter player;
private Vector3f walkDirection = new Vector3f();
private boolean left=false,right=false,up=false,down=false;
#Override
public void simpleUpdate(float tpf) {
Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
walkDirection.set(0,0,0);
if(left)
walkDirection.addLocal(camLeft);
if(right)
walkDirection.addLocal(camLeft.negate());
if(up)
walkDirection.addLocal(camDir);
if(down)
walkDirection.addLocal(camDir.negate());
player.setWalkDirection(walkDirection);
cam.setLocation(player.getPhysicsLocation());
}
private void setupKeys() {
inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this,"Lefts");
inputManager.addListener(this,"Rights");
inputManager.addListener(this,"Ups");
inputManager.addListener(this,"Downs");
inputManager.addListener(this,"Space");
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Lefts")) {
if(value)
left=true;
else
left=false;
} else if (binding.equals("Rights")) {
if(value)
right=true;
else
right=false;
} else if (binding.equals("Ups")) {
if(value)
up=true;
else
up=false;
} else if (binding.equals("Downs")) {
if(value)
down=true;
else
down=false;
} else if (binding.equals("Space")) {
player.jump();
}
}

Related

Why doesn't libgdx button work every time?

I made a button, witch stops the game. The is a menu, where you can continue the game. But if the cam moves with the player, the button doesn't work any more. You can see it, but if you click on it nothing happens. If you come back to the "start position" of the cam, the button works again. But the InputProcessor is always the stage with the button.
public class PlayState extends State {
//Objects
private final GameStateManager gameStateManager;
private final State me;
private EntityManager entityManager;
private Player player;
private Texture background;
private Texture filter;
private BitmapFont font;
private Sound click, boost;
private Drug drug;
private Border border;
private House house;
//Constants
public static final int FIELD_SIZE_HEIGHT = 1000;
public static final int FIELD_SIZE_WIDTH = 500;
//Variables
private int collectedDrugs;
private boolean pause, renderLost;
private boolean boostSound;
//Button pause
private Stage stage;
private ImageButton button;
private Drawable drawable;
private Texture textureBtn;
public PlayState(GameStateManager gsm) {
super(gsm);
gameStateManager = gsm;
me = this;
entityManager = new EntityManager();
player = new Player(this, 100, 100);
border = new Border();
background = new Texture("bggame.png");
filter = new Texture("filter.png");
cam.setToOrtho(false, MinniMafia.WIDTH, MinniMafia.HEIGHT);
click = Gdx.audio.newSound(Gdx.files.internal("Click.mp3"));
boost = Gdx.audio.newSound(Gdx.files.internal("boost.mp3"));
drug = new Drug();
house = new House();
collectedDrugs = 0;
font = new BitmapFont();
entityManager.addEntity(player);
entityManager.addEntity(drug);
entityManager.addEntity(border);
entityManager.addEntity(house);
pause = false;
renderLost = false;
boostSound = false;
stage = new Stage();
textureBtn = new Texture("pausebtn.png");
drawable = new TextureRegionDrawable(new TextureRegion(textureBtn));
button = new ImageButton(drawable);
button.setPosition(cam.position.x + cam.viewportWidth/2 - 50, cam.position.y + cam.viewportHeight/2 - 50);
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
gameStateManager.set(new PauseState(gameStateManager, me));
}
});
stage.addActor(button);
Gdx.input.setInputProcessor(button.getStage());
}
#Override
protected void handleInput() {
if (Gdx.input.justTouched()) {
click.play(0.2f);
}
if (Gdx.input.isTouched()) {
player.setStop(true);
boostSound = false;
} else {
if (!boostSound) {
boost.play(0.2f);
boostSound = true;
}
player.setStop(false);
}
}
#Override
public void update(float dt) {
Gdx.input.setInputProcessor(stage);
if(Gdx.input.getInputProcessor() == stage){
System.out.println("All working");
}else{
System.out.println("Error");
}
if (!pause) {
handleInput();
entityManager.updateEntities(dt);
setCam();
button.setPosition(cam.position.x + cam.viewportWidth/2 - 60, cam.position.y + cam.viewportHeight/2 - 60);
if (drug.collides(player.getBounds())) {
entityManager.disposeEntity(drug);
player.setGotDrug(true);
}
if (border.collides(player.getBounds()) && !border.isOpen()) {
pause = true;
renderLost = true;
}
if (house.collides(player.getBounds()) && player.isGotDrug()) {
player.setGotDrug(false);
collectedDrugs++;
drug = new Drug();
entityManager.addEntity(drug);
}
} else if (renderLost = true) {
if (Gdx.input.isTouched()) {
gsm.set(new MenuState(gsm));
dispose();
}
}
}
#Override
public void render(SpriteBatch sb) {
sb.setProjectionMatrix(cam.combined);
sb.begin();
sb.draw(background, 0, 0);
entityManager.renderEntities(sb);
button.draw(sb, 10f);
font.draw(sb, "" + collectedDrugs, cam.position.x - cam.viewportWidth / 2 + 10, cam.position.y - cam.viewportHeight / 2 + 20);
if (renderLost) {
sb.draw(filter, cam.position.x - cam.viewportWidth / 2, cam.position.y - cam.viewportHeight / 2);
font.draw(sb, "LOST! SCORE:" + collectedDrugs, cam.position.x - 50, cam.position.y);
}
sb.end();
}
#Override
public void dispose() {
background.dispose();
entityManager.disposeAll();
click.dispose();
}
private void setCam() {
float camViewportHalfX = cam.viewportWidth * .5f;
float camViewportHalfY = cam.viewportHeight * .5f;
cam.position.x = player.getPosition().x;
cam.position.y = player.getPosition().y;
cam.position.x = MathUtils.clamp(cam.position.x, camViewportHalfX, FIELD_SIZE_WIDTH - camViewportHalfX);
cam.position.y = MathUtils.clamp(cam.position.y, camViewportHalfY, FIELD_SIZE_HEIGHT - camViewportHalfY);
cam.update();
}
public Drug getDrug() {
return drug;
}
public House getHouse() {
return house;
}
}
I really don't know where the problem is. Could you help me please?

Slick2D Will not load image even though it is there

For some reason, my game will NOT freeze when the level starts, while the menu loads just fine!
The game will freeze when the boss music starts.
EDIT: Sorry, I found out that the screen froze because the canMove variables were stuck to false. But, the game will still randomly crash and say the image can not be found.
Here is my code:
This is the menu (Which works fine):
//Sprite sheeting
private SpriteSheet sleepSpriteSheet;
private Animation sleepAnimation;
private SpriteSheet walkSpriteSheet;
private Animation walkAnimation;
//System info
private String operatingSystem = Client.getOS();
//Game texuring
private static String IntroBackground = "res/images/level/IntroBackground.png";
private static String KnightQuestLogo = "res/images/icons/KnightQuestLogo.png";
//Menu Info
private static boolean readyForIntro = false;
private static boolean readyForPlay = false;
private static boolean showArrow = false;
private static String playButton = Button.PlayButton;
private static boolean playerSleeping = true;
private static boolean knightWalking = false;
private static float knightX = 145;
private static float knightY = 456;
private static float knightQuestLogoX = -750;
private static float knightQuestLogoY = 75;
private static boolean soundStarted = false;
public GameMenu(int State) {
}
// Render the game
#Override
public void render(GameContainer GameContainer, StateBasedGame SBG,
Graphics G) throws SlickException {
//Draw Background Image
G.drawImage(new Image(IntroBackground), 0, 0);
//Choose what animation to use
if(playerSleeping) {
sleepAnimation.draw(145, 406, 250, 250);
}
else {
walkAnimation.draw(knightX, knightY, 175, 200);
}
//Draw Floor
G.drawImage(new Image(Block.GroundTile), 0, 656);
//Draw The Logo
G.drawImage(new Image(KnightQuestLogo), knightQuestLogoX, knightQuestLogoY);
//Draw the Play Button
if(readyForPlay) {
G.drawImage(new Image(playButton), 750, 315);
if(showArrow) {
G.drawImage(new Image(Icon.Arrow), 730, 335);
}
}
//System Info
G.drawString("Game State: " + this.getID(), 10, 30);
G.drawString("X:" + Mouse.getX() + " Y:" + Mouse.getY(), 10, 50);
G.drawString("Your OS: " + operatingSystem, 10, 70);
}
// Update the game
#Override
public void update(GameContainer GameContainer, StateBasedGame SBG,
int Delta) throws SlickException {
//Start Sound (Would be started in init(), But the StopSound function will not work if done so.
if(!soundStarted) {
PlaySound.playSound("res/sounds/startup/MainMenu.wav");
soundStarted = true;
}
//When ready, slide the logo to the right
if (readyForIntro) {
if (knightQuestLogoX < 750.0) {
knightQuestLogoX += Delta * .5f;
}
}
//When ready, allow the player the press the play button
if(readyForPlay) {
if(Mouse.getX() > 755 && Mouse.getX() < 875 && Mouse.getY() > 345 && Mouse.getY() < 400) {
showArrow = true;
if(Mouse.isButtonDown(0)) {
playerSleeping = false;
knightWalking = true;
}
}
else {
showArrow = false;
}
}
//If the knight is walking in the intro, slide him off the screen
if(knightWalking) {
if(knightX < 1290) {
knightX += Delta* .5f;
}
else {
SBG.enterState(1, new FadeOutTransition(new Color(Color.black)), new FadeInTransition(new Color(Color.black)));
PlaySound.stopSound();
PlaySound.playSound("res/sounds/events/LeaveState.wav");
}
}
}
// Initialize the GameState
#Override
public void init(GameContainer GameContainer, StateBasedGame SBG)
throws SlickException {
//Start the thread for the Intro
new Thread(new MenuIntro()).start();
//Create the Sprite sheets
sleepSpriteSheet = new SpriteSheet("res/images/characters/knight/spritesheets/SleepAnimation.png", 52, 50);
sleepAnimation = new Animation(sleepSpriteSheet, 250);
walkSpriteSheet = new SpriteSheet("res/images/characters/knight/spritesheets/WalkAnimation.png", 35, 48);
walkAnimation = new Animation(walkSpriteSheet, 75);
}
// Get the ID of the GameState
#Override
public int getID() {
return 0;
}
// MenuIntro thread
static class MenuIntro implements Runnable {
#Override
public void run() {
try {
Thread.sleep(3000);
readyForIntro = true;
Thread.sleep(4000);
readyForPlay = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}
This is the game level (Which is broken):
//Colors RGB
private static String Grey = "rgb/Grey.png";
private static String Blue = "rgb/Blue.png";
private static String Red = "rgb/Red.png";
// Level Variables
private static boolean stateStarted = false;
private static boolean startBossBattle = false;
private static boolean startedBossBattle = false;
private static boolean startedBossMusic = false;
private static boolean BothTouching = false;
// Player Variables
/* Coordinates, And Direction */
private static float PlayerX = 25;
private static float PlayerY = 470;
private static String Knight = "res/images/characters/knight/Knight.png";
private static String PlayerDirection = "right";
private static int PlayerHealth = 100;
private static boolean PlayerWalking = false;
private static boolean PlayerJumping = false;
private static boolean PlayerJumped = false;
private static float AmountPlayerJumped;
private static boolean PlayerAttacking = false;
private static boolean PlayerCanAttack = true;
private static int PlayerRegenTime = 100;
/* Sprite Sheets */
private static String PlayerLeftSword = "res/images/icons/sword/SwordLeft.png";
private static String PlayerLeftAttackSword = "res/images/icons/sword/SwordLeftAttacking.png";
private static String PlayerRightSword = "res/images/icons/sword/SwordRight.png";
private static String PlayerRightAttackSword = "res/images/icons/sword/SwordRightAttacking.png";
private static String PlayerCurrentSword = PlayerRightSword;
private static String RightKnight = "res/images/characters/knight/ResizedKnightRight.png";
private static String LeftKnight = "res/images/characters/knight/ResizedKnightLeft.png";
/* Everything Else */
private static boolean PlayerCanMove = false;
// AI Variables
/* Coordiantes and Direction */
private static float EnemyX = 1000;
private static float EnemyY = 470;
private static String EnemyKnight = "res/images/characters/knight/Knight.png";
private static String EnemyDirection = "right";
private static int EnemyHealth = 100;
private static boolean EnemyWalking = false;
private static boolean DecidedJump = false;
private static int JumpPossibility = 1;
private static boolean EnemyJumping = false;
private static boolean EnemyJumped = false;
private static float AmountEnemyJumped;
private static boolean EnemyAttacking = false;
private static boolean EnemyCanAttack = true;
private static int EnemyRegenTime = 100;
/* Sprite Sheets */
private static String EnemyLeftSword = "res/images/icons/sword/SwordLeft.png";
private static String EnemyLeftAttackSword = "res/images/icons/sword/SwordLeftAttacking.png";
private static String EnemyRightSword = "res/images/icons/sword/SwordRight.png";
private static String EnemyRightAttackSword = "/res/images/icons/sword/SwordRightAttacking.png";
private static String EnemyCurrentSword = EnemyRightSword;
private static String RightEnemy = "res/images/characters/knight/ResizedKnightRight.png";
private static String LeftEnemy = "res/images/characters/knight/ResizedKnightLeft.png";
/* Everything Else */
private static boolean EnemyTalking = false;
private static String EnemyMessage = "";
private static boolean EnemyCanMove = false;
// Mixed Variables
/* Sprite Sheets */
private static SpriteSheet WalkRightSpriteSheet;
private static Animation WalkRightAnimation;
private static SpriteSheet WalkLeftSprite;
private static Animation WalkLeftAnimation;
private static int SpriteSheetWidth = 135;
private static int SpriteSheetHeight = 188;
// System Variables
private String operatingSystem = Client.getOS();
// Constructor
public FinalBattle(int State) {
}
#Override
public void render(GameContainer GameContainer, StateBasedGame SBG,
Graphics G) throws SlickException {
//GameContainer Things
GameContainer.setShowFPS(false);
//Level
/* Draw Background */
G.drawImage(new Image("res/images/level/FinalBattle.png"), 0, 0);
/* Draw Floor */
G.drawImage(new Image(Block.GroundTile), 0, 656);
//Player
/* Draw Player */
if(PlayerWalking) {
if(PlayerDirection.equalsIgnoreCase("right")) {
if(!PlayerJumping) {
WalkRightAnimation.draw(PlayerX, PlayerY, SpriteSheetWidth, SpriteSheetHeight);
}
else {
G.drawImage(new Image(RightKnight), PlayerX, PlayerY);
}
G.drawImage(new Image(PlayerCurrentSword), PlayerX + 60, PlayerY + 90);
}
if(PlayerDirection.equalsIgnoreCase("left")) {
if(!PlayerJumping) {
WalkLeftAnimation.draw(PlayerX, PlayerY, SpriteSheetWidth, SpriteSheetHeight);
}
else {
G.drawImage(new Image(LeftKnight), PlayerX, PlayerY);
}
G.drawImage(new Image(PlayerCurrentSword), PlayerX + 6, PlayerY + 90);
}
}
/* Draw his/her sword */
else {
if(PlayerDirection.equalsIgnoreCase("right")) {
G.drawImage(new Image(RightKnight), PlayerX, PlayerY);
G.drawImage(new Image(PlayerCurrentSword), PlayerX + 60, PlayerY + 90);
}
if(PlayerDirection.equalsIgnoreCase("left")) {
G.drawImage(new Image(LeftKnight), PlayerX, PlayerY);
G.drawImage(new Image(PlayerCurrentSword), PlayerX + 6, PlayerY + 90);
}
}
/* Draw his/her power level */
G.setColor(new Color(Color.blue.darker()));
G.drawString("Knight Power Level", 10, 20);
G.setColor(new Color(Color.white));
G.drawImage(new Image(Grey).getScaledCopy(100, 10), 10, 40);
G.drawImage(new Image(Blue).getScaledCopy(PlayerRegenTime, 10), 10, 40);
/* Draw his/her health level */
G.setColor(new Color(Color.red.darker()));
G.drawString("Knight Health", 10, 60);
G.setColor(new Color(Color.white));
G.drawImage(new Image(Grey).getScaledCopy(100, 10), 10, 80);
G.drawImage(new Image(Red).getScaledCopy(PlayerHealth, 10), 10, 80);
/* Draw his/her name */
G.setColor(new Color(Color.red.darker()));
G.drawString("You\n |\n\\ /", PlayerX + 50, PlayerY - 70);
G.setColor(new Color(Color.white));
//Enemy
if(EnemyWalking) {
if(EnemyDirection.equalsIgnoreCase("right")) {
if(!EnemyJumping) {
WalkRightAnimation.draw(EnemyX, EnemyY, SpriteSheetWidth, SpriteSheetHeight);
}
else {
G.drawImage(new Image(RightKnight), EnemyX, EnemyY);
}
G.drawImage(new Image(EnemyCurrentSword), EnemyX + 60, EnemyY + 90);
}
if(EnemyDirection.equalsIgnoreCase("left")) {
if(!EnemyJumping) {
WalkLeftAnimation.draw(EnemyX, EnemyY, SpriteSheetWidth, SpriteSheetHeight);
}
else {
G.drawImage(new Image(LeftKnight), EnemyX, EnemyY);
}
G.drawImage(new Image(EnemyCurrentSword), EnemyX + 6, EnemyY + 90);
}
}
/* Draw enemy sword */
else {
if(EnemyDirection.equalsIgnoreCase("right")) {
if(!EnemyAttacking) {
EnemyCurrentSword = EnemyRightSword;
}
G.drawImage(new Image(RightKnight), EnemyX, EnemyY);
G.drawImage(new Image(EnemyCurrentSword), EnemyX + 60, EnemyY + 90);
}
if(EnemyDirection.equalsIgnoreCase("left")) {
if(!EnemyAttacking) {
EnemyCurrentSword = EnemyLeftSword;
}
G.drawImage(new Image(LeftKnight), EnemyX, EnemyY);
G.drawImage(new Image(EnemyCurrentSword), EnemyX + 6, EnemyY + 90);
}
}
/* Draw enemy power level */
G.setColor(new Color(Color.blue.darker()));
G.drawString("Enemy Power Level", 1115, 20);
G.setColor(new Color(Color.white));
G.drawImage(new Image(Grey).getScaledCopy(100, 10), 1165, 40);
G.drawImage(new Image(Blue).getScaledCopy(EnemyRegenTime, 10), 1165, 40);
/* Draw enemy health level */
G.setColor(new Color(Color.red.darker()));
G.drawString("Enemy Health", 1115, 60);
G.setColor(new Color(Color.white));
G.drawImage(new Image(Grey).getScaledCopy(100, 10), 1165, 80);
G.drawImage(new Image(Red).getScaledCopy(EnemyHealth, 10), 1165, 80);
// System Info (Not used currently)
/*G.drawString("Game State: " + this.getID(), 10, 30);
G.drawString("X:" + Mouse.getX() + " Y:" + Mouse.getY(), 10, 50);
G.drawString("Your OS: " + operatingSystem, 10, 70);
G.drawString("Player X: " + PlayerY + " Enemy X:" + EnemyX, 10, 170);*/
}
#Override
public void update(GameContainer GameContainer, StateBasedGame SBG,
int Delta) throws SlickException {
// Fixes for some stuff that might happen
if(PlayerY > 470) {
PlayerY = 470;
}
if(EnemyY > 470) {
EnemyY = 470;
}
// Enemy
if(!EnemyTalking) {
new Thread(new startFight()).start();
EnemyTalking = true;
}
/* Boss Battle Music */
if(startBossBattle && !startedBossBattle) {
if(!startedBossMusic) {
PlaySound.playSound("res/sounds/events/BossBattleLoop.wav");
PlaySound.startLoop(1000);
startedBossMusic = true;
}
startedBossBattle = true;
}
// Player
/* Player Movement */
if(PlayerCanMove) {
Input playerInput = GameContainer.getInput();
if(playerInput.isKeyDown(Input.KEY_A)) {
PlayerX -= Delta*.3f;
PlayerWalking = true;
PlayerDirection = "left";
if(!PlayerAttacking) {
PlayerCurrentSword = PlayerLeftSword;
}
}
else if(playerInput.isKeyDown(Input.KEY_D)) {
PlayerX += Delta*.3f;
PlayerWalking = true;
PlayerDirection = "right";
if(!PlayerAttacking) {
PlayerCurrentSword = PlayerRightSword;
}
}
else {
PlayerWalking = false;
}
/* Player Jumping */
if(playerInput.isKeyPressed(Input.KEY_SPACE)) {
if(!PlayerJumped) {
new Thread(new playerJump()).start();
}
}
if(PlayerJumping) {
PlayerY -= Delta*.5f;
AmountPlayerJumped = PlayerY;
}
else {
if(PlayerY < 470) {
PlayerY += Delta*.5f;
}
if(Math.round(PlayerY) == 470 || Math.round(PlayerY) == 471) {
PlayerJumped = false;
}
}
/* Player Attack */
if(playerInput.isKeyPressed(Input.KEY_ENTER)) {
if(PlayerCanAttack) {
new Thread(new playerAttack()).start();
}
else {
}
}
}
/* Player Collision Detection */
if(PlayerX < 0) {
PlayerX = 0;
}
if (PlayerX > 1155) {
PlayerX = 1155;
}
//Enemy
/* Enemy Movement and Jumping */
if(EnemyCanMove) {
if(PlayerX < EnemyX) {
if(PlayerDirection.equalsIgnoreCase("right")) {
if(!(EnemyX - 125 < PlayerX)) {
EnemyX -= Delta*.2f;
EnemyDirection = "right";
EnemyWalking = true;
BothTouching = false;
if(!(EnemyX - 50 < PlayerX)) {
if(!DecidedJump) {
int Jump = GenerateNumber.generateNumber(JumpPossibility);
if(Jump == JumpPossibility) {
new Thread(new enemyJump()).start();
}
DecidedJump = true;
}
}
else {
DecidedJump = false;
}
}
else {
EnemyWalking = false;
BothTouching = true;
if(EnemyRegenTime == 100) {
if(EnemyCanAttack) {
new Thread(new enemyAttack()).start();
}
}
}
}
if(PlayerDirection.equalsIgnoreCase("left")) {
if(!(EnemyX - 110 < PlayerX)) {
EnemyX -= Delta*.2f;
EnemyDirection = "left";
EnemyWalking = true;
BothTouching = false;
if(!(EnemyX + 50 < PlayerX)) {
if(!DecidedJump) {
int Jump = GenerateNumber.generateNumber(JumpPossibility);
if(Jump == JumpPossibility) {
new Thread(new enemyJump()).start();
}
DecidedJump = true;
}
}
else {
DecidedJump = false;
}
}
else {
EnemyWalking = false;
BothTouching = true;
if(EnemyRegenTime == 100) {
if(EnemyRegenTime == 100) {
if(EnemyCanAttack) {
new Thread(new enemyAttack()).start();
}
}
}
}
}
EnemyDirection = "left";
}
if(PlayerX > EnemyX) {
if(PlayerDirection.equalsIgnoreCase("right")) {
if(!(EnemyX + 119 > PlayerX)) {
EnemyX += Delta*.2f;
EnemyDirection = "right";
EnemyWalking = true;
BothTouching = false;
if(!(EnemyX - 50 < PlayerX)) {
if(!DecidedJump) {
int Jump = GenerateNumber.generateNumber(JumpPossibility);
if(Jump == JumpPossibility) {
new Thread(new enemyJump()).start();
}
DecidedJump = true;
}
}
else {
DecidedJump = false;
}
}
else {
EnemyWalking = false;
BothTouching = true;
if(EnemyRegenTime == 100) {
if(EnemyRegenTime == 100) {
if(EnemyCanAttack) {
new Thread(new enemyAttack()).start();
}
}
}
}
}
if(PlayerDirection.equalsIgnoreCase("left")) {
if(!(EnemyX + 135 > PlayerX)) {
EnemyX += Delta*.2f;
EnemyDirection = "left";
EnemyWalking = true;
BothTouching = false;
if(!(EnemyX + 50 < PlayerX)) {
if(!DecidedJump) {
int Jump = GenerateNumber.generateNumber(JumpPossibility);
if(Jump == JumpPossibility) {
new Thread(new enemyJump()).start();
}
DecidedJump = true;
}
}
else {
DecidedJump = false;
}
}
else {
EnemyWalking = false;
BothTouching = true;
if(EnemyRegenTime == 100) {
if(EnemyRegenTime == 100) {
if(EnemyCanAttack) {
new Thread(new enemyAttack()).start();
}
}
}
}
}
EnemyDirection = "right";
}
/* Enemy Jumping */
if(EnemyJumping) {
EnemyY -= Delta*.5f;
AmountEnemyJumped = EnemyY;
}
else {
if(EnemyY < 470) {
EnemyY += Delta*.5f;
}
if(Math.round(EnemyY) == 470 || Math.round(EnemyY) == 471) {
EnemyJumped = false;
}
}
}
}
// Initializing Constructor
#Override
public void init(GameContainer GameContainer, StateBasedGame SBG)
throws SlickException {
WalkRightSpriteSheet = new SpriteSheet("res/images/characters/knight/spritesheets/WalkAnimationRight.png", 35, 48);
WalkRightAnimation = new Animation(WalkRightSpriteSheet, 100);
WalkLeftSprite = new SpriteSheet("res/images/characters/knight/spritesheets/WalkAnimationLeft.png", 35, 48);
WalkLeftAnimation = new Animation(WalkLeftSprite, 100);
}
// Gets the ID of the current State
#Override
public int getID() {
return 1;
}
// Start Fight
static class startFight implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
startBossBattle = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}
// Player Threads
/* Player Attack */
static class playerAttack implements Runnable {
#Override
public void run() {
try {
PlayerAttacking = true;
if(PlayerDirection.equalsIgnoreCase("right")) {
PlayerCurrentSword = PlayerRightAttackSword;
}
if(PlayerDirection.equalsIgnoreCase("left")) {
PlayerCurrentSword = PlayerLeftAttackSword;
}
if(BothTouching) {
EnemyHealth -= 10;
}
Thread.sleep(100);
if(PlayerDirection.equalsIgnoreCase("right")) {
PlayerCurrentSword = PlayerRightSword;
}
if(PlayerDirection.equalsIgnoreCase("left")) {
PlayerCurrentSword = PlayerLeftSword;
}
PlayerAttacking = false;
PlayerCanAttack = false;
PlayerRegenTime = 0;
while(PlayerRegenTime != 100) {
Thread.sleep(100);
PlayerRegenTime++;
}
PlayerCanAttack = true;
}
catch (Exception e) {
}
}
}
/* Player Jump */
static class playerJump implements Runnable {
#Override
public void run() {
try {
PlayerJumped = true;
PlayerJumping = true;
Thread.sleep(750);
PlayerJumping = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// Enemy Threads
/* Enemy Attack */
static class enemyAttack implements Runnable {
#Override
public void run() {
try {
EnemyAttacking = true;
if(EnemyDirection.equalsIgnoreCase("right")) {
EnemyCurrentSword = EnemyRightAttackSword;
}
if(EnemyDirection.equalsIgnoreCase("left")) {
EnemyCurrentSword = EnemyLeftAttackSword;
}
PlayerHealth -= 10;
Thread.sleep(100);
if(EnemyDirection.equalsIgnoreCase("right")) {
EnemyCurrentSword = EnemyRightSword;
}
if(EnemyDirection.equalsIgnoreCase("left")) {
EnemyCurrentSword = EnemyLeftSword;
}
EnemyAttacking = false;
EnemyCanAttack = false;
EnemyRegenTime = 0;
while(EnemyRegenTime != 100) {
Thread.sleep(100);
EnemyRegenTime++;
}
EnemyCanAttack = true;
}
catch (Exception e) {
e.printStackTrace();
}
}
}
/* Decide Jump */
static class decideJump implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000 * 10);
int number = GenerateNumber.generateNumber(20);
if(number == 20) {
if(!EnemyJumping) {
new Thread(new enemyJump()).start();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
/* Enemy Jump */
static class enemyJump implements Runnable {
#Override
public void run() {
try {
EnemyJumped = true;
EnemyJumping = true;
Thread.sleep(750);
EnemyJumping = false;
}
catch (Exception e) {
}
}
}
Turns out, that I wasnt adding it to the build path. If you are viewing this with this problem, make sure to add it to your build path in Eclipse (Or netbeans).

LibGDX Player only faces left and movement isn't animated

I am working on a game in LibGDX and both my players direction and walking animation won't change. He can walk up, down, left, and right, but only faces left no matter what direction he's walking.
public class WorldController {
enum KeyBinds {
LEFT, RIGHT, UP, DOWN, JUMP, FIRE
}
private World world;
private Player p;
static Map<KeyBinds, Boolean> keys = new HashMap<WorldController.KeyBinds, Boolean>();
static {
keys.put(KeyBinds.LEFT, false);
keys.put(KeyBinds.RIGHT, false);
keys.put(KeyBinds.UP, false);
keys.put(KeyBinds.DOWN, false);
keys.put(KeyBinds.JUMP, false);
keys.put(KeyBinds.FIRE, false);
};
public WorldController(World world) {
this.world = world;
this.p = world.getPlayer();
}
// ** Key presses and touches **************** //
public void leftPressed() {
keys.get(keys.put(KeyBinds.LEFT, true));
}
public void rightPressed() {
keys.get(keys.put(KeyBinds.RIGHT, true));
}
public void upPressed() {
keys.get(keys.put(KeyBinds.UP, true));
}
public void downPressed() {
keys.get(keys.put(KeyBinds.DOWN, true));
}
public void jumpPressed() {
keys.get(keys.put(KeyBinds.JUMP, true));
}
public void firePressed() {
keys.get(keys.put(KeyBinds.FIRE, false));
}
public void leftReleased() {
keys.get(keys.put(KeyBinds.LEFT, false));
}
public void rightReleased() {
keys.get(keys.put(KeyBinds.RIGHT, false));
}
public void upReleased() {
keys.get(keys.put(KeyBinds.UP, false));
}
public void downReleased() {
keys.get(keys.put(KeyBinds.DOWN, false));
}
public void jumpReleased() {
keys.get(keys.put(KeyBinds.JUMP, false));
}
public void fireReleased() {
keys.get(keys.put(KeyBinds.FIRE, false));
}
/** The main update method **/
public void update(float delta) {
processInput();
p.update(delta);
}
/** Change player's state and parameters based on input controls **/
private void processInput() {
if(Gdx.input.isKeyPressed(Keys.LEFT)) {
// left is pressed
//p.setFacingLeft(true);
p.setState(State.WALKING);
p.getVelocity().x = -Player.SPEED;
p.getVelocity().y = 0;
}
if(Gdx.input.isKeyPressed(Keys.RIGHT)){
// right is pressed
//p.setFacingRight(true);
p.setState(State.WALKING);
p.getVelocity().x = Player.SPEED;
p.getVelocity().y = 0;
}
if(Gdx.input.isKeyPressed(Keys.UP)) {
// up is pressed
//p.setFacingUp(true);
p.setState(State.WALKING);
p.getVelocity().y = Player.SPEED;
p.getVelocity().x = 0;
}
if(Gdx.input.isKeyPressed(Keys.DOWN)) {
// down is pressed
//p.setFacingDown(true);
p.setState(State.WALKING);
p.getVelocity().y = -Player.SPEED;
p.getVelocity().x = 0;
}
// need to check if both or none direction are pressed, then player is idle
// if ((keys.get(Keys.LEFT) && keys.get(Keys.RIGHT)) ||
// (!keys.get(Keys.LEFT) && !(keys.get(Keys.RIGHT)))) {
// p.setState(State.IDLE);
// // acceleration is 0 on the x
// p.getAcceleration().x = 0;
// // horizontal speed is 0
// p.getVelocity().x = 0;
// }
}
}
public class WorldRenderer {
private static final float CAMERA_WIDTH = 10f;
private static final float CAMERA_HEIGHT = 7f;
private World world;
private OrthographicCamera cam;
/** for debug rendering **/
ShapeRenderer debugRenderer = new ShapeRenderer();
private SpriteBatch spriteBatch;
private boolean debug = false;
private int width;
private int height;
private float ppuX;
private float ppuY;
private static final float RUNNING_FRAME_DURATION = 0.06f;
/** Textures **/
private TextureRegion pIdleLeft;
private TextureRegion pIdleRight;
private TextureRegion pIdleUp;
private TextureRegion pIdleDown;
private TextureRegion blockTexture;
private TextureRegion pFrame;
/** Animations **/
private Animation walkLeftAnimation;
private Animation walkRightAnimation;
private Animation walkUpAnimation;
private Animation walkDownAnimation;
private void loadTextures() {
TextureAtlas atlas = new TextureAtlas(Gdx.files.internal("images/textures/textures.pack"));
pIdleLeft = atlas.findRegion("Left1");
pIdleRight = new TextureRegion(pIdleLeft);
pIdleRight.flip(true, false);
pIdleUp = atlas.findRegion("Back1");
pIdleDown = atlas.findRegion("Front1");
blockTexture = atlas.findRegion("stone");
//Walking Left Animation
TextureRegion[] walkLeftFrames = new TextureRegion[2];
walkLeftFrames[0] = atlas.findRegion("Left1");
walkLeftFrames[1] = atlas.findRegion("Left2");
walkLeftAnimation = new Animation(RUNNING_FRAME_DURATION, walkLeftFrames);
//Walking Right Animation
TextureRegion[] walkRightFrames = new TextureRegion[2];
walkRightFrames[0] = new TextureRegion(walkLeftFrames[0]);
walkRightFrames[0].flip(true, false);
walkRightFrames[1] = new TextureRegion(walkLeftFrames[1]);
walkRightFrames[1].flip(true, false);
walkRightAnimation = new Animation(RUNNING_FRAME_DURATION, walkRightFrames);
//Walking Up Animation
TextureRegion[] walkUpFrames = new TextureRegion[2];
walkUpFrames[0] = atlas.findRegion("Back1");
walkUpFrames[1] = atlas.findRegion("Back2");
walkUpAnimation = new Animation(RUNNING_FRAME_DURATION, walkUpFrames);
//Walking Down Animation
TextureRegion[] walkDownFrames = new TextureRegion[2];
walkLeftFrames[0] = atlas.findRegion("Front1");
walkLeftFrames[1] = atlas.findRegion("Front2");
walkDownAnimation = new Animation(RUNNING_FRAME_DURATION, walkDownFrames);
}
public void drawPlayer() {
Player p = world.getPlayer();
if(p.getState().equals(State.IDLE)) {
if(Gdx.input.isKeyPressed(Keys.LEFT)) pFrame = pIdleLeft;
else if(Gdx.input.isKeyPressed(Keys.RIGHT)) pFrame = pIdleRight;
else if(Gdx.input.isKeyPressed(Keys.UP)) pFrame = pIdleUp;
else if(Gdx.input.isKeyPressed(Keys.DOWN)) pFrame = pIdleDown;
}
if(p.getState().equals(State.WALKING)) {
if(Gdx.input.isKeyPressed(Keys.LEFT)) walkLeftAnimation.getKeyFrame(p.getStateTime(), true);
else if(Gdx.input.isKeyPressed(Keys.RIGHT)) walkRightAnimation.getKeyFrame(p.getStateTime(), true);
else if(Gdx.input.isKeyPressed(Keys.UP)) walkUpAnimation.getKeyFrame(p.getStateTime(), true);
else if(Gdx.input.isKeyPressed(Keys.DOWN)) walkDownAnimation.getKeyFrame(p.getStateTime(), true);
}
spriteBatch.draw(pFrame, p.getXPosition() * ppuX, p.getYPosition() * ppuY, Player.SIZE * ppuX, Player.SIZE * ppuY);
}
public void setSize(int w, int h){
this.width = w;
this.height = h;
ppuX = (float)width / CAMERA_WIDTH;
ppuY = (float)height / CAMERA_HEIGHT;
}
public WorldRenderer(World world, boolean debug) {
this.world = world;
this.cam = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
this.cam.position.set(CAMERA_WIDTH / 2f, CAMERA_HEIGHT / 2f, 0);
this.cam.update();
this.debug = debug;
spriteBatch = new SpriteBatch();
loadTextures();
}
public void render(){
spriteBatch.begin();
drawBlocks();
drawPlayer();
spriteBatch.end();
if(debug){
drawDebug();
}
}
public void drawBlocks(){
for(Block block : world.getBlocks()){
spriteBatch.draw(blockTexture, block.getXPosition() * ppuX, block.getYPosition() * ppuY, Block.getSize() * ppuX, Block.getSize() * ppuY );
}
}
public void drawDebug() {
// render blocks
debugRenderer.setProjectionMatrix(cam.combined);
debugRenderer.begin(ShapeType.Line);
for (Block block : world.getBlocks()) {
Rectangle rect = block.getBounds();
float x1 = block.getXPosition() + rect.x;
float y1 = block.getYPosition() + rect.y;
debugRenderer.setColor(new Color(1, 0, 0, 1));
debugRenderer.rect(x1, y1, rect.width, rect.height);
}
// render Player
Player p = world.getPlayer();
Rectangle rect = p.getBounds();
float x1 = p.getXPosition() + rect.x;
float y1 = p.getYPosition() + rect.y;
debugRenderer.setColor(new Color(0, 1, 0, 1));
debugRenderer.rect(x1, y1, rect.width, rect.height);
debugRenderer.end();
}
}
public class Player {
public enum State{
IDLE, WALKING, JUMPING, DYING
}
public static final float SPEED = 4f; //units per second
public static final float SIZE = 0.5f; //half a unit
float stateTime = 0;
Vector2 position = new Vector2();
Vector2 acceleration = new Vector2();
Vector2 velocity = new Vector2();
Rectangle bounds = new Rectangle();
State state = State.IDLE;
boolean facingLeft;
boolean facingRight;
boolean facingUp;
boolean facingDown;
public Player(Vector2 position){
this.position = position;
this.bounds.height = SIZE;
this.bounds.width = SIZE;
}
public void setFacingLeft(boolean facingLeft) {
this.facingLeft = facingLeft;
}
public void setFacingRight(boolean facingRight) {
this.facingRight = facingRight;
}
public void setFacingUp(boolean facingUp) {
this.facingUp = facingUp;
}
public void setFacingDown(boolean facingDown) {
this.facingDown = facingDown;
}
public Vector2 getAcceleration() {
return acceleration;
}
public Vector2 getVelocity() {
return velocity;
}
public void setState(State newState){
this.state = newState;
}
public void update(float delta){
stateTime += delta;
position.add(velocity.cpy().scl(delta));
}
public Rectangle getBounds() {
return bounds;
}
public Object getPosition() {
return position;
}
public float getXPosition(){
return this.position.x;
}
public float getYPosition(){
return this.position.y;
}
public Object getState() {
return state;
}
public float getStateTime() {
return stateTime;
}
}
Sorry for all the code but I don't know where the problem is and didn't want to leave out anything relevant. I'm sure it's a silly mistake but I've been starring at it for a long time.
Also, I made an effort to put each class in it's own code block but it wasn't working out, I'm new to stackoverflow. Thanks to anyone who tries to help.

How to improve character control for my 3D game?

Since I changed from the helper class CharacterControl to the new BetterCharacterControl I notice some improvements such as pushing other characters is working but my main character has started sliding over steps and can't climb higher steps.
I must jump the step above which is not the right way of playing, it should be just walking over. The old helper class CharacterControl had a default way of not sliding, just walking over steps and I think it can be corrected by altering the code where I create the main character.
private void createNinja() {
ninjaNode = (Node) assetManager
.loadModel("Models/Ninja/Ninja.mesh.xml");
ninjaNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
ninjaNode.setLocalScale(0.06f);
ninjaNode.setLocalTranslation(new Vector3f(55, 3.3f, -60));
ninjaControl = new BetterCharacterControl(2, 4, 0.5f);
ninjaControl.setJumpForce(new Vector3f(6, 6, 6));
ninjaNode.addControl(ninjaControl);
rootNode.attachChild(ninjaNode);
bulletAppState.getPhysicsSpace().add(ninjaControl);
getPhysicsSpace().add(ninjaControl);
animationControl = ninjaNode.getControl(AnimControl.class);
animationChannel = animationControl.createChannel();
}
The complete code is
package adventure;
import com.jme3.system.AppSettings;
import java.io.File;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.BlenderKey;
import com.jme3.asset.plugins.HttpZipLocator;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.MaterialList;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.plugins.ogre.OgreMeshKey;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.input.MouseInput;
public class PyramidLevel extends SimpleApplication implements ActionListener,
AnimEventListener {
private Node gameLevel;
private static boolean useHttp = false;
private BulletAppState bulletAppState;
private AnimChannel channel;
private AnimControl control;
// character
private BetterCharacterControl goblinControl;
private BetterCharacterControl ninjaControl;
private Node ninjaNode;
boolean rotate = false;
private Vector3f walkDirection = new Vector3f(0, 0, 0);
private Vector3f viewDirection = new Vector3f(1, 0, 0);
private boolean leftStrafe = false, rightStrafe = false, forward = false,
backward = false, leftRotate = false, rightRotate = false;
private Node goblinNode;
Spatial goblin;
RigidBodyControl terrainPhysicsNode;
// animation
AnimChannel animationChannel;
AnimChannel shootingChannel;
AnimControl animationControl;
float airTime = 0;
// camera
private boolean left = false, right = false, up = false, down = false,
attack = false;
ChaseCamera chaseCam;
private boolean walkMode = true;
FilterPostProcessor fpp;
private Spatial sceneModel;
private RigidBodyControl landscape;
public static void main(String[] args) {
File file = new File("quake3level.zip");
if (!file.exists()) {
useHttp = true;
}
PyramidLevel app = new PyramidLevel();
AppSettings settings = new AppSettings(true);
settings.setTitle("Dungeon World");
settings.setSettingsDialogImage("Interface/splash.png");
app.setSettings(settings);
app.start();
}
#Override
public void simpleInitApp() {
this.setDisplayStatView(false);
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(false);
setupKeys();
DirectionalLight dl = new DirectionalLight();
dl.setColor(ColorRGBA.White.clone().multLocal(2));
dl.setDirection(new Vector3f(-1, -1, -1).normalize());
rootNode.addLight(dl);
AmbientLight am = new AmbientLight();
am.setColor(ColorRGBA.White.mult(2));
rootNode.addLight(am);
if (useHttp) {
assetManager
.registerLocator(
"http://jmonkeyengine.googlecode.com/files/quake3level.zip",
HttpZipLocator.class);
} else {
assetManager.registerLocator("quake3level.zip", ZipLocator.class);
}
// create the geometry and attach it
MaterialList matList = (MaterialList) assetManager
.loadAsset("Scene.material");
OgreMeshKey key = new OgreMeshKey("main.meshxml", matList);
gameLevel = (Node) assetManager.loadAsset(key);
gameLevel.setLocalScale(0.1f);
gameLevel.addControl(new RigidBodyControl(0));
getPhysicsSpace().addAll(gameLevel);
rootNode.attachChild(gameLevel);
getPhysicsSpace().addAll(gameLevel);
createCharacters();
setupAnimationController();
setupChaseCamera();
setupFilter();
}
private void setupFilter() {
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects);
fpp.addFilter(bloom);
viewPort.addProcessor(fpp);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
private void setupKeys() {
inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
inputManager.addListener(this, "wireframe");
inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S));
inputManager
.addMapping("CharSpace", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("CharShoot", new MouseButtonTrigger(
MouseInput.BUTTON_LEFT));
inputManager.addListener(this, "CharLeft");
inputManager.addListener(this, "CharRight");
inputManager.addListener(this, "CharUp");
inputManager.addListener(this, "CharDown");
inputManager.addListener(this, "CharSpace");
inputManager.addListener(this, "CharShoot");
}
private void createNinja() {
ninjaNode = (Node) assetManager
.loadModel("Models/Ninja/Ninja.mesh.xml");
ninjaNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
ninjaNode.setLocalScale(0.06f);
ninjaNode.setLocalTranslation(new Vector3f(55, 3.3f, -60));
ninjaControl = new BetterCharacterControl(2, 4, 0.5f);
ninjaControl.setJumpForce(new Vector3f(6, 6, 6));
ninjaNode.addControl(ninjaControl);
rootNode.attachChild(ninjaNode);
bulletAppState.getPhysicsSpace().add(ninjaControl);
getPhysicsSpace().add(ninjaControl);
animationControl = ninjaNode.getControl(AnimControl.class);
animationChannel = animationControl.createChannel();
}
private void createGoblin() {
goblinNode = (Node) assetManager
.loadModel("objects/goblin.j3o");
goblinNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
goblinNode.setLocalScale(4f);
goblinNode.setLocalTranslation(new Vector3f(51.5f, 3.3f, -60));
goblinControl = new BetterCharacterControl(2, 4, 0.5f);
goblinControl.setJumpForce(new Vector3f(6, 6, 6));
goblinNode.addControl(goblinControl);
rootNode.attachChild(goblinNode);
bulletAppState.getPhysicsSpace().add(goblinControl);
getPhysicsSpace().add(goblinControl);
animationControl = goblinNode.getControl(AnimControl.class);
animationChannel = animationControl.createChannel();
}
private void createCharacters() {
CapsuleCollisionShape capsule = new CapsuleCollisionShape(0.05f, 0.05f);
createNinja();
ninjaControl.setViewDirection(new Vector3f(0, 0, 1));
//getPhysicsSpace().add(ninjaControl);
createGoblin();
BlenderKey blenderKey = new BlenderKey("Models/Oto/Oto.mesh.xml");
Spatial man = (Spatial) assetManager.loadModel(blenderKey);
man.setLocalTranslation(new Vector3f(69, 15, -60));
man.setShadowMode(ShadowMode.CastAndReceive);
rootNode.attachChild(man);
//goblin = assetManager.loadModel("objects/goblin.j3o");
//goblin.scale(4f, 4f, 4f);
//goblinControl = new BetterCharacterControl(2,3,0.5f);
//goblin.addControl(goblinControl);
//goblinControl.setPhysicsLocation(new Vector3f(60, 3.5f, -60));
//goblin.setLocalTranslation(new Vector3f(150,70.5f, -5));
//control = goblin.getControl(AnimControl.class);
//control.addListener(this);
//channel = control.createChannel();
// for (String anim : control.getAnimationNames())
// System.out.println("goblin can:"+anim);
//channel.setAnim("walk");
//goblin.setLocalTranslation(new Vector3f(51.5f, 3, -55));
//rootNode.attachChild(goblin);
//getPhysicsSpace().add(goblinControl);
Spatial monster = assetManager
.loadModel("objects/creatures/monster/monster.packed.j3o");
Spatial monster2 = assetManager.loadModel("Models/Jaime/Jaime.j3o");
monster2.scale(5f, 5f, 5f);
monster.scale(2f, 2f, 2f);
monster.setLocalTranslation(new Vector3f(53, 3, -55));
monster2.setLocalTranslation(new Vector3f(48, 3, -55));
rootNode.attachChild(monster2);
rootNode.attachChild(monster);
}
private void setupChaseCamera() {
flyCam.setEnabled(false);
chaseCam = new ChaseCamera(cam, ninjaNode, inputManager);
chaseCam.setDefaultDistance(37);
}
private void setupAnimationController() {
animationControl = ninjaNode.getControl(AnimControl.class);
animationControl.addListener(this);
animationChannel = animationControl.createChannel();
}
#Override
public void simpleUpdate(float tpf) {
//goblinControl.setWalkDirection(goblin.getLocalRotation()
// .mult(Vector3f.UNIT_Z).multLocal(0.4f));
Vector3f camDir = cam.getDirection().clone().multLocal(8f);
Vector3f camLeft = cam.getLeft().clone().multLocal(8f);
camDir.y = 0;
camLeft.y = 0;
walkDirection.set(0, 0, 0);
if (left) {
walkDirection.addLocal(camLeft);
}
if (right) {
walkDirection.addLocal(camLeft.negate());
}
if (up) {
walkDirection.addLocal(camDir);
}
if (down) {
walkDirection.addLocal(camDir.negate());
}
// if (attack) {
// animationChannel.setAnim("Attack1");
// animationChannel.setLoopMode(LoopMode.DontLoop);
// }
if (!ninjaControl.isOnGround()) {
airTime = airTime + tpf;
} else {
airTime = 0;
}
if (walkDirection.length() == 0) {
if (!"Idle1".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Idle1", 1f);
}
} else {
ninjaControl.setViewDirection(walkDirection.negate());
if (airTime > .3f) {
if (!"stand".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Idle1");
}
} else if (!"Walk".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Walk", 1f);
}
}
ninjaControl.setWalkDirection(walkDirection);
}
/*
* Ninja can: Walk Ninja can: Kick Ninja can: JumpNoHeight Ninja can: Jump
* Ninja can: Spin Ninja can: Attack1 Ninja can: Idle1 Ninja can: Attack3
* Ninja can: Idle2 Ninja can: Attack2 Ninja can: Idle3 Ninja can: Stealth
* Ninja can: Death2 Ninja can: Death1 Ninja can: HighJump Ninja can:
* SideKick Ninja can: Backflip Ninja can: Block Ninja can: Climb Ninja can:
* Crouch
*/
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("CharLeft")) {
if (value) {
left = true;
} else {
left = false;
}
} else if (binding.equals("CharRight")) {
if (value) {
right = true;
} else {
right = false;
}
} else if (binding.equals("CharUp")) {
if (value) {
up = true;
} else {
up = false;
}
} else if (binding.equals("CharDown")) {
if (value) {
down = true;
} else {
down = false;
}
} else if (binding.equals("CharSpace")) {
// character.jump();
ninjaControl.jump();
} else if (binding.equals("CharShoot") && value) {
// bulletControl();
Vector3f origin = cam.getWorldCoordinates(
inputManager.getCursorPosition(), 0.0f);
Vector3f direction = cam.getWorldCoordinates(
inputManager.getCursorPosition(), 0.0f);
// direction.subtractLocal(origin).normalizeLocal();
// character.setWalkDirection(location);
System.out.println("origin" + origin);
System.out.println("direction" + direction);
// character.setViewDirection(direction);
animationChannel.setAnim("Attack3");
animationChannel.setLoopMode(LoopMode.DontLoop);
}
}
public void onAnimCycleDone(AnimControl control, AnimChannel channel,
String animName) {
if (channel == shootingChannel) {
channel.setAnim("Idle1");
}
}
public void onAnimChange(AnimControl control, AnimChannel channel,
String animName) {
}
public Node getGameLevel() {
return gameLevel;
}
public void setGameLevel(Node gameLevel) {
this.gameLevel = gameLevel;
}
public static boolean isUseHttp() {
return useHttp;
}
public static void setUseHttp(boolean useHttp) {
PyramidLevel.useHttp = useHttp;
}
public BulletAppState getBulletAppState() {
return bulletAppState;
}
public void setBulletAppState(BulletAppState bulletAppState) {
this.bulletAppState = bulletAppState;
}
public AnimChannel getChannel() {
return channel;
}
public void setChannel(AnimChannel channel) {
this.channel = channel;
}
public AnimControl getControl() {
return control;
}
public void setControl(AnimControl control) {
this.control = control;
}
public BetterCharacterControl getGoblincharacter() {
return goblinControl;
}
public void setGoblincharacter(BetterCharacterControl goblincharacter) {
this.goblinControl = goblincharacter;
}
public BetterCharacterControl getCharacterControl() {
return ninjaControl;
}
public void setCharacterControl(BetterCharacterControl characterControl) {
this.ninjaControl = characterControl;
}
public Node getCharacterNode() {
return ninjaNode;
}
public void setCharacterNode(Node characterNode) {
this.ninjaNode = characterNode;
}
public boolean isRotate() {
return rotate;
}
public void setRotate(boolean rotate) {
this.rotate = rotate;
}
public Vector3f getWalkDirection() {
return walkDirection;
}
public void setWalkDirection(Vector3f walkDirection) {
this.walkDirection = walkDirection;
}
public Vector3f getViewDirection() {
return viewDirection;
}
public void setViewDirection(Vector3f viewDirection) {
this.viewDirection = viewDirection;
}
public boolean isLeftStrafe() {
return leftStrafe;
}
public void setLeftStrafe(boolean leftStrafe) {
this.leftStrafe = leftStrafe;
}
public boolean isRightStrafe() {
return rightStrafe;
}
public void setRightStrafe(boolean rightStrafe) {
this.rightStrafe = rightStrafe;
}
public boolean isForward() {
return forward;
}
public void setForward(boolean forward) {
this.forward = forward;
}
public boolean isBackward() {
return backward;
}
public void setBackward(boolean backward) {
this.backward = backward;
}
public boolean isLeftRotate() {
return leftRotate;
}
public void setLeftRotate(boolean leftRotate) {
this.leftRotate = leftRotate;
}
public boolean isRightRotate() {
return rightRotate;
}
public void setRightRotate(boolean rightRotate) {
this.rightRotate = rightRotate;
}
public Node getModel() {
return goblinNode;
}
public void setModel(Node model) {
this.goblinNode = model;
}
public Spatial getGoblin() {
return goblin;
}
public void setGoblin(Spatial goblin) {
this.goblin = goblin;
}
public RigidBodyControl getTerrainPhysicsNode() {
return terrainPhysicsNode;
}
public void setTerrainPhysicsNode(RigidBodyControl terrainPhysicsNode) {
this.terrainPhysicsNode = terrainPhysicsNode;
}
public AnimChannel getAnimationChannel() {
return animationChannel;
}
public void setAnimationChannel(AnimChannel animationChannel) {
this.animationChannel = animationChannel;
}
public AnimChannel getShootingChannel() {
return shootingChannel;
}
public void setShootingChannel(AnimChannel shootingChannel) {
this.shootingChannel = shootingChannel;
}
public AnimControl getAnimationControl() {
return animationControl;
}
public void setAnimationControl(AnimControl animationControl) {
this.animationControl = animationControl;
}
public float getAirTime() {
return airTime;
}
public void setAirTime(float airTime) {
this.airTime = airTime;
}
public boolean isLeft() {
return left;
}
public void setLeft(boolean left) {
this.left = left;
}
public boolean isRight() {
return right;
}
public void setRight(boolean right) {
this.right = right;
}
public boolean isUp() {
return up;
}
public void setUp(boolean up) {
this.up = up;
}
public boolean isDown() {
return down;
}
public void setDown(boolean down) {
this.down = down;
}
public boolean isAttack() {
return attack;
}
public void setAttack(boolean attack) {
this.attack = attack;
}
public ChaseCamera getChaseCam() {
return chaseCam;
}
public void setChaseCam(ChaseCamera chaseCam) {
this.chaseCam = chaseCam;
}
public boolean isWalkMode() {
return walkMode;
}
public void setWalkMode(boolean walkMode) {
this.walkMode = walkMode;
}
public FilterPostProcessor getFpp() {
return fpp;
}
public void setFpp(FilterPostProcessor fpp) {
this.fpp = fpp;
}
public Spatial getSceneModel() {
return sceneModel;
}
public void setSceneModel(Spatial sceneModel) {
this.sceneModel = sceneModel;
}
public RigidBodyControl getLandscape() {
return landscape;
}
public void setLandscape(RigidBodyControl landscape) {
this.landscape = landscape;
}
}
You can download a demo of my game but how do I improve the walking?
Update
My followup at the jmonkeyforum also had 0 replies.
To do this you change the value of the max slope:
setMaxSlope()
From the jmonkey site:
"How steep the slopes and steps are that the character can climb without considering them
an obstacle. Higher obstacles need to be jumped. Vertical height in world units."
Reading this I believe it works in a way similar to, when moving 1 unit in the world what is the maximum change in height a character can experience. If you set this to the size of the steps (or a larger by <1 for safety) you'r character should be able to walk up steps
Sources:
http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:walking_character#charactercontrol
Developing for Jmonkey before

How to make my character walk properly?

I'm making a small 3D scene and the character can walk by pressing the WASD buttons but the animations that are playing are not correct and the character turns around so it looks like he is moonwalking when moving.
The control code for the buttons are
private void setupKeys() {
inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
inputManager.addListener(this, "wireframe");
inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("CharSpace",
new KeyTrigger(KeyInput.KEY_RETURN));
inputManager
.addMapping("CharShoot", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, "CharLeft");
inputManager.addListener(this, "CharRight");
inputManager.addListener(this, "CharUp");
inputManager.addListener(this, "CharDown");
inputManager.addListener(this, "CharSpace");
inputManager.addListener(this, "CharShoot");
}
And the update loop looks like this
public void simpleUpdate(float tpf) {
Vector3f camDir = cam.getDirection().clone().multLocal(0.1f);
Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f);
camDir.y = 0;
camLeft.y = 0;
walkDirection.set(0, 0, 0);
if (left) {
walkDirection.addLocal(camLeft);
}
if (right) {
walkDirection.addLocal(camLeft.negate());
}
if (up) {
walkDirection.addLocal(camDir);
}
if (down) {
walkDirection.addLocal(camDir.negate());
}
if (!character.onGround()) {
airTime = airTime + tpf;
} else {
airTime = 0;
}
if (walkDirection.length() == 0) {
if (!"Idle1".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Idle1", 1f);
}
} else {
character.setViewDirection(walkDirection);
if (airTime > .3f) {
if (!"stand".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("stand");
}
} else if (!"Walk".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Walk", 0.7f);
}
}
character.setWalkDirection(walkDirection);
}
I don't understand what is wrong since it is actually so close to working, all I need is that the character doesn't turns around and plays the correct animation when walking. Do you have any idea what the problem might be?
The entire program is
package adventure;
import java.applet.Applet;
import com.jme3.math.Quaternion;
import com.jme3.math.FastMath;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.TextArea;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import com.jme3.material.RenderState.FaceCullMode;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.BlenderKey;
import com.jme3.asset.TextureKey;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh.Type;
import com.jme3.effect.shapes.EmitterSphereShape;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.util.SkyFactory;
public class MountainWorld extends SimpleApplication implements ActionListener,
PhysicsCollisionListener, AnimEventListener, Playable {
/** Prepare Materials */
Material wall_mat;
Material stone_mat;
Material floor_mat;
/** Prepare geometries and physical nodes for bricks and cannon balls. */
private RigidBodyControl brick_phy;
private static final Box box;
private RigidBodyControl ball_phy;
private static final Sphere sphere;
private RigidBodyControl floor_phy;
private static final Box floor;
/** dimensions used for bricks and wall */
private static final float brickLength = 0.48f;
private static final float brickWidth = 0.24f;
private static final float brickHeight = 0.12f;
static {
/** Initialize the cannon ball geometry */
sphere = new Sphere(32, 32, 0.4f, true, false);
sphere.setTextureMode(TextureMode.Projected);
/** Initialize the brick geometry */
box = new Box(Vector3f.ZERO, brickLength, brickHeight, brickWidth);
box.scaleTextureCoordinates(new Vector2f(1f, .5f));
/** Initialize the floor geometry */
floor = new Box(Vector3f.ZERO, 100f, 0.1f, 50f);
floor.scaleTextureCoordinates(new Vector2f(3, 6));
}
private static World world;
private static Person person;
private static Player dplayer;
private static TextArea textarea;
private BulletAppState bulletAppState;
private AnimChannel channel;
private AnimControl control;
// character
CharacterControl character;
Node model;
// temp vectors
Vector3f walkDirection = new Vector3f();
// terrain
TerrainQuad terrain;
RigidBodyControl terrainPhysicsNode;
// Materials
Material matRock;
Material matBullet;
// animation
AnimChannel animationChannel;
AnimChannel shootingChannel;
AnimControl animationControl;
float airTime = 0;
// camera
boolean left = false, right = false, up = false, down = false;
ChaseCamera chaseCam;
// bullet
Sphere bullet;
SphereCollisionShape bulletCollisionShape;
// explosion
ParticleEmitter effect;
// brick wall
Box brick;
float bLength = 0.8f;
float bWidth = 0.4f;
float bHeight = 0.4f;
FilterPostProcessor fpp;
private Spatial sceneModel;
private RigidBodyControl landscape;
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
AppSettings settings = new AppSettings(true);
settings.setWidth(850);
settings.setHeight(440);
MountainWorld canvasApplication = new MountainWorld();
canvasApplication.setSettings(settings);
canvasApplication.createCanvas(); // create canvas!
JmeCanvasContext ctx = (JmeCanvasContext) canvasApplication
.getContext();
ctx.setSystemListener(canvasApplication);
Dimension dim = new Dimension(640, 480);
ctx.getCanvas().setPreferredSize(dim);
JFrame window = new JFrame("Mountain World");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout()); // a panel
world = new DungeonWorld(canvasApplication);
person = new Person(world, "You", null);
dplayer = new Player(world, person);
Commands commands = new Commands(person);
textarea = new TextArea("", 10, 60,
TextArea.SCROLLBARS_VERTICAL_ONLY);
textarea.append("You are in a mountain. The trolls live here.\n");
textarea.setEditable(false);
panel.add("West", ctx.getCanvas());
panel.add("East", commands);
panel.add("South", textarea);
window.add(panel);
window.pack();
window.setVisible(true);
canvasApplication.startCanvas();
}
});
}
#Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
stateManager.attach(bulletAppState);
setupKeys();
//prepareBullet();
//prepareEffect();
createLight();
//createSky();
initMaterials();
initFloor();
//createTerrain();
//createWall();
createCharacters();
setupChaseCamera();
setupAnimationController();
setupFilter();
}
/** Make a solid floor and add it to the scene. */
public void initFloor() {
Geometry floor_geo = new Geometry("Floor", floor);
floor_geo.setMaterial(floor_mat);
floor_geo.setLocalTranslation(0, -0.1f, 0);
this.rootNode.attachChild(floor_geo);
/* Make the floor physical with mass 0.0f! */
floor_phy = new RigidBodyControl(0.0f);
floor_geo.addControl(floor_phy);
bulletAppState.getPhysicsSpace().add(floor_phy);
}
/** Initialize the materials used in this scene. */
public void initMaterials() {
wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg");
key.setGenerateMips(true);
Texture tex = assetManager.loadTexture(key);
wall_mat.setTexture("ColorMap", tex);
stone_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
key2.setGenerateMips(true);
Texture tex2 = assetManager.loadTexture(key2);
stone_mat.setTexture("ColorMap", tex2);
floor_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg");
key3.setGenerateMips(true);
Texture tex3 = assetManager.loadTexture(key3);
tex3.setWrap(WrapMode.Repeat);
floor_mat.setTexture("ColorMap", tex3);
}
private void setupFilter() {
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects);
fpp.addFilter(bloom);
viewPort.addProcessor(fpp);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
private void setupKeys() {
inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
inputManager.addListener(this, "wireframe");
inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("CharSpace",
new KeyTrigger(KeyInput.KEY_RETURN));
inputManager
.addMapping("CharShoot", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, "CharLeft");
inputManager.addListener(this, "CharRight");
inputManager.addListener(this, "CharUp");
inputManager.addListener(this, "CharDown");
inputManager.addListener(this, "CharSpace");
inputManager.addListener(this, "CharShoot");
}
private void createWall() {
float xOff = -144;
float zOff = -40;
float startpt = bLength / 4 - xOff;
float height = 6.1f;
brick = new Box(Vector3f.ZERO, bLength, bHeight, bWidth);
brick.scaleTextureCoordinates(new Vector2f(1f, .5f));
for (int j = 0; j < 15; j++) {
for (int i = 0; i < 4; i++) {
Vector3f vt = new Vector3f(i * bLength * 2 + startpt, bHeight
+ height, zOff);
addBrick(vt);
}
startpt = -startpt;
height += 1.01f * bHeight;
}
}
private void addBrick(Vector3f ori) {
Geometry reBoxg = new Geometry("brick", brick);
reBoxg.setMaterial(matBullet);
reBoxg.setLocalTranslation(ori);
reBoxg.addControl(new RigidBodyControl(1.5f));
reBoxg.setShadowMode(ShadowMode.CastAndReceive);
this.rootNode.attachChild(reBoxg);
this.getPhysicsSpace().add(reBoxg);
}
private void prepareBullet() {
bullet = new Sphere(32, 32, 0.4f, true, false);
bullet.setTextureMode(TextureMode.Projected);
bulletCollisionShape = new SphereCollisionShape(0.4f);
matBullet = new Material(getAssetManager(),
"Common/MatDefs/Misc/Unshaded.j3md");
matBullet.setColor("Color", ColorRGBA.Green);
// matBullet.setColor("m_GlowColor", ColorRGBA.Green);
getPhysicsSpace().addCollisionListener(this);
}
private void prepareEffect() {
int COUNT_FACTOR = 1;
float COUNT_FACTOR_F = 1f;
effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR);
effect.setSelectRandomImage(true);
effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f,
(float) (1f / COUNT_FACTOR_F)));
effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f));
effect.setStartSize(1.3f);
effect.setEndSize(2f);
effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
effect.setParticlesPerSec(0);
effect.setGravity(0, -5, 0);
effect.setLowLife(.4f);
effect.setHighLife(.5f);
effect.setInitialVelocity(new Vector3f(0, 7, 0));
effect.setVelocityVariation(1f);
effect.setImagesX(2);
effect.setImagesY(2);
Material mat = new Material(assetManager,
"Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("Texture",
assetManager.loadTexture("Effects/Explosion/flame.png"));
effect.setMaterial(mat);
// effect.setLocalScale(100);
rootNode.attachChild(effect);
}
private void createLight() {
Vector3f direction = new Vector3f(-0.1f, -0.7f, -1).normalizeLocal();
DirectionalLight dl = new DirectionalLight();
dl.setDirection(direction);
dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
rootNode.addLight(dl);
}
private void createSky() {
rootNode.attachChild(SkyFactory.createSky(assetManager,
"Textures/Sky/Bright/BrightSky.dds", false));
}
private void createTerrain2() {
matRock = new Material(assetManager,
"Common/MatDefs/Terrain/TerrainLighting.j3md");
matRock.setBoolean("useTriPlanarMapping", false);
matRock.setBoolean("WardIso", true);
matRock.setTexture("AlphaMap",
assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
Texture heightMapImage = assetManager
.loadTexture("Textures/Terrain/splat/mountains512.png");
Texture grass = assetManager
.loadTexture("Textures/Terrain/splat/grass.jpg");
grass.setWrap(WrapMode.Repeat);
matRock.setTexture("DiffuseMap", grass);
matRock.setFloat("DiffuseMap_0_scale", 64);
Texture dirt = assetManager
.loadTexture("Textures/Terrain/splat/dirt.jpg");
dirt.setWrap(WrapMode.Repeat);
matRock.setTexture("DiffuseMap_1", dirt);
matRock.setFloat("DiffuseMap_1_scale", 16);
Texture rock = assetManager
.loadTexture("Textures/Terrain/splat/road.jpg");
rock.setWrap(WrapMode.Repeat);
matRock.setTexture("DiffuseMap_2", rock);
matRock.setFloat("DiffuseMap_2_scale", 128);
Texture normalMap0 = assetManager
.loadTexture("Textures/Terrain/splat/grass_normal.jpg");
normalMap0.setWrap(WrapMode.Repeat);
Texture normalMap1 = assetManager
.loadTexture("Textures/Terrain/splat/dirt_normal.png");
normalMap1.setWrap(WrapMode.Repeat);
Texture normalMap2 = assetManager
.loadTexture("Textures/Terrain/splat/road_normal.png");
normalMap2.setWrap(WrapMode.Repeat);
matRock.setTexture("NormalMap", normalMap0);
matRock.setTexture("NormalMap_1", normalMap2);
matRock.setTexture("NormalMap_2", normalMap2);
AbstractHeightMap heightmap = null;
try {
heightmap = new ImageBasedHeightMap(heightMapImage.getImage(),
0.25f);
heightmap.load();
} catch (Exception e) {
e.printStackTrace();
}
terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
List<Camera> cameras = new ArrayList<Camera>();
cameras.add(getCamera());
TerrainLodControl control = new TerrainLodControl(terrain, cameras);
terrain.addControl(control);
terrain.setMaterial(matRock);
terrain.setLocalScale(new Vector3f(2, 2, 2));
terrainPhysicsNode = new RigidBodyControl(
CollisionShapeFactory.createMeshShape(terrain), 0);
terrain.addControl(terrainPhysicsNode);
rootNode.attachChild(terrain);
getPhysicsSpace().add(terrainPhysicsNode);
}
private void createTerrain() {
assetManager.registerLocator("town.zip", ZipLocator.class);
sceneModel = assetManager.loadModel("main.scene");
//sceneModel = assetManager.loadModel("Scenes/ManyLights/Main.scene");
sceneModel.setLocalScale(2f);
//initFloor();
// We set up collision detection for the scene by creating a
// compound collision shape and a static RigidBodyControl with mass
// zero.
CollisionShape sceneShape = CollisionShapeFactory
.createMeshShape((Node) sceneModel);
landscape = new RigidBodyControl(sceneShape, 0);
sceneModel.addControl(landscape);
List<Camera> cameras = new ArrayList<Camera>();
cameras.add(getCamera());
rootNode.attachChild(sceneModel);
}
private void createCharacters() {
CapsuleCollisionShape capsule = new CapsuleCollisionShape(0.0f, 0.0f);
character = new CharacterControl(capsule, 0.01f);
model = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
float scale = 0.25f;
model.scale(0.05f, 0.05f, 0.05f);
model.addControl(character);
character.setPhysicsLocation(new Vector3f(0, 0f, 0));
model.setShadowMode(ShadowMode.CastAndReceive);
character.setViewDirection(new Vector3f(1, 0, 0));
rootNode.attachChild(model);
getPhysicsSpace().add(character);
//BlenderKey blenderKey = new BlenderKey("Models/Oto/Oto.mesh.xml");
//Spatial man = (Spatial) assetManager.loadModel(blenderKey);
//man.setLocalTranslation(new Vector3f(-140, 12.5f, -10));
// man.setShadowMode(ShadowMode.CastAndReceive);
//rootNode.attachChild(man);
}
private void setupChaseCamera() {
flyCam.setEnabled(false);
chaseCam = new ChaseCamera(cam, model, inputManager);
}
private void setupAnimationController() {
animationControl = model.getControl(AnimControl.class);
animationControl.addListener(this);
animationChannel = animationControl.createChannel();
// shootingChannel = animationControl.createChannel();
// shootingChannel.addBone(animationControl.getSkeleton().getBone(
// "uparm.right"));
// shootingChannel.addBone(animationControl.getSkeleton().getBone(
// "arm.right"));
// shootingChannel.addBone(animationControl.getSkeleton().getBone(
// "hand.right"));
}
#Override
public void simpleUpdate(float tpf) {
Vector3f camDir = cam.getDirection().clone().multLocal(0.1f);
Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f);
camDir.y = 0;
camLeft.y = 0;
walkDirection.set(0, 0, 0);
if (left) {
walkDirection.addLocal(camLeft);
}
if (right) {
walkDirection.addLocal(camLeft.negate());
}
if (up) {
walkDirection.addLocal(camDir);
}
if (down) {
walkDirection.addLocal(camDir.negate());
}
if (!character.onGround()) {
airTime = airTime + tpf;
} else {
airTime = 0;
}
if (walkDirection.length() == 0) {
if (!"Idle1".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Idle1", 1f);
}
} else {
character.setViewDirection(walkDirection);
if (airTime > .3f) {
if (!"stand".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("stand");
}
} else if (!"Walk".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Walk", 0.7f);
}
}
character.setWalkDirection(walkDirection);
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("CharLeft")) {
if (value) {
left = true;
} else {
left = false;
}
} else if (binding.equals("CharRight")) {
if (value) {
right = true;
} else {
right = false;
}
} else if (binding.equals("CharUp")) {
if (value) {
up = true;
} else {
up = false;
}
} else if (binding.equals("CharDown")) {
if (value) {
down = true;
} else {
down = false;
}
} else if (binding.equals("CharSpace")) {
character.jump();
} else if (binding.equals("CharShoot") && !value) {
bulletControl();
}
}
private void bulletControl() {
shootingChannel.setAnim("Dodge", 0.1f);
shootingChannel.setLoopMode(LoopMode.DontLoop);
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(matBullet);
bulletg.setShadowMode(ShadowMode.CastAndReceive);
bulletg.setLocalTranslation(character.getPhysicsLocation().add(
cam.getDirection().mult(5)));
RigidBodyControl bulletControl = new BombControl(bulletCollisionShape,
1);
bulletControl.setCcdMotionThreshold(0.1f);
bulletControl.setLinearVelocity(cam.getDirection().mult(80));
bulletg.addControl(bulletControl);
rootNode.attachChild(bulletg);
getPhysicsSpace().add(bulletControl);
}
public void collision(PhysicsCollisionEvent event) {
if (event.getObjectA() instanceof BombControl) {
final Spatial node = event.getNodeA();
effect.killAllParticles();
effect.setLocalTranslation(node.getLocalTranslation());
effect.emitAllParticles();
} else if (event.getObjectB() instanceof BombControl) {
final Spatial node = event.getNodeB();
effect.killAllParticles();
effect.setLocalTranslation(node.getLocalTranslation());
effect.emitAllParticles();
}
}
public void onAnimCycleDone(AnimControl control, AnimChannel channel,
String animName) {
if (channel == shootingChannel) {
channel.setAnim("stand");
}
}
public void onAnimChange(AnimControl control, AnimChannel channel,
String animName) {
}
// Load an image from the net, making sure it has already been
// loaded when the method returns
public Image loadPicture(String imageName) {
return null;
}
// Load and play a sound from /usr/local/hacks/sounds/
public void playSound(String name) {
URL u = null;
try {
u = new URL("file:" + "/usr/local/hacks/sounds/" + name + ".au");
} catch (MalformedURLException e) {
}
AudioClip a = Applet.newAudioClip(u);
a.play();
}
}
Update
I changed one line of code to include the transform I had to do at the beginning:
character.setViewDirection(walkDirection.add(new Vector3f(1, 0, 0)));
i.e. I added the Vector3f(1, 0, 0) and that seems to have helped, now my character can move forward and backward seemingly perfectly.
But it is still not perfect when moving sideways although the "moonwalking" disappeared and maybe you can confirm that I did the right thing using the add method of the vector?
Update 2
When changing the vector to negate the Ninja is starting to move like he should!
character.setViewDirection(walkDirection.negate());
e.g. in the update code
public void simpleUpdate(float tpf) {
Vector3f camDir = cam.getDirection().clone().multLocal(0.1f);
Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f);
camDir.y = 0;
camLeft.y = 0;
walkDirection.set(0, 0, 0);
if (left) {
walkDirection.addLocal(camLeft);
}
if (right) {
walkDirection.addLocal(camLeft.negate());
}
if (up) {
walkDirection.addLocal(camDir);
}
if (down) {
walkDirection.addLocal(camDir.negate());
}
if (!character.onGround()) {
airTime = airTime + tpf;
} else {
airTime = 0;
}
if (walkDirection.length() == 0) {
if (!"Idle1".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Idle1", 1f);
}
} else {
System.out.println("setting walk direction " + walkDirection);
character.setViewDirection(walkDirection.negate());
if (airTime > .3f) {
if (!"stand".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("stand");
}
} else if (!"Walk".equals(animationChannel.getAnimationName())) {
System.out.println("in walk Walk ");
animationChannel.setAnim("Walk", 0.7f);
}
}
character.setWalkDirection(walkDirection);
}
Now a remaining problem is to make the char jump and move over stairs.
I'm no animation expert but if you move forward while playing the walk animation it should look ok. For better results you might need some transitions between antimations (e.g. stand, walk, turn) which can either be separate animations or maybe could be achieved by using animation blending.
Nevertheless, it's hard to unterstand what actually is your problem, since the description is quite short and we can't see animation problems from looking at a bunch of code.
Besides that, if your problem is how to correctly configure JMonkeyEngine you might be better off in their forum. Or at https://gamedev.stackexchange.com/.

Categories

Resources