How to control Revolute joint using input button? - libgdx

I am trying to rotate a body connect via revolute joint, when space bar button is pressed in my desktop.it is working fine when i put all the condition in create, but not working on pressing space bar button.
here is my create method
ballBody =createBall();//first body to the joint
rectBody=createRect();//second body to the joint
revoluteJointDef = new RevoluteJointDef();
revoluteJointDef.initialize(ballBody,rectBody,new Vector2(0,0));
revoluteJointDef.lowerAngle=0;
revoluteJointDef.upperAngle=0.785f;
revoluteJointDef.localAnchorA.set(2,0);
revoluteJointDef.localAnchorB.set(0,6);
revoluteJointDef.collideConnected=false;
revoluteJointDef.lowerAngle=-0.734f;
revoluteJointDef.upperAngle=0.735f;
revoluteJointDef.maxMotorTorque=100f;
revoluteJointDef.motorSpeed=-12.6f;
revoluteJointDef.referenceAngle=0f;
revoluteJointDef.enableLimit=true;
joint = world.createJoint(revoluteJointDef);
and i am enabling motor after pressing space bar button like this
public boolean keyDown(int keycode) {
if(keycode== Input.Keys.SPACE) {
hit(); // call to hit function
}
here is hit function
private void hit(){
revoluteJointDef.enableMotor=true;
}
and my render method is like this
public void render(float delta) {
Gdx.gl.glClearColor(0.5f, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
game.batch.setProjectionMatrix(camera.combined);
world.step(1f/60f, 6, 2);
debugRenderer.render(world, camera.combined);
game.batch.begin();
game.batch.end();
}
please help me out with any suggestion.

I found mistake in your Create method last line it should be like
revoluteJoint=(RevoluteJoint)world.createjoint(revolutejointDef);
and in hit method or else than create method use revolutejoint instead revolutejointDef
revoluteJoint.enableMotor=true;

Related

LibGDX Particles not the same as in Editor

I've created a "snow" particle effect using LibGDX's ParticleEditor, and exported the effect to a snow.p file.
When I load the file in my game it looks completely different.
As seen in the editor:
As seen in game:
As you can see the editor shows the snow falling throughout the space. Can't tell from the image, but it's falling downwards.
In the game, the snow "falls" along a line and to the right. I opened the p file in a text editor, and it looks fine so I'm not sure what is wrong.
In case it's needed, here is how I load and use the particle effect.
ParticleEffect p = new ParticleEffect();
p.load(Gdx.files.internal("snow.p"), Gdx.files.internal(""));
p.setPosition(0, DonutsGame.WORLD_HEIGHT / 2);
addActor(new ParticleEffectActor(p));
The actor class:
public class ParticleEffectActor extends Actor {
ParticleEffect effect;
public ParticleEffectActor(ParticleEffect effect) {
this.effect = effect;
effect.start();
}
public void draw(SpriteBatch batch, float parentAlpha) {
effect.draw(batch); //define behavior when stage calls Actor.draw()
}
public void act(float delta) {
super.act(delta);
effect.update(delta); //update it
}
}
I can post the snow.p file, but it's a bit large, if there's a particular section that would be helpful let me know and I will post it.

Post overriding the paint method of the components in java

In java awt or swing when you want to change painting of some component you usually have to override the method paint(Graphics g) (in awt) or paintComponent(Graphics g) (in swing).
This is usually (maybe allways - I'm not sure) done when you are creating the component for example:
JPanel jPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//... my implementation of paint, some transfromations, rotation, etc
}
};
Imagine that you have container of components which could for example consists of some JLabels, some JTextFields, some image. Which will be all put on one component.
By container I mean you have some list or map with ids or some similar structure in which are all components you will put on one JFrame.
The question is if I can change the painting method after creating with all of the components which are in this list in the moment when all of them are already created. For example I want do the rotation action (rotate), which is defined in Graphisc2D, with all of them.
So basicaly what I want is that I throught the list of componets I have and say:
"All of you (components) which are in the list will be rotated by some angle". Is that possible? If yes how?
Edit:
This is my not correctly working solution:
graphicalDisplayPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.rotate(Math.PI, anchorx, anchory);
}
#Override
public void paintChildren(Graphics g) {
super.paintChildren(g);
Graphics2D g2d2 = (Graphics2D) g;
g2d2.rotate(Math.PI, anchorx, anchory);
}
};
JFrame jFrame = JFrame();
// ... setting dimension, position, visible etc for JFrame, it works correctly nonrotated
jFrame.setContentPane(graphicalDisplayPanel);
I have not tested this, but it seems like it would work. A JComponent's paint() method calls:
paintComponent(co);
paintBorder(co);
paintChildren(co);
where co is a Graphics object. In theory you create an image, retrieve the graphics object and then pass that into paintChildren(). you will have to call paintComponent() and paintBorder() yourself, if you do this. Then, just rotate the image and draw it into your component. You may have to crop the image or resize your component accordingly for this to work. It might look something like this:
BufferedImage myImage;
#Override
public void paint(Graphics g){
myImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TRANSLUCENT);
//using a transparent BufferedImage might not be efficient in your case
Graphics myGraphics = myImage.getGraphics();
super.paintComponent(g);
super.paintBorder(g);
super.paintChildren(myGraphics);
//rotation code here
// ...
//draw children onto your component
g.drawImage(myImage, 0, 0,getWidth(), getHeight(), null);
}
I hope I didn't make any mistakes, please let me know if this works.
So basicaly what I want is that I throught the list of componets I have and say: "All of you (components) which are in the list will be rotated by some angle".
If you want to rotate panel and therefore all the components on the panel as a single using then you need to do the custom painting in the paintComponent() method.
If you want to rotate, for example, individual images that each have a different angle of rotation then you can again do this in the paintComponent(...) method and change the angle for each component.
Or, in this second case you can use the Rotated Icon class. In this case the Icon is just added to a JLabel. Then you can change the degrees of rotation and repaint the label, so there is no custom painting (except in the Icon itself).

