I have created a MOUSE_MOVE MouseEvent and a code to draw circles while I move the mouse cursor. The problem is, it doesn't draw out every single circle if I move the mouse too fast.
Here are the codes I have for the MOUSE_MOVE event.
stage.addEventListener(MouseEvent.MOUSE_MOVE, mCursor);
public function mCursor(e:MouseEvent):void
{
var cursor:Shape = new Shape();
cursor.graphics.beginFill(1, 1);
cursor.graphics.drawCircle(e.stageX, e.stageY, 10);
cursor.graphics.endFill();
addChild(cursor);
}
Would there be an arithmetic equation or physics formula to have it add every single circle such that it can draw a straight line without the blanks in between?
Just use
cursor.graphics.lineTo(…);
To draw a continuous line between points instead of adding discrete individual circles.
I erased the above codes and just added this one line of code cursor.graphics.lineTo(e.localX, e.localY); I tested it and there were blanks in between
You have to set the line width first by calling lineStyle() method of the graphics object. Otherwise the line width is zero (its default value).
Here's a full working document class:
package
{
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.MouseEvent;
public class Main extends Sprite
{
private var cursor:Shape;
public function Main()
{
cursor = new Shape();
cursor.graphics.lineStyle(2);
addChild(cursor);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mCursor);
}
private function mCursor(e:MouseEvent):void
{
cursor.graphics.lineTo(e.stageX, e.stageY);
}
}
}
You likely have to fiddle around with moveTo in order to set an appropriate starting position. As the code is now, it starts at 0/0.
Related
I am making a TDS in Flash CS4 using AS3 but there seems to be a problem. It's hard to explain so I'm gonna link the flash file. Click this.
This is the first time uploading a file for sharing so for those who can't or are unable to download the file, this is what happens:
Player has mouse rotation that is, Player looks at where the mouse is. On Mouse down I've put the script for creating bullets. The bullets are being created alright. But when the bullets move that's when the problem arises. Say that at position and rotation X, I shot 5 bullets and they are moving in X direction. Now if I shoot a bullet in Y position and rotation, the bullet that was created there goes in Y direction but so do all the other bullets that were created in the X position and direction. They change their course.
Here is the code for the game.
package {
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Mouse;
import flash.events.TimerEvent;
public class Main extends MovieClip {
var player : Player = new Player();
//Customizable Weapon Settings
var bulletNumber:Number;//number of bullets per shot
var bulletOffset:Number;//bigger number = less acurate
var bulletSpeed:Number;//pixels per frame
var bulletMaxAge:Number;//1000 = 1 second
var reloadSpeed:Number;//1000 = 1 second
var randomNum:Number;
public static var xSpeed:Number;
public static var ySpeed:Number;
var bulletAngle:Number;
var timer:Number=0;
var flag:Boolean;
//other variables (do not edit)
var mouseClicked:Boolean=false;
var radians:Number=Math.PI/180;
public function Main() {
player.x=stage.stageWidth/2;
player.y=stage.stageHeight/2;
stage.addChild(player);
player.gotoAndStop(5);
loadWeapon("Machine Gun");
addEventListener(Event.ENTER_FRAME,on_enter_frame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
public function onMouseDownHandler(event:MouseEvent) {
//trace("Mouse Down");
mouseClicked=true;
flag=true;
}
public function onMouseUpHandler(event:MouseEvent) {
//trace("Mouse Up");
mouseClicked=false;
flag=false;
timer=0;
}
public function loadWeapon(weaponType:String) {
switch (weaponType) {
case "Machine Gun" :
//bulletNumber = 100;
bulletOffset=10;
bulletSpeed=10;
bulletMaxAge=1000;
break;
}
}
function on_enter_frame(e:Event) {
trace("Click: "+ mouseClicked);
fireWeapon();
}
function fireWeapon() {
//check if mouse is clicked
//if true, create bullet
if (mouseClicked) {
createBullet();
player.gotoAndStop(10);
} else {
player.gotoAndStop(1);
}
}
public function createBullet() {
var bullet : Bullet2= new Bullet2();
bullet.x=player.x;
bullet.y=player.y;
if (flag) {
timer++;
if (timer==10) {
trace("lol");
//calculate random bullet offset.
randomNum = Math.random() * (bulletOffset);
//set bullet firing angle
bulletAngle = (player.rotation + randomNum) * radians;
//set bullet speed based on angle
xSpeed=Math.cos(bulletAngle)*bulletSpeed;
ySpeed=Math.sin(bulletAngle)*bulletSpeed;
//trace (bulletAngle);
stage.addChild(bullet);
bullet.addEventListener(Event.ENTER_FRAME, runForest);
//mouseClicked = false;
timer=0;
}
}
function runForest(e:Event) {
bullet.x+=xSpeed;
bullet.y+=ySpeed;
}
}
}
}
Things that I've tried:
1) I put the "runForest()" funtion outside of "createbullet()" function which give me a "1120: Access of undefined property bullet." Error. (Which doesn't make sense since I am giving it a enter frame event listener.)
2) For solving this, I made the bullet variable global and declared it inside the "createbullet()" function like this- "var bullet : Bullet2;" And inside createbullet()- "bullet = new Bullet2();" That gives me a completely different output.
3) I put the "runForest()" function in its own class file. But the same thing is happening.
I was referring to a Tutorial that used AS2. This is the link.
Help me solve this please.
Thanks!
Review this code:
//set bullet speed based on angle
xSpeed=Math.cos(bulletAngle)*bulletSpeed;
ySpeed=Math.sin(bulletAngle)*bulletSpeed;
then take a look at how these variables for speed are created:
public static var xSpeed:Number;
public static var ySpeed:Number;
You have 1 variable for the x direction of the speed. If there is only one variable, there can only be 1 value for speed.
that's why all your bullets are moving in the same direction, because they all share that one single value for speed, which causes them to go into the same direction.
Your Main class is doing everything at the moment and you should really refactor some of that code into several other classes.
Even your own understanding of the code you are writing is not reflected by the code, your comment says:
//set bullet speed based on angle
Now why is that bullet speed a variable of Main? Object oriented programming is made exactly for that. You can literally turn your plain English description of the desired behaviour into code.
When you say that you "want to have Bullets", then create a Bullet class.
When you say "each Bullet object should have its own speed", then add a property to that class that is the speed.
You will encounter the same problem with your weapons and the same solution applies.
I am making a game for my class which is similar to Space Invaders/Galaga. I'm new to ActionScript and coding really, I have created an enemy class for which I have it spawn and then move in the x direction. I'm just wondering how I would go about having my enemy move down after it has reached the end of my stage which is 700x500 and then proceed to go to other side, I'm assuming planting an if statement in my enemy class, just unsure on how to go about it, any help will do, much appreciated guys.
Enemy Class
package
{
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
public function Enemy()
{
x = 60;
y = 30;
}
public function moveDownABit():void
{
}
public function moveRight():void
{
x = x + 2;
}
public function moveDown():void
{
}
public function moveLeft():void
{
}
public function moveUp():void
{
}
}
}
Game
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class SpaceVigilanteGame extends MovieClip
{
public var enemy:Enemy;
public var avatar:Avatar;
public var gameTimer:Timer;
var gameWidth:int = 0;
var gameHeight:int = 0;
public function SpaceVigilanteGame()
{
enemy = new Enemy();
addChild( enemy );
avatar = new Avatar();
addChild( avatar );
gameWidth = stage.stageWidth;
gameHeight = stage.stageHeight;
gameTimer = new Timer( 25 );
gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
gameTimer.start();
}
public function moveEnemy( timerEvent:TimerEvent ):void
{
//enemy.moveDownABit();
if(enemy.x+enemy.width+2<=gameWidth)
{
enemy.moveRight();
}
else if(enemy.y+enemy.height+2<=gameHeight)
{
enemy.moveDown();
}
else if(enemy.x-2>=0)
{
enemy.moveLeft();
}
else if(enemy.y-2>=0)
{
enemy.moveUp();
}
}
}
}
This is pretty basic stuff.
Lets assume you have 4 functions in your Enemy class, moveDown, moveUp, moveRight and moveLeft.
We need to know the width and height of the area the Enemy will move around in, either by hardcoding (will bite you in the butt later on, possibly) or by doing it more dynamic like this:
var gameWidth:int = stage.stageWidth;
var gameHeight:int = stage.stageHeight;
stage.stageWidth or its Height counterpart will give you the size of your SWF movie in pixels, with scaling and so on.
You already have a Timer set up in your Document Class, every 80ms the function moveEnemy will get executed. An alternative approach is to use Event.ENTER_FRAME and execute a function every frame.
Now think about it, every time your function gets called, the enemy will move down a bit. As you said, there should be some kind of...checking mechanism. But we shouldn't put it in the Enemy class, the Enemy doesn't need to know when to stop, that's the problem of the Document class. Ideally, you should be able to use that Enemy in every sort of Class, right? So giving the Enemy boundaries will just be a lot of work when the Document Class could do it instead.
The solution is very easy, you need to check the position of your enemy against the dimensions of your stage every time you want to move your Enemy.
Essentially:
private var gameWidth:int = 0;
private var gameHeight:int = 0;
public function SpaceVigilanteGame(){
//...your init code for enemy
gameWidth = stage.stageWidth;
gameHeight = stage.stageHeight;
//...your timer code
}
public function moveEnemy(timerEvent:TimerEvent):void{
//lets first check if we can go to the right
if(enemy.x+enemy.width+2<=gameWidth){
//so, we take the right outermost border of your enemy by taking its x-position and adding its width. To check if a step right would be out of bounds, we add the amount it WOULD move
//as an example, your enemy has the x-position 100, and is 200 pixel wide, is 100+200+2 smaller or equal to 700 (your stage width)? Yes it is, thus you can move it
enemy.moveRight();
}
else if(enemy.y+enemy.height+2<=gameHeight){
//but what happens if we can't go right? we jump to this additional if condition that will check if the enemy can move down
//same thing as above, but instead we use y-position and the heights
enemy.moveDown();
}
else if(enemy.x-2>=0){
//if we can't move right or down, try left instead
//this time we only need the x-position of the enemy, because we need to look at the leftmost border
enemy.moveLeft();
}
else if(enemy.y-2>=0){
//same deal with going up
enemy.moveUp();
}
}
This is untested code, but I hope you're getting the general gist of this example. The problem here is though that the Enemy will always attempt to move right first. When you start at x:0,y:0 he will move right until he hits the end, then move down until he hits an end, then move left and right alternatively forever.
Movement 101:
If you want to move to the right x = x + 1
If you want to move to the left x = x - 1
If you want to move up y = y - 1
If you want to move down y = y + 1
Essentially, I'm making a game in Flash CS6 where a light source is projected onto the screen. You get a mirror that you can drag around. When the mirror touches the light, however, it should bounce off it and end up 90 degrees offset after it hit the mirror.
I don't have enough reputation to post pictures, but here's a link to an explanation of the problem: http://raphaelhennessy.com/misc/explanation.png
If you can help me solve this I would be really happy.
Thanks in advance,
-Raph
This is an extremely quick and dirty example to get the ball rolling. There are many issues with this code, so I suggest you use it only as a jumping off point. Details are commented within the code.
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class MirrorTest extends Sprite
{
private var _mirror:Sprite;
private var _line:Sprite;
public function MirrorTest()
{
super();
// create the line clip
_line = addChild(new Sprite()) as Sprite;
_line.graphics.clear();
_line.graphics.lineStyle(3, 0xFF0000);
_line.graphics.moveTo(0, 0);
_line.graphics.lineTo(500, 0); // starting it off at an arbitrary width
_line.y = 100; // positioning line so that we can see when it bends upwards
// create the mirror clip
_mirror = addChild(new Sprite()) as Sprite;
// draw a square and rotate it so we have a diamond shape
_mirror.graphics.beginFill(0);
_mirror.graphics.drawRect(-20, -20, 40, 40);
_mirror.graphics.endFill();
_mirror.rotation = 45;
_mirror.x = _mirror.y = 200; // position the mirror away from the line
// add even listeners to trigger dragging/dropping
_mirror.addEventListener(MouseEvent.MOUSE_DOWN, dragMirror);
_mirror.addEventListener(MouseEvent.MOUSE_UP, dropMirror);
}
private function dragMirror($event:MouseEvent):void
{
// start dragging the mirror.
_mirror.startDrag(true);
// add the ENTER_FRAME listener so that we can check for colision as the mirror is being moved around
addEventListener(Event.ENTER_FRAME, onTick);
}
private function dropMirror($event:MouseEvent):void
{
// stop dragging the mirror
_mirror.stopDrag();
// remove the ENTER_FRAME listener so we don't waste cycles checking for collision when the mirror is not being moved around
removeEventListener(Event.ENTER_FRAME, onTick);
}
private function onTick($event:Event):void
{
// check to see if the mirror has collided with the line
if (_mirror.hitTestObject(_line))
{
// if so, redraw the line as a right-angle, using the mirror's position as the "collision point"
_line.graphics.clear();
_line.graphics.lineStyle(3, 0xFF0000);
_line.graphics.moveTo(0, 0);
_line.graphics.lineTo(_mirror.x - _mirror.width * .5, 0);
_line.graphics.lineTo(_mirror.x - _mirror.width * .5, -100);
}
else
{
// if not, redraw the original line
_line.graphics.clear();
_line.graphics.lineStyle(3, 0xFF0000);
_line.graphics.moveTo(0, 0);
_line.graphics.lineTo(500, 0);
}
}
}
}
I've write a actionscript 3.0 code, I have a background movie clip and and a simple space ship movie clip. I want to move spaceship right when left arrow button is pushed.To do that I've write the following code:
package{
import flash .display.*;
import flash.events.*;
public class main extends MovieClip{
public function main(){
var bground_mc:backGround_mc=new backGround_mc();
bground_mc.x=0;
bground_mc.y=0;
bground_mc.height=400;
bground_mc.width=550;
addChild(bground_mc);
var myHero:Ship=new Ship();
addChild(myHero);
// setChildIndex(myHero,numChildren - 1);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyPressedDown);
}
function keyPressedDown(event:KeyboardEvent):void{
if (event.keyCode == 37){
x+=50;
// myHero.x+=50; according to me, It should be like this???
}
else{
trace("non left arrow key is pushed");
}
}
}
}
Here is my first view of screen:
http://prntscr.com/2pkwga
When I push the left arow button, not only space ship but also background moves through right. How could I solve my problem ?
After one push to left arrow :
http://prntscr.com/2pkwxn
Your x+=50; in this case refers to whole main class. If you just want to move just a space ship you should change 'myHero' property.
So:
myHero.x += 50;
EDIT
Sorry, myHero is local variable in constructor so it's not accessible from outside.
Do:
private var myHero:Ship;
just before the constructor and inside just change it to
myHero = new Ship();
import flash.display.Shape;
import flash.display.Graphics;
stage.addEventListener(Event.ENTER_FRAME, startAnim);
function startAnim(e:Event):void
{
var shape1:Shape = new Shape();
shape1.graphics.beginFill(0x333333,1);
shape1.graphics.drawRect(40,50,250,125);
shape1.graphics.endFill();
addChild(shape1); // this will add a shape of rectangle to stage
}
This is a very simple function creating a rectangle shape on stage. Ok but the problem is how can I convert this SHAPE to MOVIECLIP using ActionScript only so I can add Events to the same (shape1).
hmmm by using a MovieClip instead of a Shape. a MovieClip also has a Graphics object.
import flash.display.MovieClip ;
//import flash.display.Graphics;//not needed
//stage.addEventListener(Event.ENTER_FRAME, startAnim); //remove enterframe
//function startAnim(e:Event):void { //no need for a handler
var shape1:MovieClip = new MovieClip();
shape1.graphics.beginFill(0x333333,1);
shape1.graphics.drawRect(40,50,250,125);
shape1.graphics.endFill();
addChild(shape1); // this will add a MovieClip of rectangle to stage
shape1.addEventListener(MouseEvent.MOUSE_DOWN, dragShape);
function dragShape(E:MouseEvent)
{
shape1.startDrag()
}
shape1.addEventListener(MouseEvent.MOUSE_UP, dropShape);
function dropShape(E:MouseEvent)
{
shape1.stopDrag()
}
//} no need for that either :)
beware that, as such, your function is called on ENTER_FRAME = 25 or more times per second, therefore you'll create and add a clip to stage 25 or more times per second
+ the reference is created locally, in the function, so you won't be able to access "shape1" from outside, once your object is created.
I don't think you can convert a Shape to a MovieClip. What you can do is to create a MovieClip class, and in the constructor generate the Shape object, and add it to the MovieClip.
public class Car extends MovieClip {
private var shape1:Shape = new Shape();
public function Car() {
shape1.graphics.beginFill(0x333333,1);
shape1.graphics.drawRect(40,50,250,125);
shape1.graphics.endFill();
addChild(shape1); // this will add a shape of rectangle to stage
}
}
Shape has also events.
activate
added
addedToStage
deactivate
enterFrame
removed
removedFromStage
render
But since it doesn't extends from InteractiveObject, you can't handle input.