-
-
Save volodymyrsmirnov/8e6c4710950d17ed3d3c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
Если затык действительно в 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
(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);
}