How to straighten line endings in Cocos2d? - ios

I'm new to Cocos2d and am trying out some of the basic drawing functions. When I draw a straight line with a high width (50 in this case), the ends of the line are not what I'd expect. What I'd like is for the line to be the same as it would be if I were using CoreGraphics, like this:
however what I see in Cocos2d is this:
The code I'm using to draw the line is in the layer's draw method:
-(void)draw
{
glColor4f(1, 0, 0, 1);
glLineWidth(50);
ccDrawLine(ccp(50, 50), ccp(250, 250));
}
Can anyone tell me how I can get cocos2d to draw a line with the same shape as the green image, rather than the red image?

Try drawing it antialiased.
glColor4f(1, 0, 0, 1);
glLineWidth(50);
glEnable(GL_LINE_SMOOTH);
ccDrawLine(ccp(50, 50), ccp(250, 250));

Related

Sorting of isometric SKTileMapNode incorrect?

I'm programmatically using SKTileMapNode. The code is C# (Xamarin.iOS) but should be readable by every Swift/ObjC developer.
The problem is that the sorting of tiles in isometric projection seems to be incorrect and I cannot see why. To test, the map has 1 row and 5 columns.
See the screenshot:
The tiles at 0|0 and 2|0 are in front of the others. The pyramid styled tile at 4|0 however, is drawn correctly in front of the one at 3|0.
I'm using two simple tiles:
The first one has a resolution of 133x83px and the second one is 132x131px
This is what it looks like in Tiled and what I am trying to reproduce:
The tile map is setup and added to the scene using the following code:
var tileDef1 = new SKTileDefinition (SKTexture.FromImageNamed ("landscapeTiles_014"));
var tileDef2 = new SKTileDefinition (SKTexture.FromImageNamed ("landscapeTiles_036"));
var tileGroup1 = new SKTileGroup (tileDef1);
var tileGroup2 = new SKTileGroup (tileDef2);
var tileSet = new SKTileSet (new [] { tileGroup1, tileGroup2 }, SKTileSetType.Isometric);
var tileMap = SKTileMapNode.Create(tileSet, 5, 2, new CGSize (128, 64));
tileMap.Position = new CGPoint (0, 0);
tileMap.SetTileGroup (tileGroup1, 0, 0);
tileMap.SetTileGroup (tileGroup2, 1, 0);
tileMap.SetTileGroup (tileGroup1, 2, 0);
tileMap.SetTileGroup (tileGroup2, 3, 0);
tileMap.SetTileGroup (tileGroup2, 4, 0);
tileMap.AnchorPoint = new CGPoint (0, 0);
Add (tileMap);
If first suspected an incorrect tile size. The tile size used to initialise the tile map (128|64) is the size of the diamond shaped base of the tile. If using a flat tile, this is identical to the texture size. For tiles with a height, it differs. However, changing the tile size affects the alignment of the tiles an the size I'm using is the same as in Tiled and it's giving the correct result, so that cannot be the culprit.
What am I doing wrong or where am I thinking wrong?
I don't have an answer for the main issue, but the tile size you use to initialise the map (128|64) is the size of the base tile, used to convert isometric coordinates into the the actual orthogonal space.
If you change this size in Tiled, it'll affect the size of the positioning grid. You can see a similar effect in Xcode's built-in tile map editor (or in any other isometric tile map editor I guess).

How to create lines, circles in stageXL?

I'm just new to stagexl, I know these are very basic questions, but I couldn't find an answer real quick, so I thought it would be nice to have this answered for anybody in the same position as I am.
How do I create a line from x to y in stagexl ?
And how do I create a circle with center x and radius y ?
You have to use the Shape display object. To draw a circle you just need to write this code:
var shape = new Shape();
shape.graphics.beginPath();
shape.graphics.circle(100, 100, 50);
shape.graphics.closePath();
shape.graphics.fillColor(Color.Red);
stage.addChild(shape);
To draw a line you have to do this:
var shape = new Shape();
shape.graphics.beginPath();
shape.graphics.moveTo(50, 50);
shape.graphics.lineTo(250, 150);
shape.graphics.closePath();
shape.graphics.strokeColor(Color.Red);
stage.addChild(shape);
You can learn more about it here:
http://www.stagexl.org/docs/wiki-articles.html?article=graphics
Please keep in mind that vector shapes are currently only supported with the Canvas2D renderer in StageXL. We are currently working on the WebGL renderer implementation too. You can use Shapes with the WebGL renderer too, if you use the applyCache method on the Shape. This will draw the Shape to a texture which can be used in WebGL too. This is also a much faster way to draw vector graphics.
Here is a full example, that you can also clone from gist if you want to try it out: https://gist.github.com/kasperpeulen/5cd660b5088311c64872
I'm not really sure if I do the WebGL example correct though, it seems like the WebGL graphic is blurry if I do it in this way.
import 'dart:html' as html;
import 'package:stagexl/stagexl.dart';
main() {
initWebGL();
initCanvas2D();
}
initWebGL() {
Stage stage = new Stage(html.querySelector('#WebGL'));
new RenderLoop().addStage(stage);
stage.addChild(circle(new Point(100, 100), 50));
stage.addChild(line(new Point(50, 50), new Point(250, 150)));
stage.applyCache(0,0,stage.sourceWidth,stage.sourceHeight);
}
initCanvas2D() {
Stage stage = new Stage(html.querySelector('#Canvas2D'),
options: new StageOptions()..renderEngine = RenderEngine.Canvas2D);
new RenderLoop().addStage(stage);
stage.addChild(circle(new Point(100, 100), 50));
stage.addChild(line(new Point(50, 50), new Point(250, 150)));
}
Shape line(Point from, Point to, {color: Color.Black}) {
return new Shape()
..graphics.beginPath()
..graphics.moveTo(from.x, from.y)
..graphics.lineTo(to.x, to.y)
..graphics.closePath()
..graphics.strokeColor(color);
}
Shape circle(Point<num> point, num radius, {color: Color.Black}) {
return new Shape()
..graphics.beginPath()
..graphics.circle(point.x, point.y, radius)
..graphics.closePath()
..graphics.fillColor(color);
}

