I'm a beginner that just followed cocos2d-x's native tutorials and I am faced with a huge wall!
This is my error:
>c:\cocos2d-2.0-x-2.0.3\cocos2dsimplegame\classes\helloworldscene.cpp(86): error C2440: 'type cast' : cannot convert from 'void (__thiscall HelloWorld::* )(cocos2d::CCTime)' to 'cocos2d::SEL_SCHEDULE'
>Pointers to members have different representations; cannot cast between them
My cpp file:
#include "HelloWorldScene.h"
using namespace cocos2d;
CCScene* HelloWorld::scene()
{
CCScene * scene = NULL;
do
{
// 'scene' is an autorelease object
scene = CCScene::create();
CC_BREAK_IF(! scene);
// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
CC_BREAK_IF(! layer);
// add layer as a child to scene
scene->addChild(layer);
} while (0);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
bool bRet = false;
_targets = CCArray::create();
_projectiles = CCArray::create();
do {
////////////////////
// super init first
////////////////////
if ( !CCLayerColor::initWithColor( ccc4(255, 255, 255, 255) ) )
{
return false;
}
////////////////////
// add your codes below..
////////////////////
// 1. Add a menu item with "X" image, which is clicked to quit the program.
// Create a "close" menu item with close icon, it's an auto release object.
CCMenuItemImage *pCloseItem = CCMenuItemImage::itemWithNormalImage(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
CC_BREAK_IF(! pCloseItem);
// Place the menu item bottom-right conner.
pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));
//Create a menu with the "close" menu item, it's an auto release object.
CCMenu* pMenu = CCMenu::menuWithItems(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
CC_BREAK_IF(! pMenu);
//Add the menu to HelloWorld layer as a child layer.
this->addChild(pMenu, 1);
//////////////////////
// 2. add your codes below...
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCSprite *player = CCSprite::spriteWithFile("Player.png", CCRectMake(0, 0, 27, 40));
player->setPosition(ccp(player->getContentSize().width/2, winSize.height/2));
this->addChild(player);
bRet = true;
} while (0);
// Call game logic about every second
this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0);
// You can shoot the bullet
this->setTouchEnabled(true);
this->schedule( schedule_selector(HelloWorld::update) );
return bRet;
}
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
// "close" menu item clicked
CCDirector::sharedDirector()->end();
}
void HelloWorld::addTarget()
{
CCSprite *target = CCSprite::spriteWithFile("Target.png", CCRectMake(0, 0, 27, 40));
// Determine where to spawn the target along the Y axis
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
int minY = target->getContentSize().height/2;
int maxY = winSize.height - target->getContentSize().height/2;
int rangeY = maxY - minY;
// srand( TimGetTicks() );
int actualY = ( rand() % rangeY ) + minY;
// Create the target slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated
target->setPosition( ccp(winSize.width + (target->getContentSize().width/2), actualY) );
this->addChild(target);
// Determine speed of the target
int minDuration = (int)2.0;
int maxDuration = (int)4.0;
int rangeDuration = maxDuration - minDuration;
// srand( TimGetTicks() );
int actualDuration = ( rand() % rangeDuration ) + minDuration;
// Create the actions
CCFiniteTimeAction* actionMove = CCMoveTo::actionWithDuration( (float)actualDuration, ccp(0 - target->getContentSize().width/2, actualY) );
CCFiniteTimeAction* actionMoveDone = CCCallFuncN::actionWithTarget( this, callfuncN_selector(HelloWorld::spriteMoveFinished) );
target->runAction( CCSequence::actions( actionMove, actionMoveDone, NULL) );
// Add to targets array
target->setTag(1);
_targets->addObject(target);
}
void HelloWorld::spriteMoveFinished(CCNode* sender)
{
CCSprite *sprite = (CCSprite *)sender;
this->removeChild(sprite, true);
if (sprite->getTag() == 1) // target
{
_targets->removeObject(sprite);
}
else if (sprite->getTag() == 2) // projectile
{
_projectiles->removeObject(sprite);
}
}
void HelloWorld::gameLogic(float dt)
{
this->addTarget();
}
void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
{
// Choose one of the touches to work with
CCTouch* touch = (CCTouch*)( touches->anyObject() );
CCPoint location = touch->locationInView();
location = CCDirector::sharedDirector()->convertToGL(location);
// Set up initial location of projectile
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCSprite *projectile = CCSprite::spriteWithFile("Projectile.png", CCRectMake(0, 0, 20, 20));
projectile->setPosition( ccp(20, winSize.height/2) );
// Determine offset of location to projectile
int offX = location.x - projectile->getPosition().x;
int offY = location.y - projectile->getPosition().y;
// Bail out if we are shooting down or backwards
if (offX <= 0) return;
// OK to add now - we've double checked position
this->addChild(projectile);
// Determine where we wish to shoot the projectile to
int realX = winSize.width + (projectile->getContentSize().width/2);
float ratio = (float)offY / (float)offX;
int realY = (realX * ratio) + projectile->getPosition().y;
CCPoint realDest = ccp(realX, realY);
// Determine the length of how far we're shooting
int offRealX = realX - projectile->getPosition().x;
int offRealY = realY - projectile->getPosition().y;
float length = sqrtf((offRealX * offRealX) + (offRealY * offRealY));
float velocity = 480/1; // 480pixels/1sec
float realMoveDuration = length/velocity;
// Move projectile to actual endpoint
projectile->runAction( CCSequence::actions( CCMoveTo::actionWithDuration(realMoveDuration, realDest), CCCallFuncN::actionWithTarget(this, callfuncN_selector(HelloWorld::spriteMoveFinished)), NULL) );
// Add to projectiles array
projectile->setTag(2);
_projectiles->addObject(projectile);
}
void HelloWorld::update(CCTime dt)
{
CCArray *projectilesToDelete = CCArray::create();
CCObject* arrayItem1;
CCARRAY_FOREACH(_projectiles, arrayItem1)
{
CCSprite* projectile = (CCSprite*)arrayItem1;
CCRect projectileRect = CCRectMake(
projectile->getPosition().x - (projectile->getContentSize().width/2),
projectile->getPosition().y - (projectile->getContentSize().height/2),
projectile->getContentSize().width,
projectile->getContentSize().height);
CCArray* targetsToDelete = CCArray::create();
CCObject* arrayItem2;
CCARRAY_FOREACH(_targets, arrayItem2)
{
CCSprite* target = (CCSprite*) arrayItem2;
CCRect targetRect = CCRectMake(
target->getPosition().x - (target->getContentSize().width/2),
target->getPosition().y - (target->getContentSize().height/2),
target->getContentSize().width,
target->getContentSize().height);
if (CCRect::CCRectIntersectsRect(projectileRect, targetRect))
{
targetsToDelete->addObject(target);
}
}
CCARRAY_FOREACH(targetsToDelete, arrayItem2)
{
CCSprite* target = (CCSprite*) arrayItem2;
_targets->removeObject(target);
this->removeChild(target, true);
}
if (targetsToDelete->count() > 0)
{
projectilesToDelete->addObject(projectile);
}
targetsToDelete->release();
}
CCARRAY_FOREACH(projectilesToDelete, arrayItem1)
{
CCSprite* projectile = (CCSprite*) arrayItem1;
_projectiles->removeObject(projectile);
this->removeChild(projectile, true);
}
projectilesToDelete->release();
}
Maybe this part is a problem:
bool HelloWorld::init()
{
....
this->schedule( schedule_selector(HelloWorld::update) );
....
}
But I don't understand why this part is a problem.
Please, help me!
change CCTime to float.
in old cocos2d-x version, they have ccTime instead of CCTime
but in 2.0 they remove it. since it is duplicated with float.
Related
I am in a project where map and other information are displayed in a Gtk window. There are several map layers, that I draw into a Cairo surface and save in a .png (plotRect() function in code below). That .png is displayed in a Gtk image when there is a Gtk draw signal (draw()).
I now want to accomplish smooth grabbing and panning. When the mouse button is pressed, I want the whole image to be translated within the window area, follow the movements of the mouse. When the button is released the image should be Cairo remade and redrawn with new bounds. During the drag/pan procedure itself there is no need to draw areas that where previously out of the window borders -- it is OK to wait for that to be done when the mouse button is released.
Enclosed you find a simplified version of my code. The main has a loop going until the windows is closed, redrawing the image after each panning. The problem is in the pan() function. After the translation in line 21 I woould expect the draw statement in line 128 to successively draw panned images while moving the mouse, but the visible image is unaffected. Uncommenting line 23 shows that graph->image has really been modified, and I can see that the draw signal of line 25 is invoking the draw() callback function. After button release, the translated image is correctly displayed.
Can anyone please give me some advice?
I'm using gcc, Cairo, Gtk3 and Ubuntu 18.04 on a double-booted MacBook Pro 64 bit i5.
#include <cairo.h>
#include <chrono>
#include <cmath>
#include <gtk/gtk.h>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
mutex mtx;
bool gtkMainLoopRunning = false;
#define SLEEP(d) this_thread::sleep_for(chrono::milliseconds(d))
template <class T>
inline T sqr(T x) {
return x * x;
}
//-----------------------------------------------------------------------------
class Graph {
double toplat, leftlon; // upper left corner
double dydlat, dxdlon; // pixels / degree lon/lat
public:
int size; // window x = y
GtkWidget *window;
GtkImage *image;
const char *png = "/tmp/image.png";
cairo_surface_t *surface{};
cairo_t *cr{};
bool closed = false;
bool leftbuttondown = false;
int mousex = 0, mousey = 0;
Graph(const double, const double, const double, const double);
~Graph();
void plotRect(const double, const double, const double, const double);
bool pan();
};
//-----------------------------------------------------------------------------
static gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data) {
Graph *graph = (Graph *)data;
if (!graph->leftbuttondown) {
mtx.lock();
gtk_image_set_from_file(graph->image, graph->png);
mtx.unlock();
}
return FALSE;
}
//-----------------------------------------------------------------------------
static gboolean clicked(GtkWidget *widget, GdkEventButton *button, gpointer data) {
Graph *graph = (Graph *)data;
if (button->button == 1) {
if (button->type == GDK_BUTTON_PRESS) {
graph->leftbuttondown = true;
} else if (button->type == GDK_BUTTON_RELEASE) {
graph->leftbuttondown = false;
}
}
graph->mousex = button->x;
graph->mousey = button->y;
return FALSE;
}
//-----------------------------------------------------------------------------
Graph::~Graph() {
do {
SLEEP(100);
} while (gtkMainLoopRunning); // wait until gtk main loop has stopped
cairo_destroy(cr);
cairo_surface_destroy(surface);
}
//-----------------------------------------------------------------------------
void destroyWindow(GtkWidget *widget, gpointer data) {
gtk_main_quit();
gtkMainLoopRunning = false;
Graph *graph = (Graph *)data;
graph->closed = true; // signal gtkThread to finish
gtk_widget_destroy((GtkWidget *)graph->image);
gtk_widget_destroy(graph->window);
}
//-----------------------------------------------------------------------------
Graph::Graph(const double minlat, const double minlon, const double maxlat, const double maxlon) {
gtk_init(NULL, NULL);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
size = 800;
gtk_widget_show(window);
image = (GtkImage *)gtk_image_new();
gtk_widget_set_size_request((GtkWidget *)image, size, size);
gtk_container_add(GTK_CONTAINER(window), (GtkWidget *)image);
gtk_widget_show((GtkWidget *)image);
g_signal_connect(image, "draw", G_CALLBACK(draw), this);
g_signal_connect(window, "destroy", G_CALLBACK(destroyWindow), this);
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, size, size);
cr = cairo_create(surface);
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON1_MOTION_MASK);
g_signal_connect(window, "button-press-event", G_CALLBACK(clicked), this);
g_signal_connect(window, "button-release-event", G_CALLBACK(clicked), this);
g_signal_connect(window, "motion-notify-event", G_CALLBACK(clicked), this);
const double coslat = cos((minlat + maxlat) / 2 * M_PI / 180);
const double extension = max(maxlat - minlat, (maxlon - minlon) * coslat); // [lat degrees]
toplat = (minlat + maxlat + extension) / 2;
leftlon = (minlon + maxlon - extension / coslat) / 2;
dydlat = -size / extension; // [pixels/degree]
dxdlon = size / extension * coslat;
gtkMainLoopRunning = true;
thread(gtk_main).detach();
}
//-----------------------------------------------------------------------------
bool Graph::pan() {
const int sqrSignifPan = sqr(4);
while (!closed) {
if (leftbuttondown) {
int x0 = mousex;
int y0 = mousey;
int dx = 0, dy = 0;
GdkPixbuf *origPixbuf = gdk_pixbuf_new_from_file("/tmp/image.png", NULL);
char *origPixels = (char *)gdk_pixbuf_get_pixels(origPixbuf);
const int rowstride = gdk_pixbuf_get_rowstride(origPixbuf);
const int nChannels = gdk_pixbuf_get_n_channels(origPixbuf);
char *imagePixels = (char *)gdk_pixbuf_get_pixels(gtk_image_get_pixbuf(image));
while (leftbuttondown) {
const int dx0 = dx, dy0 = dy;
dx = mousex - x0, dy = mousey - y0;
if (sqr(dx - dx0) + sqr(dy - dy0) >= sqrSignifPan) {
const int minx = max(0, -dx);
const int nx = max(0, size - abs(dx));
if (nx > 0) {
for (int y = max(0, -dy); y < min(size, size - dy); ++y) {
memcpy(imagePixels + (y + dy) * rowstride + (minx + dx) * nChannels, origPixels + y * rowstride + minx * nChannels, nx * nChannels);
}
// gdk_pixbuf_save(gtk_image_get_pixbuf(image), "/tmp/imagePixbuf.png", "png", NULL, NULL);
gtk_widget_queue_draw((GtkWidget *)image);
SLEEP(10); // pause for drawing
}
}
SLEEP(100);
}
// rescale graph
toplat -= (mousey - y0) / dydlat;
leftlon -= (mousex - x0) / dxdlon;
dxdlon = -dydlat * cos((toplat + size / dydlat / 2) * M_PI / 180);
gtk_widget_queue_draw((GtkWidget *)image);
return true;
}
SLEEP(100);
}
return false;
}
//-----------------------------------------------------------------------------
void Graph::plotRect(const double minlat, const double minlon, const double maxlat, const double maxlon) {
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_paint(cr);
cairo_rectangle(cr, (minlon - leftlon) * dxdlon, (minlat - toplat) * dydlat, (maxlon - minlon) * dxdlon, (maxlat - minlat) * dydlat);
cairo_set_source_rgb(cr, 0, 1, 0);
cairo_fill(cr);
mtx.lock();
remove(png);
cairo_surface_write_to_png(surface, png);
mtx.unlock();
}
//-----------------------------------------------------------------------------
int main() {
const double minlat = 59, minlon = 16, maxlat = 60, maxlon = 18;
Graph *graph = new Graph(minlat - 0.5, minlon - 1, maxlat + 0.5, maxlon + 1);
do {
graph->plotRect(minlat, minlon, maxlat, maxlon);
} while (graph->pan());
delete graph;
}
I'am trying to build a simple game with a ball and target,
and I want to increse the score when the ball touch the target,
but the callback "onContactBegin" doesnt invoke.
There is a target("goal") in the button of the screen, and when the user touch the screen the ball created and start moving.
#include <string>
#include "HelloWorldScene.h"
#define COCOS2D_DEBUG 1
USING_NS_CC;
enum class PhysicsCategory {
None = 0,
Goal = (1 << 0),
Ball = (1 << 1),
All = PhysicsCategory::Goal | PhysicsCategory::Ball
};
Scene* HelloWorld::createScene()
{
auto scene = Scene::create();
auto layer = HelloWorld::create();
scene->addChild(layer);
return scene;
}
bool HelloWorld::init()
{
CCLOG("Init");
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
height = visibleSize.height;
width = visibleSize.width;
score = 0;
m_score_label = Label::createWithTTF(Itos(score), "fonts/Marker Felt.ttf", 24);
auto vSize = Director::getInstance()->getVisibleSize();
m_score_label->setPosition(Point(origin.x + vSize.width/2,
origin.y + vSize.height - m_score_label->getContentSize().height));
this->addChild(m_score_label, 1);
goal = Sprite::create("images.jpg");
goal->setPosition(Point((visibleSize.width / 2) + origin.x , (visibleSize.height / 6) + origin.y));
auto goalSize = goal->getContentSize();
auto physicsBody = PhysicsBody::createBox(Size(goalSize.width , goalSize.height),
PhysicsMaterial(0.1f, 1.0f, 0.0f));
physicsBody->setCategoryBitmask((int)PhysicsCategory::Goal);
physicsBody->setCollisionBitmask((int)PhysicsCategory::None);
physicsBody->setContactTestBitmask((int)PhysicsCategory::Ball);
goal->setPhysicsBody(physicsBody);
mySprite = Sprite::create("CloseNormal.png");
mySprite->setPosition(Point((visibleSize.width / 2) + origin.x , (visibleSize.height / 2) + origin.y));
this->addChild(mySprite);
this->addChild(goal);
CCScaleBy* action = CCScaleBy::create(3,5);
mySprite->runAction(action);
auto eventListener = EventListenerTouchOneByOne::create();
eventListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(eventListener, this);
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegan, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener, this);
return true;
}
bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event) {
cocos2d::Sprite * sp = Sprite::create("CloseNormal.png");
sp->setPosition(Point(touch->getLocation().x , touch->getLocation().y));
MoveTo *action = MoveTo::create(2, Point(width ,0) );
auto ballSize = sp->getContentSize();
auto physicsBody = PhysicsBody::createBox(Size(ballSize.width , ballSize.height),
PhysicsMaterial(0.1f, 1.0f, 0.0f));
physicsBody->setDynamic(true);
physicsBody->setCategoryBitmask((int)PhysicsCategory::Ball);
physicsBody->setCollisionBitmask((int)PhysicsCategory::None);
physicsBody->setContactTestBitmask((int)PhysicsCategory::Goal);
sp->setPhysicsBody(physicsBody);
sp->runAction( action );
this->addChild(sp);
return true;
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
return;
#endif
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
bool HelloWorld::onContactBegan(PhysicsContact &contact)
{
CCLOG("onContactBegan");
auto nodeA = contact.getShapeA()->getBody()->getNode();
auto nodeB = contact.getShapeB()->getBody()->getNode();
nodeA->removeFromParent();
nodeB->removeFromParent();
++score ;
m_score_label->setString(Itos(score));
return true;
}
std::string HelloWorld::Itos ( int num )
{
std::ostringstream ss;
ss << num;
return ss.str();
}
HelloWorld.cpp
Scene* HelloWorld::createScene() {
auto scene = Scene::createWithPhysics();
auto layer = HelloWorld::create();
layer->setPhysicsWorld(scene->getPhysicsWorld());
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
scene->addChild(layer);
return scene;
}
bool GameScene::didBeginContact(cocos2d::PhysicsContact &contact) {
PhysicsBody *bodyA = contact.getShapeA()->getBody();
PhysicsBody *bodyB = contact.getShapeB()->getBody();
}
HelloWorld.h
cocos2d::PhysicsWorld *physicsWorld;
void setPhysicsWorld(cocos2d::PhysicsWorld *withWorld) {physicsWorld = withWorld;};
bool didBeginContact(cocos2d::PhysicsContact &contact);
My dynamic body is not falling down after setting the world. It is not following the gravity. Even I apply force on the body it isn't work.
b2Vec2 gravity(0.0f, -9.8f);
b2World world(gravity);
//PineCone
class PineCone
{
private:
//Surface box
SDL_Rect box;
//Real position
float rX, rY;
//Velocity
float xVel, yVel;
//Physics world
b2World* world;
//Body
b2Body* pBodyPineCone;
public:
//Specify
void specify(int w, int h, SDL_Surface* source, SDL_Surface* dest, b2World* world);
//Input
void handle_input();
//Motion
void updatepos();
//void checkStanding(SDL_Rect env[], int N_SOLIDS);
//Render
void show();
};
void PineCone::specify(int w, int h, SDL_Surface* source, SDL_Surface* dest, b2World* world)
{
//Source
pPineCone = source;
//Destination
pScreen = dest;
// Define the dynamic pinecone. We set its position and call the body factory.
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
// Define a ball shape for our dynamic body.
b2CircleShape dynamicPineCone;
dynamicPineCone.m_p.Set(0, 0); //position, relative to body position
dynamicPineCone.m_radius = 0.5; //radius
// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicPineCone;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
// Add the shape to the body.
bodyDef.position.Set(0, 20);
pBodyPineCone = world->CreateBody(&bodyDef);
pBodyPineCone->CreateFixture(&fixtureDef);
}
void PineCone::show()
{
int blit = SDL_BlitSurface( pPineCone, NULL, pScreen, &box );
if( blit < 0 )
{
exit(1);
}
}
I am not sure if I missed something in Main.
int main(int argc, char *argv[])
{
B2_NOT_USED(argc);
B2_NOT_USED(argv);
// Prepare for simulation. Typically we use a time step of 1/60 of a
// second (60Hz) and 10 iterations. This provides a high quality simulation
// in most game scenarios.
float32 timeStep = 1.0f / 60.0f;
int32 velocityIterations = 6;
int32 positionIterations = 2;
// Start the timer
g_dwStartTicks = SDL_GetTicks();
init();
load_files();
//PineCone
PineCone myPineCone;
myPineCone.specify(g_iPineConeSize, g_iPineConeSize, pPineCone, pScreen, &world);
//
// The Main Game Loop
//
do
{
// Record the current time
g_dwStartTime = SDL_GetTicks();
//
// Handle they keyboard events here
//
while (SDL_PollEvent(&event) > 0)
{
if (event.type == SDL_QUIT)
{
// Quit event! (Window close, kill signal, etc.)
g_iLoopDone = TRUE;
}
}
world.Step(timeStep, velocityIterations, positionIterations);
myPineCone.handle_input();
if (g_bPlaying || g_bEnd)
{
//Show pinecone
myPineCone.show();
}
// Update the display
SDL_Flip(pScreen);
g_dwEndTime = SDL_GetTicks();
if (g_dwEndTime < g_dwStartTime + (1000 / 60))
{
SDL_Delay(g_dwStartTime + (1000 / 60) - g_dwEndTime);
}
}while (!g_iLoopDone);
//Clean Up
clean_up();
return 0;
}
I can think for example that the physical self is updating're not visualizing
what the Sprite (Image) not update the corresponding value of its physical body.
Try to give it a Box2D body position if the image does not move you do not
have to be the update of physics.
Try this:
void setL1b2SpritePosition(Point position)
{
pBodyPineCone->SetAwake (true);
pBodyPineCone->setPosition(position);
//update box2d
pBodyPineCone->SetTransform(
b2Vec2(position.x / PTM_RATIO, position.y/ PTM_RATIO),
_body->GetAngle());
}
void updatePhysics()
{
_world->Step(.1, 10, 10);
for (b2Body *b = _world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL)
{
Sprite *ballData = dynamic_cast<Sprite*> ((Sprite *) b->GetUserData());
ballData->setPosition(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
ballData->setRotation(-1 * CC_RADIANS_TO_DEGREES(b->GetAngle()));
}
}
}
i try to follow the cocose2d-x 2.2 Test file :
cocos2d-x-2.2\samples\Cpp\TestCpp\Classes\SchedulerTest\SchedulerTest.h
i implemented the slider control and i see it and the :
virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
function are triggerd just right when i try to slide
but its not sliding at all this is what i have :
the default close menu is working find :
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
origin.y + pCloseItem->getContentSize().height/2));
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 1);
bSliderCtlTouched = false;
this->setTouchEnabled(true);
this->schedule(schedule_selector(HelloWorld::tick));
return true;
}
void HelloWorld::tick(float dt)
{
;
}
void HelloWorld::onEnter()
{
CCLayer::onEnter();
CCSize s = CCDirector::sharedDirector()->getWinSize();
m_pSliderCtl = sliderCtl();
m_pSliderCtl->retain();
m_pSliderCtl->setPosition(ccp(s.width / 2.0f, s.height - (m_pSliderCtl->getContentSize().height*2)));
this->addChild(m_pSliderCtl,1);
}
CCControlSlider* HelloWorld::sliderCtl()
{
CCControlSlider * slider = CCControlSlider::create("extensions/sliderTrack2.png","extensions/sliderProgress2.png" ,"extensions/sliderThumb.png");
slider->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::sliderAction), CCControlEventValueChanged);
slider->setMinimumValue(-3.0f);
slider->setMaximumValue(3.0f);
slider->setValue(1.0f);
return slider;
}
void HelloWorld::sliderAction(CCObject* pSender, CCControlEvent controlEvent)
{
bSliderCtlTouched =true;
CCControlSlider* pSliderCtl = (CCControlSlider*)pSender;
float scale;
scale = pSliderCtl->getValue();
}
void HelloWorld::registerWithTouchDispatcher()
{
// higher priority than dragging
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this,0, true);
}
bool HelloWorld::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
if(bSliderCtlTouched)
CCLOGWARN("bSliderCtlTouched is true");
CCPoint touchLocation = touch->getLocation();
CCPoint location = convertToNodeSpace( touchLocation );
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
float screenSizeW = screenSize.width;
//CCLOGWARN("pos: %f,%f -> %f,%f", touchLocation.x, touchLocation.y, location .x, location .y);
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
float halfScreen = screenSize.width/2;
if(location.x <= halfScreen)
{
left = true;
right = false;
}
else
{
left = false;
right = true;
}
#ifdef MOUSEJOINT
return isNodeTouched(locationWorld);
#else
return true;
#endif
}
void HelloWorld::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
if (!bSliderCtlTouched)
{
return;
}
CCPoint touchLocation = touch->getLocation();
CCPoint location = convertToNodeSpace( touchLocation );
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
}
void HelloWorld::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
if(bSliderCtlTouched)
{
bSliderCtlTouched = false;
}
CCPoint touchLocation = touch->getLocation();
CCPoint nodePosition = convertToNodeSpace( touchLocation );
}
As far as your question was unanswered about 7 months, I will answer your question for the new version of cocos2d-x. This code works for cocos2d-x 3.0:
cocos2d::extension::ControlSlider* slider = cocos2d::extension::ControlSlider::create(
"images/buttons/container.png", "images/buttons/progress.png", "images/buttons/knob.png");
slider->setPosition(200, 200);
slider->setMinimumValue(0);
slider->setMaximumValue(10);
slider->setValue(3);
slider->addTargetWithActionForControlEvents(this, cccontrol_selector(IntroView::valueChangedCallback), cocos2d::extension::Control::EventType::VALUE_CHANGED);
addChild(slider);
void IntroView::valueChangedCallback(Ref* sender, cocos2d::extension::Control::EventType evnt)
{
float value = static_cast<cocos2d::extension::ControlSlider*>(sender)->getValue();
CCLOG(std::to_string(value).c_str());
}
Don't forget to #include "GUI/CCControlExtension/CCControlExtensions.h" and use libExtensions in your project.
How to animate a sprite while jumping?
i.e, moving the eyes or animating the sprite using CCAnimate
CCSpriteFrameCache.sharedSpriteFrameCache().addSpriteFrames("AnimBear.plist");
this._bear = CCSprite.sprite("bear1.png", true);
spritesheet1 = CCSpriteSheet.spriteSheet("AnimBear.png");
spritesheet1.addChild(_bear, 1);
addChild(spritesheet1, 1);
ArrayList<CCSpriteFrame> animFrames = new ArrayList<CCSpriteFrame>();
CCSpriteFrameCache.sharedSpriteFrameCache();
for (int i = 1; i <= 8; i++) {
CCSpriteFrame frame = CCSpriteFrameCache
.spriteFrameByName(
"bear" + i + ".png");
animFrames.add(frame);
}
CCAnimation anim = CCAnimation.animation("AnimBear", .175f,
animFrames);
_bear.setPosition(CGPoint.make(_bear.getContentSize().width, 50));
CCIntervalAction action=CCAnimate.action(0.1f, anim, false);
this.walkAction = CCRepeatForever.action(action);
_bear.runAction(walkAction);
and moving on touch
public boolean ccTouchesEnded(MotionEvent event) {
CGPoint touchLocation = CCDirector.sharedDirector().convertToGL(
CGPoint.make(event.getX(), event.getY()));
float bearVelocity = 480.0f/3.0f;
CGPoint moveDifference = CGPoint.ccpSub(touchLocation, _bear.getPosition());
float distanceToMove = CGPoint.ccpLength(moveDifference);
float moveDuration = distanceToMove / bearVelocity;
if (moveDifference.x < 0) {
_bear.flipX_= false;
} else {
_bear.flipX_ = true;
}
_bear.stopAction(moveAction);
if (!_moving) {
_bear.runAction(walkAction);
}
CCMoveTo actionMove=CCMoveTo.action(moveDuration, touchLocation);
CCCallFuncN actionMoveDone1 = CCCallFuncN.action(this, "bearMoveEnded");
CCSequence actions = CCSequence.actions(actionMove, actionMoveDone1);
_bear.stopAllActions();
this.moveAction = actions;
_bear.runAction(moveAction);
_moving = true;
return CCTouchDispatcher.kEventHandled;
}
In this animation complete first and after this if you touch on the screen then the activity you want it'll happen.....
If you want the animation n move the sprite simultaneously, complete your all code in the
public boolean ccTouchesEnded(MotionEvent event) {
}