How to make character shoot facing the right direction in AS3? - actionscript-3

I am making a flash game and I have a game character similar to this
http://us.123rf.com/400wm/400/400/chudtsankov/chudtsankov1004/chudtsankov100400927/6906625-cartoon-character-mobster-carries-weapon.jpg
The character is able to shoot when facing left,and the bullet is shot diagonally from the direction of the gun.
However, when my character faces right, the bullet is shot from the back of the head rather than the gun itself. I did realise that when the character is facing right, the registration point is on the gun but when facing left, the registration point is on the back of her head. Could that be a problem? And how do i overcome this?
Here is my code
function shootBulletBoy():void {
var fire:myBullet2 = new myBullet2();
fire.x = GirlHero.x;
fire.y = GirlHero.y;
addChild(fire);
fire.addEventListener(Event.ENTER_FRAME, moveBullet2);
}
function moveBullet2(e:Event):void {
if (GirlHero.currentLabel == ('left')){
e.currentTarget.x += Math.cos(rads) * speed;
e.currentTarget.y += Math.sin(rads) * speed;
e.currentTarget.rotation = 265;
}
if (GirlHero.currentLabel == ('right')){
e.currentTarget.x += Math.cos(radss) * speedd;
e.currentTarget.y += Math.sin(radss) * speedd;
}}
Another issue that I am having is that when my character is facing left and shoots, the gun shoots in the left direction however if the character turns right whilst the bullet is still up in the air, my bullet all of a sudden turns in the rights direction. I don't know why its doing this.
Sorry if im asking too much. You dont have to answer both my problems, a little help would do :)
Thank you

To fix your issue with the origin of your players shoot has to do with:
fire.x = GirlHero.x;
fire.y = GirlHero.y;
You are right. the registration point will be an issue. To fix this use an if statement much like your moveBullet2 function.
if (GirlHero.currentLabel == ('left')){
fire.x = GirlHero.x + leftXOffset;
fire.y = GirlHero.y + leftYOffset;
}else if (GirlHero.currentLabel == ('right')){
fire.x = GirlHero.x + rightXOffset;
fire.y = GirlHero.y + rightYOffset;
}
The offset values will need to be played with based on you character.
For you bullet shooting problem.
your MoveBullet2() function is updating direction of you bullets while they are in the air.
Once a bullet is shot, you do not want to change its direction.
Instead in your myBullet2 Class (or in code inside myBullet2 MovieClip)
create variables rads and rotation. Then set them when you create a bullet. Then in your moveBullet2() youd have:
var b:myBullet2 = myBullet2(e.currentTarget);
b.x += Math.cos(b.rads) * speedd;
b.y += Math.sin(b.rads) * speedd;
and where you create bullet would add:
fire.rads = rads;
fire.rotation = rot;
which these values would be based on the direction character facing and where the mouse was pointing.

Related

Rotating a canvas object around the mouse cursor

I am trying to replicate this effect: http://hakim.se/experiments/html5/trail/03/
I have this as a Particle constructor:
function Particle(x, y) {
this.x = x;
this.y = y;
this.radius = 4;
this.color = '#f0f';
this.speed = 15;
this.angle = 0;
}
And I'm using this loop to animate all particle instances:
for (var i = 0, len = particles.length; i < len; i++) {
var dx = mouse.x - particles[i].x,
dy = mouse.y - particles[i].y,
angle = Math.atan2(dy, dx);
particles[i].vx = Math.cos(angle) * particles[i].speed;
particles[i].vy = Math.sin(angle) * particles[i].speed;
particles[i].x += particles[i].vx;
particles[i].y += particles[i].vy;
particles[i].draw(ctx);
}
The particles follow the mouse, but reach the cursor and start flickering around it, which is not a desired behaviour. I'd like to circle around the cursor, as in the example.. The interesting part is that if I set the particle.speed to something like 30 and add 1000 to the angle, the particles rotate around the cursor, but really fast and ruin the effect...
You can see a live example here: http://codepen.io/gbnikolov/pen/EwafI
All suggestions are more then welcome, thanks in advance!
P.S. I know that the code for the pointed example is easily findable, but I'm relatively new to javascript and I'm not that good at reading other people code and can't quite understand the logic behind it..
Currently the target of your particles is the mouse cursor. But that's not the target you want. You want a target that's moving around your cursor. And you want for every particle a different target, so they don't hover all at the same place.
There are also some other things that the original does and you don't:
in the original, the particle speed depends on the distance to the target
it seems they can't change the direction instantly, but change the direction of their movement relatively slowly.

how to make a bullet shoot diagonally in flash as3

I have been having this problem for ages and haven't found a solution for this.
Well in flash I have a character who's gun position is similar to this
http://us.123rf.com/400wm/400/400/chudtsankov/chudtsankov1004/chudtsankov100400927/6906625-cartoon-character-mobster-carries-weapon.jpg
I have been having difficulties in try to shoot the bullet in the same angle as the gun is pointing. I've tried working with angles but it just doesn't seem to be working.
Right now, the bullet is shooting straight up but i want it to shoot in an angle.
So far I have this
function shootBullet():void {
var fire:myBullet2 = new myBullet2();
fire.x = GirlHero.x;
fire.y = GirlHero.y;
addChild(fire);
fire.addEventListener(Event.ENTER_FRAME, moveBullet);
}
Any help would be much appreciated! Thank you! :) By the way, my character is controlled by the left,right and up key, The up key is to shoot and the left is to walk left and right to walk right.
There's a good example of this at:-
http://rhuno.com/flashblog/2011/11/18/calculating-angles-and-moving-objects-accordingly/
You want to do something like
var angle:int = 270;
var rads:Number = angle*Math.PI/180;
var speed:int = 2;
function moveBullet(e:Event)
{
e.currentTarget.x += Math.cos(rads) * speed;
e.currentTarget.y += Math.sin(rads) * speed;
}
You'll need to set angle accordingly depending on which way the character is facing (if it flips)

As3: Not move through objects? How is the logic behind this?

I have a function where I can control my character.
I also have a movieclip on the stage called assassin_table.
I want to make it so that the character can't move in the table, a.k.a make the table work like a wall.
I have this code:
if(!this.hitTestObject(_root.assassin_table))
{
if(upKeyDown)
{
gotoAndStop(4);
y-=Math.cos(rotation/-180*Math.PI)*(mainSpeed +7);
x-=Math.sin(rotation/-180*Math.PI)*(mainSpeed +7);
}
if(!upKeyDown)
{
gotoAndStop(3);
}
}
However, if I touch the table, then I can't move at all.
I know it's because if(!this.hitTestObject(_root.assassin_table)), but I don't understand the logic behind NOT moving through objects. I'd much rather have a near pixel-perfect collision detection system, but since it's so hard to find any good info online which isn't confusing, I'll stick with hitTestObject for now :)
EDIT: Tried something, didn't really work that well.
if(!_root.assassinDead && !teleporting && this.currentFrame != 5)
{
if(this.hitbox.hitTestObject(_root.assassin_table))
{
_root.assassin_table.gotoAndStop(2);
if(this.x > _root.assassin_table.x)
{
trace("Can't move right");
canMoveRight = false;
}
if(this.x <_root.assassin_table.x)
{
trace("Can't move left");
canMoveLeft = false;
}
if(this.y > _root.assassin_table.y)
{
trace("Can't move up");
canMoveUp = false;
}
if(this.y < _root.assassin_table.y)
{
trace("Can't move down");
canMoveDown = false;
}
}
else
{
canMoveRight = true;
canMoveLeft = true;
canMoveUp = true;
canMoveDown = true;
}
}
This causes me to sometimes be able to walk through the table. I figure it's because my character can move in essentially every possible angle (since he's always facing the mouse and there are no tiles/grids).
How would I make it so that it would work with the advanced movement I have?
Moving up runs this:
y-=Math.cos(rotation/-180*Math.PI)*(mainSpeed +7);
x-=Math.sin(rotation/-180*Math.PI)*(mainSpeed +7);
And the rotation is decided by this:
this.rotation = Math.atan2((stage.mouseY - this.y), (stage.mouseX - this.x)) * 180/ Math.PI + 90;
You should seperate your hittest functions for four different moving directions.
I mean, you shouldn't use this "hitTestObject" stuff, that only returns a boolean value "true" or "false", and that's not going to work for you.
You need a function like "testPoint(player.x, player.y);" and returns the object at the given position, so you can implement it for your game like that
if (upKeyDown && testPoint(player.x, player.y - mainSpeed +7) == null) y-=Math.cos(rotation/-180*Math.PI)*(mainSpeed +7);
player.y - mainSpeed +7 // that checks for plus mainSpeed+7 because of trying to stop your player before it get stack inside object
Basically your logic flow should be like this:
Sample input (key press)
Move character
Check for collisions
If collision then move character to it's "outside" the object that it's touching
In your particular case, if your character is on the left of the table, and you're moving right, then first things first, you move your character. At your new position, check for any collisions. If you have a collection, then because you were moving from the left, we want to be on the left of the object that we colliding with, in this case the table, so we position our character to the left of the table.
The first part of that (checking if the character has hit the table) is called collision detection. Moving the character so that it's outside the bounds of the table is called collision response. Collision detection is a pretty big field and really depends on the type of game you're making; you can do grid-based, hit-test based (if you don't have a ton of objects), physics-based, math-based etc. Collision response can be anything and everything, depending on how you want to react to a collision - you can destroy the object (balloon on a spike), change its speed (character running through mud), bounce off it (ball off wall), or stop any further movement (character against wall).
To make things a bit easier:
Separate your systems - your input shouldn't be dependant on your collision for example. If the up key is down, just register that fact - what you do with it later (make your character move) is up to you
Separate your objects position in memory from its position on screen - this will let you move it around, react to collisions etc, and only when everything is good, update the graphics (stops things like graphics entering a wall only to jump out the next frame)
Solve for one axis at a time - e.g. collide on the x axis first, then the y
Pixel perfect collision is rarely needed :) Non-rotated boxes and circles will work a lot more than you'd think
Somewhat related - the shape of your object doesn't have to be the shape that you're colliding with - e.g. your table collision shape could just be a box; your character collision shape could just be a circle
Update
This causes me to sometimes be able to walk through the table
Assuming that we're going to collide our character and table as boxes, you need to take into account their sizes - i.e. we don't just compare the x values, but the right side of our character box against the left side of the table box etc. Something like:
// assumes objects have their anchor point in the top left - if its
// not the case, adjust as you see fit
if( char.x + char.width > table.x ) // right side of the char is overlapping the left side of the table
canMoveRight = false;
else if( char.x < table.x + table.width ) // left side of char vs right side of table
canMoveLeft = false;
// etc
When working with collisions, it's always nice to see the actual boxes, for debugging. Something like this:
var debug:Shape = new Shape;
debug.addEventListener( Event.ENTER_FRAME, function():void
{
debug.graphics.clear();
debug.graphics.lineStyle( 2.0, 0xff0000 );
// char (again assuming anchor point is top left)
debug.graphics.drawRect( char.x, char.y, char.width, char.height );
// table
debug.graphics.drawRect( table.x, table.y, table.width, table.height );
});
// add our debug. NOTE: make sure it's above everything
stage.addChild( debug );

AS3: Camera-Drag is jerking

I have a big problem because I need to move my camera by dragging the mouse (finger on mobile) to a position you want.
The code itself works fine but I have a bad jerking while dragging.
My Code:
if(_drag)
{
var mousePos:Point = new Point(_gameRef._stage.mouseX, _gameRef._stage.mouseY);
var localPos:Point = _gameRef.MainElement.globalToLocal(mousePos);
var diffX:Number = MathHelper.Difference(_prevMPosX, localPos.x);
var diffY:Number = MathHelper.Difference(_prevMPosY, localPos.y);
// Add the position changes for the camera
if(localPos.x < _prevMPosX)
_gameRef.CamController.x += diffX;
if(localPos.x > _prevMPosX)
_gameRef.CamController.x -= diffX;
if(localPos.y < _prevMPosY)
_gameRef.CamController.y += diffY;
if(localPos.y > _prevMPosY)
_gameRef.CamController.y -= diffY;
// change the previous mouse position to the current
_prevMPosX = localPos.x;
_prevMPosY = localPos.y;
e.updateAfterEvent();
}
The funny thing is that when I change the + to - and opposite then it works without jerking (but it doesn't feel natural so it's not the solution to my problem).
Thanks a lot!
Alright, the fault was to use the local coordinates.
No I've made every dependency from my global stage coordinates and it works without any jerking!

