Programming a Custom Ease - actionscript-3

Trying to create a dynamic wheelSpin with an easeInOut effect, but I want to manipulate the strength of the in and out more precisely. It will have a much longer ease out for example. AS3 Tween locks you into some simple presets but doesn't give me the control I need. I haven't found any tutorials on how to make one. The only thing I've seen for this is Greensock Custom Ease, but I'm trying to either create my own or use something free that doesn't have license of use issues first.
I have an idea to create a movie clip where I tween a simple object using bezier control, then making a call to the tweened property each frame and store it in a variable. Then I make a function for the object I want to manipulate to apply this change over a time relevant to that movies length of time. It seems like a functional hack...but rather clunky. I'd rather keep this code driven.

You can use my tweening class ru.delimiter.math.TweenALot, it depends on ru.delimiter.events.Chronos from the same repo, you can grab it or you can change TweenALot to use ENTER_FRAME instead.
The class is pretty old so please don't judge me for its style.
The usage:
import ru.delimiter.math.TweenALot;
var aTween:TweenALot = new TweenALot;
// The tweening target.
aTween.target = this;
// The destination properties.
aTween.properties = {x:100, y:100, alpha:0};
// The tweening duration, in milliseconds.
aTween.duration = 3000;
// Easing.
aTween.easingFunction = TweenALot.easeInOut;
// Pass the complete handler and start tweening.
aTween.start(onComplete);
function onComplete():void
{
trace("I have disappeared!");
// Destroy and release the tween instance.
aTween.destroy();
aTween = null;
}
Then, at the bottom of the class, there are a number of easing functions, I believe I did them to be compatible with something, just don't remember what exactly. Thus, you can create your own easing functions, you don't even need to add them to the class, just assign them to easingFunction property of the tween.
function weirdEasing(t:Number, b:Number, c:Number, d:Number):Number
{
var aProgress:Number = Math.min(1, t / d);
if (aProgress <= 0.5) return b;
return b + c * Math.pow((aProgress - 0.5) * 2, 2);
}

An alternative nice tween to give a slow organic tween out effect, slower than most exponential tweens, is using plain and simple zeno's paradox:
obj.x += (targetX - obj.x) / 0.5;
Just play with parameters, or add finer control. It's fun. You can add a check to se when distance is small enough to stop motion.

Related

Check the existence of an object instance

I'm surprised I don't know how to do this, but as it turns out I really don't; simply put, I'm trying to make a side-scrolling shooter game, a basic one and in it, I have 50 stars spawned on-screen through a "for" loop upon the game starting. There is a function which does this and a listener is at the beginning. Problem is, when you lose the game and go back to main menu, 50 more stars would be spawned, which isn't what I want. So, I'm trying to make an "if" statement check at the beginning, so that the game checks whether there is an instance/movie clip of the star object/symbol before determining whether the function that spawns stars should be called out with a listener. So, how do I do this? I looked through some other checks and they didn't help as the codes presented were vastly different there and so I'm just getting errors.
Let me know if a better explanation is needed or if you would like to see some of the code. Note that the game overall already has a lot of code, so just giving all of it would probably not be helpful.
I suggest you rethink your approach. You're focusing on whether stars have been instantiated. That's ok but not the most basic way to think about it.
I would do this instead
private function setup():void{
loadLevel(1);
addListeners();
loadMusic();
// etc...
// call all functions that are needed to just get the app up and running
}
private function loadLevel(lev:int):void{
addStars();
// call all functions that are needed each time a new level is loaded
}
private function restartLevel():void{
// logic for restarting level,
// but this *won't* include adding star
// because they are already added
}
There are other ways to do this but this makes more sense to me than your approach. I always break my game functions into smaller bits of logic so they can be reused more easily. Your main workhorse functions should (IMHO) primarily (if not exclusively) just call other functions. Then those functions do the work. By doing it this way, you can make a function like resetLevel by assembling all the smaller functions that apply, while excluding the part about adding stars.
Here's what I did to solve my problem... Here's what I had before:
function startGame():void
{
starsSpawn();
//other code here
}
This is what I changed it to:
starsSpawn();
function startGame():void
{
//other code here
}
when you said existance, so there is a container, i named this container, (which contain stars , and stars was added to it) as starsRoot, which absolutely is a DisplayObject (right?)
now, to checking whole childrens of a DisplayObject, we have to do this :
for (var i:int=0; i<starsRoot.numChildren; i++) {
var child = starsRoot.getChildAt[i];
}
then, how to check if that child is really star!?
as you said
whether there is an instance/movie clip of the star
so your stars's type is MovieClip, and they don't have any identifier (name), so how to find them and make them clear from other existing movieclips. my suggestion :
define a Linkage name for stars from library, thats a Class name and should be started with a capital letter, for example Stars
now, back to the code, this time we can check if child is an instance of Stars
for (var i:int=0; i<starsRoot.numChildren; i++) {
var child = starsRoot.getChildAt[i];
if (child is Stars) {
// test passed, star exist
break;
}
}

