I implemented the EZAudioPlotGL in about 4 different view controllers. At times only the top part of it is showing , even though shouldMirror is set to YES at all times. Any Suggestions ?
I have used "EZAudioPlot.h" class rather than "EZAudioPlotGL.h". which resolves issue of inconsistent wave form and works same as "EZAudioPlotGL.h"
and implemented clear method in "EZAudioPlot.m" class because it does not have implementation or clear method.
-(void)clear
{
float empty[_changingHistorySize];
// Figure out better way to do this
for(int i = 0; i < _changingHistorySize; i++ )
{
empty[i] = 0.0f;
}
for(int i = 0; i < _scrollHistoryLength; i++)
{
_scrollHistory[i] = 0.0f;
}
_scrollHistoryIndex = 0;
[self setSampleData:_scrollHistory
length:(!_setMaxLength?kEZAudioPlotMaxHistoryBufferLength:_scrollHistoryLength)];
}
Related
I have a level select screen similar to candy crush's (a path of levels) where I plan to have more than 100 levels. When I load this many levels in one go, the time to create and load all of these levels is ~0.17 seconds. Now this is clearly much too long to wait after a user presses a button to go to the level. The game appears to freeze for a bit, then it finally goes.
Now I've been looking at a few different solutions to this. The one solution which I could revert to as a last resort is creating some sort of transition that temporarily shows a loading screen, then goes to the level select screen. It would be nice to bypass this loading all together though.
Currently my level select screen is a normal CCNode class with a scrollview on it. This means it is not a singleton, and every single time I go to it, a new instance loads. The nice thing about this is that I can constantly update whether or not someone has beaten a level, and change the color and ability to play the next level (is it possible to make this kind of update in a singleton class?). A singleton seems like the best approach to me (then I would just load in while the game loads at the beginning), but I'm not sure if the answer to my above question is yes. If someone has experience with this, please let me know!
I'm not really sure what else I could try to do. The only other good option seems to be somehow speeding up my code, but I'm not sure how I could do that (posted below). The last resort would be creating an instance of this class while my game loads, then just hide all user interaction on it whenever I don't want it to be showing. Idk though, that sounds a little sketch. Thanks for the advice, and here is my code creating the buttons.
-(void)didLoadFromCCB{
buttonArray = [NSMutableArray array];
CFTimeInterval startTime = CACurrentMediaTime();
CCSpriteFrame *redTile = [CCSpriteFrame frameWithImageNamed:#"Sprites/glossyTile.png"];
for (int l = 0; l < NUMBER_OF_WORLDS; l++) { //NUMBER_OF_WORLDS = 10
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 5; k++) {
NSString *tempTitle = [NSString stringWithFormat:#"%i",(k+1)+(l*5)];
tempButton = [CCButton buttonWithTitle:tempTitle
spriteFrame:redTile
highlightedSpriteFrame:redTile
disabledSpriteFrame:nil];
tempButton.block = ^(id sender) {
CCNode *transitionScene = [CCBReader load:#"TransitionScene"];
[self addChild:transitionScene];
int row = k+1;
int column = j+1;
int buttonIndex = (row + (column-1)*5) + l*20;
for (int m = 1; m < buttonIndex; m++) {
[[LevelManager sharedInstance] nextLevel];
}
levelNumber = i;
[self performSelector:#selector(changeScenes) withObject:nil afterDelay:8.0/30.0
];
};
tempButton.position = ccp(someConstant*j, someConstant2*k + someConstant3*l);
[self addChild:tempButton];
i++;
}
}
}
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime;
CCLOG(#"time interval media %f", elapsedTime); //logs about 0.17 seconds
}
The only way I can think to do it is to check velocities for all physics bodies during every collisions.
- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair piece:(CCNode *)pieceA piece:(CCNode *)pieceB{
float x = 0;
float y = 0;
for (int i = 0; i < [[_physicsWorld children] count]; i++) {
x = x + [[[_physicsWorld children][i] physicsBody] velocity].x;
y = y + [[[_physicsWorld children][i] physicsBody] velocity].y;
}
if ( x == 0 && y == 0 ) {
NSLog(#"stopped");
}
return YES;
}
This logs “stopped” multiple times when the scene first loads, then doesn’t log “stopped” again, even after physics bodies have clearly started moving and colliding and then come to a stop.
Ideally I'd like a delegate method that would notify me when all physics bodies have stopped moving, but I can't seem to find one.
FYI: I'm using the standard Chipmunk physics engine that's baked into Cocos2d V3.0
Chipmunk has a internal mechanism, which can, if activated, automatically deactivate physics bodies. My approach (I am using cocos2dx 3.11.1 and not -obj version with chipmunk 7.0.1) is:
activate the chipmunk idle mechanism (0.5 second - meaning, if an object is not moving for longer than 0.5 second it will be deactivated):
cpSpaceSetSleepTimeThreshold(space, 0.5f);
You do not need to use
cpSpaceSetIdleSpeedThreshold(space, <speed>);
because chipmunk calculates the threshold speed for you (according the gravitation used).
use this code for determination if all objects are not moving (static and kinetic bodies never sleep):
bool isAnyPhysicsBodyMoving(){
int i = 0; bool isMoving = false;
const Vector<PhysicsBody*>& bodies = getPhysicsWorld()->getAllBodies();
while( i < bodies.size() && !isMoving){
PhysicsBody *body = bodies.at(i);
isMoving = cpBodyGetType(body->getCPBody()) == CP_BODY_TYPE_DYNAMIC
&& !body->isResting();
i++;
}
return isMoving;
}
use static (and not kinetic) body for walls, in order to let objects sleep:
// wall
Size visibleSize = Director::getInstance()->getWinSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
float border = 10.0f;
Size wallBodySize = Size(visibleSize.width+2*border, visibleSize.height+2*border);
PhysicsBody *wallBody = PhysicsBody::createEdgeBox(wallBodySize, PhysicsMaterial(1.0f, 1.0f, 0.5f), border);
Node* wall = Node::create();
wall->addComponent(wallBody);
wall->setAnchorPoint(Vec2(0.5f, 0.5f));
wall->setPosition(Point(visibleSize.width/2+origin.x, visibleSize.height/2+origin.y));
cpVect tt;
tt.x = wall->getPosition().x; tt.y = wall->getPosition().y;
//set position manually and BEFORE adding the object into the space
cpBodySetPosition(wallBody->getCPBody(), tt);
cpBodySetType(wallBody->getCPBody(), CP_BODY_TYPE_STATIC);
addChild(wall);
Any dynamic body connected to a kinetic body (for example laying on) will never sleep.
test it with DEBUG activated
getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
the boxes (their content) must become grey (=sleeping) and not red (=active):
In order to let it work, I have:
added an access method (to get cpSpace) in CCPhysicsWorld.h:
inline cpSpace* getSpace() const { return _cpSpace; }
Fix call of
cpBodySetTorque(body, 0.0f);`
in CCPhysicsBody.cpp to
if (body->t != 0.0f){
cpBodySetTorque(body, 0.0f);
}
Fix call of
cpBodySetPosition(_cpBody, tt);`
in CCPhysicsBody.cpp to
if (!cpveql(tt, cpBodyGetPosition(_cpBody))){
cpBodySetPosition(_cpBody, tt);
}
Steps 2. and 3. are necessary to avoid setting of the same physics body properties, which wake up a sleeping body.
The advantage of this approach is, that the chipmunk does not make any calculations for such physical bodies - saving CPU and battery.
I found something that works.
tl;dr
The basic idea is to keep track of the positions of the sprites myself, and then periodically check them to see if any of them have moved since they were last checked.
Longer version
I created a subclass of CCNode with the class name Piece.
These are my objects that are added to the physics world.
#implementation Piece {
float _previousX;
float _previousY;
}
-(void)updatePreviousScreenXandY{
_previousX = self.position.x;
_previousY = self.position.y;
}
-(BOOL)hasntMoved{
float currentX = self.position.x;
float currentY = self.position.y;
if ( currentX == _previousX && currentY == _previousY ) {
return TRUE;
}else{
return FALSE;
}
}
This is in my CCNode that acts as the game scene
-(void)doStuffAfterPiecesStopMoving:(NSTimer*)timer{
BOOL noPiecesHaveMoved = TRUE;
for (int i = 0; i < [[_physicsWorld children] count]; i++) {
if ( [[_physicsWorld children][i] hasntMoved] == FALSE ) {
noPiecesHaveMoved = FALSE;
break;
}
}
if ( noPiecesHaveMoved ) {
[timer invalidate];
NSLog(“Pieces have stopped moving”);
}else{
NSLog(“Pieces are still moving”);
[self updateAllPreviousPiecePositions];
}
}
-(void)updateAllPreviousPiecePositions{
for (int i=0; i < [[_physicsWorld children] count]; i++) {
Piece *piece = (Piece*)[_physicsWorld children][i];
[piece updatePreviousScreenXandY];
}
}
All I have to do is
[NSTimer scheduledTimerWithTimeInterval:TIME_BETWEEN_CHECKS
target:_gamePlay
selector:#selector(doStuffAfterPiecesStopMoving:)
userInfo:nil
repeats:YES];
and it’ll run whatever code I want after all Piece nodes have stopped moving.
The key to getting it to work well is to get the values for the Chipmunk space’s sleepTimeThreshold and the timer above’s time as low as possible.
My experimenting suggests the following settings work okay, but anything lower will cause problems (i.e. collisions not taking place properly):
sleepTimeThreshold = 0.15
my timer = 0.05
If anyone has a different/better solution or improvements to the above code, please post.
I'm trying to manually change every pixel in a Mat.
For simplicity reasons, let's say I want to color each pixel black. I'm using the following method:
for (int i = 0; i < imageToWorkWith.rows; i++) {
for (int j = 0; j < imageToWorkWith.cols; j++) {
imageToWorkWith.at<cv::Vec3b>(i,j) = cv::Vec3b(0,0,0);
}
}
Logically, it seems like this should go over every pixel in the mat, as it reads all the possible combinations of row/col.
Unfortunately, this doesn't work. For every image, I'm missing a "chunk" of columns. For example, when loading this image:
The result is this:
This "chunk" I'm missing is the same size, no matter what image I use. I can't seem to understand the reason for that. I know that the order of row/col for the "at" function is (row, col), but i tried switching them just for kicks, and the result of course is even worse.
What am I missing here? is looping over all rows/cols not enough?
Just use Vec4b instead of Vec3b as the image by default is having 4 channels in ios. The result will be full white.
for (int i = 0; i < imageToWorkWith.rows; i++) {
for (int j = 0; j < imageToWorkWith.cols; j++) {
imageToWorkWith.at<cv::Vec4b>(i,j) = cv::Vec4b(0,0,0);
}
}
I have profiled one of my apps using Allocations, and find that whenever I call a particular method my amount of "Live Bytes" increases by 300 KB. I have no idea what could be causing this.
The following line of code is the culprit:
CNTile *newTile = [self getTileAtPosition:3];
The associated method reads like this:
- (CNTile *)getTileAtPosition:(int)pos
{
CNTile *tileToReturn;
for (int x = 0; x < [row count]; x++)
{
for (int y = 0; y < [col count]; y++)
{
The code here generates four CGPoints and a CGMutablePathRef,
then uses CGPathContainsPoint to determine which CNTile to return.
}
}
return tileToReturn;
}
I should mention that my CNTile class contains only a UIView and UIImageView, as well as a few simple variables (such as ints and BOOLs).
Any help would be greatly appreciated!
How do you create CGMutablePathRef? With CGPathCreateMutable? If yes, make sure you use CGPathRelease to release it:
CGMutablePathRef thePath = CGPathCreateMutable();
...
CGPathRelease(thePath);
I'm having trouble inserting multiple children of same sprite and accessing it (or setting positions for them on runtime). Kindly advise any suitable method preferably point out my mistake. Here is my approach.
//In the Init Method...
//int i is defined in the start.
for (i = 1; i < 4; i++)
{
hurdle = [CCSprite spriteWithFile:#"hurdle1.png"];
[self addChild:hurdle z:i tag:i];
hurdle.position = CGPointMake(150 * i, 0);
}
It spreads all the sprites on the canvas. then in some "UPDATE Function" I'm calling this.
hurdle.position = CGPointMake(hurdle.position.x - 5, 10);
if (hurdle.position.x <= -5) {
hurdle.position = ccp(480, 10);
}
It works but as expected only one instance moves horizontally. I want all the instances to be moved so I am trying to use this....
for (i = 1; i < 4; i++){
[hurdle getChildByTag:i].position = CGPointMake(hurdle.position.x - 5, 10);
//OR
[hurdle getChildByTag:i].position = CGPointMake([hurdle getChildByTag:i].position.x - 5, 10);
}
I've tried getting LOGs on various places and realized that getChildByTag doesn't work the way I'm trying to use it.
The problem is in the last block of code. You should make a local reference to each CCSprite within your for loop.
Since you added the sprites to self, you will retrieve them as children of self
for (i = 1; i < 4; i++){
CCSprite * enumHurdle = [self getChildByTag:i];
enumHurdle.position = CGPointMake(enumHurdle.position.x - 5, 10);
}
Be careful if you create any other sprites this way in the same scene. It is bad design to give any two sprites the same tag.
EDIT about avoiding duplicate tags.
If you know how many sprites you will have. Use an enum of tags and refer to the sprites by name.
If not, knowing how many groups and putting a limit on the size of groups could make it managable.
ie
say you have 3 parts of code where you are generating sprites like this. You can include an enum in your .m (under #implementation line) and put the limits there
// Choose names that describe the groups of sprites
enum { kGroupOne = 0, // limiting the size of each group to 100
kGroupTwo = 100, // (besides the last group, but that is not important)
kGroupThree = 200,
};
Then when you create each group
// group 1
for (i = kGroupOne; i < 4; i++){
// set up code here
}
// group 2
// g2_size is made up, insert whatever you want
for (i = kGroupTwo; i < g2_size; i++) {
// set up code here
}
.
.
.
Then to retrieve in groups
for (i = kGroupOne; i < 4; i++){
CCSprite * enumHurdle = [self getChildByTag:i];
enumHurdle.position = CGPointMake(enumHurdle.position.x - 5, 10);
}
.
.
.
Hopefully that sparks your creativity. Now have some fun.
Something that I do often is group objects of like kind that I want to act on in a similar way by adding them to a CCNode and add that CCNode to the layer.
I would create a class that derives from CCNode
Then I can put all my logic in that node and access then via [self children]
for(CCSprite *hurdle in [self children]) {
// Do what you need to do
}