Flixel - FlxWeapon not showing any bullet - actionscript-3

I tried to make some bullets(actually swords/daggers) using FTP FlxWeapon, but some unexpected results was given.
This is how I set up the FlxWeapon:
sword = new BasicSword("Sword", player, "x", "y");
sword.makeImageBullet(15, BasicSword.SWORD_GIF,5);
sword.setBulletDirection(FlxWeapon.BULLET_RIGHT, 400);
sword.setPreFireCallback(bulletDirectionCallback);
//load FlxControl
if(FlxG.getPlugin(FlxControl) == null){
FlxG.addPlugin(new FlxControl);
}
FlxControl.player1.setFireButton("X", FlxControlHandler.KEYMODE_PRESSED, 100, sword.fire);
}
/*A callback function, to set a proper direction before we fire the sword*/
public function bulletDirectionCallback():void{
if(player.facing == FlxObject.RIGHT){
sword.setBulletDirection(0, 400); //make the bullet move to the right side with velocity of 400.
}
else{ //if player is facing the left direction.
sword.setBulletDirection(180, 400); //make the bullet move to the left side with the velocity of 400.
}
}
Important notes:
BasicSword.as extends Sword.as and Sword.as extends FlxWeapon.
There's nothing important in BasicSword & Sword , actually Sword has only the constructer and BasicSword has only SWORD_GIF.
-What I think is working:
1-The callback function.
2-some methods and variables, like: setFireRate() and bulletsFired.
3-The fire button(FlxControl.player1.setFireButton).
-What is not working:
1-The sword is not showing up.

I solved my bug by putting this codeFlxG.worldBounds.make(0,0,level.width, level.height); after the level is loaded itself because earlier(when I had the bug) I put this code after creating the level object BUT before loading it. so the value of level.width and level.height was 0 and 0.

Related

Handle friendly fire collision detection

I want to create a friendly-fire mechanism. Essentially, my cubes fire repeatedly a bullet to hit enemies. I also want to detect the hit between the bullet and another cube (friendly fire). In order to avoid that the bullet's boundaries overlap with the cube that fired it, in my "Cube" class i overrided equals. Each Cube has a unique id, initialized as soon as the Cube is created.
The issue is that i have a very bad bug. When i add the first Cube all behaves normally, but as soon as i add the second one, a collision is detected for both the cubes' bullets, instantly, even if they are not firing to each other. This happens even if i add more cubes. I checked the boundaries and they seems fine.
I put some code:
collision detection
// check collisions between bullets and cubes (friendly fire)
for(BaseBullet bullet : bullets) {
for(BaseSquare square : squares) {
// exclude collision between bullet and its own Cube
if (!bullet.getBaseSquare().equals(square)) {
// check if bounds overlap
if (square.getBounds().overlaps(bullet.getBounds())) {
System.out.println("collision between bullet and qube");
// propagate the event to anyone is interested in it
EventsManager.qubeHitByQube(bullet, square);
bullet.remove();
bulletsToDestroy.add(bullet);
}
}
}
}
cube's equals method
#Override
public boolean equals(Object o) {
if(!(o instanceof BaseSquare) || o == null) {
return false;
}
BaseSquare baseSquare = (BaseSquare)o;
return baseSquare.getUniqueID().equals(getUniqueID());
}
NOTE
With "friendly fire" i mean when your objects hit themselves and not the enemies.
I would suspect the problem is more likely coming from 'if (square.getBounds().overlaps(bullet.getBounds()))' than the square's equals() method.
Are 'BaseBullet' and 'BaseSquare' extending LibGDX's Sprite class? Should you not be calling getBoundingRectangle()?

How to use CitrusSprite.velocity

