Flash AS3 - Centering camera on player when scaling in and out (zooming) - actionscript-3

I am building a survival horror like game and am hoping to make a very nice camera system to compliment the mechanics. Part of this is the fact that you will be able to crouch down and cover your face. The camera work I want to do with this is to zoom in to the character in order to constrain the view for the player as well.
The current MC structure that I have is:
GameMaster
>
Spawner (this is for the player and all enemies)
>
Player
The issue I'm having is that scaling the GameMaster (which is where side scrolling and other global game effects are happening) causes the centering of the camera to offset based on how far away the player is from 0,0.
You can see the issue clearly in this video. The red arrows point to the 0,0.
On this stackoverflow question the answer says to make a container for everything and center the containers 0,0 over the target that you want to zoom around. This poses a challenge for me because I would then have to get proper coordinates for an object nested 4 MC's in. I'm also unsure what that will then do for my current side scrolling camera.
Is there a way that I could mathematically figure out the offset when the character ducks? It seems like a viable option because you can't move until you let go of crouch and the camera zooms out.
If not, is the container MC a good option or is it just one of those "you gotta do what you gotta do." type situations?
[Added]
I also see something about Transform Matrices or something. Is that something that would work? I know NOTHING about them but I assume they are CPU heavy and wouldn't be a good option for a mechanic prevalent throughout the whole game.
[Added 2]
ALSO, I want to do a rotation camera effect that suffers from the same 0,0 issue. Blatantly showing up as the player and level rotating around some far off pivot point.
If a Transform Matrix can swiftly and functionally offset the 0,0 to the players location so that I can do all the camera effects and alterations. I think that may be the best way to go.
----Close to Conclusion----
In regards to Vespers answer. Would I then be able to tween the resulting transform?
If so then that completely answers my entire problem. If not, I have no clue how to get the result I want.

I think the container is the cleanest solution. Since it'll be centered on the player, rotations and scaling will work normally. You mention getting the coordinates for the nested MC is hard, but there is a built-in function to do exactly that: localToGlobal()
To get the player position in global coordinates, just do player.localToGlobal(new Point(0, 0)). This should return the Player's center in global coordinates. If your main container is not in global coordinates (because it's nested inside another transformed MC, for example), you can use the opposite function on the container to convert from global to local:
container.globalToLocal(player.localToGlobal(new Point(0, 0)))
Now you just need to center the container. That could also be used to simulate the camera movement. If you update the container position at every frame, it'll give the effect of the camera following the player.

Related

AS3 Can you make a sidescroller camera?

I've seen in flash sidescrollers they mostly use sidescroller by making the background move.
But if I had a background and I wanted the player to move and the camera to follow, how would I do it?
There are several ways to accomplish this. The first is to put all of the background objects into a container MovieClip and move that instead of the player. This also makes other aspects of having a camera, such as zoom and rotation, relatively simple, since you can just scale and rotate the container MovieClip.
Another method is putting all background objects into an array. Every time there is movement, you loop through the array and move the objects. This requires more math and separate x/ y variables for each object, so it's not as convenient.
One thing to note is that if you're going to rotate the camera, you might experience vibration issues as your camera gets further away from the origin. To prevent this, you'll have to shift all of the objects in your container MovieClip closer to the origin when they get too far away.
If you want the camera to ease towards the player's position, you just move 1/10 (or some other fraction) of the distance to the camera's target position each frame.

as3 3D global transform / rotation

