Skip to content

Instantly share code, notes, and snippets.

@volodymyrsmirnov
Created May 13, 2012 19:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save volodymyrsmirnov/8e6c4710950d17ed3d3c to your computer and use it in GitHub Desktop.
Save volodymyrsmirnov/8e6c4710950d17ed3d3c to your computer and use it in GitHub Desktop.
#define GravityDirection -1 // -1 for down, 1 for up
#define ParticleWidth 2
#define ParticleHeight 2
// Import the interfaces
#import "HelloWorldLayer.h"
// Needed to obtain the Navigation Controller
#import "AppDelegate.h"
struct SandParticle
{
CGPoint Position;
BOOL CMTop;
BOOL CMBottom;
BOOL CMLeft;
BOOL CMRight;
};
// HelloWorldLayer implementation
@implementation HelloWorldLayer
{
struct SandParticle SandMatrix[5000];
NSMutableArray *DrawLines;
int CurrentLineIndex;
int SandCount;
bool StartDrop;
CGSize WindowSize;
CCLabelTTF *label;
Byte ScreenBuffer[960*640*4];
UIColor *ClearColor;
}
// Helper class method that creates a Scene with the HelloWorldLayer as the only child.
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild: layer];
return scene;
}
-(id) init
{
self = [super init];
if (self)
{
WindowSize = [[CCDirector sharedDirector] winSize];
ClearColor = [[UIColor alloc] initWithRed:1 green:0 blue:0 alpha:1];
[self setIsTouchEnabled:YES];
DrawLines = [[NSMutableArray alloc] init];
CCLayerColor *Demo = [CCLayerColor layerWithColor:ccc4(255, 0, 0, 255)];
[self setContentSize:CGSizeMake(WindowSize.width, WindowSize.height)];
[self addChild:Demo z:-10];
[self schedule:@selector(AddNewParticle:) interval:0.03];
[self schedule:@selector(UpdateParticles:) interval:0.03];
label = [CCLabelTTF labelWithString:@"Pixeldrop" fontName:@"Game Over" fontSize:150];
[label setAnchorPoint:CGPointZero];
[label setPosition:CGPointMake(WindowSize.width/2 - label.boundingBox.size.width/2, WindowSize.height - label.boundingBox.size.height)];
[label setColor:ccc3(0, 255, 0)];
[self addChild:label];
}
return self;
}
#define MaxParticles 2000
- (void) AddNewParticle: (ccTime) dt
{
if (SandCount < MaxParticles && StartDrop)
{
struct SandParticle NewParticle;
NewParticle.Position = CGPointMake(WindowSize.width/2, WindowSize.height- label.boundingBox.size.height + 10);
NewParticle.CMBottom = YES;
SandMatrix[SandCount] = NewParticle;
SandCount++;
}
glReadPixels(0,0,WindowSize.width,WindowSize.height,GL_RGBA,GL_UNSIGNED_BYTE,&ScreenBuffer);
}
- (BOOL) GetColorAtPoint: (int) GetX : (int)GetY
{
int YSize = (int)WindowSize.width*4;
Byte R = ScreenBuffer[(YSize*GetY) + 0 + (4 * GetX)];
Byte G = ScreenBuffer[(YSize*GetY) + 1 + (4 * GetX)];
Byte B = ScreenBuffer[(YSize*GetY) + 2 + (4 * GetX)];
Byte A = ScreenBuffer[(YSize*GetY) + 3 + (4 * GetX)];
return (R==255 && G == 0 && B == 0 && A == 255);
}
- (void) UpdateParticles: (ccTime) dt
{
for (int CPLoop = 0; CPLoop <= SandCount; CPLoop++)
{
struct SandParticle CurrentParticle = SandMatrix[CPLoop];
if (CurrentParticle.Position.y < ParticleHeight + 1) continue;
CurrentParticle.CMBottom = [self GetColorAtPoint:CurrentParticle.Position.x:CurrentParticle.Position.y-1];
CurrentParticle.CMLeft = [self GetColorAtPoint:CurrentParticle.Position.x-ParticleWidth*1.5:CurrentParticle.Position.y-1];
CurrentParticle.CMRight = [self GetColorAtPoint:CurrentParticle.Position.x+ParticleWidth*1.5:CurrentParticle.Position.y-1];
int Randomized = arc4random_uniform(2);
if (CurrentParticle.CMBottom)
{
CurrentParticle.Position.y -= ParticleHeight;
if (Randomized == 1)
CurrentParticle.Position.x += 1;
else
CurrentParticle.Position.x -= 1;
}
else if (CurrentParticle.CMLeft && CurrentParticle.CMRight)
{
CurrentParticle.Position.y -=ParticleHeight;
if (Randomized == 1)
CurrentParticle.Position.x += 1;
else
CurrentParticle.Position.x -= 1;
}
else if (CurrentParticle.CMLeft)
{
CurrentParticle.Position.x -=ParticleWidth;
CurrentParticle.Position.y -=ParticleHeight;
}
else if (CurrentParticle.CMRight)
{
CurrentParticle.Position.x +=ParticleWidth;
CurrentParticle.Position.y -=ParticleHeight;
}
SandMatrix[CPLoop] = CurrentParticle;
}
}
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSMutableArray *TouchArray = [[NSMutableArray alloc] init];
[DrawLines addObject:TouchArray];
StartDrop = YES;
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *Touch = [touches anyObject];
CGPoint CurrentTouchLocation = [Touch locationInView:[Touch view]];
CGPoint PreviousTouchLocation = [Touch previousLocationInView:[Touch view]];
NSMutableArray *NewTouch = [[NSMutableArray alloc] init];
CurrentTouchLocation = [[CCDirector sharedDirector] convertToGL:CurrentTouchLocation];
PreviousTouchLocation= [[CCDirector sharedDirector] convertToGL:PreviousTouchLocation];
[NewTouch addObject:NSStringFromCGPoint(CurrentTouchLocation)];
[NewTouch addObject:NSStringFromCGPoint(PreviousTouchLocation)];
NSMutableArray *CurrentLine = [DrawLines objectAtIndex:CurrentLineIndex];
[CurrentLine addObject:NewTouch];
[DrawLines replaceObjectAtIndex:CurrentLineIndex withObject:CurrentLine];
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
CurrentLineIndex++;
}
- (void) draw
{
[super draw];
for (int CPLoop = 0; CPLoop <= SandCount; CPLoop++)
{
struct SandParticle CurrentParticle = SandMatrix[CPLoop];
if (CurrentParticle.Position.x > 0 && CurrentParticle.Position.y > 0)
ccDrawSolidRect(CGPointMake(CurrentParticle.Position.x, CurrentParticle.Position.y), CGPointMake(CurrentParticle.Position.x+ParticleWidth, CurrentParticle.Position.y+ParticleHeight), ccc4f(255, 255, 255, 255));
else break;
}
for (NSArray *Line in DrawLines)
{
for (NSArray *Point in Line)
{
CGPoint CurrentTouchLocation = CGPointFromString([Point objectAtIndex:0]);
CGPoint PreviousTouchLocation = CGPointFromString([Point objectAtIndex:1]);
glLineWidth(5.0f);
ccDrawLine(PreviousTouchLocation, CurrentTouchLocation);
}
}
}
@end
@dstd
Copy link

dstd commented May 14, 2012

  • (BOOL) GetColorAtPoint: (int) GetX : (int)GetY
    {
    //int YSize = (int)WindowSize.width_4;
    //int i = (YSize_GetY) + (4 * GetX);
    int i = (WindowSize.width_GetY + GetX)_4;
    if( i < 0 || i > bufferSize ) return NO;

    Byte R = ScreenBuffer[i];
    Byte G = ScreenBuffer[++i];
    Byte B = ScreenBuffer[++i];
    Byte A = ScreenBuffer[++i];

    return (R==255 && G == 0 && B == 0 && A == 255);
    }

@dstd
Copy link

dstd commented May 14, 2012

Если затык действительно в GetColorAtPoint, то можно попробовать или перевести GetColorAtPoint на C-функцию, или хотя бы объединить 3 вызова в один: адрес пикселя CMLeft вычисляется умножением, а две CMBottom и CMRight сложением.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment