PDA

View Full Version : [AS3] Error #1180: Call to a possibly undefined method


Rafah_CT
10-17-2011, 05:12 PM
I moved all the “movement” logic of my truck, form the truck class to a new public class called movement, the thing is that when I call for this class public functions, flash tells me Error #1180: Call to a possibly undefined method..

The reason I want to create a whole separate class that manages movement is because I want to later implement an auto/manual driving system, and some logic that makes the background scroll to the opposite direction of the truck when the truck reaches the corners of the swf, but that’s not relevant at the moment, so:

Movement Class:

package
{
public class Movement
{
public var speed:Number = 0;
public var speedMax:Number = 8;
public var speedMaxReverse:Number = -3;
public var speedAcceleration:Number = .15;
public var speedDeceleration:Number = .90;
public var groundFriction:Number = .95;

public var steering:Number = 0;
public var steeringMax:Number = 2;
public var steeringAcceleration:Number = .10;
public var steeringFriction:Number = .98;

public var velocityX:Number = 0;
public var velocityY:Number = 0;

public function Movement()
{
speed *= groundFriction;
if (speed > 0 && speed < 0.05)
{
speed = 0;
}

velocityX = Math.sin (Truck.main.rotation * Math.PI / 180) * speed;
velocityY = Math.cos (Truck.main.rotation * Math.PI / 180) * -speed;

Truck.main.x += velocityX;
Truck.main.y += velocityY;

if (steering > 0)
{
if (steering < 0.05)
{
steering = 0;
}
}

else if (steering < 0)
{
if (steering > -0.05)
{
steering = 0;
}
}

steering = steering * steeringFriction;

steering -= (steering * 0.1);

Truck.main.rotation += steering * speed;
}

public function moveUp()
{
if (speed < speedMax)
{
speed += speedAcceleration;
if (speed > speedMax)
{
speed = speedMax;
}
}
}

public function moveDown()
{
if (speed > speedMaxReverse)
{
speed -= speedAcceleration;
if (speed < speedMaxReverse)
{
speed = speedMaxReverse;
}
}
}

public function moveRight()
{
steering += steeringAcceleration;
if (steering < -steeringMax)
{
steering = steeringMax;
}
}

public function moveLeft()
{
steering -= steeringAcceleration;
if (steering > steeringMax)
{
steering = steeringMax;
}
}
}
}

Truck Class:

package
{
import flash.display.MovieClip;
import flash.events.*
import flash.ui.Keyboard;

public class Truck extends MovieClip
{
static public var main;

public var xBuffer:int;
public var yBuffer:int;

public function Truck()
{
xBuffer = 50;
yBuffer = 50;

main = this;

addEventListener(Event.ADDED_TO_STAGE, onAddToStage);
}

private function onAddToStage(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddToStage);

init();
}

private function init():void
{
addEventListener(Event.ENTER_FRAME, enterFrame);
}

private function enterFrame(event:Event):void
{
Movement();

if(Key.isDown(Keyboard.LEFT) && x > xBuffer)
{
moveLeft();
}

else if(Key.isDown(Keyboard.RIGHT) && x < Game.WIDTH-xBuffer)
{
moveRight();
}

if(Key.isDown(Keyboard.UP) && y > yBuffer)
{
moveUp();
}

else if(Key.isDown(Keyboard.DOWN) && y < Game.HEIGHT-yBuffer)
{
moveDown();
}
}
}
}

____

I originally requested help at kongregate, but the I didn't understand the tips they gave me and since it took the guy who answered 12 hours to answer I'm asking for help in here, I'm posting what he told me to do and my key class and my document class..

package
{
import flash.display.*

public class Game extends MovieClip
{
static public var main;
static public var WIDTH:int = 700;
static public var HEIGHT:int = 600;

public var movement:Movement;
public var truck:Truck;
public var background:Background;

public function Game()
{
main = this;

Key.initialize(stage);

background = new Background();
addChild(background);

truck = new Truck();
truck.x = WIDTH/2;
truck.y = HEIGHT/2;
addChild( truck );

}
}
}

