For a project I need to make a flashgame with the Kinect for Xbox.
Using the AS3NUI library to get acces to most of the Kinect functions worked well for me.
It's a pong game where you have to move your paddle vertically through hand movement.
I've tried a few ways of moving the paddle, but none of them is really accurate. And if they are more accurate, they aren't smooth at all anymore.
My first methode was setting the paddle.y to the value of the hand.y.
_paddleLeft.y = (userLeft.leftHand.position.y);
Of course the result was terrible.
This was my next try:
_paddleLeft.y = (userLeft.leftHand.position.rgbRelative.y * stage.stageHeight*2);
This was pretty accurate, but not smooth at all, and sometimes it was very hard to reach the top of the stage, or the bottom.
At last, I tried something else. I saved the hands last Y position, and checked if the new position was higher or lower, and on that I moved the paddle up or down.
currYLeft = userLeft.leftHand.position.rgb.y;
currYRight = userRight.rightHand.position.rgb.y;
if (currYLeft > prevYLeft + 10){
isDown1 = true;
isUp1 = false;
}else if( currYLeft < prevYLeft - 10){
isDown1 = false;
isUp1 = true;
}
prevYLeft = userLeft.leftHand.position.rgb.y;
prevYRight = userRight.rightHand.position.rgb.y;
In another enterframehandler, I make them move up or down.
This is the most smooth way I achieved, but it isn't very accurate anymore. There is some kind of delay wich you don't have with the first two ways.
I would like to know if it is possible to make the movement smooth AND accurate at the same time? And how this is possible.
If you already have an accurate solution, May be you can try putting some easing in it for the smoothness. You might wanna try using this instead in the enterFrame loop
_paddleLeft.y +=
((userLeft.leftHand.position.rgbRelative.y * stage.stageHeight*2)
-_paddleLeft.y)*0.3;
0.3 can be altered to other numbers between 0 and 1, depending on the easing speed you want...That's my best guess, hope this helps ^^
Related
I've been programming a side scroller based on a tutorial found in a book. My friend did the same, and his is working perfectly.
I've only really changed a few variable names around (I've also done animations differently) but for some reason, when my character is moving, there is a large amount of lag.
HOwever the lag is only present when there are 'walls' on the stage. When I scroll past them, the lag goes away, then returns.
Walls and Floors both use the same code (they are both assigned as 'floorObjects' variables) and use the same collision code, however I cannot figure out why there is lag involved.
From where the character starts (about 60x) if the character goes left, there is a HUGE amount of lag. If I go right, there isn't too much lag, until the screen starts to scroll.
The lag from going left I believe may have something to do with the program being preventing from scrolling off the map etc. But I can't figure out why there is lag when trying to move right.
I've listed the Scroll code, and the main loop, if need be I can upload the collisions code, and any help would be greatly appreciated.
Scroll code;
public function scrollGame()
{
var stagePosition:Number = gameLevel.x + player.mc.x;
var rightEdge:Number = stage.stageWidth - edgeDistance;
var leftEdge:Number = edgeDistance;
//Scroll the GameLevel to the Left if player moves right
if(stagePosition > rightEdge)
{
gameLevel.x -= (stagePosition - rightEdge);
//Prevent the game scrolling off the stage
if (gameLevel.x < -(gameLevel.width-stage.stageWidth))
gameLevel.x = -(gameLevel.width-stage.stageWidth);
}
//Scroll the GameLevel to the right if player moves left
if(stagePosition < leftEdge)
{
gameLevel.x += (leftEdge - stagePosition);
//Prevent the game scrolling off the stage
if(gameLevel.x > 0)
gameLevel.x = 0;
}
}
Main Loop:
public function gameLoop(e:Event)
{
//Get Time Difference
if(lastTime == 0) lastTime = getTimer();
var timeDiff:int = getTimer() - lastTime;
lastTime += timeDiff;
//Game Cycle tasks
//Only perform if in play mode
if(gameMode == "play")
{
moveCharacter(player, timeDiff);
moveEnemies(timeDiff);
checkCollisions();
scrollGame();
}
}
UPDATE:
So I "profiled" it, most of the time is being spent either in the MoveCharacter() function, using the gotoAndStop() command. So I removed that, and it made no difference, still lagging. I then removed the enemies also, still lagging. But turning quality down to low has somehow fixed it (though at a poor quality now ) Any ideas as to what is causing the lag and how to fix it?
this is from the flash university book isn't it?
The code is fine.
I know what will lag your flash game.
This is a guess though, and I do get this error some times.
Make sure your images are optimized!
If they're imported from photo shop or illustratro then flash will have to deal with those complicate vector points.
Use .png for transparent images, bitmaps don't hurt either.
I'm new to ActionScript 3 and I have a character which you can control, the screen scrolls right along the stage and he can fire missiles.
The problem I'm getting is the missiles are created via these co-ords:
bullet.x = hero.mc.x;
bullet.y = hero.mc.y
These work fine untill the screen has scrolled to the right. I assume it's because the bullets are being spawned as a result of them using the canvas x,y and not the stages x,y
So i'm wondering how to find out the x and y of my hero in relative to the canvas so i can spawn the missiles on top of him!
Thanks, and if you need any more information let me know, I'm new to all this. Thank you.
You can do that with localToGlobal and globalToLocal. Your solution would be something like:
bulletPos = bullet.parent.localToGlobal(new Point(bullet.x, bullet.y));
Beware, though, as those are last resort functions. Normally, you'd have all your elements using the same 'layer', so comparisons are easier and faster.
I am always trying to make a simple sound player which also has volume control but i cant figure out how to make it connected with the sound volume ,
i did make a Button which can be dragged but i wanted to set its maximum x and y ,
so i did this ,
vol_player_btn.addEventListener(MouseEvent.MOUSE_MOVE,buttonInside);
protected function buttonInside(e:MouseEvent):void {
if (e.buttonDown) {
vol_player_btn.x = 480;
vol_player_btn.y = mouseY;
}
}
but then
two problems arise which tells me i am making the volume button the wrong way
and maybe i need help
The two problems are
How do i link it with sound that volume is 100,90,80 etc. (i know about sound transforms but still not on how to link it with this button)
And it can go up and and down as much as the mouse moves , Yes i know i can set it
something like this in the function and inside the if(e.buttonDown)
if (mouseY is less than the number i will guess randomly)
{then do the things}
But what i know is that this is not an efficient way and so i will be eager to hear your ways ideas about the volume functionality
Lets start with solving the second problem. You want to implement an upper and lower 'cap' so that the volume button can't go above or below a certain height. Pretty simple to do:
if (e.buttonDown) {
vol_player_btn.x = 480;
vol_player_btn.y = mouseY;
// Logic to keep button y value between a min and max value
if(vol_player_btn.y > MAX_HEIGHT)
vol_player_btn.y = MAX_HEIGHT;
if(vol_player_btn.y < MIN_HEIGHT)
vol_player_btn.y = MIN_HEIGHT;
}
To solve the first issue you want to convert the height range of the button (eg. 120 to 320) into a typical volume value (0 to 100). You can do this simply by finding the percentage:
percentage = (vol_player_btn.y - MIN_HEIGHT) / (MAX_HEIGHT - MIN_HEIGHT)
Using the above equation, if the button height is at its lowest (eg y = 120px) the percentage will equal 0. If it's at its highest (eg y = 340) the percentage will equal 100. At it's mid point (eg y = 230) the percentage will equal 50, and so on.
I am making an achtung die kurve-like game in AS3.0. So far I've done the movements of the 4 different players, and it works alright.
I am now to make collision detection, in order to test if a 'worm'-so to speak, is colliding with eachother or its own tail.
As I understand it, if I use hitTestObject(); it will use the registration area of the whole object, which would be a huge problem, seeing since this registration makes a 4-sided registration that contains all of the object. So if this is used, it will 'collide' just by entering this rectangle instead of hitting the actual worm. Is this correctly understood?
I've been looking through different methods of collision detection, and can't seem to find an optimal one for my project.
My thought were to check if the 'worms' are drawing their new sprites on a white background. if they aren't, then it must have hit something.
You can see how I used my code here: code in .as format linked to an .fla file
Sorry for my ill-formulated question, hope it makes somewhat sense.
Any help is greatly appreciated!!
Best regards - Jesper
Try this function if you want a Pixel Perfect Collision Detection with efficient CPU usage:
trace("Collided: " + (areaOfCollision(mc1, mc2) != null));
trace("Where: " + areaOfCollision(mc1, mc2));
function areaOfCollision(object1:DisplayObject, object2:DisplayObject, tolerance:int = 255):Rectangle {
if (object1.hitTestObject(object2)) {
var limits1:Rectangle = object1.getBounds(object1.parent);
var limits2:Rectangle = object2.getBounds(object2.parent);
var limits:Rectangle = limits1.intersection(limits2);
limits.x = Math.floor(limits.x);
limits.y = Math.floor(limits.y);
limits.width = Math.ceil(limits.width);
limits.height = Math.ceil(limits.height);
if (limits.width < 1 || limits.height < 1) return null;
var image:BitmapData = new BitmapData(limits.width, limits.height, false);
var matrix:Matrix = object1.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object1, matrix, new ColorTransform(1, 1, 1, 1, 255, -255, -255, tolerance));
matrix = object2.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object2, matrix, new ColorTransform(1, 1, 1, 1, 255, 255, 255, tolerance), BlendMode.DIFFERENCE);
var intersection:Rectangle = image.getColorBoundsRect(0xFFFFFFFF, 0xFF00FFFF);
if (intersection.width == 0) return null;
intersection.offset(limits.left, limits.top);
return intersection;
}
return null;
}
After a successful preliminary hitTestObject(), this function backgroundly takes a snapshot from the shapes of both objects painted with different colors each, then overlays them intersecting the colors on a new one, returning the Rectangle of the resulting shape. So cool.
To learn more about Pixel Perfect Collision Detection you can google Collision Detection followed by one of these names: "The ActionScript Man", "Troy Gilbert", "Boulevart (wim)", "Grant Skinner (gSkinner)" or "Senocular". Those guys are awesome AS3 references by the way.
The problem you discribe is a very common problem for collission detection because the object has a set width and height and therefor defines a rectangle as the object.
There is a solution however to make a colission detection system on pixel level I have found this on the official site and this made me able to make collission detection for bitmaps on pixel level.
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d55.html
hope it helps you out in the same way.
Looking at the screenshots of that game, I think the best model would be to describe each worm as a chain of circles. Then divide the world/level in a grid with cells somewhat larger than the circle radii.
The collision check would then be:
clear grid
place each circle into the 1 or more grid cells it falls in
iterate over all cells, for each cell:
for each pair of circles (partially) in this cell, check if they intersect. If they do; collision.
Note that this may result in more than 1 collision occurrence between circle A and B, so you'd also need to check that to avoid duplicates.
Step 1 and 2 can be optimized by not clearing the grid, and instead of step 2, updating each circle's cell after it moves. If you size your cells like 5x the size of a circle, a circle can stay in the same cell for a few frames, avoiding excessive add/remove operations.
I'm doing something similar in a project of mine right now, except with space ships! My grid cells are currently 256x256 (too big for your project I think) and my units have radii of about 20.
I am struggling with this for 3 days now, would appreciate your help!
I am trying to make simple continuous animation on y axis.
The problem is that the animation is not smooth!!!
It has jumps and hiccups.
It is hard to see in the beginning, but once you see it, you can't get rid of it.
Here is an example:
http://dl.dropbox.com/u/19570262/movementTest.swf
Here is the source file:
http://dl.dropbox.com/u/19570262/movementTest.fla
This particular code is pretty simple:
import flash.events.Event;
addEventListener(Event.ENTER_FRAME, moveRoad);
var deltaY:Number = 0;
function moveRoad(event:Event):void
{
deltaY = (deltaY < stage.stageHeight) ? deltaY + 5 : 0;
road1.y = deltaY;
road2.y = deltaY - road1.height
}
But trust me until now I tried like 20 different solutions which also didn't work.
The solutions I tried until now:
animate by setInterval()
animate by getTime()
animate bitmaps
animate by copyPixels
The only one that worked was using stage3D and Starling! But I can't use it for my project.
Anyone?
You could try using TweenLite and BlitMask
http://www.greensock.com/blitmask/