Moving away object when hit each other - actionscript-3

I don't wanna to overlap each other the objects.Also I wanna keep the objects in stage limit.The buttons must move away when hit each other.I tried hitTestObject but buttons move like this.
Sample move code for fish 2 *UPDATE
var fish2x:Number=10;
var fish2y:Number=14;
 
stage.addEventListener(Event.ENTER_FRAME,h42);
function h42(s:Event = null) {
fish2.x+=fish2x;
fish2.y+=fish2y;
if ((fish2.x>=stage.stageWidth-fish2.width/2)|| (fish2.x <= fish2.width/2 )) {
fish2x*=-1;
}
if ((fish2.y>=stage.stageHeight-fish2.height/2)|| (fish2.y <= fish2.height/2 )) {
fish2y*=-1;
}
if (fish2.hitTestObject(fish3)){
fish2y *= -1;
fish3y *= -1;
h42();
}
}
Also I tried in diffrent function
stage.addEventListener(Event.ENTER_FRAME,crash);
function crash(s:Event) {
 
if (fish2.hitTestObject(fish || fish3 )) {
fish2y*=-1;
message.text="crash";
}
}
For more than 2 fish not work.
I set null fish2 and fish 3 than I use this code.
if (fish2.hitTestObject(fish3 || fish4)){
fish2y *= -1;
fish2x *= -1;
h42();
}
I changed hittestoject all off them.All function change like this but it not work.
Update 2
Now it's no error,but not happens when fish3 hit each other.I removed "null" fish and fish 3 just used for fish 2.
if (fish2.hitTestObject(fish || fsih3)){
fish2y *= -1;
fish2x *= -1;
fishy*=-1;
fishx*=-1;
fish3y*=-1;
fish3x*=-1;
}
}