I have a little problem. I have 2D image of roulette wheel on the stage and used 3D rotation tool to get a little 3D effect (Image 1). Now I want to rotate it on it's Z axis so that I can get spining effect of wheel. I tried to use rotationZ += ... but it doesn't rotate it the way I want. I saw one tool in flash toolbar called "Global transform" (Image 2). When I click it I see transformation lines for image (Image 3), that I need for rotation, the blue line is one I need (Z axis). But I don't know how to use that kind of transformation via code. I don't even know if that is local or global rotation. I hope you understand me, maybe pictures will help you! Thanks!
HERE IS DROPBOX LINK FOR IMAGES --> Dropbox Images
What you are trying to do is simply an issue of nesting elements and applying effects on them in certain ways.
To accomplish the rotation as you want, you'll want to create your roulette wheel image in 2D as if you were looking at from a birds eye view. I highly recommend creating this graphic in vector format. Import this graphic into Flash and turn it into a movieclip. For arguments sake, I'm going to give this movieclip an instance name of wheel so it is easy for us to follow along with these instructions. Now, within the wheel instance, you'll want to apply a rotation to the roulette wheel. You can accomplish this either by using a Motion tween on the timeline, but the best way would probably be to use a programmatic approach so you can randomize the rotation in some way.
Now, place the 'wheel' instance on the stage and use the 3D Rotation Tool and rotate the wheel on it's X axis, this will make the wheel look like one in your image.
Now if you have performed the rotation within the wheel instance properly, you will have your spinning wheel.
I've created a sample of what you want with the following files using Flash CC 2014 that you can download here:
FLA File
Sample compiled SWF FILE
There is actually some math involved in understanding 3D transformations - including rotations - and how they combine with each other.
If your are interested in further explanations, and have a bit of math background, have a look at the theory
otherwise, the first thing you should remember is that rotation/scaling/translations may be composed (combined) but that the order is very important. rotationX, rotationY, rotationZ are sort of "coordinates" that enable to describe any orientation in the vector space, like x,y,z describe any position. But they are not sufficient to allow to do any rotation around any axis from any current orientation.
In your case, what you want is to combine a rotation around it's own local z (blue) axis, which means before the initial rotation you have already applied. ex:
roulette.transform.matrix3D.prependRotation(10, new Vector3D(0,0,1));
where 10 would be the angle you chose for the rotation, and the pivot of your object would be the pivot of the rotation (ohterwise, specify your own pivot by passing an additional Vector3D
To complete the picture, if you use appendRotation() instead of prependRotation(), you will rotate your object in the z axis of the world (global) coordinates (after it's current trnasformation).
You may also as already suggested create a Symbol to use as a container, and rotate you object inside it's container, but messing with Matrix3D will give you more control in the end, often with just one line of code like in this case.

AS3: having problems implementing correct rotation with atan2

I have the following scenario: player is in the middle of the screen and never moves from those coordinates. If I click with the mouse on the far right of the screen, the A* script kicks in and moves the background the player is on according with its own walkable/not walkable criteria, so for example if there is an obstacle in between the center of the screen where the player always is in the far right of the screen, the background correctly moves in the opposite direction And when needed moves around the obstacle, so you have the illusion of player walking, but instead only the background moves.
my problem is that I don't know how to rotate my player to simulate that he is following the path that the actual background is making. For example, in the beginning, the player is facing down. If I click on the right side of the screen, the player should face right. When an obstacle is present, the player should face the direction of the path around the obstacle and so on
but again technically my player never moves, so I don't know what coordinates should I have the atan2 use. In my mind I thought that the player should rotate toward the center of the next best hop in the array of best path created during the A* script, but for some reason I can't figure out the correct coordinates y and x for the atan2 command
I bet this is a simple thing I overlooked, but apparently my mind is in shutdown mode, so I can use a new fresh perspective :-)
thanks!
First, do not code in brain shutdown mode, this can save you lots of brainhurt time.
You don't need atan2() in this scenario, since your player is technically on a grid instead of on the screen. Give the player internal coordinates on the grid that will be updated as the player walks around the world, and use them in your A* script. The A* script generates a sequence of tiles the player should walk, thus you derive player's facing from current and next tile, for example, if the next tile to walk is adjacent upwards, you make the player face up and continue moving.

Joining Sprites together in AS3?

So created a Sprite to which I add other Sprites which are game tiles. Each tile is 60 x 60 px big. In result I've the Sprite with about 200 childs (those tiles).
When I try to startDrag() the container sprite the lag when moving it is very noticeable..
Is there a way like to join the tile Sprites so the container would have only 1 child Sprite instead of 200? Because it lags so much probably cause it needs to move (change the x and y) all those 200 tiles.. Am I correct?
In this case I can't use the cacheAsBitmap property, cause user can zoom in or zoom out the map..
Glycerine & Aurel do touch the crux of the real solutions. However I'd like to add.
You are correct by the way, when you said it has to manage so many sprite locations when you move the container around. CacheAsBitmap sure does does tackle this to great extent but the real solution is blitting. Try this link for that :
http://www.adobe.com/devnet/flash/articles/blitting_mc.html
It doesn't matter if a user zoom or something of that sort is required cause you can always switch between bitmap data & the original vector sprites. Your problem arises in moving.managing lotsa sprites, so just before doing that use optimizations, after that let them be back to their selves.
I've had the same issue before. Is it possible to 'join' them together - in a sense.
When you add your 200 sprites onto a screen - I assume you put them all into another parent sprite.
A this point - you will take a snapshot, or a screenshot - or a photographic replica (whatever you want to call it) of all the sprites and write the image (bitmapData) to a parent sprite. At this point. delete/remove/hide/nullify the original sprites and you'll be left with a sprite containing bitmap data.
One big image to move about and zooming and the like is no bother.
If you need code - ask. It's time consuming code so you tell me first then I'll write it :P
Hm, joining them would actually be quite hard... You would need to get the graphics, the code and all and put that into the parent...
I don't think that is the problem - you should do something else... In this case, I think that by "tiles" you mean that the parent would be a tile map, correct? So, you probably have a 2-dimensional array (array of arrays) with tile types - instead of parsing that array at initialization, creating A LOT of Sprites, try re-parsing it in each frame (it is faster), but add only the Sprites that are possible to see. That is - their X position (after adding the zoom and camera X) is greater than -sprite.width, where the height is also scaled by the zoom, and lesser than stage.width + sprite.width (again, width after zoom). Same goes for Y, only with the height attributes.

Does the player move or the tiles in a tile-based game?

I'm not sure if this question fits properly, but I'm wondering in tile-based games, does the tiles 'shift' when the player is moving (and the player stays in the same place) or does the player move instead (and instead the tiles stay in the same place)?
Visually or in the model?
Visually, there’s usually some code that keeps the player fixed in the middle of the screen while the tiles scroll under him, with the tiles stopping and the player moving to the edge of the screen when the end of the map is reached. Typically this implies some sort of camera that knows how to follow the player, and perhaps changes its behavior depending on which direction the player is facing, and can also be locked for special effects and cutscenes.
In the model, it makes no sense to update the positions of all the tiles and every single object relative to the player, when you could instead just move the player.
Well, the specifics of how you want to draw it are up to you. Some tile-based games show the player fixed in the center of the screen -- in that case, your function to draw the character sprite always centers the character, while the function to draw the background would take an offset.
Others might give the player a pixel offset as well, either to show movement or to give "edges" to a map, not allowing the player to see what lies beyond.
How you implement it in your game is really up to you -- there's no "right" way to draw your sprites.
The tiles do. Unless there's no more to scroll in a certain direction, then the character moves. It's better to have as much as possible that's static cached together rather than move all the tiles individually.
The player moves, and the camera moves. The tiles are drawn shifted by the camera's position so that the world appears to scroll while the player stays roughly centered on screen. The camera follows the player, but usually a little loosely. (For example, you'll notice that you can walk a bit towards the edge of the screen before it starts scrolling in Super Mario Brothers.)