As3: Bullet giving me errors? - actionscript-3

I have an enemy class which spawns bullets at the player.
private function fireBullet()
{
if(isFiring)
{
fire();
}
}
public function fire():void
{
var bullet:Bullet = new Bullet(x, y, rotation);
stage.addChild(bullet);
}
And in the bullet class:
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Bullet extends MovieClip {
private var _root:MovieClip;
private var isVanished:Boolean = false;
public function Bullet(x:int, y:int, rotation:Number)
{
this.x = x;
this.y = y;
this.rotation = rotation;
_root = MovieClip(root);
addEventListener(Event.ENTER_FRAME, loop);
}
private function loop (event:Event):void
{
if(this.hitTestObject(_root.assassin.hitbox))
{
_root.hitPoints -= 30;
}
else
{
y-=Math.cos(rotation/-180*Math.PI)*(15);
x-=Math.sin(rotation/-180*Math.PI)*(15);
}
if(this.x < 0 || this.x > _root.stageWidth || this.y > _root.stageWidth || this.y < 0)
{
removeChild(this);
removeEventListener(Event.ENTER_FRAME, loop);
}
}
}
}
However, when I start the game, I get a 1009 error regarding line 23, and the game slows down rapidly as the bullets don't even move.
I also get an 1063 error, expecting 3 but having 0.
ArgumentError: Error #1063: Argumentblabla for Bullet(). Expected 3 but 0 were shown. ((translated))
at flash.display::Sprite/constructChildren()
at flash.display::Sprite()
at flash.display::MovieClip()
at Main()[C:\Venture Inc\Main.as:189]
This is what main looks like
//Constructor
public function Main()
{
addChild(container_staff);
addChild(container_wall);
etc etc etc

ArgumentError: Error #1063: Argumentblabla for Bullet(). Expected 3 but 0 were shown. ((translated))
Bullet class constructor has 3 arguments. Check your code more precisely, I think you have something like this:
var bullet: Bullet = new Bullet();
Also there is problem with your code. Every bullet subscribes for the ENTER_FRAME. Centralize your game, create main loop, and update all game actors(bullets, enemies, etc) from there.

Related

Looping Error when doing a hitTest in as3

So, I have this code:
public function hitTest1(e:Event) : void
{
if (hitTestObject(target.hit)){
gotoAndStop(2,"Scene 1");
removeEventListener(Event.ENTER_FRAME, hitTest1);
}
}
In which target is the object that is going to be hit, and hit is a symbol in a layer over said object. When I run the code I get this error over an over again.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.Mass.basics1::Asteroid/hitTest1()
NOTE: Asteroid is the .as file that contains all of this code.
Here is the rest of the code for reference :
package com.Mass.basics1
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
public class Asteroid extends MovieClip
{
public var target:Cosmo;
private var stageRef:Stage;
private var speed:Number;
// public var ourAsteroid:Asteroid = new Asteroid(stage);
public function Asteroid(stageRef:Stage)
{
this.stageRef = stageRef;
setupAsteroid(true);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
addEventListener(Event.ENTER_FRAME, hitTest1);
}
public function hitTest1(e:Event):void
{
if (hitTestObject(target.hit))
{
gotoAndStop(2,"Scene 1");
removeEventListener(Event.ENTER_FRAME, hitTest1);
}
}
public function setupAsteroid(randomizeY:Boolean = false):void
{
//inline conditional, looks complicated but it's not.
y = randomizeY ? Math.random() * stageRef.stageHeight:0;
x = Math.random() * stageRef.stageWidth;
rotation = Math.random() * 360;
scaleX = Math.random();
scaleY = scaleX;
speed = 20 + Math.random() * 10;
}
public function loop(e:Event):void
{
y += speed;
if (y > stageRef.stageHeight)
{
setupAsteroid();
}
}
}
}
So, where is the "target" object? You're just declaring a variable, but not creating the object or setting a reference. It's a public variable, so maybe you are setting a reference somewhere else? In that case, make sure you assign a reference before you are calling hitTest1 function...

Pong: How to pass position of ball on the stage to the cpu paddle? -AS3