I have the following function in a scene that extends citrus.core.starling.StarlingState - it loads the PlayerRun animation and displays it on the screen. For the most part, this code works: I see the sprite on the screen (it's running in place).
protected final override function DrawScene ():void
{
Player = new CitrusSprite ( "Player" );
Player.velocity = [60, 0]; // Doesn't seem to have an effect
Player.x = 40;
Player.y = 40;
var oClip:MovieClip = new MovieClip ( Resources.getTextures (
"PlayerRun" ), 24 );
Player.view = oClip;
add ( Player );
}
I'm not sure how I'm supposed to use the velocity property - there's no documentation for it and no matter what numbers I use in the code above, it doesn't change the display: the animation plays but the sprite is stationary (it doesn't move horizontally as I would expect it).
Am I using the velocity property incorrectly? Does Citrus support sprite velocity or is this something I'd have to implement myself?
As it turns out, CitrusSprite has a property, updateCallEnabled that's false by default and disables calls to update(). Once I set this property to true, the code started working as expected.
I haven't used Citrus yet, but looking at the source code it should work the way you've gone about it assuming that the update method is called on your player:
You can review the way the velocity property works at these locations:
The getter and setter for velocity.
The update loop for CitrusSprite.
MathVector, the type used for velocity internally.
I suspect you need to add the player to something that will queue it for updating.

button inside a movieclip that changes depending on the frame

I'm making a dynamic map of France going from Roman times to 2014 and I have a problem.
Most of my interface is working except for one feature that requires a lot of mc inside the main movieclip.
I can't post pictures so i'll try to explain what i did.
I have a main movieclip ("france_map"). Inside it, i have several layers including one called "rulers". In this layer, I have the timeline of every king/president of France.
We'll focus on two of them: Sarkozy (frame 2007 to frame 2012) and Hollande (frame 2013 to frame 2014).
The mc "sarkozy" is only accessible between 2007 and 2012. On frame 2013, it disappears, replaced by the mc "hollande".
When I click on one of them from root, a biography of the one concerned opens.
It works thanks to that code:
france_map.sarkozy_btn.addEventListener(MouseEvent.CLICK, fl_sarkozy_btn);
function fl_sarkozy_btn(MouseEvent: Event): void {
sarkozy.visible = true;
close_fiches_btn.visible = true;
close_arbre_btn.visible = false;
sarkozy_txt.visible = true;
};
france_map.hollande_btn.addEventListener(MouseEvent.CLICK, fl_hollande_btn);
function fl_hollande_btn(MouseEvent: Event): void {
hollande.visible = true;
close_fiches_btn.visible = true;
close_arbre_btn.visible = false;
hollande_txt.visible = true;
};
But, I have two button I use to navigate the timeline (controlled by that code:
/* Avancer ou Reculer d'un an */
flecheg_sym.addEventListener(MouseEvent.CLICK, fl_gotoprev);
function fl_gotoprev(MouseEvent: Event): void {
for each(var item: MovieClip in maps) {
if (item.currentFrame > 0) {
item.prevFrame();
} else {
item.nextFrame();
}
}
fleched_sym.addEventListener(MouseEvent.CLICK, fl_gotonext);
function fl_gotonext(MouseEvent: Event): void {
for each(var item: MovieClip in maps) {
if (item.currentFrame > 0) {
item.nextFrame();
} else {
item.prevFrame();
}
}
}
When I use these button, all timelines move together. It works.
My problem is that:
when I reach frame 2013 ("sarkozy" disappears, "hollande" appears), the new button ("hollande") doesn't work. And when I go back to 2012 ("hollande" disappears, "sarkozy" appears), "sarkozy" doesn't work anymore either.
I don't understand the problem (i'm fairly new at as3 and flash).
If i wasn't clea enough (english is not my first language), tell me, i'll try to explain more.
Thanks for your help.
Jeryl
And when I go back to 2012, "sarkozy" doesn't work anymore either
If you want to use MovieClip as a navigation instrument you should master it. When you go back from current keyframe that contains new assets and logic, and I assume previous frame isn't keyframe with listeners and logic, you will see graphics without any binded scripts. Briefly speaking, reassign your listeners for the buttons, use constant movieclip names, design your timeline appropriately and all be ok.

How to make a stick man running when pressing a key?

I created a movieclip named stickman. In that, I created an animation by drawing a sequence of move in everyframe, so that stickman can run. Now what I want is that when I press a key, the stick man will run from left to right and when I release the key, it will stop. This is my code:
RunningMan.stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN,keypresseddown);
function keypresseddown(event:KeyboardEvent):void
{
var key:uint = event.keyCode;
switch (key) {
case Keyboard.LEFT :
{
RunningMan.play();
RunningMan.x-=10;
RunningMan.scaleX=-1;
if(RunningMan.x<=0)
{
RunningMan.x=0;
}
};
case Keyboard.RIGHT :
{
RunningMan.play(); //play animated run
RunningMan.x+=10;
RunningMan.scaleX=1;
if(RunningMan.x>=stage.width)
{
RunningMan.x=stage.width;
}
};
default: RunningMan.stop();
}
}
However, when I pressed and held a key, it moved from left to right without animated run.
How can I fix it?
Thanks in advance.
EDIT:
I have a movieclip called character containing 3 movieclip named: standing, running and jumping, respectively. When I pressed up arrow key, it would jump, but if I released the key right away, it did not jump high as the jump movieclip could not finish its frames. This is the code:
if (key.isDown(Keyboard.LEFT))
{
gotoAndStop("running");
BGround.x+=speed;
scaleX=-1;
if(BGround.x>=stage.stageWidth)
BGround.x=stage.stageWidth;
}
else if (key.isDown(Keyboard.RIGHT))
{
gotoAndStop("running");
BGround.x -= speed;
scaleX=1;
}
else
if (key.isDown(Keyboard.UP))
{
gotoAndStop("jumping");
}
else
gotoAndStop("standing");
How can I fix that?
First of all, I hope RunningMan is an instance of the class, not the class itself. And if it is an instance, you should really follow common naming conventions for when you share your code with others (like you are doing now) so it would be runningMan.
So 1st, make the 1st frame of the runnigMan's timeline a picture of the man standing still and name it "still" or something. then name the second "running" and extend that like 20 frames or however long your animation is. at the last frame you will have to use timeline code. just one line of gotoAndPlay("running") will cause those frames of 2 to 20 (or whatever) to loop. When you tell the timeline to go to frame 1 from outside the timeline code, it wont loop anymore and will stay on the frame of the man standing still. So from outside when you want the loop to start:
runningMan.gotoAndPlay("running"); // frame 2
To stop:
runningMan.gotoAndStop("still"); // frame 1
Or you could do it from inside the RunningMan class
public function startRunAnimation():void{
this.gotoAndPlay("running");
}
public function stopRunAnimation():void{
this.gotoAndStop("still");
}
And you could use them just by replacing these function names with the ones you have if your code ex( instead of play() it would be startRunAnimation() )
EDIT
What you could do for this problem is to have a boolean variable for when your character is in the air (somewhere in your code where you do collision detection with the ground or where you handle gravity - however it is set up) so that this part of your code know when your character is in the air. And then you could simple test for this however way you need it.
...
if (key.isDown(Keyboard.UP) || this.inAir==true)
{
gotoAndStop("jumping");
}
else
gotoAndStop("standing");
Although if your character does not inheirt from a collidable object that has gravity, friction etc... then you would have to make the inAir property of whatever other class, public or make getter function for it - so that you can access it here. I hope this helps.

Removing Children in AS3

My flash game exists of a timeline with multiple frames (I know I should avoid the timeline)
The point of the game is a point and click adventure. The object that you are able to pick up get spawned and destroyed accordingly as you enter and leave the room. now my problem is when entering frame 14 (accessibel from frame 12) it creates a piece of paper which you are able to pick up if you have another item. Now my problem is when you can't or don't pick up the paper and go back to frame 12 (only exit is to frame 12), you can't click on any other object and you are basicly stuck on frame 12. When leaving and entering other rooms it works properly but for some reason it doesn't for on the paper on frame 14.
My code to remove objects works as following
In my Main.as Documentclass I have a function that called as soon as the game starts which does the following
if (lastframe == 14)
{
trace (prop.numChildren);
while (prop.numChildren )
{
prop.removeChildAt(0);
}
}
The lastframe variable is established when moving from frames
this function is found on the frame itself (each exit function on it's own respective frame)
function exitKantine(event:MouseEvent):void
{
Main.lastframe = 14;
gotoAndStop(12);
}
The function to remove the prop actually removes it but then causes all other clickable objects to be unusable.
Thanks for looking at my question and thanks in advance for your suggestions
I would say instead of removing children, add it once in the beginning, add all the listeners in the beginning, and toggle the visibility instead of trying to addChild and removeChild every time you want to hide it. Use an array so you can have a few happening at the same time.
something like this:
private function init():void
{
assignVars();
addListeners();
stage.addChild // make sure this is in document class or you are passing stage to the class using it
}
for (var i = 0; i < _thingsAry.length; i++)
{
if (_thingsAry[i] == 14)
{
_thingsAry[i].visible = false;
trace("the visibility of _thingsAry[" + i + "] is " + _thingsAry[i].visible
}
}