I am trying to rotate my image. I wrote my function to check rotate speed in the image. In the logic everything is ok but I am using runnable and the setrotate method is working only once.
This is a my source:
public void rotateimages() {
myHandler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
double k = 30;
double speed = Math.PI / k;
for (alpa = 0; alpa < (Math.PI * 6 + res * 2 * Math.PI / 5); alpa += speed) {
latcirclelayout.setRotation(latcirclelayout.getRotation()
- ((float) alpa));
k = Math.min(k + 0.2, 240);
speed = Math.PI / k;
}
}
};
myHandler.postDelayed(runnable, 100);
}
I debugged it and the alpha value is changed everytime but the rotate is working only once.
What am I doing wrong?
Your loop is just a tight loop - you're executing all the iterations in one go, basically, calling setRotation lots of times. I strongly suspect that all the calls to setRotation are being made... but you're not seeing anything but the last one. If you want to use this code for animation, you'd need to execute your code repeatedly - but only calling setRotation once per iteration.
You could check that by adding a log entry on each iteration of the loop - I'm sure you'll see that it executes all the iterations in very quick succession.
(I suspect there may be something else built into Android to make animation simpler than that, but I don't know offhand. The animation tutorial may well help you.)
Related
I'm trying to make a simple game in Unity for GearVR. In the game I have a scene where the user can navigate through a list of items. An item can be selected if the user clicks while looking at one. For the navigation part, the user should be able to use both head movement and swipe to rotate the items (shifting by one/minus one at every right/left swipe).
Now the problem: I can make all of this work with the code below (set as component to the parent of the items), but the rotation keeps increasing the more I use swipes. I can't seem to figure out why ... still working on it.
Any kind of help is appreciated XD
private void ManageSwipe(VRInput.SwipeDirection sw)
{
from = transform.rotation;
if (sw == VRInput.SwipeDirection.LEFT)
{
to = Quaternion.Euler(new Vector3(0, from.eulerAngles.y + 30, 0));
}
if (sw == VRInput.SwipeDirection.RIGHT)
{
to = Quaternion.Euler(new Vector3(0, from.eulerAngles.y - 30, 0));
}
StartCoroutine(Rotate());
}
IEnumerator Rotate(bool v)
{
while (true)
{
transform.rotation = Quaternion.Slerp(from, to, Time.deltaTime);
yield return null;
}
}
I'm using Unity 5.4.1f1 and jdk 1.8.0.
PS. Don't be to hard on me, since this is my first question here.
By the way ... hello everyone XD
You fixed most of the problems I discussed in the comment section. One things left is still the while loop. Right now, there is no way to exit that while loop and this will result to multiple instance of the Rotate function running at the-same time.
but the rotation keeps increasing the more I use swipes
Solution is to store reference to one coroutine function then stop it before starting a new one.
Something like this.
IEnumerator lastCoroutine;
lastCoroutine = Rotate();
...
StopCoroutine(lastCoroutine);
StartCoroutine(lastCoroutine);
Instead of while (true), you should have a timer that exists the while loop. At this time, the Rotate function is continuously running. You should make it stop after moving from the rotation to the destination rotation.
Something like this should work:
while (counter < duration)
{
counter += Time.deltaTime;
transform.rotation = Quaternion.Lerp(from, to, counter / duration);
yield return null;
}
Here is what your whole code should look like:
IEnumerator lastCoroutine;
void Start()
{
lastCoroutine = Rotate();
}
private void ManageSwipe(VRInput.SwipeDirection sw)
{
//from = transform.rotation;
if (sw == VRInput.SwipeDirection.LEFT)
{
to = Quaternion.Euler(new Vector3(0, from.eulerAngles.y + 30, 0));
}
if (sw == VRInput.SwipeDirection.RIGHT)
{
to = Quaternion.Euler(new Vector3(0, from.eulerAngles.y - 30, 0));
}
//Stop old coroutine
StopCoroutine(lastCoroutine);
//Now start new Coroutine
StartCoroutine(lastCoroutine);
}
IEnumerator Rotate()
{
const float duration = 2f; //Seconds it should take to finish rotating
float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
transform.rotation = Quaternion.Lerp(from, to, counter / duration);
yield return null;
}
}
You can increase or decrease the duration variable.
Try to use Lerp from the current Rotation not the last one:
transform.rotation = Quaternion.Slerp(transform.rotation, to, Time.deltaTime);
There all, i'm a newbie in android programming and i've a school task to analysis some project. So, i choose a Guitar Tuner project from github called pTune (link: here).
I've read the code and analyze it, from what i read and see there are a needle with an arc meter to see if the input sound (guitar voice) was fit.
In that project i want to display Toast if the tuning process are fit when the dial in 90 degree. So, i've add this Toast but its not displayed..
if (relativeFrequency == targetFrequency){
Toast.makeText(PTuneActivity.this, "FIT", Toast.LENGTH_SHORT).show();
}
That code placed in updateDisplay class, i've placed it in other class but still not work as i want.
public void updateDisplay(float frequency) {
// Calculate difference between target and measured frequency,
// given that the measured frequency can be a factor of target.
float difference = 0;
if (frequency > targetFrequency) {
int divisions = (int) (frequency / targetFrequency);
float modified = targetFrequency * (float) divisions;
if (frequency - modified > targetFrequency / 2) {
modified += targetFrequency;
divisions++;
}
difference = (frequency - modified) / (float) divisions;
} else {
// If target is greater than measured, just use difference.
difference = frequency - targetFrequency;
}
float relativeFrequency = targetFrequency + difference;
// Update TextView
if (relativeFrequency < 1000f)
t.setText(String.format("%.1f Hz", relativeFrequency));
else
t.setText(String.format("%.2f kHz", relativeFrequency/1000));
//My code
if (relativeFrequency == targetFrequency){
Toast.makeText(PTuneActivity.this, "FIT", Toast.LENGTH_SHORT).show();
}
// Update DialView
float value = difference / (targetFrequency / 2) * 90;
dial.update(value);
}
I know this is useless in real implementation but i want to learn android programming.
You're testing equality between 2 floats, one comes from an input ? It might never be exactly equal. You should add some log and an "else" statement to see if it goes inside the "if" because the Toast may not be the real problem
i've just try it by my self by digging and its worked for me, though its not good at all but i thinks ok, just add this line of code upper dial.update(value);
if (frequency >= targetFrequency) {
Toast.makeText(PTuneActivity.this, "FIT", Toast.LENGTH_SHORT).show();
}
I've had a problem for a long time with smooth camera on mobile phone (platformer game), but I reported that my game works well when my fps don't drop below 60. I notice that my fps are fine when i touch a screen, but when i don't do it, fps drop to approximately 58, 59 and after that my camera don't follow my player smoothly. For testing i create new scene with only FPSCounter script and the effects are the same. Could someone help me with it? I think that it is engine settings reasons, but i can't handle with it.emphasized text
//---------------------------------------------
// VARIABLES
//---------------------------------------------
private float deltaTime = 0.0f;
//---------------------------------------------
// METHODS FROM SUPERCLASS
//---------------------------------------------
void Update()
{
deltaTime += (Time.deltaTime - deltaTime) * 0.1f;
}
void OnGUI()
{
GUIStyle style = new GUIStyle();
float x = Screen.width - 110;
float fps = 1.0f / deltaTime;
Rect rect = new Rect(x, 90, 100, 50);
style.fontSize = 18;
style.normal.textColor = getColor(fps);
string text = string.Format("{0:0,0.0000 FPS}",fps);
GUI.Label(rect, text, style);
}
//---------------------------------------------
// CLASS LOGIC
//---------------------------------------------
private Color getColor(float fps)
{
if (fps >= 60)
{
return Color.yellow;
}
return Color.red;
}
Have you tried using the new UI system introduced in Unity 4.6? Maybe that fixes your issues.
https://www.youtube.com/watch?v=EOX6itCuKOc
As previously mentioned, you should really switch to the new UI system as the old GUI system was always a nightmare.
However, if you aren't wanting to switch, try setting more of your variables outside of OnGUI.
OnGUI is called multiple times per frame and it is expensive to set up a GUI style etc. so frequently - especially on an already poorly performing behaviour.
I want to moove two objects smoothely at Touching.
Here is my Code:
for(int i = 0; i <96; i++){
Asstest.rect_pipe_down.y--);
}
This should move the rect 96 pixels down (SMOOTH)
But it just close without smoothed...
What did I wrong?
If you Touch, the pipes should close, but not hard, smooth should they close.
But with following code they just close hard...
Here is the full touched code:
if(Gdx.input.isTouched()){
Assets.rect_pipe_down.y = 512 - 320/2;
Assets.rect_pipe_up.y = -320 + 320/2;
for (int i = 0; i < 96; i++){
smoothTime = TimeUtils.millis();
if(TimeUtils.millis() - smoothTime > 10) {
Assets.rect_pipe_down.y--;
Assets.rect_pipe_up.y++;
batch.begin();
batch.draw(Assets.region_pipe_down, Assets.rect_pipe_down.x, Assets.rect_pipe_down.y);
batch.draw(Assets.region_pipe_up, Assets.rect_pipe_up.x, Assets.rect_pipe_up.y);
batch.end();
}
}
closed = true;
}
You cannot do rendering multiple times in one render() call, one call is for drawing exactly one frame. In your current code, the later images simply overwrite the previous ones.
What you could do is have a variable which persists between frames which stores whether or not the pipes are currently closing, a constant for the speed and some condition to tell when they can stop - maybe when they are some given distance from each other, not sure what you would want here. Anyway, that's what I'll use in my example.
Then in the render() method, before drawing anything, you can do this:
if (closing) {
Assets.rect_pipe_down.y -= CLOSE_SPEED * delta;
Assets.rect_pipe_up.y += CLOSE_SPEED * delta;
if (Assets.rect_pipe_down.y - Assets.rect_pipe_up.y < TARGET_DIST) {
Assets.rect_pipe_down.y = Assets.rect_pipe_up.y + TARGET_DIST;
closing = false;
}
}
Here, closing is a variable you set to true when you want them to start closing, the others are constants. You could add some more variables/constants if you want to make sure they end up at a specific height independent on framerate.
I'm new in Android Game Development and I started a simple Game in that a Droid can jump over incoming boxes.
I want to call my droid.jump() method in the surface view with an onTouchEvent (just by a simple tap on the screen)
I created a class called Droid:
public class Droid {
// Log Tag for Debugging
public static final String LOG_TAG = "_1Projekt";
private Bitmap bitmap; // the actual bitmap
private int x; // the X coordinate
private int y; // the Y coordinate
private boolean touched; // if droid is touched/picked up
private Speed speed; // the speed with its directions
private long mLastTime;
public Droid(Bitmap bitmap, int x, int y) {
this.bitmap = bitmap;
this.x = x;
this.y = y;
this.speed = new Speed();
}
.......
...
And the jump() method is my problem. I would like to have a smooth jump but I don’t know how to calculate this with the current System Time.
My idea was that the droid should update it Y position every –TimePeriod- and should start with a fast velocity and then decrease it to 0 to get a smooth jump.
But I don’t know how to calculate this in my while loop.
My current jump():
public void jump() {
Log.d(LOG_TAG, "Jumping");
long now = System.currentTimeMillis();
int elapsedTime = 100;
int jump = y-30;
while(y > jump)
{
if(System.currentTimeMillis() > now + elapsedTime)
{
now = now + elapsedTime;
elapsedTime -=3;
y = y-1;
}
}
}
Up to know I only implemented the "up" part of Jump.
Thank you for your answers! Greetings DroidDude
You may want to look here (the third post):
Before the mainloop, have
//Get the current time
timeStep = System.currentTimeMillis();
And then do your stuff. Then before the loop goes back to start, have
// Hold to lock at FPS
while(System.currentTimeMillis()-timeStep < 1000/60);
Where 60 is the frames per second to run.
This method also allows you to get the difference in times after the
while loop in order to find out how much time it took to render one
frame. Using this, you could have a variable that you can multiply all
your increments by to get frame-independent speed.
For example, if you divide the number of milliseconds it took to
handle the frame by 16.666, the number will equal 1 when the program
runs at about 60 FPS. When the frame rate is lower, it takes more
milliseconds to render the frame and that factor gets bigger.
Be sure to put it BEFORE repaint however. This is the way video games
are timed also. An example is shown in my video game base applet code
snippet under JAVA.