I am a beginner with AS3 and I am trying to make a basic Player vs CPU pong game(using a tutorial as reference). I apologize if this sounds stupid or obvious. I have a document class and individual classes for Ball, Player and CPU. My problem is that I don't know how to make CPU class use the co-ordinates of the movie clip ball on the stage so that it can move with respect to the ball as required to form the AI. The tutorial I have been referring has all the code for ball, player and cpu in the document class only but I have written code for everything in their respective classes.
The tutorial link http://as3gametuts.com/2011/03/19/pong-1/
My version of code. Currently the ball is bouncing off the walls but HitTest has not been applied to anything. The player paddle is moving with the arrow keys. No warnings or errors are being displayed.
Main
public class Main extends MovieClip
{
public function Main()
{
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
trace("Initialized");
}
}
Ball
public class Ball extends MovieClip
{
public var ballSpeedX:int = 5;
public var ballSpeedY:int = 6;
public function Ball()
{
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage)
}
public function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage)
this.x = stage.stageWidth / 2;
this.y = stage.stageHeight / 2;
this.addEventListener(Event.ENTER_FRAME, loop)
}
public function loop(e:Event):void
{
this.y += ballSpeedY;
this.x += ballSpeedX;
if ((this.y <= 0 + this.height/2) || (this.y >= stage.stageHeight - this.height/2))
{
ballSpeedY *= -1;
}
else if ((this.x <= 0 + this.width/2) || (this.x >= stage.stageWidth - this.width/2))
{
ballSpeedX *= -1;
}
}
}
TheCpu
public class TheCpu extends MovieClip
{
public var cpu:TheCpu;
public var ball:Ball;
private var vx:Number = 5;
public function TheCpu()
{
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
this.x = 240;
this.y = 10;
this.addEventListener(Event.ENTER_FRAME, loop);
}
private function loop(e:Event):void
{
/*if (this.x < ball.x - 10)
{
this.x += vx;
}
else if (this.x > ball.x + 10)
{
this.x -= vx;
}*/
}
}
I added this to my main class
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
trace("It's Alive!");
addBall();
addCPU();
}
public function addBall():void
{
var ball:MovieClip = stage.getChildByName("ball") as MovieClip
stage.addChild(ball);
}
public function addCPU():void
{
var cpu:MovieClip = stage.getChildByName("cpu") as MovieClip
stage.addChild(cpu);
}
}
but now it is giving error
TypeError: Error #2007: Parameter child must be non-null.
at flash.display::DisplayObjectContainer/addChild()
at flash.display::Stage/addChild()
at src::Main/addBall()
at src::Main/onAddedToStage()
and if I use
var ball:Ball = new Ball();
var cpu:TheCpu = new TheCpu();
I get
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at src::TheCpu()
at src::Main/addCPU()
at src::Main/onAddedToStage()
I think I am being really dumb now.
As a simpler solution.
Basically when you create the ball you could pass the instance of the ball to the CPU so that the CPU can just check where the ball is on each update/enter frame. Something like this:
var ball:Ball = new Ball();
var cpu:CPU = new CPU(ball);
I think ideally you would have an update loop that just tells each part to update itself in sequence and passes along any important information between the objects so they can update themselves appropriately (and the main update loop can track things like ball out of region/point scored etc.)
EDIT
If I understand you correctly you've placed symbols on the stage in Flash and have assigned these code blocks to each of them. So your issue is you don't know how to reference each of the instances. You could use this method to retrieve the instances you put on the stage by naming them and referring to them by name:
How do I access a movieClip on the stage using as3 class?
Alternatively you could create the instances in the Main class in the added to Stage handler by creating instances as shown in the code block above then calling:
stage.addChild(cpu);
stage.addChild(ball);
Just be sure to use the MovieClip symbol name from the library in place of CPU and Ball.
In your commented-out code in the TheCpu class, you put "ball.y" when I think you meant "ball.x".

as3 Error 1009 at Coin1/coin1go(), i am trying to get an enemy to drop a coin

