1

In Cut the Rope's level clear screen, the score increments up to the value of the score you got in the level. How can I do something like this? I tried using a for loop and just stopped incrementing once I hit the value but this crashes my app. I guess it would need to set the text of the textview on each increment. Any ideas?

Currently this is how I pull the score to display in my Game Over:

// get score and set text field
        scorePreferences = getSharedPreferences("score", 0);
        score = scorePreferences.getInt("score", 0);
        scoreValue.setText(Integer.toString(score));

I'd like it to increment up to value saved in the preferences. I tried to do it like this:

for (int i = 0; i < score; i++) {
    scoreValue.setText(i);
}

Log cat messages:

01-30 14:11:19.606: E/AndroidRuntime(26279): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.main.francois/com.main.francois.GameOverActivity}: android.content.res.Resources$NotFoundException: String resource ID #0x0
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.app.ActivityThread.access$800(ActivityThread.java:135)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.os.Handler.dispatchMessage(Handler.java:102)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.os.Looper.loop(Looper.java:136)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.app.ActivityThread.main(ActivityThread.java:5017)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at java.lang.reflect.Method.invokeNative(Native Method)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at java.lang.reflect.Method.invoke(Method.java:515)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at dalvik.system.NativeStart.main(Native Method)
01-30 14:11:19.606: E/AndroidRuntime(26279): Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x0
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.content.res.Resources.getText(Resources.java:244)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.widget.TextView.setText(TextView.java:3888)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at com.main.francois.GameOverActivity.incrementScore(GameOverActivity.java:135)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at com.main.francois.GameOverActivity.load(GameOverActivity.java:130)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at com.main.francois.GameOverActivity.onCreate(GameOverActivity.java:78)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.app.Activity.performCreate(Activity.java:5231)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-30 14:11:19.606: E/AndroidRuntime(26279):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)

Edit: I wrote my timer to count the score like this:

public void scoreTimer() {
        timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                if (incrementScore < score) {
                    incrementScore++;
                    scoreValue.setText(String.valueOf(incrementScore));
                }
            }
        }, delay, period);
    }

But I now get this error:

01-30 14:57:55.006: E/AndroidRuntime(1383): Process: com.main.francois, PID: 1383
01-30 14:57:55.006: E/AndroidRuntime(1383): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-30 14:57:55.006: E/AndroidRuntime(1383):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:857)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at android.view.ViewGroup.invalidateChild(ViewGroup.java:4320)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at android.view.View.invalidate(View.java:10935)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at android.view.View.invalidate(View.java:10890)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at android.widget.TextView.checkForRelayout(TextView.java:6587)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at android.widget.TextView.setText(TextView.java:3813)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at android.widget.TextView.setText(TextView.java:3671)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at android.widget.TextView.setText(TextView.java:3646)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at com.main.francois.GameOverActivity$3.run(GameOverActivity.java:145)
01-30 14:57:55.006: E/AndroidRuntime(1383):     at java.util.Timer$TimerImpl.run(Timer.java:284)

I'm guessing I need to use the "asynchronise" or "runonuithread" methods? But I'm not sure how to do this?

Adam Short
  • 498
  • 7
  • 28
  • We need more information if you want this question to remain open. The code you have tried, for example, would help along with the logcat from the crash. Just the most relevant parts of the code for now... – codeMagic Jan 30 '14 at 14:36
  • You need to update the display over time. You presumably have game code working, so the logic is the same as if you want to move a game object from one position to another over time. Simply putting the score increment in a for loop won't do it for you, because it'll execute that for loop in a single frame. You have to space the incrementing over multiple frames. – Kevin Workman Jan 30 '14 at 14:37
  • I thought it would be the same way as I have at the moment (which is a timer) but didn't think this would be suitable. – Adam Short Jan 30 '14 at 14:40
  • @codeMagic - this didn't help it won't let me invoke .size() on an int. – Adam Short Jan 30 '14 at 14:53
  • I'm converting the int to a string as Adil has stated but still crashes. – Adam Short Jan 30 '14 at 14:56
  • [See this answer about using runOnUiThread()](http://stackoverflow.com/questions/21212631/how-to-use-run-runonuithread/21212662#21212662) and [this one about debugging and reading logcat](http://stackoverflow.com/questions/16782558/what-is-the-best-way-to-debug-the-android-code-in-eclipse/16782621#16782621) – codeMagic Jan 30 '14 at 15:01

1 Answers1

1

Set score as a String

for (int i = 0; i < score; i++) {
    scoreValue.setText(String.valueOf(i));
}

Actually when you pass an int to setText() method, it takes it as a resource id and tries to find out the string in string resources (written in res/string.xml). Thats why you are having a ResourceNotFoundException:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.main.francois/com.main.francois.GameOverActivity}:
android.content.res.Resources$NotFoundException: String resource ID #0x0
Adil Soomro
  • 37,609
  • 9
  • 103
  • 153