Using PathModifier or MoveYModifier to simulate sprite jumping - java

I am using this method in AndEngine to determine the scene being touched by the user.
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if(pSceneTouchEvent.isActionDown()) {
Log.e("Arcade", "Scene Tapped");
//Simulate player jumping
}
return false;
}
What i want to do is when the scene is tapped, i want to allow the player to jump.
Now two things for this would it be better to use PathModifier, or MoveYModifier considering it is landscape mode?
If either please provide an example of such.
Thanks
EDIT:
ive managed to use Physics to simulate a jump using this..
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if(pSceneTouchEvent.isActionDown()) {
Log.e("Arcade", "Scene Tapped");
final Vector2 velocity = Vector2Pool.obtain(mPhysicsWorld.getGravity().x * -0.5f,mPhysicsWorld.getGravity().y * -0.5f);
body.setLinearVelocity(velocity);
Vector2Pool.recycle(velocity);
return true;
}
return false;
}
As you said in the answer by changing the gravity. The only issue is, when the user keeps touching the screen the sprites keep going up and up and up. How can i set it where the user can only click once and cant make him jump again until the sprite hits the ground, which is a rectangle?

Use the MoveYModifier. remember, you can register as many modifiers as you want. So if, for example, the game a platform game and the character always moves on the X axis, and he can jumpt if he wants (Like Gravity Guy or Yoo Ninja, although these games change the gravity which is something else).
You could do like:
Entity playerEntity = ..//It doesn't matter if the player is a sprite, animated sprite, or anything else. So I'll just use Entity here, but you can declare your player as you wish.
final float jumpDuration = 2;
final float startX = playerEntity.getX();
final float jumpHeight = 100;
final MoveYModifier moveUpModifier = new MoveYModifier(jumpDuration / 2, startX, startX + jumpHeight);
final MoveYModifier moveDownModifier = new MoveYModifier(jumpDuration / 2, startX + jumpHeight, startX);
final SequenceEntityModifier modifier = new SequenceEntityModifier(moveUpModifier, moveDownModifier);
playerEntity.registerEntityModifier(modifier);
EDIT:
For your second question:
Create a variable boolean mIsJumping in your scene; When the jump starts - set it to true. If the user taps the screen and mIsJumping == true, don't jump.
Now, register a ContactListener to your PhysicsWorld. Whenever there is contact between the player and the ground, set mIsJumping to false.
There are many samples of using ContactListeners in AndEngine forums, a quick search yields some. If you need an example, you can ask for one :)
EDIT 2: ContactListener sample:
Have 2 variables to hold IDs for the player and the ground: private static final String PLAYER_ID = "player", GROUND_ID = "ground";
When you create the ground body and the player body, set their IDs as the user data: playerBody.setUserData(PLAYER_ID); and groundBody.setUserData(GROUND_ID);
Create a ContactListener as a field in your scene:
private ContactListener mContactListener = new ContactListener() {
/**
* Called when two fixtures begin to touch.
*/
public void beginContact (Contact contact) {
final Body bodyA = contact.getFixtureA().getBody();
final Body bodyB = contact.getFixtureB().getBody();
if(bodyA.getUserData().equals(PLAYER_ID)) {
if(bodyB.getUserData().equals(GROUND_ID))
mIsJumping = false;
}
else if(bodyA.getUserData().equals(GROUND_ID)) {
if(bodyB.getUserData().equals(PLAYER_ID))
mIsJumping = false;
}
}
/**
* Called when two fixtures cease to touch.
*/
public void endContact (Contact contact) { }
/**
* This is called after a contact is updated.
*/
public void preSolve(Contact pContact) { }
/**
* This lets you inspect a contact after the solver is finished.
*/
public void postSolve(Contact pContact) { }
};
Lastly, register that contact listener: physicsWorld.setContactListener(mContactListener);
EDIT 3:
To move your sprite over the X axis, you can apply a force using Body.applyForce method, or apply an impulse using Body.applyLinearImpulse method. Play around with the arguments and find what works the next.
The vector should consist a X part only; Try Vector2 force = Vector2Pool.obtain(50, 0);. Then apply the force this way: body.applyForce(force, body.getWorldCenter());.

