hitTestPoint or hitTestObject? - arrays

I'm needing to make my character land on a ledge and stay there, but it only keeps going straight through it. Would I create an array for all my different ledges and test whenever my character hits them? Any help would be appreciated.
Thanks.

Collision detection for floors and stuff is actually alot diffrent from hitTesting in the idea that needs to consistently see that the objects are touching. Try something like this!
//loop through all the platform objects to generate the level
var level:Array = new Array();
for (var i=0; i<numChildren; i++)
{
if (getChildAt(i) is platform)
{
level.push(getChildAt(i).getRect(this));
}
}
for (i=0; i<level.length; i++)
{
if (player.getRect(this).intersects(level[i]))
{
if (speedX > 0) ////moving right collision and stuffs
{
player.x = level[i].left-player.width/2;
}
if (speedX < 0) ////moving left collision and stuffs
{
player.x = level[i].right+player.width/2;
}
speedX = 0 //kills the speed
}
}
speedX is the speed at which the characters move horizontally, and "platform" is the name of the variable that you're using as the cliff. Also, "player" can be substituted by whatever you are calling your object that's going onto the ledge. That's how I did it in one of my computer classes anyways :) Hope that helps!

Related

Checking shot collisions and removing shot and target in AS3

Last year was my first successful year in teaching my students to create catch and avoid games in Flash with AS3. This year is getting better. Each year I come here for help at least once.
I'm trying to add shooting into the possibilities for their second game project. I can make the shot happen from the ship, gun, whatever, and make it move, and get rid of it when it is off screen, but have not figured out a clean way to have both the shot and the target go away (removeChild and array.splice) upon collision.
The code I have sort of works, but I keep getting the error,
TypeError: Error #1010: A term is undefined and has no properties. at
DropShootV02_fla::MainTimeline/checkShots()
.
Normally I know that this is because of a mismatch between objects and index numbers, but this is related to the call to a second array in removing boxes and bullets.
For simplicity I'll just include the shooting code. Similar organization creates and drops the boxes.
Any help is appreciated. BTW we are not using external script in an AS file.
var shotSpeed = 18;
var shots:Array = new Array();
import flash.events.MouseEvent;
import flash.events.Event;
stage.addEventListener(MouseEvent.CLICK, fireLaser);
function fireLaser(e:MouseEvent):void
{
if (gameOn==true)
{
var shot:Shot=new Shot();
addChild(shot);
shots.push(shot);
shot.gotoAndStop(1);
shot.x = user.x;
shot.y = user.y;
trace(shots.length);
}
}
addEventListener(Event.ENTER_FRAME, moveShot);
function moveShot(e:Event):void
{
for (var i:int=shots.length-1; i>=0; i--)
{
shots[i].y -= shotSpeed;
if (shots[i].y < -25)
{
removeChild(shots[i]);
shots.splice(i,1);
}
}
}
addEventListener(Event.ENTER_FRAME, checkShots);
function checkShots(e:Event):void
{
for (var i:int=shots.length-1; i>=0; i--)
{
for (var k:int=boxes.length-1; k>=0; k--)
{
if (shots[i].hitTestObject(boxes[k]))
{
if (boxes[i].type == "good")
{
score--;
scoreDisplay.text = "Score:" + score;
}
if (boxes[i].type == "bad")
{
score++;
}
removeChild(boxes[k]);
boxes.splice(k,1);
//if I leave this part out I get no errors,
//but but the bullet goes on to strike again
removeChild(shots[i]);
shots.splice(i,1);
}
}
}
}
Thanks kaarto:
I had tried that previously and kept getting the same error. I used that elsewhere in this game code. Turns out I needed to moderate how often the player was shooting. I changed from shooting with the mouse to using space instead and now the problem is gone. Break is definitely a good one here.
Merge move shot and checkShots in one ENTER_FRAME handler.

AS3: Creating and accessing movieclips from an array