cocos2dx/coco2d layer transition

I hope to pop down a score panel when players win and pass the gate.
Normally it will pop down score board.
I think the best way is to use layer and pull down it.
But I only get the transition of scene, just wonder is there any way for layer transition?
Did not see an equivalent of CCTransitionScene :CCScene for CCLayer but layers can runActions using which we can bring out most of the animations/transitions.
Here is what I do in such situations but I guess you are thinking of the same thing. Nevertheless,
1.Create a layer and add it as a child at a position outside of your screen frame.
2.Then use CCMoveTo to move it to the desired location when you want to pull it down.
I have done something similar in the past.
Display your layer offscreen
i.e setposition(0, CCDirector::sharedDirector()->getWinSize().height*1.5f);
create an action to move it onscreen (I like to use CCEaseSineOut)
you can also use a callfunc to call a function when it has finished its animation
scoreLayer->runAction( CCSequence::create( CCEaseSineOut::create(CCMoveTo::create(1.0f, ccp(0, 0-_screenHeight*1.5f))), CCCallFunc::create(this, callfunc_selector(MainLayer::scorefinishedMove)), NULL));
Note: that function might need some fixes to ending brackets etc. And you may want to seperate out some of those actions rather than putting the initialization right in the runAction function
For layer transition you can do this:
CCScene* newScene = CCTransitionCrossFade::create(.5f,Layer2::scene());
CCDirector::sharedDirector()->pushScene(newScene);
In Layer2.cpp
CCScene* Layer2::scene()
{
CCScene* scene = CCScene::create();
CCLayer* layer = new Layer2();
scene->addChild(layer,1);
return scene;
}

Tweening with actionscript 3

