Flash as3 image slider - actionscript-3

Im trying to get an image slider to work properly. But i don't get the next/prev functionality to work.
I have a container mc that holds all images, and a mask that acts as a mask for that container.
Here is how i add the images.
for(var i:int = 0; i<this.container.numChildren; i++) {
var mc:DisplayObject = this.container.getChildAt(i);
if(mc is MovieClip) {
mc.x = xPos;
xPos += mc.width + margin;
mc.y = 0;
}
}
So all images are now positioned in nice row with some margin.
the mask and container has same x/y-position. So, lets say now that i set the witdth of the mask to display 5 of the images that the container holds.
How would i program the next/prev buttons so it displays or hide only one image on click?
eg. tween the container position so it looks correct.
Here is my next and pre function. with is not working. Basically i want the container to always show same amount of items.
private function slideLeft(event:MouseEvent):void {
if(!TweenMax.isTweening(container)) {
var tx:Number = Math.min(container.x + itemWidth, _mask.x);
TweenMax.to(container, 0.3, {x:Math.floor(tx)});
}
}
private function slideRight(event:MouseEvent):void {
if(!TweenMax.isTweening(container)) {
var tx:Number = Math.max(container.x - itemWidth, _mask.x-_mask.width);
TweenMax.to(container, 0.3, {x:Math.floor(tx)});
}
}
Whats wrong? Anyone?

You need to account for the width of the container when showing items to the right. So the minimum x value for the container should be _mask.x - (container.width - _mask.width)
You should also account for the margins or you will see the offset you described in your comment.
private function slideLeft(event:MouseEvent):void {
if(!TweenMax.isTweening(container)) {
var tx:Number = Math.min(container.x + (itemWidth + margin), _mask.x);
TweenMax.to(container, 0.3, {x:Math.floor(tx)});
}
}
private function slideRight(event:MouseEvent):void {
if(!TweenMax.isTweening(container)) {
var tx:Number = Math.max(container.x - (itemWidth + margin), _mask.x - (container.width - _mask.width);
TweenMax.to(container, 0.3, {x:Math.floor(tx)});
}
}
Good luck!

Related

Why does my table and background not expand correctly LibGDX?

I have an Image for drawing my background that I add to the stage. For some reason, there is a small space on the bottom - it's not laid out correctly
See attached image. I draw the background yellow to make it more visible. Why doesn't expand the background all the way to the bottom?
#Override
public void show() {
cam = new OrthographicCamera(Helper.RESOLUTION_WIDTH, Helper.RESOLUTION_HEIGHT);
cam.position.set(Helper.RESOLUTION_WIDTH / 2, Helper.RESOLUTION_HEIGHT / 2, 0);
stage = new Stage(Helper.RESOLUTION_WIDTH, Helper.RESOLUTION_HEIGHT, true);
stage.setCamera(cam); // !IMPORTANT
Image img = new Image(Assets.background);
img.setFillParent(true);
img.setSize(Helper.RESOLUTION_WIDTH, Helper.RESOLUTION_HEIGHT);
stage.addActor(img);
Table table = new Table(skin);
table.debug();
table.setBounds(0, 0, Helper.RESOLUTION_WIDTH, Helper.RESOLUTION_HEIGHT);
table.setFillParent(true);
/* add all the menu items to table */
stage.addActor(table);
}
RESOLUTION_WIDTH = 800
RESOLUTION_HEIGHT = 1280;
I figured out why it would draw that border:
I completely overlooked, that I implemented the resize method and did something weird with the zoom.
cam.viewportHeight = height; //set the viewport
cam.viewportWidth = width;
if (Helper.RESOLUTION_WIDTH / cam.viewportWidth < Helper.RESOLUTION_HEIGHT / cam.viewportHeight)
{
//set the right zoom direct
cam.zoom = Helper.RESOLUTION_HEIGHT / cam.viewportHeight;
} else {
//set the right zoom direct
cam.zoom = Helper.RESOLUTION_WIDTH / cam.viewportWidth;
}
cam.update();
Leaving the resize function to its default implementation fixed the problem.
Thanks, Pranav008 for all the help though!

how to remove a child and center after that

Im struggling with a problem and dont know how to solve it.
I want every time i click the mouse the cards to be 1 less from the previous time, and at the same time to center the new (in my case when i click ill have -> 3 cards) again on the stage.
but i can only think of doing this by pushing the newly created cards in a Sprite but dont know how to remove the last card after that.
i did try just myArray[lastElement] but it gives me
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at MainClass/onClick()
CardClass is representing a simple picture of a card
so i have this code so far:
public class MainClass extends MovieClip
{
private var myArray:Array = new Array();
private var myContainer:Sprite = new Sprite();
public function MainClass()
{
for (var i:int=0; i<4; i++)
{
myArray[i]= new CardClass();
myArray[i].x = myArray[i].width * i + i * 10;
myContainer.addChild(myArray[i]);
}
myContainer.x = stage.stageWidth / 2 - myContainer.width / 2;
myContainer.y = 40;
this.addChild(myContainer);
stage.addEventListener(Event.ENTER_FRAME, onEveryFrame);
}
private function onEveryFrame(ev:Event):void
{
stage.addEventListener(MouseEvent.CLICK, onClick);
myContainer.x = stage.stageWidth / 2 - myContainer.width / 2;
myContainer.y = 40;
}
private function onClick(evt:MouseEvent):void
{
var lastElement = myArray.length - 1;
trace(lastElement);
this.removeChild(myArray[lastElement]);
myArray.pop();
}
}
}
if i try just to add the cards on the stage directly (not like here -> in the Container) it does what i want from it (it removes the last card), but then i cant figure out how to center the whole array of cards on the stage.
any ideas ?
Try this in your onClick method:
myContainer.removeChild(myArray[lastElement]);
You are adding the cards to myContainer, so you remove them from myContainer as well.
You add cards to myContainer element, but remove them from this element, but this didn't consist from this objects.
Your code:
private function onClick(evt:MouseEvent):void
{
var lastElement = myArray.length - 1;
trace(lastElement);
this.removeChild(myArray[lastElement]);
myArray.pop();
}
Replace on this:
private function onClick(evt:MouseEvent):void
{
var lastElement = myArray.length - 1;
trace(lastElement);
myContainer.removeChild(myArray[lastElement]);
myArray.pop();
}

