Drawing a rectangle in AS3, the border is partially off-screen - actionscript-3

I am drawing a rectangle at 0,0 with a line-style-thickness of 4px. It has height 100% and width 50%. The right-hand edge has a border 4px wide, but all 3 other sides are only 2px, suggesting the mid-point of the edge is classed as the border. Why isn't the edge drawn 'inside' the rectangle?

Because to draw a line, you only specify two points: A beginning, and an end. The line will be centered between them, making the left and right sides "stand out".
If you want to have a rectangle with a frame inside of the specified coordinates, consider creating a filled shape out of two Rectangles (the inner one will be subtracted from the outer one), without a lineStyle.
var sprite : Sprite = new Sprite( );
var g : Graphics = sprite.graphics;
g.lineStyle( null );
g.beginFill( 0, 1 );
g.drawRect( 0, 0, 200, 100 );
g.drawRect( 2, 2, 194, 96 );
g.endFill( );
addChild (sprite);

Related

Scaling up viewport

My game is 200 x 320 pixels and I want to scale this up to fit any screen. The problem is I need to scale this up in integer multiples of these dimensions so the upscaled pixels don't look uneven.
What should I put in my constructor, render() and resize() methods to achieve this?
In the constructor I now have:
camera = new OrthographicCamera();
camera.setToOrtho(false,200,320);
stage = new Stage(new ScalingViewport(Scaling.fill,200,320, camera));
In render():
camera.update();
game.batch.setProjectionMatrix(camera.combined);
And in resize():
int widthScale = width/200;
int heightScale = height/320;
int newScale = Math.max(widthScale, heightScale);
int multiplesWidth = newScale*200;
int multiplesHeight = newScale*320;
stage.getViewport().update(multiplesWidth, multiplesHeight, true);
camera.setToOrtho(false, 200, 320);
My problem is that the content isn't centered. How and where can I center whatever is on the screen? I tried with:
camera.position.set(Gdx.graphics.getWidth()/2f, Gdx.graphics.getHeight()/2f, 0);
but the screen is blank!
I think the problem is that you are trying to center the screen using the screen dimensions and not the world dimensions.
Try replacing
camera.position.set(Gdx.graphics.getWidth()/2f, Gdx.graphics.getHeight()/2f, 0);
with
camera.position.set(stage.getViewport().getWorldWidth()/2f, stage.getViewport().getWorldHeight()/2f, 0);
EDIT:
Okay, so here is an explanation why I proposed you set the camera to (width/2, height/2). (I will leave out the third z-Coordinate from now on as it will always be 0.)
camera.position.set() sets the center point of the camera. At (0,0) the camera is positioned right at the center of the screen, depicted by the red rectangle below. What libgdx does by default, and what I proposed offsets the camera by width/2(the blue line) and height/2(the green line) which translates to the magenta rectangle.
Side note: the reason camera.position.set(Gdx.graphics.getWidth()/2f, Gdx.graphics.getHeight()/2f, 0); didn't work is because Gdx.graphics.getX() returns the width and height of the window in pixels, not in the measurement system the Viewport uses. This offsets the camera about a meter up and to the right, where you obviously didn't draw anything.
If you want the red rectangle as camera, you can change the last argument of
stage.getViewport().update(multiplesWidth, multiplesHeight, true);
to false. Or use camera.position.set(0,0,0);

How to draw a rectangle or curve between two co-ordinates in libGDX

I am new to libGDX.I just want a Rectangle or a small curve drawn between the object and the clicked position .I know libGDX has RECTANGLE class but I need to rotate it but the problem is, it gets rotated in center origin and i want to rotate it from its starting position.
I just want to draw a rectangle or a curved line to be drawn between the object and the clicked position like this >>>
Code to get user click position :
int x1 = Gdx.input.getX();
int y1 = Gdx.input.getY();
Code to get the width(distance) between the object and the clicked position :
float abwidth = x1 - position.x;
Code to compute the rotation :
float f1 = Math.abs(y1 - position.y);
float f2 = Math.abs(x1 - position.x);
abwidth = Math.abs(abwidth);
float abdegree = Math.toDegrees(Math.atan((f1)/(f2)));
abdegree = abdegree * (-1);//done this because it was giving the opposite rotation i dont know if this is wrong but it made the angle upwards
The above computed degree when put in the following code -- > shapeRenderer.rect(x,y,width,height, 0, 0, abdegree ); is not giving me the perfect angle So what would be a perfect way to rotate the straight horizontal rectangle to the click position.
Or is there any way of achieving this in some other way instead of using rectangle like using curve or something else ?
You can use this class for rendering shapes
and it has
rect(float x, float y, float width, float height, float originX, float originY, float rotation)
method for drawing rectangles
set originX,originY to 0,0 or other numbers to change rotation origin point

clearRect issue in animation