I have been working on this one a while. I have an object in this case a movieClip called "mcBall". I set up two buttons "btnLeft" and "btnRight"with a tween so that the mcBall will ease between the two points smoothly.
Works fine, but where it gets glitchy is the the two buttons are still active an if the user clicks on either button of course the ball goes back to the starting point like it's supposed to.
My question is this ... What is the best way to have the buttons be de-activated while the "mcBall" object is moving. Would it be best to use a removeEventListener for the buttons and then have it added again. Would it be better to use an if statement like "If (mcBall.x = >=81 || <=469) removeEventListener"? Maybe use the tweenEvent.MOTION_FINISH to set up the eventListener again.
Any help would be greatly appreciated. Thanks
using Flash cs3
In this code I managed to turn off one button so that while the ball is moving it remains inactive but the other is still active. I'm not sure of the placement of the removeEventListener.
import fl.transitions.Tween;
import fl.transitions.easing.*;
function moveBallRight(evt:MouseEvent):void {
var moveBall:Tween=new Tween(mcBall,"x",Regular.easeOut,80,470,4,true);
btnRight.removeEventListener(MouseEvent.CLICK,moveBallRight);
btnLeft.addEventListener(MouseEvent.CLICK,moveBallLeft);
}
btnRight.addEventListener(MouseEvent.CLICK,moveBallRight);
function moveBallLeft(evt:MouseEvent) {
var moveBall:Tween=new Tween(mcBall,"x",Regular.easeOut,470,80,4,true);
btnRight.addEventListener(MouseEvent.CLICK,moveBallRight);
btnLeft.removeEventListener(MouseEvent.CLICK,moveBallLeft);
}
btnLeft.addEventListener(MouseEvent.CLICK,moveBallLeft);
Personally, I would recommend using the Actuate tween library. Unlike TweenLite/Max, it is fully opensource, and has most of the features, and is faster, with no pro/pay version.
I also like Actuate's interface much better than TweenLite. It is very similar so easy for people to start using it, but I like how tween modifiers are added in a more explicit way.
Simple example:
Actuate.tween(mySprite, 1, { alpha:1 });
Then is you want to specify an easing equation, just chain it on the end:
Actuate.tween(mySprite, 1, { alpha:1 }).ease(Quad.easeOut);
Want a delay as well? Add that to the chain:
Actuate.tween(mySprite, 1, { alpha:1 }).delay(1).ease(Quad.easeOut);
Of course you can also call a function onComplete, even with parameters:
Actuate.tween(mySprite, 1, { alpha:1 }).onComplete(trace, 'Tween finished');
Check out the Actuate Google Code page linked above for the full list of methods with examples.
I would recommend not using the native Tween class from fl.transitions.Tween. Its not very good. The industry standard is TweenMax from greensock.
Using TweenMax it is trivially easy to respond to end-of-tween events. You simply add an onComplete:myhandlerfunction to your tween.
An example from your above code would look like this:
Instead of
var moveBall:Tween=new Tween(mcBall,"x",Regular.easeOut,80,470,4,true);
You would have:
TweenMax.to(mcBall, 4, {x:470, ease:Expo.easeOut, onComplete:onBallMovedLeftComplete};
Hope that helps. And I hope you never have to use those native tween classes again. They are the pits.
I agree that you should use TweenLite or TweenMax as the other answers suggests.
From what I gather though, the question is the best approach in activating/deactivating your event listeners for the buttons.
I'd say the best approach is to have a function for adding your button listeners and another function for removing them.
Then, whenever you call a tween, you first call the removal function before executing the tween.
Then upon completion, you call the function to add them again. You can use the onComplete parameter with Tweenlite to specify the function to add the button listeners.
for example :
function moveBallRight(evt:MouseEvent):void
{
removeButtonListeners();
TweenLite.to(mcBall, 4, {x:470, ease:Expo.easeOut, onComplete:addButtonListeners};
}
function moveBallLeft(evt:MouseEvent):void
{
removeButtonListeners();
// do your tween
TweenLite.to(mcBall, 4, {x:80, ease:Expo.easeOut, onComplete:addButtonListeners};
}
function addButtonListeners():void
{
// add both listeners here
}
function removebuttonListeners():void
{
// remove both listeners here
}
Also, you'd obviously want to call addButtonListeners at the beginning of your program as well, so that the listeners are initially active when the program runs.

Is my class-less AS2 programming close to OOP in spirit?

So I'm a flash game developer trying to make the transition from AS2 to AS3+OOP, only 3 years or so after everybody else did. There's a plethora of free, very helpful material to go through and I've been spending 2-3 days wrapping my head around some of it, but by now I feel like I just want to start and try it out and learn the harder stuff as I go (just like I did with AS2).
I get the benefits of (most aspects of) OOP and I was once forced to learn to do a couple of games in Processing which had me write a few classes and I really liked the whole inheritance thing, which is the biggest reason I'm keen to move on, I think.
I just wanted to ask about game structure - is my current way of AS2 programming (see the example below, with some pseudo code) close to the way you'd organize things in OOP, or are there some big flaws in my game logic/structure that I can't see? The way I understand I would have to do differently in AS3/OOP is to have a class for moving stuff such as the player, hero, missiles etc, then have an enemy class that extends that class, then have classes for each enemy that extends the enemy class, unlike now where each "class" is instead an object and a function called from the main game loop, and sub-classes are instead "if"-clauses in each function. But except for that, is my programming style on the right track or do I need to re-think the logic behind my code for it to work effectively in an AS3/OOP setting?
Any advice will be much appreciated!
function initializeF() {
initializeVariablesF();
startGameF();
}
function initializeVariablesF() {
enemyO = new Object(); //which will contain each enemy instance
enemyA = new Array(); //which will be a list of all the enemies, maybe superfluous?
playerShotsA=new Array();
//and so on...
enemyDataO = new Object();
enemyDataO.goblin = new Object();
//and then some vars relating to the goblin, sort of a class without methods, right?
}
function startGameF() {
this.onEnterFrame = function() { //my game loop
checkKeysF(); //checks which keys are pressed, saves it to a global object
playerMovementF(); //moves the player about depending on which keys are pressed
playerShotsF(); //deals with the missiles/shots/lasers the player has shot
enemyCreatorF(); //decides when to create a new enemy
enemyF(); //deals with all enemies in the enemyA
enemyShotsF(); //deals with the missiles/etc the enemies have created
};
}
function enemyCreatorF(){
//randomly creates an enemy through a "factory" function:
if (random(20)==1){
attachEnemyF(enemyDataO.goblin, ...and some values like position etc)
}
}
function attachEnemyF(a_enemyType, ... a bunch of values like position){
//create a new enemy object
var enemy=enemyO[new unique enemy name]
enemy.enemyType=a_enemyType
enemy.clip=attachMovie(a_enemyType,"clip", [values like x and y passed on])
enemyA.push(enemy)
}
function playerShotsF(){
for (every shot in playerShotsA){
//move it about
for (every enemy in enemyA){
//if it hits an enemy, add damage to the enemy
}
}
}
function enemyF() {
for (every enemy in enemyA) {
//check if it's dead/less health than zero, if so remove it from the array, remove it's clip, null it's object
//if it's not, move it about, maybe have it shoot
//if it touches the player, decrease the player's health
//different behavior depending on the enemy's type by "if" or "switch" statements
}
}
I'm not sure the question is a good fit for SO as it's mostly asking for opinions, but anyway:
Having a base class with basic functions such as "move", "hitTest", "render", etc. is indeed what you should do. Then have the player's avatar, enemies, etc. inherit from this class.
The F suffix (and even O and A suffixes) are quite superfluous, since any good AS3 editor will already tell you whether the class member is a function, or an array, object, etc.
You don't need to store your enemies in both an array and an object, it's going to make it unnecessary complicated to remove or add an enemy. Instead, just store them all in an array and use simple loops to inspect their properties.

Game logic and game loops in ActionScript 3

I am making a Shooting game in flash actionscript 3 and have some questions about the flow of logic and how to smartly use the OOPs concepts.
There are mainly 3 classes:
Main Class: Initializes the objects on the screen.
Enemy Class: For moving the enemies around on the screen.
Bullet Class: For shooting.
What I want to do is find out if the Enemy has been hit by a bullet and do things which must be done as a result ...
What I am doing right now is that I have a ENTER_FRAME event in which i check collision detection of each enemy unit (saved in an array) with the bullet instance created, and if it collides then perform all the necessary actions in the Main class .. clogging the Main class in the process ..
Is this the right technique ? or are there better solutions possible ?
Try to think more OOP, what is every object responsible for?
We have the enemies wich we can hit:
class Enemy : extends NPC implements IHittable {
. . .
function update(delta) {
// move, shoot, etc.
}
function handleHit(bullet) {
// die
}
}
A hittable object:
interface IHittable {
function handleHit(bullet);
}
The bullet is suppose to move and hit things:
class Bullet : {
function update(delta) {
// update position
}
function checkHits(world:World) {
for each(var hittable:IHittable in world.objects) { // might want to cluster objects by location if you're handling lots of objects / bullets)
if (isColidingWith(hittable))
o.handleHit(bullet);
}
}
}
And then we have the world with everything inside:
class World {
var npcs: Array ...
var bullets: Array ...
var hittables: Array ...
function update(delta) {
foreach(var c:NPC in npcs)
c.update(delta);
foreach(var b:Bullet in bullets) {
b.update(delta);
b.checkCollisions(world);
}
}
}
And your main loop is just simple as that:
var lastTime:int;
function onEnterFrame(...) {
var now:int = getTimer(); // FlashPlayer utility function to get the time since start (in ms)
world.update(now - lastTime);
lastTime = now;
}
A few other notes:
try to do all the computation based on a delta of time, otherwise the game's speed will vary with the framefrate.
what happens when a character dies? bullet disappear? Well, you could do it several ways:
fire an event, like EnemyDied and remove it from the world
implement an interface CanDie that has a (get dead():Boolean property) and use that to cleanup the world at every update.
but don't write the code to remove the enemy in the Enemy class, because then you will be polluting the class with code that should be handled by the World, and that will be hard to maintain later.
Sorry for the long answer, but I couldn't help myself :)
Was clogging the Main class the problem, or finding out what bullet hit what enemy the problem? If it was the bullet, you need to describe the bullet behavior - can it hit multiple enemies, how fast does it move (is it possible that when testing using "enterFrame" the bullet will first appear in front of the enemy, and, on the second frame, it will appear behind the enemy?). May enemy be simplified to some basic geometrical shape like circle or rectangle, or do you need pixel-perfect precision? Finally, how many bullets and how many enemies are you planning to have at any one time? It could be too expensive to have a display object per bullet, if you are going to have hundreds of them, and then it could make more sense to draw them into single shape / bitmapdata.
If the problem is that the Main class is too long, there are several possibilities here.
A nobrainer answer to this problem - use inheritance to simply put parts of the code in separate files. Not the best way, but a lot of people do it.
If you did the first, then you'd realize that there are certain groups of functions you put into superclass and subclasses - this will help you split the "clogged" class into several smaller independent pieces that have more particular specialization.
After you did the second, you may find out that there is certain dependency between how you split the big class into smaller classes, so you can try generating those smaller classes by a certain pattern.
And then you write the clogged code that generalizes those parts you just managed to split.
Above is basically the cycle from more concrete to more generic code. In the process of perfecting the last step, you'll write some concrete code again. And that will move you to the step 1. Lather, rinse, repeat :) In fact, you don't want to write OO code, or procedure code or anything that fashion of the day tells you to do. You want to write good code :) And you do it by moving from more generic to more specific and back to more generic, until it's perfect :P
Probably not the best answer, but you must admit, you didn't give much info to give you more precise answer.