Referencing hashMap values

I am working on Swing code that has a bunch of radio buttons associated with a hashmap of their hex values. It will then display (in a display area) the color (in the background) along with some text of the hex value of that color.
I'd like it to do this by referencing the values stored in my hashMap and populating these fields accordingly but don't know quite how to do it. I could hard-code individual ActionListeners (20 in all) but what's the point of coding if you have to do everything the hard way?
Below is my ActionListener & a couple entries in my hashMap. Thanks in advance!
//---- Action Listener
jrbRed.addActionListener(new ActionListener() {//<---Reference whichever button is selected instead of just 'jrbRed'
#Override
public void actionPerformed(ActionEvent e) {
jlblMessage.setForeground(Color.decode("#000000"));
jlblMessage.setText("FF0000");//<---Reference hashmap value
getContentPane().setBackground(Color.red);//<---Reference hashmap value
}
});
// ...my color map of hex values for referencing...
hashMap.put("Blue", "#0000FF");
hashMap.put("Purplish", "#DF01D7");
hashMap.put("Red", "#FF0000");
// ...etc...
What if you're map looked like this?
JButton blueButton = new JButton("Blue");
hashMap.put(blueButton, "#0000FF");
MyActionListener listener = new MyActionListener();
for(JButton button : hashMap.keySet()) {
button.addActionListener(listener);
}
Then to get the value depending on the button in your listener:
jbliMessage.setText(hashMap.get((JButton)e.getSource());
You can subclass your radio buttons to have foreground, background, and text Color variables, and reference them in your ActionListener:
private class ColorSettingListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
ColorRadioButton crb = (ColorRadioButton) e.getSource();
jlblMessage.setForeground(crb.getForegroundColor());
jlblMessage.setText(crb.getColortext());
getContentPanel().setBackground(crb.getBackgroundColor());
}
}
If you think this is too obtrusive, you can use JComponent.getClientProperty(Object) and JComponent.setClientProperty(Object, Object) to do the same thing. Then you don't have to subclass.

Canvas repaint should be called by itself