I think it is because they are both moving. When you check collisions between A and B Fishes, if the collision is true, don't just change their speed by *=-1. Instead, also move them one time.
if (A.hitTestObject(B)){
Ay *= -1;
Ax *= -1;
By *= -1;
Bx *= -1;
h42();
}
and add null to your default value like this:
function h42(s:Event = null) {

Related

Game Maker:DoAdd:2:undefined value

Code in Step:
If (keyboard_check(ord("W"))) { phy_position_y -= 4;
}
If (keyboard_check(ord("A"))) { phy_position_x -= 4;
}
If (keyboard_check(ord("S"))) { phy_position_y += 4;
}
If (keyboard_check(ord("D"))) { phy_position_x += 4;
}
Pressing any of the WASD keys produces the above error.
Check if phy_position_y and phy_position_x have been initialised before.
It tries to add 4 to it's value, but it can't do that because it doesn't know it's own value. (Even if it's 0, you should initialise it with 0)
So for example, you can put this in your Create Event:
phy_position_x = 0;
phy_position_y = 0;
Alternatively, assuming you'll decide the objects current position, you can also use the build-in variables x and y:
If (keyboard_check(ord("W"))) { y -= 4;
}
If (keyboard_check(ord("A"))) { x -= 4;
}
If (keyboard_check(ord("S"))) { y += 4;
}
If (keyboard_check(ord("D"))) { x += 4;
}
I think eventually, you'll need to define the x and y anyways if you want to move your object, but understanding custom variables and the need to define them first is a key.
phy_position_x and phy_position_y can only be used if Uses physics flag is checked for the object. Either enable that, or use the regular x and y as Steven suggested.

as3 move object back and forth on iPad or tablet

I am working on a 2d project for iPad where a ball moves back and forth. When it hits the border it has to rotate a bit and roll back in another direction and leaving a child behind that also starts to move and follows a random path. (I made the project in Scratch. See code.)
ball_mc.addEventListener(Event.ENTER_FRAME, moveBall);
function moveBall(e:Event):void {
ball_mc.rotation += 1;
if (ball_mc.x < (stage.stageWidth - 100)) {
//trace('move forward');
ball_mc.x += 2;
} else {
// while(ball_mc.x > 100)?
// trace('move backward');
// how does it roll back?
ball_mc.x += -2;
}
}
}
You need a variable that holds the value of the direction or velocity. This variable should be changed to 2 if the ball passes a left side boundary and changed to -2 if the ball passes a right side boundary. Like this:
var ballSpeed:Number = 0; // this should go where you declare global variables such as at the beginning of your main class before the constructor
ball_mc.addEventListener(Event.ENTER_FRAME, moveBall);
function moveBall(e:Event):void {
ball_mc.rotation += ballSpeed;
if (ball_mc.x < (stage.stageWidth - 100)) {
ballSpeed = 2;
} else if (ball_mc.x > stage.stageWidth){
ballSpeed = -2;
}

How can I code an object to spawn onto the stage in the Actions panel?

I am trying to introduce a new ball into my pong game, sort of like a power up. I am writing all of my code in the Actions panel in the first frame. The new ball should appear on the stage and start moving around randomly like the original ball. Although I am using a code snippet and not .as file. So all of my code is in the Actions panel(Accessed by pressing f9).
I would also like my dynamic text box to merge with the stage colour so that you can't see the white background.
I can't show you what the fla looks like because I have less than 10 reputation, but the dynamic text box will not merge into the background and instead has a white surrounding. This hides the ball when the ball goes up.
import flash.events.Event;
import flash.ui.Mouse;
//hide mouse
Mouse.hide();
init(); //initialises everything
var bSpeedX:int = -3.5;
var bSpeedY:int = -2.5;
// assign a maximum speed to the AI
var compPaddleSpeed:int = 3.5;
var pScore:int = 0;
var cScore:int = 0;
// Updates the score
function scoreUpdate():void {
playerScore.text = ("Player Score: " + pScore);
computerScore.text = ("AI Score: " + cScore);
}
function init():void //tells flash not to return values
{
stage.addEventListener(Event.ENTER_FRAME, loop);
}
/*we want the ySpeed to be larger if there
is a greater difference between the y
positions of the ball and paddle, so I started with
(gameBallY-padY). To convert this difference
into a number between -1 and 1, I divided
this number by 25, which
is half the height of the paddle. Finally, I wanted
the ySpeed to be more powerful than
just -1 to 1, and after a bit of trial and error
I decided to times by 5 at the end
to change the total magnitude of the new ySpeed.*/
//defying the laws of Physics
function calculategameBallAngle(padY:Number, gameBallY:Number):Number
{
var ySpeed:Number = 5 * ((gameBallY-padY) / 25 );
return ySpeed;
}
//main loop
function loop(e:Event):void
{
//makes the paddle track the mouse
playerPaddle.y = mouseY;
//paddle AI
if(compPaddle.y < gameBall.y - 10){
compPaddle.y += compPaddleSpeed;//make it go up
} else if(compPaddle.y > gameBall.y + 10){
compPaddle.y -= compPaddleSpeed;//make it go down
}
//Collisions
if( playerPaddle.hitTestObject(gameBall) == true ){
if(bSpeedX < 0){
bSpeedX *= -1;
bSpeedY = calculategameBallAngle(playerPaddle.y, gameBall.y);
}
} else if(compPaddle.hitTestObject(gameBall) == true ){
if(bSpeedX > 0){
bSpeedX *= -1;
bSpeedY = calculategameBallAngle(compPaddle.y, gameBall.y);
}
}
//makes the gameBall move
gameBall.x += bSpeedX; //each frame, we add the bSpeedX to the ball's x position.
gameBall.y += bSpeedY; //same for the bSpeedY to the ball's y postion.
// checks to see if the ball misses the paddle
if(gameBall.x <= gameBall.width/2){
gameBall.x = gameBall.width/2;
bSpeedX *= -1;
cScore ++;
scoreUpdate();
//keeps the ball within the stage
} else if(gameBall.x >= stage.stageWidth-gameBall.width/2){
gameBall.x = stage.stageWidth-gameBall.width/2;
bSpeedX *= -1;
pScore ++;
scoreUpdate();
}
if(gameBall.y <= gameBall.height/2){
gameBall.y = gameBall.height/2;
bSpeedY *= -1;
}
else if(gameBall.y >= stage.stageHeight-gameBall.height/2){
gameBall.y = stage.stageHeight-gameBall.height/2;
bSpeedY *= -1;
}
//-------------------------------------------------------
//keeps the player paddle within the stage
//check if paddle is above top of the screen
if(playerPaddle.y - playerPaddle.height/2 < 0){
playerPaddle.y = playerPaddle.height/2;
} else if(playerPaddle.y + playerPaddle.hieght/2 > stage.stageHeight){
playerPaddle.y = stage.stageHeight - playerPaddle.height/2;
//check if paddle is below bottom of the screen
} else if(playerPaddle.y + playerPaddle.height/2 > stage.stageHeight){
playerPaddle.y = stage.stageHeight - playerPaddle.height/2;
}
}
If you only want your ball to be replaced with new one which has diffrent grphics and/or speed you can for example export your ball class to action script:
Library>RMB on your symbol>Properties>ActionScript Linkage>Export for ActionScript
Type your class name under Class: field like "MyBallClass" and hit OK.
Now you can construct this ball in your code and replace old one like this:
var newBall:MyBallClass = new MyBallClass();
addChild(newBall);
newBall.x = gameBall.x; newBall.y = gameBall.y;
gameBall = newBall;
Additionally you can define new variable like var speedModifier:Number = 1; to use with:
gameBall.x += bSpeedX * speedModifier;
gameBall.y += bSpeedY * speedModifier;
And change that also when you change the ball.
If You want to have multiple balls at same time You really should consider build this in OOP. For simplest example in addition to previous one
You can create MyBallClass.as file and write in it something like:
package
{
import flash.display.Sprite;
import flash.geom.Point;
public class MyBallClass extends Sprite
{
public var speedFactor:Number;
public var speed:Point = new Point(-3.5, -2.5);
public function MyBallClass(x:Number, y:Number, speedFactor:Number = 1)
{
this.x = x; this.y = y;
this.speed = speed;
}
}
}
Now you can create container for all the balls in yor game.
var balls:Vector<MyBallClass> = Vector<MyBallClass>([]);
and run your physics for all of them in a loop.
Generally main code would look something like this:
var balls:Vector.<MyBallClass> = Vector.<MyBallClass>([]);
addBall(...)//place first ball.
function loop(e:Event):void {
processBalls();
if(wantToAddNewSuperSpeedBall) addBall(x,y,3);
...
}
function processBalls() {
for (var i:int = 0; i < balls.length; i++) {
detecCollision(balls[i]);
moveBall(balls[i]);
//any code that process a single ball...
}
}
function addBall(x:Number, y:Number, speedFactor:Number = 1) {
var newBall:MyBallClass = new MyBallClass(x,y, speedFactor);
addChild(newBall);
balls.push(newBall);
}
function moveBall(ball:MyBallClass) {
ball.x += ball.speed.x * ball.speedFactor;
ball.y += ball.speed.y * ball.speedFactor;
}
So you should modify all functions which affect ball behavior to work with ball passed as argument, not only one specific instance and then use them for all balls.
There are more to cover in this topic and this isn't maybe the best approach but I've tried to make it easy to understend. There a lot of guides for OOP so you can get better idea about what is going on if you read them.
I hope that helped you somehow.

How to scale an object so that when it equals 0 it will go to the next frame? AS3

Ok, I've got some script for the Alice in Wonderland scene were she is eating cake and drinking potion to be bigger and smaller. I have been able to link two buttons so that when eat_me is clicked she is made smaller and when drink_me is clicked she is made bigger.
What I want to achieve is for Alice to be given a number like 2 and when you click eat_me it goes down by 1 and when you click drink_me it goes up by 1. I then want AS3 to recognise when Alice is at 0 to then move to the next frame. I have some code but not too sure whether I am close or not.
var alice_size:Number = 2;
drink_me.addEventListener(MouseEvent.MOUSE_DOWN, resizeAlice);
function resizeAlice(event:MouseEvent):void {
sitting_alice.width = sitting_alice.width * 2;
sitting_alice.height = sitting_alice.height * 2;
{if (drink_me.hitTestObject(sitting_alice))
alice_size = alice_size +1;}
}
eat_me.addEventListener(MouseEvent.MOUSE_UP, resizeAlice2);
function resizeAlice2(event:MouseEvent):void {
sitting_alice.width = sitting_alice.width / 2;
sitting_alice.height = sitting_alice.height / 2;
{if (eat_me.hitTestObject(sitting_alice))
alice_size = alice_size -1;}
}
if (alice_size == 0){
gotoAndStop (405)
}
Move alice_size's declaration so that is a member of the current class. I would advise doing the same for resizeAlice() and resizeAlice2(), though you don't have to do it for them. Also drink_me and eat_me are listening for different types of events; make them both either listen for MouseEvent.MOUSE_UP or MouseEvent.CLICK. I'm not sure why hitTestObject() is being used, but the reason may lie in other code you have.
What you have is pretty close.
The event you want is MOUSE_CLICK.
Test for the less than zero condition when you are deciding whether or not to advance the frame -- so you don't 'pass' 0, and never get to the frame you want.
Try to use more descriptive function names.
Get rid of the hit test too, unless there is some other reason you need it there (I left it in).
My version of your code:
var alice_size:Number = 2;
drink_me.addEventListener(MouseEvent.MOUSE_CLICK, growAlice);
function growAlice(event:MouseEvent):void {
sitting_alice.width *= 2;
sitting_alice.height *= 2;
if (drink_me.hitTestObject(sitting_alice)) {
alice_size = alice_size +1;
}
}
eat_me.addEventListener(MouseEvent.MOUSE_CLICK, shrinkAlice);
function shrinkAlice(event:MouseEvent):void {
sitting_alice.width *= 0.5;
sitting_alice.height *= 0.5;
if (eat_me.hitTestObject(sitting_alice)){
alice_size = alice_size -1;
}
}
if (alice_size <= 0){
gotoAndStop (405);
}

Flash (AS3) Movieclip Rotation

if (rotCW)
{
tramp1.rotation += 3;
if (tramp1.rotation = 90){
tramp1.rotation += 0;
}
}
I'm trying to make it so that if the movieclip's rotation is 90, its rotation speed is 0.
But every time I press the ' key (which triggers rotCW), the movieclip's rotation just goes to 90.
your problem is assignment within the 2nd condition. you need to use "=="
if (rotCW)
{
tramp1.rotation += 3;
if (tramp1.rotation == 90){
tramp1.rotation += 0;
}
}
edit: the +=3 line you have executes regardless of angle. if you are passing 90 and dont want to, you can test for the opposite condition and increment in that case. eg: if less than 90.
if (rotCW)
{
if (tramp1.rotation < 90){
tramp1.rotation += 3;
}
}