AS3 - How to Draw and Align a Circle? - actionscript-3

I want to draw a circle and align it center. My code doesn't do that:
var circle:Shape = new Shape(); // The instance name circle is created
circle.graphics.beginFill(0x990000, 1); // Fill the circle with the color 990000
circle.graphics.lineStyle(2, 0x000000); // Give the ellipse a black, 2 pixels thick line
circle.graphics.drawCircle((stage.stageWidth - 100) / 2, (stage.stageHeight - 100) / 2, 100); // Draw the circle, assigning it a x position, y position, raidius.
circle.graphics.endFill(); // End the filling of the circle
addChild(circle); // Add a child

drawCircle((stage.stageWidth - 100) / 2, (stage.stageHeight - 100) / 2, 100);
The first two parameters of drawCircle are the X and Y position of the center of the circle, not the top left position of the circle.
If you want your circle in the center of the stage, you just need to put the circle’s center at the same position, so you’d call drawCircle like this:
drawCircle(stage.stageWidth / 2, stage.stageHeight / 2, 100);

I think your approach, although it would work, will just make working with your shape a bit tougher.
consider this approach :
var circle:Shape = new Shape();
circle.graphics.clear();
circle.graphics.lineStyle(2,0x000000);
circle.graphics.beginFill(0x990000);
circle.graphics.drawCircle(0,0,100);
circle.graphics.endFill();
addChild(circle);
circle.x = stage.stageWidth / 2;
circle.y = stage.stageHeight/ 2;
By drawing the circle centered on the 0,0 location in your shape and then placing it via the x and y properties is a far better approach. Suppose you want to move that circle ? Trying to figure out the offsets would be a nightmare.

Related

Getting the right width and height of a canvas element

I am having difficulties with setting the correct width and height of my canvas element.
I have a ball, that I'd like to bounce back whenever it hits a screen boundary by changing it's vertical velocity. It works, but instead of moving back as soon as it hits the edge of the screen, it goes on for a couple of seconds and THEN moves back. I have these variables to determine the viewport's size:
var left = 0,
right = canvas.width,
top = 0,
bottom = canvas.height;
If my ball's x or y positions are outside these boundaries, the velocity should be changed to a negative one. However, during my animation I console.log it's x position and by the time it reaches the right edge of the screen the value is around 600, which is really strange, since I'm on a 1366x768px monitor.
Also, it doesnt't fully reach the left screen edge, but bounces off like 50px from it.
Any ideas are really appreciated, because I've been stuck on this for quite some time.
You can see a working example here: http://codepen.io/gbnikolov/pen/puiwk
Update your draw to the following.
Ball.prototype.draw = function(ctx) {
ctx.save();
// you've translated to the x and y position of the ball.
ctx.translate(this.x, this.y);
ctx.rotate(this.rotation);
ctx.scale(this.scaleX, this.scaleY);
ctx.lineWidth = this.lineWidth;
ctx.fillStyle = this.color;
ctx.strokeStyle = this.strokeColor;
ctx.beginPath();
// Draw at 0,0 since we are already translated to the x and y.
ctx.arc(0, 0, this.radius, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
}
Live Demo
Your problem is in the draw method, you're translating the context and then making the arc at the x and y of the ball so if you translate to 20, 20 for example and then draw at 20,20 your ball is actually at 40,40.

Gradient stroke along canvas arc disappearing when context translates to center

I am very new to canvas drawings. I am trying to apply gradient along the arc of a circle. I can get it to appear fine when I draw the arc with center offset from the context coordinates. Lets say centerX and centerY denote the center of the canvas. I can get a gradient arc using context.arc(centerX, centerY, radius, ......).
Working example: http://jsfiddle.net/m5Pmb/
But when I try to draw the arc around the context coordinates, the gradient disappears. For example, I take the above working jsfiddle example, do context.translate(centerX, centerY), then do context.arc(0,0,radius,......), the resulting arc does not have any gradient on it.
Example here: http://jsfiddle.net/N6NMB/
In my case, I need to spin the resulting circle around its axis using context.rotate(), so I must translate to the center and draw circle around (0,0). But I cant understand why the gradient disappears when trying to draw arc around context's (0,0) point. Any insight would be really helpful.
Since you are translating the context centerX and centerY are not where you think anymore.
When you translate the context you are saying you want that x and y to be the new 0,0. So now your 0,0 is in the center of the canvas, so centerX and centerY are offset by themselves putting them further away from the center.
One method you can use is the following
var grad = context.createLinearGradient(
-radius,
radius / 2,
radius,
radius / 2
);
live Demo
The above works because its called after you translate the context, so centerX and centerY (like I said previously) are 0,0 meaning they don't need to be referenced in that function.
The gradients that you create will be painted with the actual transform in use.
So if you are not using any transform, no need to wonder anything : define your gradient where you're about to draw, and you'll be fine.
If you are using transform, you must think of the coordinates of the gradient as relative to the point/angle/scale when you'll use them.
To explain further, i modified your example and used a radial gradient.
I created a normalized gradient : it is defined in between 0.0 and 1.0 radius, meaning it will have its x and y in [-1; 1].
var eyeGrad = context.createRadialGradient(0, 0, 0, 0, 0, 1.0);
Then to use the gradient i must :
1) translate to be in the center of the figure i want to draw.
2) scale to have normalized coordinates.
function drawEye(x, y, r) {
context.save();
//translate context to center
context.translate(x, y);
// scale to radius
context.scale(r, r);
context.beginPath();
// draw an arc with radius of 1
context.arc(0, 0, 1, 0, 2 * Math.PI, false);
context.fillStyle = eyeGrad;
context.fill();
context.restore();
}
fiddle is here :
http://jsfiddle.net/gamealchemist/N6NMB/3/
Result for :
drawEye(100, 100, 40);
drawEye(250, 120, 20);

