I'm trying to scroll a series of thumbnails horizontally based on the mouseX position. I can get it to scroll but it's very choppy and for some reason it's not reading my start and end numbers so it will stop scrolling. Can anyone point me in the right direction? Thanks.
var thumbBounds:Object = new Object();
thumbBounds = thumbContainer.getBounds(this);
thumbContainer.addEventListener(MouseEvent.MOUSE_OVER, setScrolling);
private function setScrolling(me:MouseEvent):void
{
thumbContainer.removeEventListener(MouseEvent.MOUSE_OVER, setScrolling);
stage.addEventListener(Event.ENTER_FRAME, scrollThumbs);
}
private function scrollThumbs(e:Event):void
{
if(mouseX <= thumbBounds.x || mouseX > thumbBounds.width ||
mouseX < thumbBounds.y || mouseX > thumbBounds.height)
{
thumbContainer.addEventListener(MouseEvent.MOUSE_OVER, setScrolling);
stage.removeEventListener(Event.ENTER_FRAME, scrollThumbs);
}
if(thumbContainer.x >= 0)
{
thumbContainer.x = 0;
}
if(thumbContainer.x <= -842)
{
thumbContainer.x = -842;
}
var xdist:Number = new Number();
xdist = mouseX - 382;
thumbContainer.x += Math.round(-xdist / 10);
}
One error I see immediately is:
if(mouseX <= thumbBounds.x || mouseX > thumbBounds.width ||
mouseX < thumbBounds.y || mouseX > thumbBounds.height)
Shouldn't you be checking the mouseY agains the thumbBounds.y and thumbBounds.height?
As for the choppyness, that could be related to the framerate of the movie, the size and the number of the images. It also depends on the magnitude of your xdist value. I'd try and use interpolation (tweening) some how. Calculate the end destination of the container and animate it towards there using Tweener or TweenLite.
e.g.
TweenLite.to(thumbContainer.x, 0.5, { x: thumbContainer.x + Math.round(-xdist / 10) });
This will cause the movement between the thumbcontainer current position and the new position will happen smoothly over half a second (instead of immediately).
Related
private function scrollStage():void
{
if (lastPosX != lastPosX)
{
canScrollStage = false;
}
else
if (lastPosX == lastPosX)
{
canScrollStage = true;
}
if (canScrollStage)
{
if (rightKey)
{
//move background left
//something.x +=(stage.stageWidth * 0.5) - character.x * 2;
}
else
if (leftKey)
{
//move backgrounf Roight
}
for (var b:int = 0; b < childrenOnStage; b++)
{
if (getChildAt(b).name == "enemy")
{
getChildAt(b).x +=(stage.stageWidth * 0.5) - character.x
}
}
ground.x += (stage.stageWidth * 0.5) - character.x
}
else
{
//move the background
}
// do this last, everything moves around object
character.x = stage.stageWidth * 0.5;
lastPosX = character.x;
}
Someone told me to move the objects around the player and then update the players x position.
This is what I've done by looking at a tutorial ("Cartoon Smart");
In my player class I have a reset function.
private var xSpeed:int;
private var resetPos:Point;
public function player()
{
addEventListener(Event.ADDED_TO_STAGE, onAdd)
}
private function onAdd(e: Event): void
{
xSpeed = 3;
resetPos = new Point(x, y);
}
public function reset():void
{
x = resetPos.x;
y = resetPos.y;
//trace(resetPos);
//trace(resetPos + "player");
}
When the player falls to death this function is called
private function playerFalls():void
{
if (character.y > stage.stageHeight)
{
//take life away and go back to check point or back to reset
character.x = stage.stageWidth * 0.5;
character.y = 20;
//goblin1.reset();
//goblin2.reset();
//goblin3.reset();
//stage.x = stage.stageWidth * 0.5;
//canScrollStage = false;
}
}
if I use
character.x = stage.stageWidth * 0.5;
Then my character ends up in the middle, but it will end up in the middle since the scroll function dictates the player to be in the center always.
character.x = (stage.stageWidth * 0.5) - 400;// moves him back
but if character falls off left of the screen then he is moved back.
Any one have a solution for this please?
My question is, I want to reset the player's x position to 300 and y position to 10;
But I can't do this because the stage shifts and the co ordinate system changes.
In order for the player to go back to the original coordinate of the stage, the stage must scroll.
That's my idea, or perhaps the ground and enemies must do the opposite?
I sincerely apologize for the late answer. Okay, so your saying that when the character falls you don't want the screen to scroll all the way back to the character's start position. What you need to do is find the start positions of your character and ground (as well as any other layers such as backgrounds etc). Then wherever your fall function comes into place simply set the character and background positions to their starting coordinates.
function fall(){
char.x=charStartX;
char.y=charStartY;
ground.x=groundStartX;
ground.y=groundStartY;
//etc
}
For example, let's say you have a check point. If player hits check point charResetPoint = 100. If player falls then set it's x pos to charResetPoint
But I can't move the players x position because it will always be stage.stageWidth/2 due to my code.
So in theory it will be difficult to make a resetPoint, because when I add goblin 1.x , it's x pos is 900, if I scroll right goblon1 x pos will change. Everythings x pos changes and so does the stages.
I can't get a grasp on the concept, sortlry
I've been stuck on this problem for a very long time now, I've searched around alot and tried stuff, but nothing works. Some explanations are just very hard for me to understand as Im pretty new to programming overall and got alot to learn.
I have two problems
1: The ball wont collide with the bricks sometimes when the speed is too fast.
2: The ball is capable of hitting 2 bricks.
Both problems is related to the fact that 60 fps isnt enough for my type of collision detection to work properly.
I just need someone to explain in a simple way as possible what I need to do to make a collision detection that will prevent this from happen.
Here's my current collision code:
private function checkCollision(): void {
grdx = Math.floor((ball.x) / 28);
grdy = Math.floor((ball.y) / 14);
ngrdx = Math.floor((ball.x + dx) / 28);
ngrdy = Math.floor((ball.y + dy) / 14);
var flipX: Boolean = false;
var flipY: Boolean = false;
if ((grdy <= level.length - 1) &&
(ngrdy <= level.length - 1) &&
(grdy >= 0 && ngrdy >= 0)) {
if (testBlock(grdx, ngrdy)) {
flipY = true;
paddleFlag = 1;
}
if (testBlock(ngrdx, grdy)) {
flipX = true;
paddleFlag = 1;
}
if (testBlock(ngrdx, ngrdy)) {
flipX = true;
flipY = true;
paddleFlag = 1;
}
dx *= flipX ? -1 : 1;
dy *= flipY ? -1 : 1;
}
}
private function testBlock(xPos: int, yPos: int): Boolean {
if (level[yPos][xPos] > 0 && level[yPos][xPos] != 13) {
trace("hit on X,Y");
level[yPos][xPos] = 0;
breakBlock("Block_" + yPos + "_" + xPos);
trace("Block: " + totalBreaks + " / " + totalBlocks);
return true;
}
return false;
}
private function breakBlock(blockName: String): void {
if (this.getChildByName(blockName)) {
this.removeChild(this.getChildByName(blockName));
totalBreaks++;
}
}
Thank you and sorry for my bad english, its not my motherlanguage.
One solution is to move the ball in smaller iterations, multiple times in a given frame.
For example, and I am giving this solution assuming that you are moving the ball based on the time elapsed from the last frame.
Suppose that 30 milliseconds have elapsed since the last frame update. In that case you would update the movement/collision twice in that frame using 15 millisecond as your time elapsed.
The higher resolution of collision you want, the more iterations you would do.
Here's an example :
// class declarations
var lastFrame:Number;
var iterationsPerFrame:int;
function startGame():void
{
// lets specify 3 updates per frame
iterationsPerFrame = 3;
// save initial time
lastFrame = getTimer();
// create your listener
addEventListener(Event.ENTER_FRAME, update);
}
function update(e:Event):void
{
var currentFrame:Number = getTimer();
var deltaTime:Number = (currentFrame - lastFrame)/1000;
var iterationDelta:Number = deltaTime/iterationsPerFrame;
for (var index:int = 0;index < iterationsPerFrame;index++)
{
// I'm assuming dx,dy are the velocity of the ball, in pixels per second
ball.x += dx * iterationDelta;
ball.y += dy * iterationDelta;
// check collision
}
// set lastFrame to the currentFrame time, preparing for next frame
lastFrame = currentFrame;
// after this, your frame is going to render
}
You could work out how far the ball travels each frame (A) based on its speed, how far the ball is from the paddle (B) and if A > B manually trigger a collision that frame.
You're essentially checking every bricks X and Y coordinate to the balls X and Y coordinate, so if the bricks are stored in an array this becomes: Sqrt( Sqrd(p2.x - p1.x) + Sqrd(p2.y - p1.y))
for(var i=0; i<brickArray.length; i++)
{
var distance:Number = Math.sqrt((brickArray[i].x - ball.x) * (brickArray[i].x - ball.x) +
(brickArray[i].y - ball.y) * (brickArray[i].y - ball.y));
}
This is a very good tutorial on high speed collison detection:
http://www.newgrounds.com/bbs/topic/1072673
So I have been searching for a way to have a background orbit around a centerpoint. I came across the greensock blitmask that does an amazing job of wrapping the bitmap data to do infinte scrolling effects. However, I can't figure out a way to use this blitmask to rotate the bitmap data and still have the wrapping effect. Below is a link to my SWF.
The image that moves is the one that I wish to wrap and have the infinite scrolling effect. The problem is dealing with repositioning after the image has moved off the screen since it has been rotated.
EDIT: I totally forgot about this issue and decided put it on the backburner for my game since it was taking too long to figure. I recently returned to this concept because I had an idea to make it work. Below is a link to the .SWF that shows what I was trying to accomplish. Though this example works, I dont feel its the best solution.
"WASD" control movement
Orbiting Background
I used some trigonometry to calculate the distance a star is from the player. If that star is beyond that distance, reposition it using it's angle * -1. The code for this is under the link.
var travelVal:Number = 0;
var turnVal:Number = 0;
var currentChild:DisplayObject;
var currentStar:Star;
var childIndex:int = 0;
var angle:Number = 0;
var distance:Number = 0;
if (controller.isKeyDown(Keyboard.A))
{
turnVal += TURN_SPEED;
}
if (controller.isKeyDown(Keyboard.D))
{
turnVal -= TURN_SPEED;
}
if (controller.isKeyDown(Keyboard.W))
{
travelVal += PLAYER_SPEED;
}
if (controller.isKeyDown(Keyboard.S))
{
travelVal -= PLAYER_SPEED
}
for (childIndex = 0; childIndex < numChildren; childIndex++)
{
currentChild = getChildAt(childIndex);
//if (currentChild != player && currentChild != debugOutput && currentChild != blackBkgd)
if(currentChild is Star)
{
currentStar = currentChild as Star;
//move this child based on the travel value
currentChild.y += travelVal * currentStar.speed;
//calculate the orbiting
distance = Math2.distanceBetweenObjects(player, currentChild);
angle = Math.atan2(currentChild.y - player.y, currentChild.x - player.x);
if (distance > STAGE_WIDTH ) angle = angle * -1;
//get orginal angle in radians
//angle = Math.atan2(currentChild.y - player.y , currentChild.x - player.x);
angle = Math2.radiansToDegress(angle);
angle += turnVal;
//currentStar.rotation = angle;
angle = Math2.degreesToRadians(angle);
currentChild.x = player.x + (distance * Math.cos(angle));
currentChild.y = player.y + (distance * Math.sin(angle));
}
}
In order to rotate around a certain centerpoint, you first translate by (-centerpoint.x,-centerpoint.y), then rotate around (0,0) and then translate back by (centerpoint.x,centerpoint.y).
I have an animated MovieClip of a fly that spawns at a random location and moves across the screen by bouncing off the walls. But every time the animation starts over, it seems to "jump" to a random location. Here is the code I have for when it spawns:
private function beginClass(e:Event):void{
_root = MovieClip(root);
do {
xRandom = Math.floor(Math.random() * 500);
yRandom = Math.floor(Math.random() * 350);
this.x = xRandom;
this.y = yRandom;
} while (Math.abs(xRandom - mouseX) > 20 && Math.abs(yRandom - mouseY) > 20);
}
And this is the code for its movement:
//Bouncing the fly off of the walls
if(this.x >= stage.stageWidth-this.width){
//if the fly hits the right side
//of the screen, then bounce off
flyXSpeed *= -1;
}
if(this.x <= 0){
//if the fly hits the left side
//of the screen, then bounce off
flyXSpeed *= -1;
}
if(this.y >= stage.stageHeight-this.height){
//if the fly hits the bottom
//then bounce up
flyYSpeed *= -1;
}
if(this.y <= 0){
//if the fly hits the top
//then bounce down
flyYSpeed *= -1;
}
How do I fix it so that the fly continues moving in its appropriate path every time the animation starts over?
If I understand the problem correctly, when starting the animation you have to check if it has already been started before.
A simple boolean variable would do:
private var hasStarted:Boolean = false;
private function beginClass(e:Event):void{
_root = MovieClip(root);
if (!hasStarted) {
hasStarted = true;
do {
xRandom = Math.floor(Math.random() * 500);
yRandom = Math.floor(Math.random() * 350);
this.x = xRandom;
this.y = yRandom;
} while (Math.abs(xRandom - mouseX) > 20 && Math.abs(yRandom - mouseY) > 20);
}
}
This way it'll only execute the random placing code once.
I have this code that I found online that does an infinite rotating gallery, now my problem is that on enter frame it jumps and too fast. I want it to be as fast at after you hover out of the logo.
Here is the code:
//Import TweenMax
import com.greensock.TweenMax;
//Save the horizontal center
var centerX:Number = stage.stageWidth / 2;
//Save the width of the whole gallery
var galleryWidth:Number = infiniteGallery.width;
//Speed of the movement (calculated by the mouse position in the moveGallery() function)
var speed:Number = 0;
//Add an ENTER_FRAME listener for the animation
addEventListener(Event.ENTER_FRAME, moveGallery);
function moveGallery(e:Event):void {
//Calculate the new speed
speed = -(0.02 * (mouseX - centerX));
//Update the x coordinate
infiniteGallery.x+=speed;
//Check if we are too far on the right (no more stuff on the left edge)
if (infiniteGallery.x>0) {
//Update the gallery's coordinates
infiniteGallery.x= (-galleryWidth/2);
}
//Check if we are too far on the left (no more stuff on the right edge)
if (infiniteGallery.x<(-galleryWidth/2)) {
//Update the gallery's coordinates
infiniteGallery.x=0;
}
}
and here is the demo ยป
The speed of the scroller is based on three things:
1- The frame rate. The ENTER_FRAME event handler gets called on every frame, thus is directly influenced by the frame rate.
2- The speed damping number. In your case this is equal to 0.02. If you want to slow down the scrolling, make this a smaller number. Try 0.01 for half the speed.
3- The distance of the mouse pointer to the center x coordinate of your stage. The difference between the mouse pointer and the center of your stage is multiplied by your speed damping number. If you want the movement to stop when you are at or around the center change you code as follows:
var buffer:Number = 50;
function moveGallery(e:Event):void {
var diff = mouseX - centerX;
if (Math.abs(diff) > buffer)
speed = -(0.02 * (diff + (diff > 0 ? -buffer : buffer)));
else
speed = 0;
AS REQUESTED:
var centerX:Number = stage.stageWidth / 2;
var galleryWidth:Number = infiniteGallery.width;
var speed:Number = 0;
addEventListener(Event.ENTER_FRAME, moveGallery);
var buffer:Number = 100;
function moveGallery(e:Event):void {
var diff = mouseX - centerX;
if (Math.abs(diff) > buffer)
speed = -(0.02 * (diff + (diff > 0 ? -buffer : buffer)));
else
speed = 0;
infiniteGallery.x += speed;
if (infiniteGallery.x>0) {
infiniteGallery.x = -galleryWidth / 2;
}
if (infiniteGallery.x < -galleryWidth / 2) {
infiniteGallery.x = 0;
}
}