package
{

import flash.display.Stage;
import flash.events.Event;
import flash.events.KeyboardEvent;

public class Key
{
private static var initialized:Boolean = false;
private static var keysDown:Object = new Object();

public static function initialize(stage:Stage)
{
if (!initialized)
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
stage.addEventListener(Event.DEACTIVATE, clearKeys);

initialized = true;
}
}


public static function isDown(keyCode:uint):Boolean
{
return Boolean(keyCode in keysDown);
}


private static function keyPressed(event:KeyboardEvent):void
{
keysDown[event.keyCode] = true;
}


private static function keyReleased(event:KeyboardEvent):void
{
if (event.keyCode in keysDown) {
delete keysDown[event.keyCode];
}
}


private static function clearKeys(event:Event):void
{
keysDown = new Object();
}
}
}

(I didn't make this key class, I got it from a game's source code, I understand most of it(this is in case you say "but if you coded that key class you should know how to solve your problem))"


@Rafael:
So you refactored your movement into its own class? Great.
But why the heck did you hardcode the “Truck” into it? That breaks pretty much everything.
Stop abusing the static keyword.
Your Movement Class needs a reference to a DisplayObject it is supposed to move.
to do this, pass the reference to the constructor of the Movement class.
Your Truck should never react on Key-presses, it is just an graphical asset, keep logic and visuals separated.
In your Main class (aka document class):
- create a new Truck object, addChild it
- create a Movement Object, pass the reference to the Truck
- change variables of the Movement Object when a Key is pressed (in the Main class)


I replied:

I hardcoded truck into because it said it had no X or Y values.

I make the truck class react to the keys because when I extend my game, truck will be the class that governs all the truck clips that I have on my game, truck itself won’t do anything to a graphic, I believe I’m just thinking ahead of time when I do this.

In any case I am lost in how to do this: " pass the reference to the Truck"

Also, when you say make them static, you refer to the speed variables?

He just posted:

private var _target:DisplayObject;

public function Movement(target:DisplayObject)
{
_target = target;

I understand nothing from his tips, I'm hoping you can either explain them to me since he seems reluctant to do so, or just give new advice (the more details the better)

Sorry for the bother and any inconvinience.

arkitx
10-17-2011, 05:35 PM
public var movement:Movement;

movement.moveLeft();
movement.moveRight();
movement.moveUp();
movement.moveDown();

If not work, pack all source in a zip and post it here.




arkitx

solisarg
10-17-2011, 05:44 PM
Where are you instantiating Movement?

Jorge

Rafah_CT
10-17-2011, 08:08 PM
Didn't work, I instantiated it on the truck class, also I noticed a new error this time, on the Movement(); call from the truck class, it said something about expecting a value of 1, anyways here's the link, leave as many explainatory comments on the AS files as possible or explain any changes here please.

This says I need more than 50 comments to post a link so just add this ?d=PLNSHHXS next to the megaupload dot com link

solisarg
10-17-2011, 09:02 PM
Just fix or understand, that's the question :)
Probably you don't know what a static class is, but in a short way, you can't have instances, just a static representation, defeating the OOP principle of encapsulation and reuse. Since probably is not important by itself (the only important thing is that works), following and understanding OOP principles will allow you to scale your game or just stuck on the next step (because you're mixing a truck instance with a static class)
You mention you use a static instance because it said it had no X or Y values ... where? Inside Movement class? What about pass an instance of your truck to the constructor (as suggested by the kongregate huy)?


private function target:MovieClip
public function Movement(t:MovieClip){
target =t
}
(...)
target.main.rotation = xxxxx


This way your class aply the movement to the instance passed to the constructor as oposed to operate over a static class, breaking encapsulation and reuse

Jorge

Rafah_CT
10-17-2011, 09:12 PM
Oh ok, so the thing is I must tell the movement class to use target, then in the truck class I say t is truck, but if I want to move car (a new class for an example ) in the car class I say car is t...ok now that I got that, I still get the same "Error #1180: Call to a possibly undefined method..", and an error 1136: incorrect number of arguments. Expectd 1 on this line:

private function enterFrame(event:Event):void
{
Movement(); // the error 1136 is in this line

How can I fix that, since I suspect that until I fix that I don't think I'll fix the other four #1180 errors

solisarg
10-17-2011, 11:16 PM
To instantiate a class you need to use something like this:

var movement:Movement = new Movement();

and after that use class methods like arkitx suggest. So your Movement() call make no sense to me, since it suppose to call a method inside Truck class

Jorge

Rafah_CT
10-18-2011, 03:09 AM
Ok, I added this to the truck class

public var movement:Movement = new Movement();
public var movement:Movement = new moveUp();
public var movement:Movement = new moveDown();
public var movement:Movement = new moveLeft();
public var movement:Movement = new moveRight();

The pros: I don't get the error #1136 anymore! Neither do I get the error #1180!

The cons: I now get Error #1151 "A conflict exists with definition movement in namespace internal." for move up, down, left and right code lines, I google'd a bit and I got a tip that said I should uncheck the “Automatically declare stage instances”, and so I did, but I get the same error T_T

I haven't removed the "truck.main." part since I'm trying to figure this out first and then move on to removing the hardcoding of truck into the movement class..

So please help guys D: Try it out yourselves if you have the time, I know this sounds like I want you to get the work done for me but I'm stuck with this problem since friday night :/

solisarg
10-18-2011, 01:58 PM
The problem is that you don't have the base knowledge to write an OOP design. but that's not a problem, just an oportunity to growth if you have the patience.
Now you declare an instance of Movement as a property of your class (usually in OOP this is named composition) And you declare 4 times (so each new overwrites the previous) Instead something like this makes more sense


private var movement:Movement;

//constructor is not the best place, but an init method ... but it-s fine at current state
public function Truck()
{
...
movement = new Movement(this); //remember, Movement receives the target as argument
....

if(Key.isDown(Keyboard.LEFT) && x > xBuffer)
{
movement.moveLeft();
}

...


Play around this idea

Jorge

Rafah_CT
10-19-2011, 04:27 PM
Ok so I do that and I get Error 1151 on these lines


15
16 public function Truck()
17 {
18 xBuffer = 50;

I believe you're either latin-american or spanish. could you please then give me your msn so I can add you and you can explain how to solve the problem? I just want my truck to move again, but I want the movement logci away from it's class :/

solisarg
10-19-2011, 06:09 PM
Is you are spanish and want to ask in spanish, please move your question to a spanish Board, I'm moderator at http://foros.cristalab.com
I don't give MSN of mail support, sorry

Jorge

Rafah_CT
10-19-2011, 06:36 PM
Nah I don't have a problem with english, it's AS3 that I don't finish to understand, anyways, any clue on how to fix that error?

solisarg
10-19-2011, 07:25 PM
What the text of the error?

Rafah_CT
10-19-2011, 11:22 PM
It's the same error 1151 I posted twod days ago, but this time I get it on these lines:

15
16 public function Truck()
17 {
18 xBuffer = 50;

Error #1151 "A conflict exists with definition movement in namespace internal."

solisarg
10-20-2011, 03:25 PM
You probably instantiate twice the same class, probably movement is used also for another thing, use another name variable for the instance, i.e mov

Jorge

Rafah_CT
10-21-2011, 01:19 PM
You were right, I had instantiated movement in another class (game class or the document class), but now I get this:

"error# 1136 Incorrect number of arguments, expected 1." on this line:

public var movement:Movement = new Movement(this);

even though i have this:

public var target:MovieClip
public function Movement(t:MovieClip)
{
target = t;

So now I don't understand what I've got wrong, since I passed the "this" value D:

solisarg
10-21-2011, 01:41 PM
Sometimes errors are tricky, and not allways are in the exact line the compiler reports. You pass this as the argument and the class receives only one in the constructor, so this sounds perfectly right. Look around the line if you have miss an argument in another call (a listener perhaps), or probably you have another call, etc

Jorge

Rafah_CT
10-22-2011, 12:29 AM
Ok so just for the heck of it, I go to try and change whatever on my scripts, the thing is that before I do anything, I decide to test again, so I do, and instead of the error #1151, I get a new one, this one:

error #1067 implicit coercion of a value type Class to an unrelated type flash.display.MovieClip

TYhis error presents to me on this line, twice:


public var movement:Movement = new Movement(this);

I'm totally confused o_o

solisarg
10-22-2011, 01:52 AM
The argument for the constructor of Movement class should be a MovieClip, and Truck extends MovieClip, so you can use

new Movement(MovieClip(this));

or set to Truck the argument in Movement constructor

Jorge