I'm developing a small game currently that involves players guessing. The player can additionally use special cards, that, for example, reveal one letter/add time he/she has for guessing and so on. Game is divided into two scenes -> one with shop, inventory, player profile etc the second one is strictly for guessing.
Currently, almost everything runs in the update in the second scene, but I really hate it. I was trying to rewrite everything into coroutines BUT the problem is that it seems impossible to use cards inside IEnumerator (or maybe I'm doing something wrong?).
For example, a simple countdown. If it's in Update I can easily influence the time with using cards(f.e. add 30 seconds). In the case of IEnumetor, I can't (Or maybe better, I don't know how to do it).
int secondsForGuess = 30;
IEnumerator Countdown () {
int counter = secondsForGuess;
while (counter > 0) {
yield return new WaitForSeconds (1);
counter--;
}
}
Any general suggestion how to do it without using Update will be greatly appreciated :D
If I understand your question right, you want to be able to increase the counter from the outside of the routine. So simply make it a field in the class so anyone can increase or decrease it:
const int secondsForGuess = 30;
private int counter;
public void AddToCounter(int seconds)
{
counter += seconds;
}
private IEnumerator Countdown ()
{
counter = secondsForGuess;
while (counter > 0) {
yield return new WaitForSeconds (1);
counter--;
}
// Do something when finsihed
}
Also just in case: Make sure to somewhere start the routine using StartCoroutine.
Related
In my single page, there were so many textures those I require to render before I was just facing problem in just screen opening but this I was able to resolve this suggestion:
OnBecomeVisible for Canvas UI Objects
Here is the actual code that I used for this purpose:
public void OnValueChangeRefreshCards (Vector2 valueChange)
{
elapsedYDist += valueChange.y;
if (elapsedYDist > 3f) {
elapsedYDist = 0f;
for (int i = 0; i < GameConstants.TOTAL_ROSE_COUNT; i++) {
Card card = roseList [i].GetComponent<Card> ();
if (RendererExtensions.IsVisibleFrom (card.MyRectTransform, Camera.main))
card.roseImage.enabled = true;
else
card.roseImage.enabled = false;
}
}
}
But now I started too much framerate lose related issue so even scrolling of page become really difficult for me.
Please check the attached video for more clearance about the issue, I was facing.
NameThatRose - Low Frame Rate
Please give me some suggestions for next improvements.
EDIT: Here are my profiler output.
Detailed Deep Profiler
Overview Deep Profiler
You can try few things to find out whats causing the low fps.
Use profiler to deep profile to find out which UI call is taking more time. Like what I did here.
As Image inherits from UIMaskableGraphics, it calls MaskableGraphics.OnEnable() every frame for every image in your list. This takes up time which you can see here:
I believe your OnValueChanged method is called every frame this would only multiply the enable/disable iterations and its processing time. You can limit the call by some time, processing 4 times a second for example.
float timeSinceLastUpdate = 0;
void Update()
{
timeSinceLastUpdate += Time.deltaTime;
}
public void OnValueChangeRefreshCards (Vector2 valueChange)
{
if(timeSinceLastUpdate < 0.25f)
{
return;
}
timeSinceLastUpdate = 0;
// do your stuff here...
}
You have 250+ images to process every frame which is a big deal for older Android devices, again as MaskableGraphics.OnEnable() call can be the culprit. You can avoid changing the state if it is required:
if (RendererExtensions.IsVisibleFrom (card.MyRectTransform, Camera.main))
{
if(!card.roseImage.enalbed)
card.roseImage.enabled = true;
}
else
{
if(card.roseImage.enalbed)
card.roseImage.enabled = false;
}
Furthermore, following are some helpful links to optimize UI in Unity:
Some of the best optimization tips for Unity UI
Tantzy Games
Gemserk
Other UI Optimization Techniques and Tips
A guide to optimizing Unity UI
UPDATE:
The following blog provides more information about UI rendering:
Making the UI Backend Faster
Hope this helps :)
I have made 2 different animations in Adobe flash professional cs5.5 for an Android aplication.
And I want a code that makes it possible for a user of the app to play the animation as often they want, so if the user wants the animation to play 1 time the first animation will be playes, if the user wants to play it 2 times the animation 1 and 2 will be played, if the user wants the animation 3 times played the animation 1, 2 and 1 will be played and so on.
Can somebody help me with this problem and tell me if this is possible in jquery.
If I was you, the way I would approach this is by having a keyframe after each of the animations where you can type some code.
On the menu page or where ever you have the code for how many times the code should run, define a variable and call it something like "runTimes" which should become the amount of times the animation should run.
At the end of the animations do a simple if statement to check what the value of "runTimes" is and then decrement it. Depending on the value, it should use gotoAndPlay/gotoAndStop.
So, put this on the keyframe after the first animation:
if (runTimes > 0) {
runTimes--;
gotoAndPlay(<FIRST FRAME OF SECOND ANIMATION>);
} else {
gotoAndStop(<FRAME OF MAIN MENU>);
}
and this after the second animation:
if (runTimes > 0) {
runTimes--;
gotoAndPlay(<FIRST FRAME OF FIRST ANIMATION>);
} else {
gotoAndStop(<FRAME OF MAIN MENU>);
}
On the mainmenu frame, let's assume you have a textbox named "numTimes_txt" for the number of times to play and a button "playAnimations_btn" to start the animations.
import flash.events.MouseEvent;
var runTimes:int = 0;
playAnimations_btn.addEventListener(MouseEvent.CLICK, playAnims);
function playAnims(e:MouseEvent):void {
runTimes = parseInt(numTimes_txt.text);
play(); // or gotoAndPlay(<FIRST FRAME OF FIRST ANIMATION>);
}
I haven't tested this as I don't have my IDE on me right now, but this should work if I understand the question properly.
I am trying to develop a android runner game for school purpose..
I am still new to this and please I need your assistance..
You guys can view my CS5flash file at >>> http://www.filedropper.com/test_37
The obstacles and coins are on random. But the obstacles and coins are overlapping each other.. Which is very bad for a runner game because it looks very bad and the gameplay gets very very complicated.
How can i fix it??. Is there any way to fix it?.
And i am also thinking if I can set the obstacles and coins to a specific area (not on random). So the game will be more oganized and the gameplay won't be complicated. Which i still don't know -_-.
But i still prefer it on random. So guys please help me fix it..
You will need to change the way you are adding the coins and obstacles! I suggest using a timer for each. Atm you are adding a ton of them on every frame, calculating overlaps would use too much resources! and put them in an array or better a vector! i would reccomend using an object Pool aswell!
so limit the amout of coins and hurdles that can be present, like 5 or so. then remove them from the array/vector when they are offscreen or collected! then when you add new stuff you can check against the array/vector what the allowed values are!
when you got your Array you can pass it to the randomRange() function and exlcude those values!
would look somthing like this! not testet!!
function randomRange (min:Number, max:Number, exclude:Array = null):int
{
var val:int = (min + Math.random() * (max - min)) >> 0;
if (exclude)
{
for (var i:int = 0; i < exclude; i++)
{
while ((val < exclude[i].x + exclude[i].width) && (val > exclude[i].x))
{
val = (min + Math.random() * (max - min)) >> 0;
}
}
}
return val;
}
Its still quite exspensive performance wise. but with only a few object you should be fine
I am making a game and would like To display the score in such a fashion that if my score is 0 and is increased by 10, then the score should increment through all of the numbers from 0 to 10. After reaching the new score it should stop, for at least a small pause.
If, again, the score is increased by another 10, the scoreboard should increment through every number from 10 to 20 and then stop again.
I have tried using handlers but unsuccessful in getting them a pause or stop, in any way.
The example in this video demonstrates what I am trying to accomplish. If you look at the scoreboard in the top right, you will see the score constantly incrementing. Here is the url in case the above link does not work: http://www.youtube.com/watch?v=NdZ8YupmEmA&feature=fvwrel
This is the code for my Runnable to increment the score.
final Handler mHandler=new Handler();
mRunnable=new Runnable() {
public void run() {
String s = null;
++i;
s= new Integer(i).toString();
tv.setText(s);
mHandler.postDelayed(mRunnable,1000);
}
/*protected void onStop() {
mHandler.removeCallbacks(mRunnable);
}*/
};
mHandler.postDelayed(mRunnable,1000);
What I specifically need is how to get the code to stop counting.
You can simply print all the numbers between 2 end points.
Say:
int counter = 0;
while(counter%10 != 0)
{
textView.setText(counter.toString());
counter++;
}
And then again continue with the loop, just start with 11 this time,not 0.
I'm not sure it'll work as you want, like in your Temple Run example. I would want to add a little sleep() of very small amount, but yesterday I was advised not use sleep() method in Android development.
EDIT:
Ok. This tutorial seems pretty easy to handle. You can apply the same logic to your score display mechanism using Handler(as you probably guessed).
I've been raking my brains on this one for a while.
when I'm running my application (opengl game) eveyrthing goes fine but when I touch the screen my application slows down quite seriously (not noticeable on powerful phones like the nexus one, but on the htc magic it gets quite annoying).
I did a trace and found out that the touch events seem to be handled in a different thread and even if it doesn't take so much processing time I think androids ability to switch between threads is not so good...
What is the best way to handle touch when speed is an issue ?
Currently I'm using :
in the GLSurfaceView
#Override
public boolean onTouchEvent(MotionEvent event) {
GameHandler.onTouchEvent(event);
return true;
}
Any ideas are welcome
I have a feeling the bug report below may be relevant. Sadly in seems its only going to be fixed in gingerbread.
Bug report
Have just seen that SO prefers details in the answers in case links vanish etc. the above refers to a google accepted bug in Adnroid 2.1 targetted for a fix in the gingerbread release.
Issue 7836: system_server consumes excessive CPU processing touch events
I can't vouch for this myself, but my research has shown that touching the screen fires so many events that it floods the events queue and therefore lags the CPU taking your resources.
Try putting: -
try {
Thread.sleep(16);
} catch (InterruptedException e) {} //ignore
before any returns that you have in the onTouch method (usually there's only the one at the end - but just making sure). I know sleep is usually a very bad thing to do, but its not in the UI thread so it should be ok. Sleep 16 should cap the FPS to 60.
Don't put heavy computation to your onTouchEvent(). The OnTouchEvent can be fired tens or hundred of times per second per finger, you should defer the heavy computation to the other part of your game (e.g. the physics engine or the graphic engine). In particular avoid drawing in your onTouchEvent.
You should preferrably use onClickEvent or other less intensive mouse event and only use onTouchEvent when you really need to track the motion of the touch.
#Jason:
This was going to be a comment, but it grew too big and it is a different [better] answer to the one I just gave.
I have changed my implementation using this method as described here
http://obviam.net/index.php/the-android-game-loop/
By employing the method described above means you should not need to sleep the OnTouch events.
Also don't forget to protect your game loop thread as mentioned here http://wonton-games.blogspot.com/2010/06/lunar-lander-resume-game-workaround.html
Also also keep in mind that Chris Pruett when writing Replica Island said he used 2 threads, one for the update() and the other for render() - both will have to be protected.
Chris does sleep his OnTouch with 16 milliseconds (60 fps) to cut back the events - so I would say its best to experiment if you still need to cut the events down - you need only touch the screen whilst stuff is happening to see if it lags and thus subsequently speeds up when let go.
For my needs currently I am using the same thread as I haven't progressed into OpenGL, I still use the canvas. But when I go OpenGL, it will be 2 threads, and each will be a complete class of its own.
Finally, I don't time my sprites by counting frames, I've wrapped them with a timer. I'll share my Class and show you how I call it. Bear in mind I am still new to Java so apologies for poor code.
package com.yourname.yourapplication;
//Used for doing something after a set time
public class TimeDo {
private int mRepeat = 0; //Stores the last wait period for the reset() later
private long mTime = 0; //The goal time of when its due
private boolean mFlagged = false; //Stop them getting a second true on a subsequent check
public TimeDo(int milliseconds) {
reset(milliseconds);
}
public TimeDo() {
this(0);
}
public void reset(int milliseconds) {
mRepeat = milliseconds;
mTime = System.currentTimeMillis() + milliseconds;
mFlagged = mRepeat==0; //ignore if zero
}
public void reset() { //Set it back to the delay used last time
reset(mRepeat);
}
public boolean check() {
if (mFlagged) //Assert: shouldn't really happen
return false;
mFlagged = System.currentTimeMillis() > mTime;
return mFlagged;
}
public boolean checkAndReset() {
if (check()) {
reset();
return true;
}
return false; //note mFlagged could be true here, so don't use it
}
}
And it is implemented thusly: -
public class Gem {
private TimeDo mMoveGem = new TimeDo(100); //move 10 times a second, 100ms
private int mX = 0;
private int mY = 0;
private int mMoveX = 3;
private int mMoveY = 4;
.
.
.
public void update() {
if (mMoveGem.checkAndReset()) {
mX += mMoveX;
mY += mMoveY;
.
.
}
}
public void render(Canvas canvas) {
//etc etc
.
.
}
}
Hope any of that helps!
Sorry if you have to rewrite lots of your application - I did.
Edit: That TimeDo class is not a postDelayed runnable, like an automatic alarm. If you don't check it no "event" will fire. You could get excited and have it create a runnable and pass it a callback method that resides within your class (think of an OnClick method) - but defeats the purpose of running an exclusive time-able update() thread that updates all your components.