AS3 - Finding the Y position of a rotated object if X is known

I am trying to find out the Y position of a rotated object on stage, when only the X position is known. I am not extremely formiliar with how I'd go about doing this, but I know it'll be related to the Rotation of the border object.
What I need to do is know that based on the below X position that is worked out, what the exact maximum Y position can be before it hits the black border that is onscreen. I know that the original position is 280, but I am not sure at all how I then work out what the Y position is further down the line.
I have attached the code to find the X (all be it, it doesn't take into account any rotation as on this level it isn't needed), as well as a screenshot so you can understand clearly.
Thank you for your time.
private function init(e:Event = null):void{
var maxX:int = stage.width
var freeSpace:int = 300
var startX:int = Math.ceil(Math.random() * (maxX - (freeSpace+this.width))) + freeSpace;
this.x = startX
}
I'm not entirely sure on your question but hopefully these suggestions will help:
You can use the localToGlobal() function on a display object to return a rotated, translated, and scaled point within that display container to the stage. Example, $p:Point = myMovieClip.localToGlobal(new Point(10, 10));
A Matrix is also a nice and easy way to rotate a point. Example, var $mtx:Matrix = new Matrix(); $mtx.tx = 10; $mtx.ty = 10; $mtx.rotate(); and now $mtx.tx and $mtx.ty have the rotated result
Those probably won't answer your question, but I figured I'd mention them just in case and before I get into something more complex. Like wvxvw said you can't really solve the equation you're trying to do without some other variables. I wrote some code that shows how to find Y when comparing X to a point in a line segment:
import flash.display.Shape;
import flash.geom.Point;
import flash.display.Graphics;
import flash.events.MouseEvent;
var $s:Shape = new Shape();
addChild($s);
var borderStart:Point = new Point(stage.stageWidth/2, stage.stageHeight/2);
var borderRotation:Number = 45;
var borderLength:Number = 800;
var borderRad:Number = borderRotation * (Math.PI/180);
var borderEnd:Point = new Point(borderStart.x + Math.cos(borderRad) * borderLength, borderStart.y + Math.sin(borderRad) * borderLength);
stage.addEventListener(MouseEvent.MOUSE_MOVE, update);
function update(e:MouseEvent):void{
var $g:Graphics = $s.graphics;
$g.clear();
//Drawing the rotated border
$g.lineStyle(3, 0xff0000, .5);
$g.moveTo(borderStart.x, borderStart.y);
$g.lineTo(borderEnd.x, borderEnd.y);
//Finding if and where mouseX collides with our border
if (stage.mouseX >= Math.min(borderStart.x, borderEnd.x) && stage.mouseX <= Math.max(borderStart.x, borderEnd.x)){
var $x:Number = stage.mouseX;
//SOLVING HERE : Solve collision with X
var $percent:Number = ($x - borderStart.x)/(borderLength * Math.cos(borderRad));
var $y:Number = borderStart.y + Math.sin(borderRad) * borderLength * $percent;
//Drawing to our collision
$g.lineStyle(1, 0xffff00, .6);
$g.moveTo($x, 0);
$g.lineTo($x, $y);
$g.lineStyle(2, 0xffff00, 1);
$g.drawCircle($x, $y, 3);
trace("----\nCollision #\t" + "x: " + $x + "\ty:" + Math.round($y));
}
}
Hopefully this will give some insight on how to solve your particular issue.
I'm not sure if I'm answering the right question, because as you worded it, it's impossible to solve, or rather you would have to accept that Y can be just anything... (In order to be able to find a point in a vector space over R^2 you need a basis of two vectors of a form (x,y), but you only have a vector in R^1).
But it looks like you want to find an intersection of the "black line on the screen" - i.e. an arbitrary line and a vertical line through the lowest point of the "shape" which you want to fit. It's hard to tell from the question, what shape are you trying to fit, but if it is a rectangle, which is not rotated, then it would be either its bottom right or bottom left corner. You can then find which point to choose by comparing the angle between a horizontal line and the "black line" and the horizontal line and the bottom of the rectangle.
Next, you would need to find an intersection between these two lines, the formula can be found here: http://en.wikipedia.org/wiki/Line_intersection