Draw a circle with different colored section

So I want to draw a circle, filled blue with a black and red outline. The red part is determined by the look angle. The ctx variable holds the 2d context.
Relevant code:
ctx..lineWidth = 0.5
..fillStyle = "#0000AA"
..strokeStyle = "red";
ctx.beginPath();
ctx.arc(pos.x, pos.y, radius, look - PI / 6, look + PI / 6);
ctx..fill()
..closePath()
..stroke()
..beginPath();
ctx.strokeStyle = "black";
ctx.arc(pos.x, pos.y, radius, look + PI / 6, look - PI / 6);
ctx..fill()
..closePath()
..stroke();
This, however draws an additional red line inside the circle, that I don't want. How can I get rid of this line?
Remove the closePath when drawing the red line.
closePath will draw a line connecting the endpoints of your red arc (not what you want).

AS3 move object towards x,y and then continue in the same direction (using tweener)

I'm building a simple space shooter game
using Tweener class I wrote a code that fires a bullet from the hero spaceship current position to the mouse current position
var fire = new Bullet();
addChild(fire);
fire.x = ship.x + (ship.width * 0.5);
fire.y = ship.y
Tweener.addTween(fire, {x:_me.currentTarget.mouseX, y:_me.currentTarget.mouseY, time: 5} );
the problem is this code makes the bullet stop at the last mouse position
and I want the bullet to continue moving in the same direction until it's outside of the stage.
theoretically, the most simple way would be to input x.y position of the mouse as if it was at the same angle but outside of the stage
but how can i get those x,y coordinates??
determine the angle of the bullet.
using the angle, consider the origin of the bullet the center of a circle and the first point as a coordinate at the edge of the circle.
for the bullet to follow the same path, its just a larger circle, so the radius will increase.
the angle will be the same and so will the origin.
I think what you you want is to find a point one the same straight line with (fire.x, fire.y) , (_me.currentTarget.mouseX, _me.currentTarget.mouseY). And the point's x would be stage width.
So assume target point is A(stage.width, targetY)
We get
(targetY - mouseY)/(targetX - mouseX) = (mouseY - fire.y)/(mouseX - fire.x)
So
targetY = (mouseY - fire.y)/(mouseX - fire.x)*(targetX - mouseX) + mouseY;
Hero mouseX is _me.currentTarget.mouseX, mouseY is _me.currentTarget.mouseY
You can set targetX = stage.width + 10, then targetY
So you can get targetY, and do another tween
Tweener.addTween(fire, {x:targetX, y:targetY , time: 5} );

How to get visual corner (eg. topLeft) of rotated displayObject in actionscript 3?

When rotating a display object (around its center) the visual corner of the element moves (the actual x and y of the "box" remains the same). For example with 45 degrees of rotation the x coordinate will have increased and the y coordinate will have decreased as the top left corner is now at the top center of the "box".
I've tried to use displayObject.getBounds(coordinateSpace).topLeft however this method is simply returning the x and y of the box and thus doesn't change after an object has been rotated.
So, how do you get the x and y of a visual corner of a rotated display object?
Update: this is what I mean with the position of a visual corner after rotation -->
alt text http://feedpostal.com/cornerExample.gif
You simply need to translate the point to its parent's coordinate space.
var box:Shape = new Shape();
box.graphics.beginFill(0xff0099);
box.graphics.drawRect(-50, -50, 100, 100); // ... the center of the rectangle being at the middle of the Shape
addChild(box);
box.x = 100; // note: should be 100 + box.width * .5 in case you want to use the topleft corner to position
box.y = 100;
box.rotation = 45;
// traces the result (Point)
trace( box.parent.globalToLocal(box.localToGlobal(box.getBounds(box).topLeft)) );