I'm quite new to AS3, and I need some help. I'm trying to make a game like Mario. I've made a character which can jump right now, but I've got some problems with collision detection.
I would like my character to jump on a bar, which is placed higher. My collision detection doesn't work at all I gues..
I've made a cirle which has a instance name mcMain and I've made a MovieClip of it. T also made a rectangle which has a instance name balkje, I also made aMovieClip of it.
I hope you can tell me what is wrong about my code and what I've to change to make the collision detection work! Thanks a lot!
balkje.addEventListener(KeyboardEvent.KEY_DOWN, drag);
stage.addEventListener(KeyboardEvent.KEY_UP, drop);
function drag(e:KeyboardEvent):void
{
e.target.startDrag();
}
function drop(e:KeyboardEvent):void
{
stopDrag();
if (balkje.hitTestObject(mcMain))
{
trace("Collision detected!");
}
else
{
trace("No collision.");
}
}
I think you should be using mouseEvent, not keyboard event.
How can you drag with the keyboard?
balkje.addEventListener(MouseEvent.MOUSE_DOWN, drag);
balkje.addEventListener(MouseEvent.MOUSE_UP, drop);
function drag(e:MouseEvent):void
{
e.target.startDrag();
}
function drop(e:MouseEvent):void
{
e.target.stopDrag();
if (balkje.hitTestObject(mcMain))
{
trace("Collision detected!");
}
else
{
trace("No collision.");
}
}
Related
Alright the problem is that I'm trying to make a sphere disappear only when it is touching my crosshair, the problem is that the sphere will disappear whether the crosshair is touching it or not.
My symbols are:
crosshair with an instance of crosshair on the stage
target with an instance of targetBlue on the stage
Mouse.hide();
crossHair.startDrag(true);
stage.addEventListener(MouseEvent.CLICK, _onStageMouseDown);
function _onStageMouseDown(e:MouseEvent):void
{
if (crossHair.hitTestObject(targetBlue), true)
{
targetBlue.visible = false;
trace("the mouse is in the target");
} else if (crossHair.hitTestObject(targetBlue), false){
trace("the mouse is not in the target");
}
}
Your If-Statement is kinda weird.
Try it like this:
if (crossHair.hitTestObject(targetBlue) == true) {
targetBlue.visible = false;
trace("the mouse is in the target");
} else {
trace("the mouse is not in the target");
}
Btw, since you're probably making some sort of shooting game, I suggest you check out the hitTestPoint() function, which will be much more suitable for this.
how to stop drag(event) the object with hittestobject.. thanks.
object.addEventListener(TouchEvent.TOUCH_BEGIN, drag);
object.addEventListener(TouchEvent.TOUCH_END,drop);
addEventListener(Event.ENTER_FRAME, loop);
function drag(e:TouchEvent):void {
e.target.startTouchDrag(e.touchPointID);
}
function drop(e:TouchEvent):void {
e.target.stopTouchDrag(e.touchPointID);
}
function loop(e:Event):void {
if (object.hitTestObject(collision)) {
//code to stop drag event?
}
}
or is there other way to stop drag event aside from function drop?
sorry for my bad english.
//edited
In the function drop() e.target is the object that currenty processes the event. In the function loop() you also have some objects. It is not clear which of them is dragging but you should call either object.stopTouchDrag() or collision.stopTouchDrag().
UPDATE
There is an argument for both startTouchDrag and stopTouchDrag functions - touchPointID, it is used to determine what touch point (of many) is processed. When stopping the drag, you need to use the same touchPointID which was used for starting it. When calling the stopTouchDrag from a non-event context, you can't know what touch point it should use. So you need to remember it somehow. If your target object is a MovieClip you can just add a dynamic property to it and save the touchPointID there:
function drag(e:TouchEvent):void {
(e.target as MovieClip).touchPointID = e.touchPointID;
e.target.startTouchDrag(e.touchPointID);
}
function loop(e:Event):void {
if (object.hitTestObject(collision)) {
object.stopTouchDrag(object.touchPointID);
}
}
I'm new to AS3 and although I was looking for a solution to my problem truly long time, I was not successful. I have an animated presentation and I just want to make navigation through that by arrows. Everything is on the main timeline. In the first frame I made this code
var zpet: Number;
if (currentFrame == 1) {
zpet = 1;
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, posun);
function posun(event: KeyboardEvent): void {
if (event.keyCode == 37) {
addEventListener(Event.ENTER_FRAME, playReverse);
function playReverse(event: Event): void {
if (currentFrame == zpet) {
stopPlayReverse();
} else {
prevFrame();
}
}
function stopPlayReverse(): void {
if (hasEventListener(Event.ENTER_FRAME)) {
removeEventListener(Event.ENTER_FRAME, playReverse);
}
}
} else if (event.keyCode == 39) {
if (currentFrame < totalFrames - 1) {
play();
} else {
stop();
}
}
}
stop();
Moving forward works perfect as I put stop(); in every keyframe of the presentation. The problem is how to go back just to the previous keyframe (and I also want to go back in reverse playing). I thought it would be quite easy if I made a variable (called "zpet") and set it the specific number of frame where to go back in each keyframe. But it doesn't work, all the time it's going back to frame 1. For example I put in the frame 26 the code zpet = 13; that should say when playing back from the frame 26 stop at the frame 13. Any ideas how to solve this? I would be really grateful for that..
You can label each keyframe of your animation anything you want directly from the timeline and then something like this :
function playReverse(event: Event): void
{
prevFrame();// You can also use gotoAndStop(currentFrame - 1)
if(currentFrameLabel != null)
stopPlayReverse();
}
Looks cleaner imo, plus you can use labels value later in case you make a scene selection menu.
I have action
MC1.addEventListener (MouseEvent.MOUSE_OVER, MC1_over);
can a use other MC instead of Mouse?
In other words, when MC2 will be over MC1, my action will start. How do that?
Thanks for help
You'll have to check for intersection. It's called HitTesting and there are several ways to approach this. But first - it won't be an Event anymore, you'll have to check for an intersection in every frame. So first of all, we need to create a new Event.ENTER_FRAME listener.
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(e:Event):void
{
//Your code will go here
}
Second, we check our objects for an intersection of their boudary rectangles. It's ok if you have sqare or rectangular movieclips, if your MCs are more complex (two circles for example) you'll have to use other ways of getting this intersection.
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(e:Event):void
{
if(MC1.getRect(this).intersects(MC2.getRect(this)))
{
//Two movieclips are intersecting
}
}
Third, as long as this condition will be true as long as your MCs are intersecting, we need to define a flag that will tell us if we've already done something we wanted to do.
var alreadyHandled:Boolean = false;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(e:Event):void
{
if(MC1.getRect(this).intersects(MC2.getRect(this)))
{
if(!alreadyHandled)
{
doSomething();
alreadyHandled = true;
}
}
else
{
//When our movieclips are apart again, we reset our helping variable
alreadyHandled = false;
}
}
function doSomething():void
{
//We do what we want to do if our MCs are intersecting
}
If you want to do something continiously, when your movieclips are intersecting, just ignore that helping flag thing.
And by the way, I suggest you to start names your variables with a lowercase letter. In AS3 only Classes and Interfaces have names that start with a capital letter.
Thank you.
Everything works great when I do this on new as3 file.
But i need to use this in class document
When i use
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(e:Event):void
{
if(MC1.getRect(this).intersects(MC2.getRect(this)))
{
trace("intersects")
}
}
Erron#1034: cannot convert type global#23b3a0d1 on
flash.display.DisplayObject.
Perhaps You known where is problem?
I have this code which makes the ball bounce, but what I am looking for is to shoot bullets from the ground and once they hit the ball they should bounce it back upwards. The goal is not to let the ball hit the ground. I am sure this has been done before, but I guess am too dumb to figure it out.
The Code:
package {
public class ball extends MovieClip {
var timer:Number=0;
var initialPos:Number=0;
var finalPos:Number=0;
var currentPos:Number=0;
var initialSpeed:Number=0;
function ball() {
startFallingBall();
}
function moveBallDown(e:Event) {
timer+=1;
this.y = initialPos + .5 *(timer * timer);
checkBottomBoundary();
}
function moveBallUp(e:Event) {
timer+=1;
var posA=this.y;
this.y = currentPos - initialSpeed*timer + .5*(timer * timer);
var posB=this.y;
checkTopBoundary(posA, posB);
}
function checkBottomBoundary() {
if (this.y+this.height>stage.stageHeight) {
finalPos=this.y;
stopFallingBall();
}
}
function checkTopBoundary(firstPos:Number, secondPos:Number) {
if (secondPos>firstPos) {
stopRisingBall();
startFallingBall();
}
}
function startFallingBall() {
timer=0;
initialPos=this.y;
this.addEventListener(Event.ENTER_FRAME, moveBallDown);
}
function stopFallingBall() {
this.removeEventListener(Event.ENTER_FRAME, moveBallDown);
if (finalPos-initialPos<.1*this.height) {
stopRisingBall();
} else {
startRisingBall();
}
}
function startRisingBall() {
initialSpeed=Math.sqrt(Math.abs(finalPos-initialPos));
timer=0;
currentPos=this.y;
this.addEventListener(Event.ENTER_FRAME, moveBallUp);
}
function stopRisingBall() {
this.removeEventListener(Event.ENTER_FRAME, moveBallUp);
}
function stopEverything() {
this.removeEventListener(Event.ENTER_FRAME, moveBallUp);
this.removeEventListener(Event.ENTER_FRAME, moveBallDown);
}
}
}
A simple way is to use DisplayObject's hitTestObject. This checks for overlapping. You can of course write something more advanced yourself.
For each game update you check if any bullets hit the ball, and take action if they did. You should also consider separating game logic and display updating. Look into using Timer.
package {
public class BallGame extends Sprite
{
private var ball:Ball;
private var bullets:Array;
public function BallGame() {
addEventListener(Event.ENTER_FRAME, checkCollision);
addEventListener(MouseEvent.CLICK, fireBullet);
}
private function fireBullet(e:MouseEvent):void {
// adds a fired bullet to an array so we can loop over all bullets
bullets.push(new Bullet());
}
private function checkCollision(e:Event):void {
// loops through all bullets in play
for each(var bullet:Bullet in bullets) {
// check if the bullet is inside the ball
if (ball.hitTestObject(bullet)) {
// the bullet hit the ball
ball.startRisingBall();
// TODO: remove the bullet :)
}
}
}
}
}
There's a function for preforming hittest you can read about it here:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObject.html#hitTestObject()
Though with circles it's pretty easy if you know the radius, if the distance between the centers is less than the sum of their radii; they touch each other.
But by looking at your code you should properly rewrite the whole thing. The ball really should not handle collision and movement logic internally. It should only have a positon and speed vector, and the movement and colission logic should be in other classes.
As for the code for reaction, it depends on how complicated you want it. And can be anthing from simply flipping the y part of the speed vector, to fairly complicated math.
There's alot of toturial and examples in this area, I think you would be better of finding some on google and playing with it. Then write your own.