how to make collisions with skshapenode circles - geometry

I am working on a game that incorporates touch detection with skShapenodes that are circles, and can not find a good method to check if they are touching. Code for the player class is below
-(void)SpawnPlayer
{
_player = [[SKShapeNode alloc] init];
CGMutablePathRef myPath = CGPathCreateMutable();
CGPathAddArc(myPath, NULL, 0,0, 15, 0, M_PI*2, YES);
_player.path = myPath;
_player.lineWidth = 1.0;
_player.fillColor = [SKColor whiteColor];
_player.strokeColor = [SKColor whiteColor];
_player.glowWidth = 0.5;
_location = CGPointMake(375, 400);
_player.position = CGPointMake(375, 400);
_player.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:0.5];
_player.physicsBody.dynamic = NO;
_player.physicsBody.categoryBitMask = playerCategory;
_player.physicsBody.contactTestBitMask = enemyCategory;
_player.physicsBody.collisionBitMask = 0;
[self addChild:_player];
}
The enemy code is similar, with the exception that its bitmask and testbitmask are switched.

Think of it as this:
The categoryBitMask specifies the type of body a node is.
The collisionBitMask specifies which type of bodies it can collide with.
The contactTestBitMask specifies which type of contactTestBitMasks will interact with it.
e.g. to detect contact between player and enemy, which have different categoryBitMasks, their contactTestBitMasks should be:
_player.physicsBody.categoryBitMask = playerCategory;
_player.physicsBody.contactTestBitMask = playerCategory | enemyCategory ;
For enemy:
_enemy.physicsBody.categoryBitMask = enemyCategory;
_enemy.physicsBody.contactTestBitMask = playerCategory | enemyCategory ;
now you can handle what to do on contact in didBeginContact method

Related

Metal blending alpha under 0.5

