I want to use CCTimer class for the Timer but I can't sort out. After I use to manually create a function for this but it seems not effective .
protected GameLayer(ccColor4B color)
{
super(color);
schedule(new UpdateCallback() {
#Override
public void update(float d) {
countTime(d);
}
},0.99f);
}
public void countTime(float scr) {
if(_label != null){
this.removeChild(_label,true);
}
j=j-(int)scr;
CGSize winSize = CCDirector.sharedDirector().displaySize();
_label = CCLabel.makeLabel("Time Left :" + j, "Verdana", 20);
_label.setColor(ccColor3B.ccGREEN);
_label.setPosition(155f, winSize.height - 15);
addChild(_label);
if(j<=0){
CCDirector.sharedDirector().pause();
}
}
it run from 1 to the the point which i want to stop ... !!!
what should i do to use the CCTimer class to resolve this problem ?
CCTimer is available but I haven't tried this earlier but you can do this thing through Timer class :
Timer timer = new Timer();
timer.scheduleAtFixedRate( new TimerTask(){
public void run() {
updateTimeLabel();
}
public void updateTimeLabel() {
float time += 1;
String string = CCFormatter.format("%02d:%02d", (int)(time /60) , (int)time % 60 );
CCBitmapFontAtlas timerLabel = (CCBitmapFontAtlas) getChildByTag(TIMER_LABEL_TAG) ;
timerLabel.setString(string);
}
Related
I am trying to do a project is creating some graphics on window with Qt GUI C++ 5.6.2.
I have two methods named 'createVerticalSpeedIndicator' and 'createAirSpeedIndicator'. These methods need to create some graphics with a while(1) loop and use qApp->processEvents(); on window and they are doing it perfectly when one of them is working the other one is deactive. But I need to run both of them simultanously and always.
What can I do to run them simultanously and always.
Thank you So much
The solution is to invert the control flow. The while() { ... processEvents() ... } is an anti-pattern in asynchronous code, because it assumes that you have locus of control whereas you really don't. You're lucky that you didn't run out of stack since processEvents could potentially re-enter the createXxx methods.
Here's a complete example of a transformation:
// Input
void Class::createVerticalSpeedIndicator() {
for (int i = 0; i < 100; i ++) {
doStep(i);
QCoreApplication::processEvents();
}
}
// Step 1 - factor out state
void Class::createVerticalSpeedIndicator() {
int i = 0;
while (i < 100) {
doStep(i);
QCoreApplication::processEvents();
i++;
}
};
// Step 2 - convert to continuation form
void Class::createVerticalSpeedIndicator() {
int i = 0;
auto continuation = [=]() mutable {
if (!(i < 100))
return false;
doStep(i);
QCoreApplication::processEvents();
i++;
return true;
};
while (continuation());
};
// Step 3 - execute the continuation asynchronously
auto Class::createVerticalSpeedIndicator() {
int i = 0;
return async(this, [=]() mutable {
if (!(i < 100))
return false;
doStep(i);
i++; // note the removal of processEvents here
return true;
});
};
template <typename F> void async(QObject * parent, F && continuation) {
auto timer = new QTimer(parent);
timer->start(0);
connect(timer, &QTimer::timeout, [timer, c = std::move(continuation)]{
if (!c())
timer->deleteLater();
});
}
At that point you can apply the same transformation to createAirSpeedIndicator and start them in the constructor of your class:
Class::Class(QWidget * parent) : QWidget(parent) {
...
createVerticalSpeedIndicator();
createAirSpeedIndicator();
}
Both tasks will run asynchronously and pseudo-concurrently within the main thread, i.e. each task will alternatively execute a single step.
Suppose we wanted to chain the tasks, i.e. have a task start only after the previous one has finished. The modification in the user code can be simple:
Class::Class(QWidget * parent) : QWidget(parent) {
...
createVerticalSpeedIndicator()
>> createAirSpeedIndicator()
>> someOtherTask();
}
The async function must now return a class that allows such connections to be made:
struct TaskTimer {
QTimer * timer;
TaskTimer & operator>>(const TaskTimer & next) {
next.timer->stop();
connect(timer, &QObject::destroyed, next.timer, [timer = next.timer]{
timer->start(0);
});
timer = next.timer;
return *this;
}
};
template <typename F> TaskTimer async(QObject * parent, F && continuation) {
TaskTimer task{new QTimer(parent)};
task.timer->start(0);
connect(task.timer, &QTimer::timeout,
[timer = task.timer, c = std::move(continuation)]{
if (!c())
timer->deleteLater();
});
return task;
}
I have an issue. I am making a game where i check if a projectile is below the screen, if true i want to delete that object. My problem is that when the projectile actually goes below sceen my game crashes with the error:
pure virtual method called terminate called without an active
exception
which i think is very wierd because my projectile class has nothing to do with a virtual method or abstract class. This is the update methods:
void GameScene::updateLogic() {
if (projectile) {
if (projectile -> position().y > 1200) {
t1Turn = true;
delete projectile;
}
else {
projectile->update();
}
}
}
void GameScene::draw() {
if (projectile) {
projectile->draw(_window);
}
}
The projectile pointer is set to nullptr in the constructor of the gamescene:
_p = nullptr;
The projectile class:
Projectile::Projectile(sf::Vector2f spawnPoint, sf::Vector2f initVel, Tank* target, bool& turn) : _spawnPoint(spawnPoint), _initVel(initVel), _target(target), _turn(turn) {}
Projectile::~Projectile(){}
void Projectile::update(){
if (_collisionBox.intersects(_target->getBox())) {
_target->removeHealth(20);
}
_elapsed = clock.getElapsedTime().asSeconds();
_time += _elapsed;
clock.restart();
dx = (_initVel.x * _time);
dy = (_initVel.y * _time + (1900*pow(_time, 2) / 2));
_position = sf::Vector2f(_spawnPoint.x+dx, _spawnPoint.y+dy);
_collisionBox = _projectileSprite.getGlobalBounds();
}
void Projectile::draw(sf::RenderWindow &window) {
_projectileSprite.setPosition(_position);
window.draw(_projectileSprite);
}
sf::Vector2f Projectile::position () {
return _position;
}
The projectile inherits from a sprite class but thats about it:
class Projectile : Sprites {
It has no association with a pure virtual method...
EDIT: When running the debugger it breaks at:
void Projectile::draw(sf::RenderWindow &window) { window <incomplete type>
_projectileSprite.setPosition(_position);
window.draw(_projectileSprite); <--------------------
}
But how can window be of incomplete type? What has that to do with a virtual method which the original error message say?
Speaking "ok glass" brings up a command list that automatically scrolls based on the user's head motion.
Is there a built-in UI element in the GDK that implements this? Or will I have to write my own code that uses sensors?
I tried reimplementing parts of this. It's not as shiny as the google one, but those could serve as a starting point:
https://github.com/pscholl/glass_snippets/blob/master/lib/src/main/java/de/tud/ess/HeadListView.java
https://github.com/pscholl/glass_snippets/blob/master/lib/src/main/java/de/tud/ess/HeadScrollView.java
I went through the GDK's Developer Guides at https://developers.google.com/glass/develop/gdk/dev-guides and Reference at https://developers.google.com/glass/develop/gdk/reference/index and there's definitely no such built-in UI elements in GDK, as of XE 12 released in December 2013.
So the answer for now is yes you have to use sensors to implement that.
There is currently no native GDK UI element for scrolling a list using sensors (in fact, according to this issue, use of ListView at all appears to be discouraged).
However, I was able to get the following to work reasonably well in my app. My list is fixed at 4 elements (which helps determine how much scrolling happens), so you can tweak this accordingly (see comments).
import com.google.android.glass.media.Sounds;
import com.google.android.glass.touchpad.Gesture;
import com.google.android.glass.touchpad.GestureDetector;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.view.MotionEvent;
import android.widget.ListView;
/**
* Implements sensor-based scrolling of a ListView
*/
public class SensorListController implements SensorEventListener, GestureDetector.BaseListener {
static final String TAG = "SensorListController";
Context mContext;
ListView mList;
SensorManager mSensorManager;
private float[] mRotationMatrix = new float[16];
private float[] mOrientation = new float[9];
private float[] history = new float[2];
private float mHeading;
private float mPitch;
boolean mActive = true;
GestureDetector mGestureDetector;
public SensorListController(Context context, ListView list) {
this.mContext = context;
this.mList = list;
history[0] = 10;
history[1] = 10;
mGestureDetector = new GestureDetector(mContext);
mGestureDetector.setBaseListener(this);
}
/**
* Receive pass-through of event from View
*/
public boolean onMotionEvent(MotionEvent event) {
return mGestureDetector.onMotionEvent(event);
}
#Override
public boolean onGesture(Gesture gesture) {
switch (gesture) {
case TWO_LONG_PRESS:
// Toggle on and off accelerometer control of the list by long press
playSuccessSound();
toggleActive();
return true;
case TWO_TAP:
// Go to top of the list
playSuccessSound();
scrollToTop();
return true;
}
return false;
}
/**
* Should be called from the onResume() of Activity
*/
public void onResume() {
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
SensorManager.SENSOR_DELAY_UI);
}
/**
* Should be called from the onPause() of Activity
*/
public void onPause() {
mSensorManager.unregisterListener(this);
}
/**
* Toggles whether the controller modifies the view
*/
public void toggleActive() {
mActive = !mActive;
}
#Override
public void onSensorChanged(SensorEvent event) {
if (mList == null || !mActive) {
return;
}
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X,
SensorManager.AXIS_Z, mRotationMatrix);
SensorManager.getOrientation(mRotationMatrix, mOrientation);
mHeading = (float) Math.toDegrees(mOrientation[0]);
mPitch = (float) Math.toDegrees(mOrientation[1]);
float xDelta = history[0] - mHeading; // Currently unused
float yDelta = history[1] - mPitch;
history[0] = mHeading;
history[1] = mPitch;
float Y_DELTA_THRESHOLD = 0.13f;
// Log.d(TAG, "Y Delta = " + yDelta);
int scrollHeight = mList.getHeight()
/ 19; // 4 items per page, scroll almost 1/5 an item
// Log.d(TAG, "ScrollHeight = " + scrollHeight);
if (yDelta > Y_DELTA_THRESHOLD) {
// Log.d(TAG, "Detected change in pitch up...");
mList.smoothScrollBy(-scrollHeight, 0);
} else if (yDelta < -Y_DELTA_THRESHOLD) {
// Log.d(TAG, "Detected change in pitch down...");
mList.smoothScrollBy(scrollHeight, 0);
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private void scrollToTop() {
mList.smoothScrollToPosition(0);
}
private void playSuccessSound() {
// Play sound to acknowledge action
AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
audio.playSoundEffect(Sounds.SUCCESS);
}
}
I used the above in a ListActivity. I initialize it in onCreate(), and here is the method that initializes it:
private void initListController() {
mListView = getListView();
mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
mListView.setSelector(android.R.color.transparent);
mListView.setClickable(true);
mListController = new SensorListController(this, mListView);
}
This also removes the selection indicator from view by making it transparent.
The above controller also uses two finger press to pause/resume scrolling, and a two finger tap to scroll to the top of the list (and acknowledges both these actions with a sound). Note that for these gestures to work, you will need to override onGenericMotionEvent() in your Activity and pass through the event, like:
#Override
public boolean onGenericMotionEvent(MotionEvent event) {
// We need to pass events through to the list controller
if (mListController != null) {
return mListController.onMotionEvent(event);
}
return false;
}
Full source code for this solution can be seen on Github, and the APK can be downloaded here.
I'm new to iphone development but I have done android before. The following is something I have done in java and I want to convert this over to iphone.
public class RelationshipTipsActivity extends Activity implements
OnClickListener {
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private GestureDetector gestureDetector;
View.OnTouchListener gestureListener;
String facts[] = {"Coming soon",
"Coming soon", };
TextView display, display1;
TextView counter;
Button begin;
Button next;
Button previous;
Button random;
Random myRandom;
int index = facts.length;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(starting.rt.R.layout.relationship);
AdView ad = (AdView) findViewById(R.id.ad);
ad.loadAd(new AdRequest());
display1 = (TextView) findViewById(starting.rt.R.id.Begin);
display = (TextView) findViewById(starting.rt.R.id.tvResults);
counter = (TextView) findViewById(starting.rt.R.id.tvCounter);
next = (Button) findViewById(starting.rt.R.id.Next);
previous = (Button) findViewById(starting.rt.R.id.Previous);
random = (Button) findViewById(starting.rt.R.id.Random);
next.setOnClickListener(this);
previous.setOnClickListener(this);
random.setOnClickListener(this);
// display.setOnTouchListener(this.gestureListener);
myRandom = new Random();
// gestureDetector = new GestureDetector(new MyGestureDetector());
// gestureListener = new View.OnTouchListener() {
// public boolean onTouch(View v, MotionEvent event) {
// return gestureDetector.onTouchEvent(event);
// }
// };
}
private void showDisplay() {
display.setText(facts[index]);
counter.setText(String.valueOf(index + 1) + "/"
+ String.valueOf(facts.length));
}
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId()) {
case starting.rt.R.id.Next:
index++;
if (index > facts.length - 1) {
index = 0;
}
showDisplay();
break;
case starting.rt.R.id.Previous:
index--;
if (index < 0) {
index = facts.length - 1;
}
showDisplay();
break;
case starting.rt.R.id.Random:
index = (myRandom.nextInt(facts.length) - 1);
if (index < 0) {
index = facts.length - 1;
}
showDisplay();
break;
}
}
}
How would you convert something along the lines of that code from android to iphone.
I have this code so far for iphone, I just don't know where to go from there.
(IBAction) clicked:(id)sender{
NSArray *titleOfButton = [sender titleForState:UIControlStateNormal];
//NSString *newLabelText = [[NSString alloc]initWithFormat:#"%#", titleOfButton];
NSArray *initializedNSArray = [NSArray arrayWithObjects: #"red",
#"blue",
#"green",
#"yellow",
nil];
labelsText.text = initializedNSArray;
[initializedNSArray release];
}
I want to be able to display those strings within the Iphone View. And be able to click a next or previous button to go to the next or previous string which could be from blue to red or red to blue. Basically if there are any tutorials out there that help me with that or if you know how to help I would appreciate. Thanks!
Why not have a int variable with the current position of the string from the array and two methods goPrev - goNext that increments and decrements the int variable.
In the interface:
UIButton *btn;
int step;
NSArray *titles;
And in the implementation:
-(void)setup {
titles = [NSArray arrayWithObjects:#"Title 1",#"Title 2",#"Title 3",#"Title 4", nil];
btn = [UIButton buttonWithType:UIButtonTypeCustom];
}
-(void)goPrev {
if (step>0) {
step--;
}
[btn setTitle:[titles objectAtIndex:step] forState:UIControlStateNormal];
}
-(void)goNext {
if (step<titles.count-1) {
step++;
}
[btn setTitle:[titles objectAtIndex:step] forState:UIControlStateNormal];
}
I'm trying to write an OO menu system for a game, loosely based on the idea of a Model,View,Controller. In my app so far I've named the views "renderers" and the models are without a suffix. I created a generic menu class which stores the items of a menu, which are menu_item objects, and there is also a menu renderer class which creates renderers for each item and renders them. The problem is I'm not sure where to store the data and logic to do with where on the screen each item should be positioned, and how to check if it is being hovered over, etc. My original idea was to store and set a selected property on each menu item, which could be rendered differently by different views, but even then how to I deal with positioning the graphical elements that make up the button?
Code excerpts so far follow: (more code at https://gist.github.com/3422226)
/**
* Abstract menu model
*
* Menus have many items and have properties such as a title
*/
class menu {
protected:
std::string _title;
std::vector<menu_item*> _items;
public:
std::string get_title();
void set_title(std::string);
std::vector<menu_item*> get_items();
};
class menu_controller: public controller {
private:
menu* _menu;
public:
menu_controller(menu*);
virtual void update();
};
class menu_item {
protected:
std::string _title;
public:
menu_item(std::string title);
virtual ~menu_item();
std::string get_title();
};
class menu_renderer: public renderer {
private:
menu* _menu;
bitmap _background_bitmap;
static font _title_font;
std::map<menu_item*, menu_item_renderer*> _item_renderers;
public:
menu_renderer(menu*);
virtual void render();
};
font menu_renderer::_title_font = NULL;
menu_renderer::menu_renderer(menu* menu) {
_menu = menu;
_background_bitmap = ::load_bitmap("blackjack_menu_bg.jpg");
if (!_title_font)
_title_font = ::load_font("maven_pro_regular.ttf",48);
}
void menu_renderer::render() {
::draw_bitmap(_background_bitmap, 0, 0);
/* Draw the menu title */
const char* title = _menu->get_title().c_str();
int title_width = ::text_width(_title_font, title);
::draw_text(title, color_white, _title_font, screen_width() - title_width - 20, 20);
/* Render each menu item */
std::vector<menu_item*> items = _menu->get_items();
for (std::vector<menu_item*>::iterator it = items.begin(); it != items.end(); ++it) {
menu_item* item = *it;
if (!_item_renderers.count(item))
_item_renderers[item] = new menu_item_renderer(item, it - items.begin());
_item_renderers[item]->render();
}
}
class menu_item_renderer: public renderer {
private:
unsigned _order;
menu_item* _item;
static font _title_font;
public:
menu_item_renderer(menu_item*, unsigned);
virtual ~menu_item_renderer();
virtual void render();
};
font menu_item_renderer::_title_font = NULL;
menu_item_renderer::menu_item_renderer(menu_item* item, unsigned order) {
_item = item;
_order = order;
if (!_title_font)
_title_font = ::load_font("maven_pro_regular.ttf",24);
}
menu_item_renderer::~menu_item_renderer() {
// TODO Auto-generated destructor stub
}
void menu_item_renderer::render() {
const char* title = _item->get_title().c_str();
int title_width = ::text_width(_title_font, title);
unsigned y = 44 * _order + 20;
::fill_rectangle(color_red, 20, y, title_width + 40, 34);
::draw_text(title, color_white, _title_font, 30, y + 5);
}
Your Model class menu needs a add_view(menuview *v) and update() method.
Then you can delegate the update of your widget to the derived View (menu_renderer or a cli_menu_renderer).
The Controller needs to know the Model (as member), when the Controller runs (or executes a Command) and has to update the Model with a Setter (like m_menu_model->set_selected(item, state)) and the Model calls update() on Setters.
Your Controller menu_controller has a update method, there you could also ask for Input, like if (menuview->toggle_select()) m_menu_model->toggle_selected(); (which all menuviews have to implement) and invoke the setter, but thats a inflexible coupling of View and Controller (you could check MVC with the Command Pattern for a more advanced combination).
For the Position you can set member vars like int m_x, m_y, m_w, m_h.
But these members are specific to a View with GUI, so only the derived View needs them.
Then you could use these values to compare against mouse Positions and use a MouseOver Detection Method like this:
// View menu_item
bool menu_item::over()
{
if (::mouse_x > m_x
&& ::mouse_x < m_x + m_w
&& ::mouse_y > m_y
&& ::mouse_y < m_y + m_h) {
return true;
}
return false;
}
// update on gui menu item
bool menu_item::update()
{
if (over()) {
m_over = true;
}
else {
m_over = false;
}
// onclick for the idea
if ((::mouse_b & 1) && m_over) {
// here you could invoke a callback or fire event
m_selected = 1;
} else {
m_selected = 0;
}
return m_selected;
}
// update the command line interface menu item
bool cli_menu_item::update()
{
if ((::enterKeyPressed & 1) && m_selected) {
// here you could invoke a callback or fire event
m_selected = 1;
} else {
m_selected = 0;
}
return m_selected;
}
void menu_item_renderer::render() {
// update widgets
_item->update();
// ...
}
// Model
void menu::add_view(menuview *v) {
m_view=v;
}
void menu::update() {
if (m_view) m_view->update();
}
bool menu::set_selected(int item, int state) {
m_item[index]=state;
update();
}