I know there are quite similar questions here, but I haven't found the proper details. What would be helpful is definitely an explanation of the problems, and perhaps a base example, that anyone who searches later may be able to apply. (Not asking that you write it for me, I just find the examples helpful) I don't want to upset anyone and am kind of worried to post in a forum...
I am wondering alternatives to creating a screen based off tiles created from an array. I have been having an issue myself trying to access the movieclips that have been placed on screen, and trying to trace to find a way to reference them hasn't been working.
Anyway, take something basic like an array, and connecting it to movieclips, then how to access the movieclip itself once done. So I have been working on this, and used many different online resources, so I'm sure a lot of this is going to look familiar, just in a much messier way.
This takes the array to make the movieclips appear (Im sure at least one part in here is unnecessary, and I'm thinking I'm doing something wrong here that makes it not work out later) So this works, but feels pretty bulky.
Both are from the same main class file.
function makeWorld (anyMap, tileW, tileH) {
var worldWidth = anyMap[0].length;
var worldHeight = anyMap.length;
var MAP = this.addChild(new mapHolder());
function tiler(MAP, i, j, tileW, tileH, tile)
{
MAP.addChild(tile);
tile.x = (j * tileW);
tile.y = (i * tileH);
}
for (var i = 0; i < worldWidth; ++i) {
for (var j = 0; j < worldHeight; ++j) {
var curTile:int = anyMap[i][j];
if (curTile == 101) {
var tile1 = new tileGround();
tiler (MAP, i, j, tileW, tileH, tile1);
...
else {
var tile3 = new empty();
tiler (MAP, i, j, tileW, tileH, tile3);
}
}}}
Then there is attempting to reference it, where I'm having the issue. I don't know what to call this.MAP.tileGround by, and I have tried many things. I've read it's not such a good idea to reference by name when not very advanced so I wanted to avoid that sort of thing too.
addEventListener (Event.ENTER_FRAME, hits);
function hits (event:Event) {
var tileCatchG:MovieClip = this.MAP.tileGround;
if(tileCatchG.hitTestPoint(this.MAP.Char.x + leftBumpPoint.x, this.MAP.Char.y + leftBumpPoint.y, true)){
leftBumping = true;
} else {
leftBumping = false;
}
...
}
Thank you!
In looking over what you're doing a second time it would appear that you should have a reference to the 2-indexed array that represents the map.
You can create a regular (single indexed) Array at the top of the file like
public var tileArray:Array = [];
Then where you create them push them into the array
var tile1 = new tileGround();
tileArray.push(tile1);
then to reference them all you can just run a simple loop
for each(var tile:MovieClip in tileArray)
{
//Do stuff
if(tile instanceof tileGround)
{
//Do stuff specific to tileGround
}
}

Creating an If statement for an entire array

So here is my situation. I'm new to programming and I've just started making a very, very basic platform game. And I mean literally a game with platforms.
I've got my character in and jumping about and I've created my platforms as an array. This was so that I could put them all side by side at the bottom. Now there is other ways I can do this to get round the problem but I wanted to find out how to do it for an array.
So I've got my character falling with this
kirby.yVelocity += 1.0f
Which is all fine but I want his yVelocity to go to 0.0f when he hits any of the platforms in the array.
So I tried this piece of code
if (plat[i].drawRect.Intersects(kirby.drawRect))
{
kirby.yVelocity = 0.0f
}
which I thought would work but it gives me an error for the [i] saying that it isn't applicable in this context.
few notes:
kirby is my character name, drawRect is the definition for Rectangle, plat is my Platform array which consists of 13 platforms.
Thanks to anyone who can help
Update
The problem is any variation of plat.drawRect or plat[i].drawRect don't work. Here is all my code relating to the platform arrays.
struct Platform
{
public Texture2D txr;
public Rectangle drawRect;
}
Platform[] plat;
plat = new Platform[13];
for (int i = 0; i < plat.Length; i++)
{
plat[i].txr = Content.Load<Texture2D>("platform");
plat[i].drawRect = new Rectangle(i * plat[i].txr.Width, 460, plat[i].txr.Width, plat[i].txr.Height);`
}
for (int i = 0; i < plat.Length; i++)
{
spriteBatch.Draw(plat[i].txr, plat[i].drawRect, Color.White);
}
spriteBatch.End();
Seems like you have to add a for loop, to loop over the platforms. Maybe like this:
for(Platform : plat){
if (platform.drawRect.Intersects(kirby.drawRect)){
kirby.yVelocity = 0.0f;
}
}
Here, I'm assuming you're using Java and Platform is the class of your plat-array, which has class List<Platform>.

Actionscript 3.0 Get all instances of a class?

I got a ton of movieclips in a class. Is there a more efficient way to apply a function to every instance in the class other than this?
var textArray:Array = [
interludes.interludeIntro.interludeBegin1,
interludes.interludeIntro.interludeBegin2,
interludes.interludeIntro.interludeBegin3,
interludes.interludeIntro.interludeBegin4,
interludes.interludeIntro.interludeBegin5,
interludes.interludeIntro.interludeBegin6,
interludes.interludeIntro.interludeBegin7,
//... ... ...
interludes.interludeIntro.interludeBegin15
];
for each (var interludeText:MovieClip in interludeBeginText)
{
interludeText.alpha = 0 //clear all text first
}
Also for some reason this doesn't work:
interludes.interludeIntro.alpha = 0;
It permanently turns that class invisible, even if I try to make specific instances visible later with:
interludes.interludeIntro.interludeBegin1.alpha = 1;
I have NO idea why the above doesn't work. I want to turn every single instance in the class interludeIntro invisible, but I want to turn specific instances visible later.
(btw I have no idea how to insert code on this website, pressing "code" doesn't do anything, so pardon the bad formatting)
I'm not really sure what you're asking, but what may be useful is that, in ActionScript you can refer to properties by name, like myObject["someProperty"].
Using that, you can iterate over properties if they follow some naming scheme, so for example:
for (var i:int = 1; i <= 15; i ++)
interludes.interludeIntro["interludeBegin" + i].alpha = 0;
That iterates over interludes.interludeIntro.interludeBegin1 through ...15 and sets their alpha properties to 0.
When you do that:
interludes.interludeIntro.alpha = 0;
you turn the movie clip and all its children invisible.
So later when you do that:
interludes.interludeIntro.interludeBegin1.alpha = 1;
You make the movie clip visible, but since its parent is still invisible, you don't see anything. The solution is to loop through the movie clips and make each of them invisible/visible.
// Keep the parent visible at all time
interludes.interludeIntro.alpha = 1;
for (var i:int = 0; i < textArray.length; i++) {
textArray[i].alpha = 0;
}
// Now this will work:
interludes.interludeIntro.interludeBegin1.alpha = 1;

multiple instances of the same object spaced out using a loop is only creating one

I had a hard time trying to word my question properly, so i'm sorry if it seems confusing. Also i'm using the flixel library in flash builder. It may not be that important butcause probably anyone that knows a little more than me or even a little AS3 could probably see what i'm doing wrong.
Anyway, what i'm trying to do is basically create 10 instances of this square object I made. all I have to do is pass it an x an y coordinate to place it and it works. so ive tested if i just do:
var testsquare:Bgsq;
testsquare = new Bgsq(0,0);
add(testsquare);
it works fine and adds a square at 0,0 just like i told it to, but i want to add 10 of them then move the next one that's created 25 px to the right (because each square is 25px)
my problem is that I only ever see 1 square, like it's only making 1 instance of it still.
anyone possibly have an idea what I could be doing wrong?
var counter:int = 0;
var bgsqa:Array = new Array;
for (var ibgs:int = 0; ibgs < 10; ibgs++)
{
bgsqa[counter] = new Bgsq(0,0);
bgsqa[counter].x += 25;
add(bgsqa[counter]);
counter++;
}
There's a lot you're doing wrong here.
First off, you're using a pseudo-iterator (counter) to access array elements through a loop instead of, well, using the iterator (ibgs).
Second, I don't see anything in the array (bgsqa) you're iterating through. It's no wonder you're having problems. Here's what you should do.
var bgsqa:Array = [];
for(var i:int=0;i<10;i++)
{
var bgsq:Bgsq = new Bgsq(i * 25, 0);
add(bgsq);
bgsqa.push(bgsq);
}
That should probably do it if your post is accurate.
for (var ibgs:int = 0; ibgs < 10; ibgs++)
{
bgsqa[counter] = new Bgsq(0,0);
bgsqa[counter].x = counter * 25;
add(bgsqa[counter]);
counter++;
}
They start at 0, so applying += is simply adding 25 to 0. This should do the trick.

Resources