I want to make a shooting game with animate AS3, and i stuck with with this code - actionscript-3

I want to improve this coding of mine but i cant find a way. so everytime i press "space" the bullet came out from the object, and if i pressed it again, the bullet that already called to the stage will reset its coordination, instead of calling another one. or can u only called one child at a time? is there any way for me to calling many child instead of just 1?
import flash.events.KeyboardEvent;
import flash.events.Event;
var fl_MyInstance:bullet = new bullet();
function move(event:Event):void
{
if(fl_MyInstance.hitTestObject(wall))
{
removeChild(fl_MyInstance);
stage.removeEventListener(Event.ENTER_FRAME, move);
}
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, summon);
function summon(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.SPACE){
addChild(fl_MyInstance);
fl_MyInstance.x = hero.x
fl_MyInstance.y = hero.y
stage.addEventListener(Event.ENTER_FRAME, move);
}
}
stage.addEventListener(Event.ENTER_FRAME, gerak);
function gerak(e:Event):void
{
fl_MyInstance.y += 5;
}

Related

I am having trouble with hit detection

I am having trouble with getting my hit detection to work in as3. I am making a flappy bird like game and when the player dies and goes back to frame 2, we get error #1009. I am new to this so if you could make this as simple as possible it would be much appreciated.Thank you! Here is my code.
import flash.events.Event;
stage.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
player.y += -100;
}
var randomX:Number = Math.random() * 550;
player.x = 50;
player.y = 50;
var speed:Number = 5;
player.addEventListener(Event.ENTER_FRAME, moveDown);
function moveDown(e:Event):void {
e.target.y += speed;
if(e.target.y >= 400) {
{
gotoAndStop(2);
player.removeEventListener(Event.ENTER_FRAME, moveDown);
}
}
}
var gravity = 8;
stage.addEventListener(Event.ENTER_FRAME, movewt);
function movewt(e:Event):void
{
wt.x = wt.x - 5;
}
stage.addEventListener( Event.ENTER_FRAME, handleCollision)
function handleCollision( e:Event ):void
{
if(player.hitTestObject(wt))
{
gotoAndStop(2);
stage.removeEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
player.removeEventListener(Event.ENTER_FRAME, moveDown);
stage.removeEventListener(Event.ENTER_FRAME, movewt);
stage.removeEventListener( Event.ENTER_FRAME, handleCollision);
}
}
Problem
When this code goes to frame 2
if(e.target.y >= 400)
{
{
gotoAndStop(2);
player.removeEventListener(Event.ENTER_FRAME, moveDown);
}
}
it only removes the ENTER_FRAME event listener from player, all other handlers persist, namely:
fl_MouseClickHandler
movewt
handleCollision
The latter two are executed on their own, which makes them the problematic ones, because the objects that they access are not necessarily present on frame 2.
movewt accesses wt, handleCollision accesses both player and wt. If either player or wt does not exist on frame 2, they are null.
Solution
Don't use frames! While it appears to be very easy to build navigations based on frames, you quickly run into problems like the one at hand. Frames were made for animations and they are great at doing that, so use them for that. How to not use frames is beyond the scope of this answer, there are many resources on the web on how to do that. Most game frameworks don't even have frames and use state machines for that purpose. It's highly recommended to take a look at how game frameworks handle this.
Another problem is the inconsistent way you switch between frames. Sometimes you remove one event listener, sometimes you remove some others...did you just forget to remove all of them? Why do you have this duplicated logic in the first place? If you have different states of your game (say for example, the game itself, which is currently on frame 1 (or whatever frame the code you posted is on) and some game over screen at frame 2), then you should have a clearly defined way to transition between the two states.
If you want to go to the game over state, have one function that does this and do all the cleanup in that function:
function gameOver():void
{
gotoAndStop(2);
stage.removeEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
player.removeEventListener(Event.ENTER_FRAME, moveDown);
stage.removeEventListener(Event.ENTER_FRAME, movewt);
stage.removeEventListener( Event.ENTER_FRAME, handleCollision);
}
Now, whenever you want to change to that state, be it because if the end of the level or because of a collision, call that function:
import flash.events.Event;
var speed:Number = 5;
var gravity = 8;
var randomX:Number = Math.random() * 550;
player.x = 50;
player.y = 50;
stage.addEventListener(Event.ENTER_FRAME, movewt);
stage.addEventListener( Event.ENTER_FRAME, handleCollision);
player.addEventListener(Event.ENTER_FRAME, moveDown);
stage.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
player.y += -100;
}
function moveDown(e:Event):void
{
e.target.y += speed;
if(e.target.y >= 400)
{
gameOver();
}
}
function movewt(e:Event):void
{
wt.x = wt.x - 5;
}
function handleCollision(e:Event):void
{
if(player.hitTestObject(wt))
{
gameOver();
}
}
function gameOver():void
{
gotoAndStop(2);
stage.removeEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
player.removeEventListener(Event.ENTER_FRAME, moveDown);
stage.removeEventListener(Event.ENTER_FRAME, movewt);
stage.removeEventListener( Event.ENTER_FRAME, handleCollision);
}
Again, ideally you'd use a framework that provides classes that represent game states. This allows for clearly defined transitions between states:
As the code stands now, you have to remember that gameOver() should be called in order to make a proper transition to the game over state and you could still do it in another way. With a library, there's no "other way", only one. But for now, gameOver() will do and should solve your problem.