Related

How to switch between the classes, in JavaFX?

I have a game template which has two classes as its levels.
The game has a player, enemies, treasure chests, and walls.
When I run the program, it loads Level 1, successfully. I have designed the code so if a certain condition is met, Level 2 must load. Now, Level 2 loads. But certain elements from Level 1 remain on screen, ignoring certain elements from Level 2.
To be exact:
From Level 2, it loads the player's initial coordinates, the treasure chests, and the final destination, ignoring the enemies and the walls.
It brings with itself from Level 1 to Level 2: the walls, the treasure chests, and the enemies. The latter two are in a frozen state. They don't function.
//Instance variables:
private int lvlCount = 1;
// Game() method
public Game(Stage stage) {
this.score = new SimpleIntegerProperty(0);
this.mobs = new ArrayList<>();
this.hitBoxes = new ArrayList<>();
this.treasure = new ArrayList<>();
this.newLevel = new ArrayList<>();
this.enemyCount = 0;
bg();
loadLevel(1);
living();
stuff();
mob2();
finalText();
stage.setOnShown(e -> this.run());
}
//The switch for loading the Levels:
void loadLevel(int in) {
switch (in) {
case 1:
this.level = new Level1();
break;
case 2:
this.level = new Level2(); // placeholder for second level
break;
}
hitBoxes.clear(); // clear the list of hitboxes
mobs.clear(); // remove any existing old mobs
this.getChildren().addAll(hitBoxes); // add all the hitboxes for the walls to the scene
background.setImage(level.getImage()); // get the background image
hitBoxes.addAll(level.getWalls()); // get all the wall hitboxes
enemyCount = level.getEnemyCount(); // get the enemy count from the level
chestCount = level.treasureCount(); // get the treasure count from the level
this.initTreasure(chestCount); // add the treasure chests for the level
this.initMobs(enemyCount); // initialize our mobs
lvlCount = level.lvlCount();
this.initLevel(lvlCount);
}
//The collision check:
private void collisionCheck() {if (r.getFill().equals(Color.WHITE)){lvlCount--;}
//Main Game loop method:
private void play() {
AnimationTimer gameLoop = new AnimationTimer() {
public void handle(long arg0) {
for (int i = 0; i < mobs.size(); i++) {
MOB m = mobs.get(i);
if (m instanceof Enemy) {
((Enemy) m).moveCheck(arg0);
}
}
collisionCheck();
if (lvlCount == 0){
loadLevel(2);} //The condition that loads Level 2
gameLoop.start();
}
Please help me to figure out how I can load Level 2, successfully.
Please note that it does not produce any errors in the console. So, I am having a very hard time figuring out where the problem lies.
I only pasted the code that I thought is necessary to achieve my goal. Here you can see the full code, for veiwing purposes only, no download necessary:
http://paste.mooc.fi/955c6d30
Thank you very much in advance.

How to record a longer touch for a higher jump on libgdx

So in my game I want to have it so the longer someone holds down on the screen the higher my character jumps. However I don't know how to check if someone is holding down on the screen.
My current attempt is to do this:
And run it every frame in the update method
public void handleInput(float dt) {
if (Gdx.input.isTouched()) {
if (sheep.getPosition().y != sheep.maxHeight && sheep.getPosition().y == sheep.minHeight) {
sheep.jump(1);
}
if (sheep.getPosition().y == sheep.maxHeight && sheep.getPosition().y != sheep.minHeight) {
sheep.jump(-1);
}
}
}
I am suggesting two way to detect long touch, choose one according to your requirement.
You can use longPress method of GestureListener interface to detect there is a long press or not. By default longPress duration is 1.1 seconds that mean user have to touch the screen equal to this duration, to fire a longPress event.
#Override
public boolean longPress(float x, float y) {
Gdx.app.log("MyGestureListener","LONG PRESSED");
return false;
}
Set your implementation as InputProcessor.
Gdx.input.setInputProcessor(new GestureDetector(new MyGestureListener()));
longPress only gets called one time after holding the screen for X time. so it's better to create own logic and check how long user touched the screen.
if (Gdx.input.isTouched()) {
//Finger touching the screen
counter++;
}
And on touchUp of InputListener interface make jump according to value of counter and reset value of counter to zero.
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
//make jump according to value of counter
counter=0; //reset counter value
return false;
}
Set your implementation as InputProcessor.
Gdx.input.setInputProcessor(new MyInputListener());

JavaFX rectangle mouseonclick grid return

I am writing a board game which has a 20x20 grid.
This is in my board class:
private final Position[][] grid = new Position[GRID_SIZE][GRID_SIZE];
each position has :
public class Position {
private final Coordinates pos;
private Player player;
private final static double RECTANGLE_SIZE = 40.0;
private final Rectangle rect = new Rectangle(RECTANGLE_SIZE, RECTANGLE_SIZE);
}
so basically I have 20x20 Positions and each positions has a Rectangle
This is what I do to display the grid
for (int cols = 0; cols < GRID_SIZE; ++cols) {
for (int rows = 0; rows < GRID_SIZE; ++rows) {
grid.add(gameEngine.getBoard().getGrid()[cols][rows].getRect(), cols, rows);
}
}
Anyway, the grid is initialized and works properly. What I want to do is to make the rectangle objects clickable and to be able to return their Coordinates when they are clicked.
This is how I handle the mouse click
private void setUpRectangle() {
rect.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
rect.setFill(Color.BLACK);
}
});
}
What this code does is to change the color of the rectangle to black, but how could I return the Coordinates.
Basically, I can edit the onclick function to return the coordinates of this position, but how can I acquire them later?
This is not a JavaFX question as much as it is a design question. You have a container (Position) of 2 objects (Coordinates and Rectangle) and you want one of them to know about the other. That is, the rectangle should know the coordinates of its position.
There are a few approaches here, and depending on the bigger picture, one might be better than the others. James_D mentioned a couple in a comment.
Keep a reference of the position object in the rectangle object. This is useful if rectangle needs to access various datum in the container from various places. You would do something like rectangle.getPosition().getCoordinates() or .getPlayer().
Keep a reference of the coordinates object in the rectangle object. This is a more specific approach of 1 useful if you only need that object. You would do something like rectangle.getCoordinates().
Pass the coordinates to your setUpRectangle method. This is useful if you rectangle doesn't need access to this data from various places, it's a local solution. Then in the handle method you would return the coordinates you passed to setUpRectangle, though we can't see what class this method is in.
Use external help. You can keep something like Map<Rectangle, Coordinates> and then call map.get(rectangle). You can hide this map in a method Coordinates getCoordinatesForRectangle(Rectangle rectangle) instead of calling it directly.
You could store this data as userData (or use properties in case userData is preserved for something else in your program):
private final Rectangle rect;
public Position() {
rect = new Rectangle(RECTANGLE_SIZE, RECTANGLE_SIZE);
rect.setUserData(this);
}
rect.setOnMouseClicked((MouseEvent event) -> {
Position pos = (Position) ((Node) event.getSource()).getUserData();
...
});
You could also use a listener that knows about the position:
class CoordinateAwareListener implements EventHandler<MouseEvent> {
private final int coordinateX;
private final int coordinateY;
public CoordinateAwareListener(int coordinateX, int coordinateY) {
this.coordinateX = coordinateX;
this.coordinateY = coordinateY;
}
#Override
public void handle(MouseEvent event) {
// do something with the coordinates
}
}