as3 MovieClip not scaling properly

I'm trying to program a main menu with buttons in it. I have a class called MenuAchievementsButton, and in its constructor, it is passed down the stage width and stage height from the document class. When I trace this, it is the correct width/ height.
I'm trying to get the button's height to be the stage height / 100. I've tried doing this.height = stage height / 100, but whenever I do so, it gives me 4x the result I want, even when I enter in a number like 5 and measure the px in Photoshop.
Also, when I try to move the object, a similar problem exists: When I want it to be, say, 20px right and down, it turns out to be 80px left and down.
Any help is appreciated!
package menus {
import flash.display.MovieClip;
public class MenuAchievementsButton extends MovieClip {
private var _stageWidth, _stageHeight:int;
public function MenuAchievementsButton(stageWidth:int, stageHeight:int) {
_stageWidth = stageWidth;
_stageHeight = stageHeight;
alpha = 1;
rescaleMe();
repositionMe();
trace(_stageWidth, _stageHeight);
}
private function rescaleMe():void {
var oldWidth = this.width;
var oldHeight = this.height;
this.height = _stageHeight/100;
this.width = (this.height * oldWidth) / oldHeight;
}
private function repositionMe():void {
this.x = 20;
this.y = 20;
trace(x,y,width,height);
trace("Stage height is: ",_stageHeight,"Stage height divided by 100 is: ", _stageHeight/100, "And the object's height, which should be stageheight / 100 is:", this.height);
//Gives Stage height is: 800 Stage height divided by 100 is: 8 And the object's height, which should be stageheight / 100 is: 8
//Actually, though, it's 36px!
}
}
}
The code seems correct. No issues there.
Is the instance of the class added on stage? or on some other object?
See if you don't change the scale of a parent, something like this:
var parentMC:MovieClip=new MovieClip();
addChild(parentMC);
var rectangle:Shape = new Shape; // initializing the variable named rectangle
rectangle.graphics.beginFill(0xFF0000); // choosing the colour for the fill, here it is red
rectangle.graphics.drawRect(0, 0, 100,100); // (x spacing, y spacing, width, height)
rectangle.graphics.endFill(); // not always needed but I like to put it in to end the fill
parentMC.addChild(rectangle); // adds the rectangle to the stage
trace(rectangle.width) // result 100
parentMC.scaleX=2;
trace(rectangle.width) // result 100 altough it looks like it has 200

Screen Scrolling not working for Right and Bottom edges AS3