I have an application with jTabbedPane. There are two tab (JPanel) in jTabbedPane. First tab includes canvas and second one includes simple JLabel. Button draws rectangle into canvas.
Every thing is fine until then. However, when switching tabs, canvas would lose everything. It should be repainted by itself.
Rectangle should exist after changing tabs. Do you have any idea about the problem?
My button code is here:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Graphics g = canvas1.getGraphics();
g.drawRect(10, 10, 100, 100);
}
Thanks in advance.
First of all, you shouldn't put AWT components inside Swing components. Use JComponent or JPanel instead of Canvas.
Second, no, it shouldn't repaint itself. When the button is clicked, you should simply store what should be painted in some variable, and the paintComponent() method should be overridden in order to paint what is stored in this variable. This way, every time the component is repainted, it will repaint what has been stored last in this variable.
For example:
public class RectangleComponent extends JComponent {
private boolean shouldPaintRectangle = false;
public void setShouldPaintRectangle(boolean b) {
this.shouldPaintRectangle = b;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (shouldPaintRectangle) {
g.drawRect(10, 10, 100, 100);
}
}
}
In general, you should never ask the Graphics of a component and paint on it. Instead, you should override paintComponent() and paint the component using the Graphics passed as argument.

How to finish animation with libgdx

I am trying to implement a simple animation with libGDX and I am currently stuck on one thing. Lets say I have a bunch of sprites which take some time to finish. For example, around 30 sprites like this link: https://github.com/libgdx/libgdx/wiki/2D-Animation
However, before the animation completes some key is pressed. For smooth animation I want the 30 frames to be completed before I start the next set of animation, to prevent an abrupt stop.
So my question is how do I achieve it this in libGDX? My current idea is to extend the Animation class, which would keep track of how frames I have and how many have been rendered and then display the rest. Or use the isAnimationFinished(float stateTime) function (though I haven't had luck using that).
The examples I have seen like superjumper have very few animations and don't really change that much.
Also, is there a way to hold the list of sprites from a TextureAtlas.createSprites method and use those with the Animation class? If not, whats the purpose of providing this function?
Thanks
You can use
animation.isAnimationFinished(stateTime);
To see if your animation is finished.
For the sprites : personnaly I use TextureRegion from a TextureAtlas and I store them in an array for my animation
I create a class AnimatedImage that extends Image to automate spriting in Image. My code will be like this:
public class AnimatedImage extends Image{
private Array<Array<Sprite>> spriteCollection;
private TextureRegionDrawable drawableSprite;
private Animation _animation;
private boolean isLooping;
private float stateTime;
private float currentTime;
public AnimatedImage(Array<Array<Sprite>> _sprites, float animTime, boolean _looping){
// set the first sprite as the initial drawable
super(_sprites.first().first());
spriteCollection = _sprites;
// set first collection of sprite to be the animation
stateTime = animTime;
currentTime = 0;
_animation = new Animation(stateTime, spriteCollection.first());
// set if the anmation needs looping
isLooping = _looping;
drawableSprite = new TextureRegionDrawable(_animation.getKeyFrame(currentTime));
this.setDrawable(drawableSprite);
}
public void update(float delta){
currentTime += delta;
TextureRegion currentSprite = _animation.getKeyFrame(currentTime, isLooping);
drawableSprite.setRegion(currentSprite);
}
public void changeToSequence(int seq){
// reset current animation time
resetTime();
_animation = new Animation(stateTime, spriteCollection.get(seq));
}
public void changeToSequence(float newseqTime, int seq){
_animation = new Animation(newseqTime, spriteCollection.get(seq));
}
public void setRepeated(boolean _repeat){
isLooping = _repeat;
}
public boolean isAnimationFinished(){
return _animation.isAnimationFinished(currentTime);
}
public void resetTime(){
currentTime = 0;
}
}
changetosequence method will make new Animation that will be used to update the current TextureRegionDrawable at the update method. resetTime will reset the total time for the animation when you call changeToSequence. You could add the event listener to call changeToSequence method.
Here is the example:
private AnimatedImage _img;
then I add the InputListener like this:
_img.addListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
_img.changeToSequence(1);
return true;
}
});
Hope it helps.
Use tween engine for this kind of animation. Its well documented and libgdx supports it .. Google about it , and you can find bunch of examples using libgdx .. Hope it will help you !!