JAVA Greenfoot Game Over / Win check on yCoordinate

I'm having this issue with my 2 checks for a frogger-style game.
So the Gameover check is a simple collision check on the frog object.
The next check does a getY coord check for checking if the frog object has hit the roof of the world ergo has beaten the game.
Now when the GameOver check is fulfilled there is no more object to do a getY check on. So it gives an error.
How can I bypass this ?
full code of the Frogger class:
public class Frogger extends Actor
{
public void act()
{
checkKeys();
hitEnemy();
atTop();
}
private void checkKeys()
{
if (Greenfoot.isKeyDown("up")) {
setLocation(getX(), getY()-3);
}
if (Greenfoot.isKeyDown("down")) {
setLocation(getX(), getY()+3);
}
if (Greenfoot.isKeyDown("left")) {
setLocation(getX()-3, getY());
}
if (Greenfoot.isKeyDown("right")) {
setLocation(getX()+3, getY());
}
}
public void hitEnemy()
{
Actor Enemy = getOneIntersectingObject(Enemy.class);
if(Enemy != null)
{
World myWorld = getWorld();
Gameover gameover = new Gameover();
myWorld.addObject(gameover, 300, 200);
myWorld.removeObject(this);
}
}
private void atTop()
{
if (getY() < 30)
{
World myWorld = getWorld();
Youwin youwin = new Youwin();
myWorld.addObject(youwin, 300, 200);
myWorld.removeObject(this);
}
}
}
Different approaches. When the game is over, you could just not do a getY() check anymore. Do not continue running the game, but rather to back to a main menu or something. the getY() method is irrelevant here. You could halt the program completely.
But your code looks weird. GameOver is an object? Rather than a simple method in your game. It does look like your code has a weird structure for a game. Anyway, when the game is over the 'gamelogic' loop should no longer be running, bur rather go to a menu.
Or you could keep the game running and do a null check. But reading your code, it seems like the whole structure is not that good. Is the aTop part of your Frog class? If so, it should exist for it to be called on. If you remove the Frog class from the world, you could do something like (but I do not see where the aTop method gets called)
if(myWorld.getFrog()!=null){
// Get method
}
Could you maybe share a bit more of your code? I think this should give you an idea though, there should be no more calls to the object when the object is removed, because the game ended and the normal game loop should no longer be running. And otherwise, nullchecks.