When I try to blend with a color with an alpha of 0.5 or below, metal seemingly discards the color like it has an alpha of 0. When I set the alpha to 0.51, I can see it fine. When I set it to 0.5, it's invisible. Here is a simple implementation of the issue:
#implementation Renderer
{
id <MTLDevice> _device;
id <MTLCommandQueue> _commandQueue;
id<MTLLibrary> defaultLibrary;
id <MTLBuffer> _vertexBuffer;
id <MTLBuffer> _indexBuffer;
id <MTLRenderPipelineState> _pipelineState;
}
-(nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)view;
{
self = [super init];
if(self)
{
_device = view.device;
view.colorPixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
_commandQueue = [_device newCommandQueue];
[self _createRenderObject];
}
return self;
}
-(void)_createRenderObject
{
Vertex verts[4] = {
simd_make_float2(-0.5f, -0.5f),
simd_make_float2(0.5f,-0.5f),
simd_make_float2(0.5f,0.5f)
};
uint16_t indices[3] = {0,1,2};
_vertexBuffer = [_device newBufferWithBytes:&verts length:sizeof(verts) options:MTLResourceStorageModeShared];
_indexBuffer = [_device newBufferWithBytes:&indices length:sizeof(indices) options:MTLResourceStorageModeShared];
// Create Pipeline State
defaultLibrary = [_device newDefaultLibrary];
MTLRenderPipelineDescriptor *pd = [[MTLRenderPipelineDescriptor alloc] init];
pd.vertexFunction = [defaultLibrary newFunctionWithName: #"VertShader"];
pd.fragmentFunction = [defaultLibrary newFunctionWithName: #"FragShader"];
pd.alphaToCoverageEnabled = YES;
MTLRenderPipelineColorAttachmentDescriptor *cad = pd.colorAttachments[0];
cad.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
cad.blendingEnabled = YES;
cad.alphaBlendOperation = MTLBlendOperationAdd;
cad.sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
cad.destinationAlphaBlendFactor = MTLBlendFactorDestinationAlpha;
cad.rgbBlendOperation = MTLBlendOperationAdd;
cad.sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
cad.destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
NSError *error = NULL;
_pipelineState = [_device newRenderPipelineStateWithDescriptor:pd error:&error];
}
- (void)drawInMTKView:(nonnull MTKView *)view
{
id <MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
MTLRenderPassDescriptor* renderPassDescriptor = view.currentRenderPassDescriptor;
id <MTLRenderCommandEncoder> renderEncoder =
[commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
[renderEncoder setFrontFacingWinding:MTLWindingCounterClockwise];
[renderEncoder setCullMode:MTLCullModeBack];
[renderEncoder setRenderPipelineState:_pipelineState];
[renderEncoder setVertexBuffer:_vertexBuffer offset:0 atIndex:0];
[renderEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:3
indexType:MTLIndexTypeUInt16
indexBuffer:_indexBuffer
indexBufferOffset:0];
[renderEncoder endEncoding];
[commandBuffer presentDrawable:view.currentDrawable];
[commandBuffer commit];
}
#end
Shader.metal:
typedef struct {
float4 position [[position]];
} VertexOut;
vertex VertexOut
VertShader(const uint vertexID [[vertex_id]],
constant Vertex *vertices [[buffer(0)]])
{
VertexOut out;
Vertex v = vertices[vertexID];
out.position = (float4){v.position.x,v.position.y,0,1};
return out;
}
fragment half4
FragShader(VertexOut in [[stage_in]])
{
return half4(1,1,1,0.50f);
}
With that code, specifically the FragShader having 0.50f as the alpha value, I get a blank canvas:
If I change the alpha value to 0.51f:
fragment half4
FragShader(VertexOut in [[stage_in]])
{
return half4(1,1,1,0.51f);
}
I then get this:
Any help is appreciated!
Solved. The problem was that alphaToCoverageEnabled was set to true, while the render target texture type was NOT MTLTextureType2DMultisample. It appears the two work in tandem, but it's beyond my understanding how.
If not using multi-sampling, set alphaToCoverageEnabled to false.
Otherwise, make sure the render target is of type MTLTextureType2DMultisample.
If using MTKView, set the render target texture type by setting the sampleCount on the MTKView object:
_view = (MTKView *)self.view;
_view.sampleCount = 2;
and the render pipeline descriptor of the pipeline state:
MTLRenderPipelineDescriptor *pd = [[MTLRenderPipelineDescriptor alloc] init];
pd.sampleCount = 2;

SKLabelHorizontalAlignmentMode

Can someone give me an example of how to use SKLabelHorizontalAlignmentMode?
Here's how I'm defining my label:
RunningLevelLabel = [SKLabelNode labelNodeWithFontNamed:#"Chalkduster" ];
RunningLevelLabel.text = [NSString stringWithFormat:#"%i",numberOfBonusAlienPoints];
RunningLevelLabel.fontSize = 36;
RunningLevelLabel.position = CGPointMake(-10,-50); // offscreen
RunningLevelLabel.fontColor = [SKColor grayColor];
[StartScreenWindow addChild:RunningLevelLabel];
thanks,
rich
First create a label:
SKLabelNode *scoreLabel = [SKLabelNode labelNodeWithFontNamed:#"Arial"];
scoreLabel.text = #"00000";
scoreLabel.fontSize = 18;
scoreLabel.fontColor = [UIColor blackColor];
scoreLabel.position = CGPointMake(200, 300);
[self addChild: scoreLabel];
Now, you can align the label with:
scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
OR
scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeRight;
OR
scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
This outputs are shown in figure below:
Keep coding............. :)
Hasn't been answered yet and I was just looking for this myself...
See the 2nd line...vertical alignment works the same way.
SKLabelNode *RunningLevelLabel = [SKLabelNode labelNodeWithFontNamed:#"Chalkduster" ];
[RunningLevelLabel setHorizontalAlignmentMode:SKLabelHorizontalAlignmentModeCenter];
RunningLevelLabel.text = [NSString stringWithFormat:#"%i",numberOfBonusAlienPoints];
RunningLevelLabel.fontSize = 36;
RunningLevelLabel.position = CGPointMake(-10,-50); // offscreen
RunningLevelLabel.fontColor = [SKColor grayColor];
[StartScreenWindow addChild:RunningLevelLabel];

start at the top of the page when changing page

ı have a problem about scrollview.
my project about a newspaper.my problem about : I want to start at the
top of the page when changing page.
scrollview have 8 news.ı want to beginning at the top of the text on
the page when change 2. or 3. or.. news..
please help me about it.because ı need to deliver the project on Monday.for this reason ı
must do today or tomorrow.
code of project in here
myScrollview = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
myScrollview.pagingEnabled = YES;
myScrollview.scrollEnabled =YES;
myScrollview.clipsToBounds = NO;
myScrollview.indicatorStyle = UIScrollViewIndicatorStyleWhite;
myScrollview.showsHorizontalScrollIndicator = YES;
myScrollview.backgroundColor = [UIColor blackColor];
myScrollview.delegate = self;
NSInteger viewcount=4;
NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:#"photo1.png"],[UIImage imageNamed:#"photo2.png"],[UIImage imageNamed:#"photo3.png"],[UIImage imageNamed:#"photo4.png"],nil];
for (int i = 0; i <viewcount; i++)
{
CGFloat x = i * self.view.frame.size.width;
subView = [[UIScrollView alloc]initWithFrame:CGRectMake(x, 0, self.view.frame.size.width, self.view.frame.size.height)];
[subView setBackgroundColor:[UIColor blackColor]];
[subView setCanCancelContentTouches:NO];
subView.clipsToBounds = NO; // default is NO, we want to restrict drawing within our scrollview
subView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
aImageView = [[UIImageView alloc ] initWithImage:[images objectAtIndex:i]];
aImageView.frame=CGRectMake(0, 0, 320, 900);
[aImageView setTag:viewcount];
[subView addSubview:aImageView];
[subView setContentSize:CGSizeMake(aImageView.frame.size.width, subView.frame.size.height)];
subView.minimumZoomScale = 1;
subView.maximumZoomScale = 9;
subView.delegate = self;
[subView setScrollEnabled:YES];
subView.contentSize = aImageView.frame.size;
[myScrollview addSubview:subView];
}
myScrollview.contentSize = CGSizeMake(self.view.frame.size.width*viewcount,self.view.frame.size.height);
[self.view addSubview:myScrollview];
https://biliyomusunuz.com

cocos2d box2d scale sprite -> removechild (how?)

I am little slow in English, please do understand.
Here is my source code:
- (void)createBall:(CGPoint)touchedAt{
CGSize winSize = [CCDirector sharedDirector].winSize;
ball2 = [CCSprite spriteWithFile:#"Ball.png" rect:CGRectMake(0, 0, 54, 54)];
ball2.position = ccp(touchedAt.x,touchedAt.y);
[self addChild:ball2];
b2BodyDef ballBodyDef2;
ballBodyDef2.type = b2_dynamicBody;
ballBodyDef2.position.Set(touchedAt.x/PTM_RATIO, touchedAt.y/PTM_RATIO);
ballBodyDef2.userData = ball2;
b2Body *body2 = _world->CreateBody(&ballBodyDef2);
b2CircleShape circle;
circle.m_radius = 89.0/PTM_RATIO;//(arc4random()*26.0)/PTM_RATIO;
b2FixtureDef ballShapeDef2;
ballShapeDef2.shape = &circle;
ballShapeDef2.density = 1.0f;
ballShapeDef2.friction = 0.2f;
ballShapeDef2.restitution = 0.8f;
body2->CreateFixture(&ballShapeDef2);
}
-(void)createBall2
{
CGSize winSize = [CCDirector sharedDirector].winSize;
globalSprite = [CCSprite spriteWithFile:#"Ball.png"];
globalSprite.position = ccp(winSize.width/2 + globalSprite.contentSize.width, winSize.height/2);
[self addChild:globalSprite];
b2BodyDef ballBodyDef3;
ballBodyDef3.type = b2_dynamicBody;
ballBodyDef3.position.Set(100/PTM_RATIO, 100/PTM_RATIO);
ballBodyDef3.userData = globalSprite ;
b2Body *body3 = _world->CreateBody(&ballBodyDef3);
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;//(arc4random()*26.0)/PTM_RATIO;
b2FixtureDef ballShapeDef3;
ballShapeDef3.shape = &circle;
ballShapeDef3.density = 1.0f;
ballShapeDef3.friction = 0.2f;
ballShapeDef3.restitution = 0.8f;
body3->CreateFixture(&ballShapeDef3);
}
// initialize your instance here
-(id) init
{
if( (self=[super init])) {
// enable touch
// enable accelerometer
CGSize winSize = [CCDirector sharedDirector].winSize;
self.isAccelerometerEnabled = YES;
self.isTouchEnabled = YES;
// Create sprite and add it to the layer
// Create a world
b2Vec2 gravity = b2Vec2(0.0f, 0.0f);
bool doSleep = true;
_world = new b2World(gravity, doSleep);
// Create edges around the entire screen
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
b2Body *groundBody = _world->CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundBox;
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(0, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(0, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
// Create ball body and shape
[self schedule:#selector(tick:)];
//[self schedule:#selector(gameLogic:) interval:1.0];
[self createBall2];
}
return self;
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
[self createBall:location];
}
- (void)tick:(ccTime) dt {
_world->Step(dt, 10, 10);
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *ballData = (CCSprite *)b->GetUserData();
ballData.position = ccp(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
ballData.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
I want to
touch -> sprite create(circle) -> sprite scale -> sprite remove
but
- (void)tick:(ccTime) dt <---------- this is simulator turn off!
I want to way
Try this :
world->DestroyBody(sprite);

Any way to disable CALayer's rasterizationScale interpolation / anti-aliasing in objective-c / iPhone / iOS SDK?

I want to get rid of any interpolation/antialiasing/etc when setting myLayer.rasterizationScale = 0.01 and myLayer.shouldRasterize = YES;
Example:
Here's the code I'm trying:
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CALayer *sourceLayer = self.delegate.sourceImageView.layer;
sourceLayer.rasterizationScale = 0.01;
sourceLayer.shouldRasterize = YES;
[sourceLayer renderInContext:ctx];
CGContextSetShouldAntialias(ctx, NO);
CGContextSetAllowsAntialiasing(ctx, NO);
CGContextSetInterpolationQuality(ctx, kCGInterpolationNone);
}
The expected result is that the image would display as a chunky/pixelated bitmap.
Any ideas? Thanks!
Edit: added full drawRect code, also tried moving the Antialias functions immediately following the UIGraphicsGetCurrentContext line.
Edit: Try #2 (fail!)
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetShouldAntialias(ctx, NO);
CGContextSetAllowsAntialiasing(ctx, NO);
CGContextSetInterpolationQuality(ctx, kCGInterpolationNone);
CALayer *layer = [CALayer layer];
layer.contents = (id)[UIImage imageNamed:#"test.jpg"].CGImage;
layer.frame = CGRectMake(0, 0, 320, 411);
layer.rasterizationScale = 0.0001;
layer.shouldRasterize = YES;
layer.geometryFlipped = NO;
layer.edgeAntialiasingMask = 0;
layer.minificationFilter = kCAFilterNearest;
[layer renderInContext:ctx];
}
For no interpolation, set the layer's magnificationFilter property to kCAFilterNearest. If desired, set the minificationFilter as well.
In addition, you shouldn't set up the layer's properties inside the -drawRect: method. Instead, initialize the layer properties when initializing the view, or when you want to change the layer content.

Resources