My programs detects collision between the image and the edge of the screen, but I cannot drag the image after collision. What do I change so I could still be able to drag the image around and didn't let the image go outside of the screen edges?
Gif example I made: https://s31.postimg.org/f60hh3z2z/Animation.gif
inside render
batch.begin();
batch.draw(texture, spritePosition.x, spritePosition.y);
batch.end();
if (Gdx.input.isTouched() && isNotColliding()) {
camera.unproject(spritePosition.set(Gdx.input.getX() - texture.getWidth() / 2, Gdx.input.getY() + texture.getHeight() / 2, 0));
}
textureBounds.set(spritePosition.x, spritePosition.y, texture.getWidth(), texture.getHeight());
.
private boolean isNotColliding(){
return screenBounds.contains(textureBounds);
}
The position of the sprite is the lower left corner. This position is what you use to check if the sprite is colliding with the edge.
Because you can move the sprite more than 1 pixel in a frame you can have the sprite x position to be negative. If spritePosition.x == -1 you will be able to see the sprite just fine, but the first line of pixels will be outside the screen.
The reason you are not able to move the sprite anymore is becouse of your if
(Gdx.input.isTouched() && isNotColliding()) {
When spritePosition.x is < 0 isNotColliding() will be true.
Insead of not alowing the sprite to be moved, make it stay inside the screen.
if(spritePosition.x < 0){
spritePosition.x = 0;
}
Related
I have a Touchpad which I want to use to move my camera. My current code moves the camera by adding the camera.direction vector scaled by 1 to the position vector. It seems that I can't use anything less than one because it starts rotating weirdly when I do. I am wanting to use the
touchpad.getKnobPercentX()
touchpad.getKnobPercentY()
methods to scale it based on the position of the knob. The problem with this is that it returns a value that is less than one. Anything greater than one moves the camera too fast. This is the code I am using to update my camera since I can't use the Touchpad knob.
private void setKnobAction() {
if (pad.getKnobPercentY() > 0f) {
camera.position.add(camera.direction.scl(1f));
camera.update();
}
if (pad.getKnobPercentY() < 0f) {
camera.position.sub(camera.direction.scl(1f));
camera.update();
}
if (pad.getKnobPercentX() > 0f) {
right = camera.direction.cpy().crs(Vector3.Y).nor();
camera.position.add(right.scl(1));
camera.update();
}
if (pad.getKnobPercentX() < 0f) {
right = camera.direction.cpy().crs(Vector3.Y).nor();
camera.position.sub(right.scl(1));
camera.update();
}
}
This method is getting called in my render() method so it is getting called several times. Also, if the knobPercent is at 0, it will start rotating weirdly.
The javadoc of Vector3.scl(float scalar) says:
Scales this vector by a scalar
This means, that you actually scale the camera.direction Vector.
Given, that a direction Vector usually is a Vector3 with a length of 1, giving the percentage of each axis you should notice the problem.
Scaling it up results in faster movement each frame, scaling it down results in slower movement each frame.
For example: You move in x-Direction, your camera.direction is Vector3(1, 0, 0). You scale it by 2.
Now it is Vector3(2, 0, 0) and you move by 2 units in this frame. Again, it is scaled and in the next frame it is Vector3(4, 0, 0), you move by 4 units in this frame. And so it goes on and on.
The same goes for scaling lower then 1.
Even worse is a scaling with zero, cause it sets the length of the camera.direction to zero. This means, that you don't have any informations about the direction anymore, which causes the strange rotation.
So what you shoul do:
Store another Vector3, copy the values of camera.direction to it (at the beginning of each frame), scale it by the getKnobPercentY() (actually you should scale it by getKnobPercentY() * delta * speed) and add this to the position.
Then reset this Vector again (copy the values of the camera.direction to it) and do the same things for the x-values (ofc now with the crs(Vector3.Y))
my app contains an object moving on a surfaceview. I am able to move it around via accelerometer.
Here's the movement code of the player object:
if(x + mx*speed > 0 && x + mx*speed < GameView.WIDTH) {
x += mx*speed;
}
if(y+ my*speed > 0 && y+ my*speed < GameView.HEIGHT) {
y+=my*speed;
}
x and y are the player's coordinates
mx is the value the player gets from the accelerometer, for example: when tilting to the left, mx is -2, when tilting more, mx is -4, -5, -6 etc. --> my is the same for the y-axis
the speed is a variable to modify and play around when i want to have a faster movement.
as you can see I tried to limit the movement to only move when the player is inside of the view.
Now my problem is: when tilting the device intensively to the right, mx turns to something like 6. speed is set to 5. This means, when the player's position + 6 * 5 is bigger than the game view it should not move any more. But this results in the player stopping pixels in front of the right side of the view... when tilting lightly to the right, the object stops perfectly at the border of the view...
Now how should i change the code to achieve an object that stops it's movement perfectly at borders of the screen?
On this picture you can see the circle not stopping quite at the bottom, as there are some pixels between the circle and the bottom border. when going slightly back with the accelerometer, the circle aligns itself to the bottom of the screen:
But now, i can only reach the screen borders when moving slowly, which means with a low mx or my.
the screenshots you can see the mY values. On the first picture my = ca. 8 and on the second ca. 6.
Any ideas?
Thanks in advance
Try to instead cap the value to the border like so
x = Math.max(Math.min(x + mx*speed, GameView.WIDTH), 0.0f));
y = Math.max(Math.min(y + my*speed, GameView.HEIGHT, 0.0f));
I am trying to make a small game where you can fling a coin on the screen. while i was searching for that kind of animation i found this page
http://mobile.tutsplus.com/tutorials/android/android-gesture/
I managed to customise the events according to my aim, but i couldn't manage to set boundaries on the screen so that the coin(bitmap) will bounce back when it comes to the edges.
I tried several calculations but in the end the coin moves weirdly based on the contact points on the edges.
Can someone help me about it, according to the working code on the website
Below is a sample code from my pong game. Each object has position (x,y) and its speed. Movement is speed applied to position. One extra info is that the screen coordinate system starts from the left top corner. Y axis go down but increasing. Since screen coordinates start from 0, the boundaries become screen.width -1 and screen.height -1
#Override
public void onDraw(Canvas c){
p.setStyle(Style.FILL_AND_STROKE);
p.setColor(0xff00ff00);
// If ball's current x location plus the ball diameter is greater than screen width - 1, then make speed on x axis negative. Because you hit the right side and will bounce back to left.
if((Px+ballDiameter) > width - 1){
Vx = -Vx;
}
// If ball's current y location plus the ball diameter is greater than screen height -1, then make speed on y axis negative. Because you hit the bottom and you will go back up.
if((Py + ballDiameter) > height - 1){
Vy = -Vy;
}
// If current x location of the ball minus ball diameter is less than 1, then make the speed on x axis nagative. Because you hit to the left side of the screen and the ball would bounce back to the right side
if((Px - ballDiameter) < 1){
Vx = -Vx;
}
// If current y location of the ball minus ball diameter is less than 1, then make the speed on y axis negative. Because the ball hit the top of the screen and it should go down.
if((Py - ballDiameter ) <1){
Dy = 1;
Vy = -Vy;
}
Px += Vx; // increase x position by speed
Py += Vy; // increase y position by speed
c.drawCircle(Px, Py, ballDiameter, p);
invalidate();
}
I am attempting to create simple top down side scrolling style app in android. Basically an image sits in the bottom center of the screen which does not move. A background image behind this will move based on the tilt of the device.
If I don't move (translate) the image and I rotate it based upon the first images center point, the background image rotates correctly around this point. If I translate the background image at all however, the rotation is no longer accurate. It seems that the rotation is applied based on the images Top, Left not the screen top left, so if I translate the image by 100 units down the screen, it now rotates 100 units below where I want it to.
Basically I am looking for a way to rotate an image no matter where it is located on the screen by a fixed position on the screen that never changes. Hopefully this will create the illusion that the image at the bottom of the screen is moving when in fact it is the background that is moving. Thanks.
Here's some simple code snippets of what Im doing, not sure if it really helps:
m_X & m_Y are variables holding the tilt of the device
That horrible hard coded value of 264, 628 is the location of my animating character at the bottom of the screen. (what I want the background image to rotate around no matter where it has translated itself to)
Update Function:
protected void Update(float a_GameTime)
{
super.Update(a_GameTime);
m_CharacterAnimator.Update(a_GameTime);
if ((m_CurrentCharacterDirection.contains(LEFT) || m_CurrentCharacterDirection.contains(RIGHT)) && (m_X > 1.0f || m_X < -1.0f))
{
m_BackgroundWorldMatrix.preRotate(m_X * .05f, 264, 628);
}
if ((m_CurrentCharacterDirection.contains(FORWARD) || m_CurrentCharacterDirection.contains(BACKWARD)) && (m_Y > 1.0f || m_Y < -1.0f))
{
m_BackgroundWorldMatrix.postTranslate(0.0f, m_Y * -0.25f);
}
}
Draw Function:
protected void Draw(Canvas a_Canvas)
{
super.Draw(a_Canvas);
a_Canvas.drawBitmap(m_Background, m_BackgroundWorldMatrix, null);//, m_BackgroundWorldMatrix, null);
// Draw the animating Character
m_CharacterAnimator.Draw(a_Canvas);
}
I am experimenting with 2D graphics in Android during my off time, and I'm intrigued by the idea of creating a sprite based "sandbox" for playing around. I've looked around online and found some good tutorials, but I'm stuck with a fairly basic problem: My sprite moves faster than the terrain and "glides" over it. Also, he slowly outpaces the terrain scrolling and moves to the edge of the view.
I've got an animated sprite that I want to move around the world. I do so by changing his absolute coordinates(setting X and Y position in an 'update()' function and applying a scalar multiple to speed up or slow down the rate at which he's moving around.
this.setXPos(currX + (speed * dx2));
this.setYPos(currY + (speed * dy2));
Underneath that sprite, I'm drawing "terrain" from a bitmap. I want to continue to move that sprite around via the coordinate accessors above, but also move my view and scroll the terrain so that the sprite stays in the same relative screen location but moves through the "world". I have an imperfect implementation where player is my sprite and field is my terrain:
#Override
protected void onDraw(Canvas canvas)
{
player.updateLocation(GameValues.speedScale);
field.update(new Point(player.getXPos(), player.getYPos()));
field.draw(canvas);
player.draw(canvas);
//more stuff here...
}
And field.update() looks like(Warning: Hard-coded scariness):
public void update(Point pt)
{
sourceRect.left = pt.x - 240;
sourceRect.right = pt.x + 240;
sourceRect.top = pt.y - 400;
sourceRect.bottom = pt.y + 400;
}
The thinking there was that I would eventually just get screen dimensions and make it less 'hack-y', but get something together quickly. This could easily be where my issue is coming from. Of immediate interest is field.draw():
#Override
public void draw(Canvas canvas)
{
try
{
canvas.drawBitmap(fieldSheet, sourceRect, destRect, null);
}
catch(Exception e)
{
//Handle Exception...
}
}
You'll notice I'm using the overload of drawBitmap() that accepts a source and destination Rect and that the field.update() method moves that sourceRect to match the movement of the sprite. How can I keep the "camera (so to speak)" centered on the sprite and scroll the terrain appropriately? I had thought that moving just the sourceRect and maintaining a constant destRect would do so, but now I'm thinking I have to move the destRect around the "world" with the sprite, while maintaining the same dimensions.
Is there a better (read functional) way of making this work? I'm coming here somewhat shamefully, since I think this should be somewhat easier than it seems to be for me. Any and all help or suggestions are appreciated. Thanks!
*Edit:*Does it make sense to also move the destination Rect at the same speed as the sprite? I think I conflated the source and destination Rect's and left the destRect immobile. I'll update with the results after I get a chance to try it (maybe during lunch).
*Edit_2:*Changing the destination rectangle didn't get me there, but using the View.scrollBy(x, y) method gets me close to totally satisfied. The remaining question to be satisfied is how to "clip" the View scrolling to a rectangle that represents the "field". I believe that the View.getLeft() and View.getTop() functions, offset by the screen width and height, can be used to specify a Rect that can be virtually moved around within the constraints of the "world" and block further deltas from being argued to the View.scrollBy() method. The reason I look toward this approach is because the View doesn't seem to be positioned in absolute space, and a View.getLeft() call, even after a View.scrollBy(x, y) where x > 0, returns a 0.