How to display dashed lines in objective-c?

I have this code to display a grid with dashed line. In runtime on an iphone 5 below it shows fine, but if I run the app on iphone 5s there's no grid. I tested in iPhone Simulator and on real devices and happens the same.
Here's the code:
if (self.dashLongitude) {
CGFloat lengths[] = {3.0, 3.0};
CGContextSetLineDash(context, 0.0, lengths, 2);
}
//other stuff here
CGContextSetLineDash(context, 0, nil, 0);
So anyone could help??
EDIT: Hey guys I solved the issue using the same code I posted here, but in a different method. So I have now two methods: one just for the drawing the grid and another on to draw the line with data and finally got everything working.
The code looks fine.
As I look into the code I saw you are setting the nil in the context. nil is used to remove the dashed line.
Try to use
CGFloat dash[] = {2.0, 2.0};
CGContextSetLineDash(context, 0.0, dash, 2);
where you are creating or provide stroke your line(underneath).
CGContextSetLineDash(context, 0, NULL, 0);
is used to remove that dash pattern.
Instead of setting nil in CGContextSetLineDash, just wrap your code into CGContextSaveGState/CGContextRestoreGState to preserve context state before applying line dash:
CGContextSaveGState(context);
CGFloat dash[] = {2.0, 2.0};
CGContextSetLineDash(context, 0.0, dash, 2);
// Draw some lines here
CGContextRestoreGState(context);

Using drawImage to draw a filled rectangle

if I want to draw a filled rectangle, I could do
g.fillRect(0, 0, 100, 100)
But if I want to draw the same filled rectangle with drawImage, what do I do? I tried the below:
g.drawImage(null, 0,0,100, 100, Color.BLACK, null);
And it does not work. I am not going to use an image, but must the Image still be non-null? What would be the correct way to do this?

Issue with transparency while drawing with RenderToSurface

I am facing issue while drawing semitransparent object with RenderToSurface(While it working file when i am drawing object direct on device). Issue is when i m drawing a object with Alpha value 50% on RenderToSurface, and when i am drawing surface to device then transparency of object is not valid. My code is as follow.
[code] RenderingSurface.BeginScene(RenderTexture.GetSurfaceLevel(0), view);
_device.Clear(ClearFlags.Target| ClearFlags.ZBuffer, Color.FromArgb(0, Color.Black), 1.0f, 0);
using (Sprite s = new Sprite(_device))
{
s.Begin(SpriteFlags.DoNotSaveState);
s.Draw(ObjecTexture, new Microsoft.DirectX.Vector3(0, 0, 0), new Microsoft.DirectX.Vector3(0, 1, 0), Color.White.ToArgb());
s.End();
}
RenderingSurface.EndScene(Filter.None);
RenderSurface have same shape with 50% tranparency.
Code to Draw Surface.
_device.BeginScene();
_device.Clear(ClearFlags.Target | ClearFlags.ZBuffer | ClearFlags.Stencil, BackgroundColor, 1, 0);
using (Sprite s = new Sprite(_device))
{
s.Begin(SpriteFlags.DoNotSaveState);
s.Draw(RenderTexture, new Microsoft.DirectX.Vector3(0, 0, 0), new Microsoft.DirectX.Vector3(0, 1, 0), Color.White.ToArgb());
s.End();
}
Make sure your RenderSurface render target is created with a PixelFormat that has an alpha channel (A8R8G8B8 rather than X8R8G8B8).
Also, when rendering in the render target, make sure the resulting alpha is being written to the surface using the right blend mode render states for the alpha channel. Please note that blend modes for alpha (AlphaDestinationBlend, AlphaSourceBlend, ...) and colors (DestinationBlend, SourceBlend, ...) are different; make sure you set both.

Resources