Hi the following code works when scrolling to either the left or right edges of the screen in my game; however when scrolling to the right or bottom edge of the screen when the edge of the "map" has been reached I am able to see beyond the edge of the map i.e. i am seeing white space i.e. the colour of the stage. Whereas, when scrolling to the edge of the map's left or top edge I am not able to see beyond the edge of the map.
public function scroll_screen():void { //scrolling left, right, up, down
var stagePositionX:Number = container.x+player.x;
var rightEdge:Number = stage.stageWidth-edgeDistance;
var leftEdge:Number = edgeDistance;
var stagePositionY:Number = container.y+player.y;
var bottomEdge:Number = stage.stageHeight-edgeDistance;
var topEdge:Number = edgeDistance;
//horizontal scrolling
if (stagePositionX > rightEdge) {
container.x -= (stagePositionX-rightEdge);
if (container.x < -(container.width-stage.stageWidth)) container.x = -(container.width-stage.stageWidth);
}
if (stagePositionX < leftEdge) {
container.x += (leftEdge-stagePositionX);
if (container.x > 0 )container.x = 0;
}
//vertical scrolling
if (stagePositionY > bottomEdge) {
container.y -= (stagePositionY-bottomEdge);
if (container.y < -(container.height-stage.stageHeight)) container.y = -(container.height-stage.stageHeight);
}
if (stagePositionY < topEdge) {
container.y += (topEdge-stagePositionY);
if (container.y > 0) container.y = 0;
}
}
hope that makes sense, thanks
**updated**
Your problem is that container.width is changed when your shapes fly away from initial rectangle.
If you create a var initialContainerWidth and save your container width there until you add any shapes to it and then use this saved variable instead of container.width, it will work fine. Or you can add your flying shapes directly to the stage so that they will not extend container's sizes.
You can just hardcode 1386 instead of container.width to check it.

AS3 - removing childs in parent container doesn't reposition childs correctly

I made this plugin wich positions all child objects of a container in a grid formation. Now I added a clickhandler to the childs in the container, and when I click one of them, it is removed. When I remove a full row (from top to bottom) on the right hand side, all goes well, but when I remove a full row on the left hand side, the position of all the items in the container stay on their place but the container itself will be moved to x = 0 and y = 0. What I want is that all childs in the container are moved to x:0, y:0 as one group.
some pictures on what I get and what I want:
1) What I get:
2) What I get when I remove a full row on the left:
3) What I want:
The code I use:
private function clickHandler(event:MouseEvent):void {
var name:String = event.currentTarget.name;
if(container.getChildByName(name) != null)
container.removeChild(container.getChildByName(name));
trace(name, "container.width: ", container.width);
trace(name, "container.width: ", container.height);
trace(name, "container.x: ", container.x);
container.graphics.clear();
container.graphics.beginFill(0x2C2C2C);
container.graphics.drawRect(container.x ,container.y, container.width, container.height);
container.graphics.endFill();
}
Anyone got an idea on how to fix this? :)
EDIT: Code for creating the grid:
private function generateGrid(rows:int, cols:int, spacing:int):void
{
for (var py:int = 0; py <rows; py++)
{
for (var px:int = 0; px <cols; px++)
{
if(childs.length > 0)
{
var child:* = childs.shift();
child.x = (child.width + spacing) * px;
child.y = (child.height + spacing) * py;
} else {
break;
}
}
}
}
There's not really anything to 'fix', you just haven't written any code to move those objects, so they're not moving. You're redrawing the background of the container based on the new width, but you haven't actually moved any of the objects inside that container.
There are a lot of ways you could do this. The simplest solution that comes to mind would be something like this:
- loop through all the children of the container and find the lowest x position.
- loop through again and subtract that lowest x value from the x position of each child.
(You probably want to do this for the y position too, so they'll move up when you remove the top row.)
You would run that entire process each time a child is removed. If the lowest position is 0, meaning there is an object in the leftmost position, then nothing moves, if there is a blank row, the lowest x will be greater than 0, and everything will move over by that amount.
Disclaimer:
It would probably be 'better' to not muddle the graphical views with the data structure so much, but that's the best suggestion I can offer without seeing the rest of your code.
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
public class Grid extends Sprite{
private var _squ:Square;
private var _cont:Sprite;
public function Grid() {
// constructor code
_cont = new Sprite();
addChild(_cont);
for( var i:uint = 0;i< 20; i++){
_squ = new Square(50,50,2,Math.random() * 0xFFFFFF);
_cont.addChild(_squ);
_squ.name = "square_"+i;
_squ.x = 100 + 52 * Math.round(i%5);
_squ.y = 50 + 52 * Math.floor(i/5);
_squ.buttonMode = true;
}
this.addEventListener(MouseEvent.CLICK, onClickAction);
}
public function gridAlign(cont:Sprite):void{
for( var i:uint = 0;i< cont.numChildren; i++){
_cont.getChildAt(i).x = 100 + 52 * Math.round(i%5);
_cont.getChildAt(i).y = 50 + 52 * Math.floor(i/5);
}
}
private function onClickAction(e:MouseEvent):void{
_cont.removeChild(_cont.getChildByName(e.target.name));
this.gridAlign(_cont);
}
}
}
try this.