So the enemy does drop a coin but i does not get the properties of the coin( if it hits the player it gives him +5 coins)
The coin will be removed if it hits the bottom of the stage, if the player dies or if the player hits it. Sadly, it does not work.
But this does work if i place a coin on the stage before i start the game, it gets all its properties, so then it must be the moment it gets added to the stage that it does not get linked with the coding or something..... and that is where i am right now.
this is the .as file for the coin:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Coin1 extends MovieClip
{
private var _root:Object;
private var speed:int = 0;
public function Coin1()
{
addEventListener(Event.ENTER_FRAME, Speed1);
addEventListener(Event.ADDED, beginClass);
addEventListener(Event.ENTER_FRAME, coin1go);
}
private function beginClass(event:Event):void
{
_root = MovieClip(root);
}
private function Speed1(event:Event):void
{
y += speed;
}
private function coin1go(event:Event):void
{
if (this.y > stage.stageHeight)
{
removeEventListener(Event.ENTER_FRAME, coin1go);
_root.removeChild(this);
}
if (hitTestObject(_root.player_mc))
{
_root.coin += 1;
removeEventListener(Event.ENTER_FRAME, coin1go);
_root.removeChild(this);
}
if (_root.playerhealth <= 1)
{
removeEventListener(Event.ENTER_FRAME, coin1go);
_root.removeChild(this);
}
}
}
}
This is the part from where it gets added to the stage:
if (enemy2health <= 0)
{
removeEventListener(Event.ENTER_FRAME, eFrame);
_root.score += _root.Enemy2Score * _root.scoremultiplyer;
stage.addChild(newExplosionSmall)
newExplosionSmall.x = this.x;
newExplosionSmall.y = this.y;
stage.addChild(newCoin1)
newCoin1.x = this.x;
newCoin1.y = this.y;
Ass you can see there is also an addchild for an explosion wich works perfectly fine but that may jus be because it does nothing else than appear and remove itself.
So long story short: enemy drops coin but it does nothing and floats to the bottom of the screen and i get a constant stream of 1009 errors. so does anyone know how to fix this?
You should add an enterframe listener only after receiving a valid stage reference, which only appears when Event.ADDED_TO_STAGE event is received. This is because your enterframe listener refers stage.
public function Coin1()
{
addEventListener(Event.ENTER_FRAME, Speed1);
addEventListener(Event.ADDED_TO_STAGE, beginClass);
}
private function beginClass(event:Event):void
{
_root = MovieClip(root);
addEventListener(Event.ENTER_FRAME, coin1go);
}

AS3 Error #1004 occur when removeChild() in stage

//Main Class
package{
public class Main extends MovieClip{
private var bombCarrier:BombCarrier;
private var building:Building;
private var bomb:Bomb;
public var buildingArray:Array;
public function Main(){
bombCarrier = new Carrier();
addChild(bombCarrier);
for(var i:int=0;i<5;i++){
var xPosition:Number = i*105;
building = new Building(xPosition, stage.stageHeight);
addChild(building);
buildingArray.push(building);
}
stage.addEventListener(Event.KeyboardEvent, keyDownFunction);
}
public function keyDownFunction(event:KeyboardEvent){
if(event.keyCode == 70){
bomb = new Bomb(bombCarrier.x, bombCarrier.y, 0.5);
addChild(bomb);
}
}
}
}
//Bomb Class
package{
public class Bomb extends MovieClip{
private var speed:Number;
public function Bomb(x, y, speed){
this.x = x;
this.y = y;
this.speed = speed;
addEventListener(Event.ENTER_FRAME, loop);
}
public function loop(event:Event){
this.y += speed;
for(var i:int=0;i<Main(parent).buildingArray.length;i++){
if(hitTestObject(Main(parent).buildingArray[i])){
this.removeEventListener(Event.ENTER_FRAME, loop);
Main(parent).buildingArray.splice(i, 1);
parent.removeChild(this); //This line got Error
}
}
}
}
}
I try many approach, but i still get the same error which is TypeError: Error #1009: Cannot access a property or method of a null object reference. at Bomb/loop(). I already try to debug with command line by line, it seem to be just this line of code "parent.removeChild(this);" showing the problem.
It looks like your trying to remove your bomb multiple times (in a for loop). So after the first time, it no longer is a child of the parent.
Also, you start your enter frame handler before you're bomb has been added to the stage, so parent will be null until that time.
Your going to want to break; out of your loop once you've removed the bomb the first time.
//Bomb Class
package{
public class Bomb extends MovieClip{
private var speed:Number;
private var buildingArray:Array;
public function Bomb(x, y, speed){
this.x = x;
this.y = y;
this.speed = speed;
addEventListener(Event.ADDED_TO_STAGE,addedToStage,false,0,true);
}
private function addedToStage(e:Event):void {
buildingArray = Main(parent).buildingArray; //it would be better to just pass it in the constructor
addEventListener(Event.ENTER_FRAME, loop);
}
public function loop(event:Event){
this.y += speed;
for(var i:int=0;i<buildingArray.length;i++){
if(hitTestObject(buildingArray[i])){
this.removeEventListener(Event.ENTER_FRAME, loop);
buildingArray.splice(i, 1);
parent.removeChild(this);
break; //get out of the loop
}
}
}
}
}
On an efficiency note, it would be faster if you held a reference to buildingArray in your bomb class so you don't have to do Main(parent). everytime you need to access it.

My class has some timing issues

I have a class that I use to display text on stage, with some number effects. It works pretty well, but when I chain it like this
public function onAdd(e:Event) {
//stuff
addChild(new messager("Welcome."));
addChild(new messager("WASD to move, mouse to shoot."));
addChild(new messager("Kill zombies for XP and collect ammo boxes.",waveOne));
}
public function waveOne(){
addChild(new messager("Good luck and have fun.",newWave));
}
The text (Good luck and have fun) is not displayed, but newWave is called. The reason why I don't call waveOne in onAdd is so that it doesn't happen too quick - my class just throws the text at the user once every 50 frames (which is intended, for later when you kill enemies and the text needs to catch up).
Here is my class (with the effects removed):
package {
import flash.display.MovieClip;
import flash.events.*;
import flash.utils.Timer;
public class Messager extends MovieClip{
var actualText:String;
var callback:Function;
var upTo:int = 0;
static var waitingFor:int = 0;
public function Messager(text:String,callback:Function=null) {
this.callback = callback;
actualText = text;
x = 320 - actualText.length * 6.5;
y = 0 - waitingFor * 60;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
waitingFor++;
}
public function onEnterFrame(e:Event) {
y+= 1;
if(y > 60){
waitingFor--;
}
if(y > 200){
alpha -= 0.03;
if(alpha <= 0){
if(callback != null){
callback();
}
removeEventListener(Event.ENTER_FRAME, onEntFrm);
this.parent.removeChild(this);
}
}
}
}
It is set to linkage with a movieclip that has a textfield.
Thanks for any help.
y = 0 - waitingFor * 60; Maybe y of the last Mesager is a big negative number? Have you tried to trace waitingFor?