Im having issue with clearRect, i have an image u can move up and down and which follow the angle where the mousse is but in some frames of the animation the clearRect let a small edge of the previous image state ( 'this' reference to the image and 'ctx' is the 2d context, 'this.clear()' is called each frame before redrawing the image at the new coordinates )
this.clear = function(){
game.ctx.save();
game.ctx.translate(this.x+this.width/2, this.y+this.height/2);//i translate to the old image center
game.ctx.rotate(this.angle);//i rotate the context to the good angle
game.ctx.clearRect(this.width/-2, this.height/-2, this.width, this.height);//i clear the old image
game.ctx.restore();
};
if i replace the clearRect line by
game.ctx.clearRect(this.width/-2-1, this.height/-2-1, this.width+2, this.height+2);
it works but its not the logical way
The problem is that you are only clearing at position half the width/height, not position minus half the width/height.
Regarding anti-aliasing: when you do a rotation there will be anti-aliased pixels regardless of the original position being integer values. This is because after the pixels relative positions are run through the transformation matrix their offsets will in most cases be float values.
Try to change this line:
game.ctx.clearRect(this.width/-2, this.height/-2, this.width, this.height);
to this instead including compensation for anti-aliased pixels (I'll split the lines for clearity):
game.ctx.clearRect(this.x - this.width/2 - 1, /// remember x and y
this.y - this.height/2 - 1,
this.width + 2,
this.height + 2);

Make disappear image on the edge of rectangle

I have to move some pictures in my flash. So I have got a background image in my main MovieClip(which I get by Loader class). Inside the image I have rectangles. I'm going to put small image in this rectangle and move it. I need the small image slowly disappear while crossing the rectangle boundaries.
I tried to put another movieclip in rectangles and moved image in this movieclip. But while crossing the rectangle the image didnt disappear. The image just continued its motion without disappearing.
How can I make dissapearing of image while crossing rectangle boundaries?
Sorry for my English.
Get TweenLite. It's an animation "tweening" library that makes animation a breeze. There are others, but this is the one I use.
It depends on the methodology you employ to move and detect your overlaps of image & rectangles.
Let's imagine you have two squares (red square, and blue square) and you want red square to fade-out whenever it overlaps blue square. Is this controlled with the mouse, keyboard, or a pre-calculated move that performs a guaranteed eclipse? Is the fade a factor of the percentage of overlap, or a straight-up 0-to-100 timed transition the moment it comes in contact with blue square? It's not clear from the description you gave as to what exactly you expect your code to do. Please review SO's "Asking" section, to help improve the quality of your question so that you get the right answer you're looking for.
That said, here's one way you could resolve the issue:
import com.greensock.*;
// Create some sample red & blue squares
var red:Sprite = new Sprite();
red.graphics.beginFill(0xFF0000, 1);
red.graphics.drawRect(0, 0, 100, 100);
red.graphics.endFill();
addChild(red);
stage.addEventListener(MouseEvent.MOUSE_MOVE, updateRed);
var blue:Sprite = new Sprite();
blue.graphics.beginFill(0x0000FF, 1);
blue.graphics.drawRect(0, 0, 100, 100);
blue.graphics.endFill();
addChild(blue);
blue.x = 200;
blue.y = 100;
var overlap:Boolean = false; // global state tracker
function updateRed(e:MouseEvent):void {
// Position the red square every time the mouse moves
red.x = stage.mouseX - red.width/2; // center relative to red square's dimensions
red.y = stage.mouseY - red.height/2;
if (red.hitTestObject(blue) && overlap != true) {
// Make sure we only animate on the initial overlap
overlap = true;
TweenLite.to(red, 1, {alpha:0});
} else if (red.hitTestObject(blue) == false && overlap) {
// And converserly, on the initial exit
overlap = false;
TweenLite.to(red, 1, {alpha:1});
}
}

How do i get the x/y coordinates of the first and last points of the drawn arc relative to the top left corner of the canvas?

I have a square canvas with a width of 100 and a height of 100.
Within that square I draw an arc like so:
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0,0,100,100) // clears "myCanvas" which is 100pixels by 100 pixels
ctx.beginPath();
ctx.arc( 50, 50, 30, 0, Math.PI*2/6 , false )
ctx.stroke();
The question is: How do i get the x/y coordinates of the first and last points of the drawn line relative to the top left corner of the canvas?
The starting point is trivially (x + radius, y). The ending point is, by simple trigonometrics, (x + radius*cos(angle), y + radius*sin(angle)). Note that the starting point in this case is a special case of the more general ending point, with angle equal to zero. These values also need to be rounded to the nearest integer, for obvious reasons.
(Note that this applies only when the anticlockwise argument is false, and assuming all coordinates are measured from the top left. If anticlockwise is true, reverse the sign of the second component of the y coordinate. If coordinates are measured from another corner, apply simple arithmetics to correct for this. Also note that this is completely backwards for any real mathematician.)