Labyrinth/maze game

I'm creating a very simple game in Flash AS3 including labyrinth. Here's the code:
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
oseba.addEventListener(Event.ENTER_FRAME, premik);
oseba.addEventListener( Event.ENTER_FRAME, handleCollision)
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
var keys:Array = [];
function keyDownHandler(e:KeyboardEvent):void{
keys[e.keyCode] = true;
}
function keyUpHandler(e:KeyboardEvent):void{
keys[e.keyCode] = false;
}
function premik(e:Event):void{
if (keys[Keyboard.RIGHT]) {
oseba.x += 5;
}
if (keys[Keyboard.LEFT]) {
oseba.x -= 5;
}
if (keys[Keyboard.UP]) {
oseba.y -= 5;
}
if (keys[Keyboard.DOWN]) {
oseba.y += 5;
}
}
function handleCollision(e:Event ):void{
if(oseba.hitTestObject(nazaj)){
gotoAndPlay(2,"igra");
}
if(oseba.hitTestObject(gozd)){
gotoAndPlay(2);
}
I'd like to add collision detection, that will disallow my ''oseba'' that is walking around from walking over unmarked terrain. Below I've created a non visible MC ''potke''. I supposed the best way would be to calculate ''oseba'' 's next position and if it's on ''potke'' then ''oseba'' can't move there. I'm looking for suitable example of code, cos I've tried few different already, but non seems to work.
I'm also receiving the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at XYgame_fla::MainTimeline/handleCollision()
Everything seems to work fine otherwise, but this error keeps showing up.
I would try using nazaj.hitTestPoint(oseba.x, oseba,y, true) and put the EventListener to the stage to fix the error.

Problems getting keyboard input in AS3

So I'm workin on a flash project where I want keyboard input. In the stage there's an instance "Car" seen from above which is supposed to be rotate and drive direction of rotation. This is what I've put together so far in AS3:
//Required stuff
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.Stage;
import flash.display.MovieClip;
Car.addEventListener(Event.ENTER_FRAME, this.RunGame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
//Variables
var keys:Array = []
var vDrive:Number = 3; //Car's current base speed
var vx:Number = 0; //Speed along x axis
var vy:Number = 0; //Speed along y axis
var vMax:Number = 30; //Top speed
var vRot:Number = 3; //Rotation speed
var vAcc:Number = 1.1; //Factor for acceleration
var vDeAcc:Number = 0.90; //Factor for de-acceleration
//Game Loop
RunGame();
function RunGame():void
{
// Drive forwards
if (keys[Keyboard.UP])
{
if (vDrive < vMax)
vDrive += vAcc;
}
// Reverse
if (keys[Keyboard.DOWN])
{
if (vDrive > vMax)
vDrive *= vAcc;
}
// Turn right
if (keys[Keyboard.RIGHT])
{
Car.rotation += vRot;
}
// Turn left venstre
if (keys[Keyboard.LEFT])
{
Car.rotation -= vRot;
}
//Movement
// Friction
vDrive *= vDeAcc;
//Calculating movement vector
vx = vDrive * Math.cos(toRad(Car.rotation));
vy = vDrive * Math.sin(toRad(Car.rotation));
//Update car position
Car.x -= vx ;
Car.y -= vy;
}
However, when I run the program, the arrow keys don't seem to do anything.
I also get the following compiler warnings for both "onKeyDown" and "onKeyUp":
Migration issue: The onKeyDown event handler is not triggered
automatically by Flash Player at run time in ActionScript 3.0. You
must first register this handler for the event using addEventListener
( 'keyDown', callback_handler)
Trying to add what it suggested just makes errors saying callback_handler ain't defined.
I'm now stuck trying to figure out how to make the keyboard input work. Anyone know?
You are currently missing the functions for the key listeners. You have added the listeners to the stage here:
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
Now you just need to create the functions:
function onKeyDown( e:KeyboardEvent ):void {
//add our key to the keys array
keys[e.keyCode] = e.keyCode;
}
function onKeyUp( e:KeyboardEvent ):void {
//if the key is in the keys array, set the value to null
keys[e.keyCode] = null;
}
But there is another problem here:
Car.addEventListener(Event.ENTER_FRAME, this.RunGame);
You do not need the this.RunGame, just RunGame will do, but you should get an error this method needs a parameter of type Event, so your RunGame() definition should look like this:
function RunGame(e:Event):void
Then you wouldn't call RunGame(), it is called each frame while tied to the event listener.
Edit: Please note that there are many ways to handle key events, my answer will work with your current implementation.

EventListener AS3 problems reset problems

Hey guys I am having a problem with Event Listeners in my AS3 file. I am trying to make this object that lasts for 83 frames to appear in a different location every time the parent (83 frame) movie clip resets. The problem is I have a function that places the object at a random y value which works great once. When it resets the ojbect appears on the same Y point. This is because I removeEventListener the function otherwise the object goes shooting off the screen when it loads. How do I call that event listener again without causing a loop that will shoot the object off screen?
Here is my code:
import flash.events.Event;
stop();
addEventListener(Event.ENTER_FRAME, SeaWeedPostion);
//stage.addEventListener(Event.ADDED_TO_STAGE, SeaWeedPostion);
function SeaWeedPostion(e:Event):void{
// if(newSeaWeed == 1) {
var randUint:uint = uint(Math.random() *500 + 50);
this.seaweedSet.y += randUint;
trace(randUint);
stopPos();
//}else{
//nothing
// }
}
function stopPos():void{
removeEventListener(Event.ENTER_FRAME, SeaWeedPostion);
//var newSeaWeed = 0;
}
function resetSeaWeed():void{
addEventListener(Event.ENTER_FRAME, SeaWeedPostion);
}
I have some // code in there from trying different things.
Anyone have any suggestions?
Thanks!
ENTER_FRAME event is triggered every frame, so rather than changing position on each frame maybe it's better to create a counter, count frames and if it reaches 82 change position of SeaWeed.
var counter:uint = 0;
Now add ENTER_FRAME listener
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function SeaWeedPostion(e:Event):void {
counter++;
//Are we there yet?
if(counter < 83) {
//Nope, carry on
}
else {
//Yey!
changePosition();
counter = 0;
}
}
//Reset SeaWeed position when called
function changePosition() {
var randUint:uint = uint(Math.random() *500 + 50);
this.seaweedSet.y += randUint;
trace(randUint);
}

Make Flash Parent Fade Out & adding sound BrickBreaker Game

Hi i am trying to get this brick to fade out when the ball hits it in my brickbreaker game in flash AS3. Here is the code. At the moment there is just a removechild function which makes it just dissapear i want to know how to make it fade out instead. Also i have a breaking sound i would like to add when the ball hits the brick and wonder how i would add this aswell?
EDIT: I have managed to add sound by using Var & Play after the remove child line
package {
import flash.display.*;
import flash.events.*;
public class Brick extends MovieClip {
private var _root:MovieClip;
public function Brick(){
addEventListener(Event.ADDED, beginClass);
addEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
private function beginClass(event:Event):void{
_root = MovieClip(root);
}
private function enterFrameEvents(event:Event):void{
if(this.hitTestObject(_root.Ball)){
_root.ballYSpeed *= -1;
this.parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
}
}
}
No need for any tweener pack for just one tween.
You can use the Tween class provided in AS3 itself. Try this :
new Tween(mc,"alpha",
Strong.easeIn,
mc.alpha,
0,
2,
true).addEventListener(
TweenEvent.MOTION_FINISH,
function() { removeChild(mc); },
false, 0, true);
Note:
mc is the movieclip (or the brick).
The code removes the movieclip from stage after the tween completes.
You may play the sound as soon as the ball touches the brick & put
this code after that.
The last three parameters (false, 0, true) set the motion finish listener to be garbage collected.
How I would do it would be to first create a variable hit:Boolean and set it to true when it gets hit and change your code inside enterFrameEvents function to something like this
if(!hit && this.hitTestObject(_root.Ball)){
hit = true;
_root.ballYSpeed *= -1;
//this.parent.removeChild(this);
//removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
if(hit){
this.alpha -= 0.1; //change value to preference
if(this.alpha <= 0){
this.parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
}