JSlider question: Position after leftclick

Whenever I click a JSlider it gets positioned one majorTick in the direction of the click instead of jumping to the spot I actually click. (If slider is at point 47 and I click 5 it'll jump to 37 instead of 5). Is there any way to change this while using JSliders, or do I have to use another datastructure?
As bizarre as this might seem, it's actually the Look and Feel which controls this behaviour. Take a look at BasicSliderUI, the method that you need to override is scrollDueToClickInTrack(int).
In order to set the value of the JSlider to the nearest value to where the user clicked on the track, you'd need to do some fancy pants translation between the mouse coordinates from getMousePosition() to a valid track value, taking into account the position of the Component, it's orientation, size and distance between ticks etc. Luckily, BasicSliderUI gives us two handy functions to do this: valueForXPosition(int xPos) and valueForYPosition(int yPos):
JSlider slider = new JSlider(JSlider.HORIZONTAL);
slider.setUI(new MetalSliderUI() {
protected void scrollDueToClickInTrack(int direction) {
// this is the default behaviour, let's comment that out
//scrollByBlock(direction);
int value = slider.getValue();
if (slider.getOrientation() == JSlider.HORIZONTAL) {
value = this.valueForXPosition(slider.getMousePosition().x);
} else if (slider.getOrientation() == JSlider.VERTICAL) {
value = this.valueForYPosition(slider.getMousePosition().y);
}
slider.setValue(value);
}
});
This question is kind of old, but I just ran across this problem myself. This is my solution:
JSlider slider = new JSlider(/* your options here if desired */) {
{
MouseListener[] listeners = getMouseListeners();
for (MouseListener l : listeners)
removeMouseListener(l); // remove UI-installed TrackListener
final BasicSliderUI ui = (BasicSliderUI) getUI();
BasicSliderUI.TrackListener tl = ui.new TrackListener() {
// this is where we jump to absolute value of click
#Override public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
int value = ui.valueForXPosition(p.x);
setValue(value);
}
// disable check that will invoke scrollDueToClickInTrack
#Override public boolean shouldScroll(int dir) {
return false;
}
};
addMouseListener(tl);
}
};
This behavior is derived from OS. Are you sure you want to redefine it and confuse users? I don't think so. ;)

Categories

Resources