ActionsScript 3 Collision - actionscript-3

Frog
I'm developing a flash game called Frog, at the moment my code for collision between my frog and fly doesn't work as expected. I'd like to have it so it works something similar to the method linked below (last example).
Collision detection methods, hitTest and hitTestObject alternatives
Any help would be appreciated.
function hitTargetFunction():void {
for (i = 0; i < insectsMC.length; i++) {
for (j = 0; j < insectsMC[i].length; j++) {
if (frogMC.hitTestObject(insectsMC[i][j])) {
trace('Target: ' + insectsMC[i][j].name);
score += 1;
trace('Score: '+score);
insectsMC[i][j].x = 0 - insectsMC[i][j].width * 2;
}
}
}
}

Might I suggest trying out the fantastic Collision Detection Kit?
I'm sure it will do everything you need and more. It's also AS3 which is what your code sample is written in, so I hope you find it useful.

Creating a movieclip/sprite inside the frog movieclip will probably be the best thing for you in this situation. PixelPerfectCollision is very awesome and useful(however on larger games, expensive) but the collision would then be with any piece of the frog. You could of course break apart your frog movieclip and just do PixelPerfectCollision on just the tongue. But if this is for coursework I'd stick to just doing hitTest() on a display object of some kind inside the the frog.

If you're not allowed to use a third-party library for your coursework you should have a look at this excellent tutorial on pixel-level collision detection with ActionScript 3.0.
The general idea is that you create BitmapData copies of your vector graphics and use the hitTest method of that class to check for a collision at a pixel-level.

Related

Actionscript3 Simple platform collision confusion

I'm making a 2D platformer game and i'm trying to add collisions to the platforms so that when the character hits it it cannot pass through. I'm struggling to find the syntax to use to create this collision. So far this is what I have.
Also i would still like to be able to use hitTestObject within the if statement.
thanks
public function platform1Collision():void
{
if (fireboy1.hitTestObject(Platform1))
{
//fireboy1 cannot pass through
}
}
You'll probably want to prevent fireboy1's y property from extending past Platform1's y property:
function platform1Collision():void
{
if(fireboy1.hitTestObject(Platform1))
{
if(fireboy1.y > Platform1.y)
{
fireboy1.y = Platform1.y + Platform1.height;
}
else
{
fireboy1.y = Platform1.y - fireboy1.height;
}
}
}
NOTE: The above code sample assumes top-left orientation for both fireboy1 and Platform1.
EDITED: The above edited code will allow fireboy1 to walk beneath Platform1, but not pass through it.
This is a very rudimentary example to give you an idea of the type of logic you can use. If you want to allow fireboy1 to pass through Platform1 from below, you'll have to update the logic to allow for that. For example, if you take out the if/else and just automatically place fireboy1 above Platform1 every time they collide, it will appear as if player1 is jumping onto Platform1 when it is approached from below.

Action Script 3. Multiple stages are like 1

I'm creating a simple flash game, where characters move on the groundwith some stages to jump over.
The problem is all the stages are acting as 1 object, which can make the character appear like it's flying in the air:
All stages are called: ground3
Here is part of code where the character jumps and stay on the ground:
if(Hero.y_speed>0 && Hero.hitTestObject(ground3)){
Hero.y_speed=0;
if(space){
trace("You clicked SPACE");
Hero.y -= 80;
}
Have you any ideas how to fix this?
Use external libraries for your purposes, like
this one.
Here is described, how to use it (you can find there also other useful informations).
import com.coreyoneil.collision.CollisionList;
var myCollisionList:CollisionList = new CollisionList(hero);
//add all stages separately
myCollisionList.addItem(stage[1...n]);
if(myCollisionList.checkCollisions().length > 0) {
//colision detected
}

why is only one actionscript working at a time?

I'm new to Flash and trying to build a very simple game involving moving one movieclip using arrowkeys and avoiding three other movie clips. There is also a start button on the first frame. Each individual actionscript works by itself as long as the other 4 are commented out. But as soon as I try to use more than one actionscript, none of them work. I have each actionscript in it's own layer.
I'm sure it's something obvious I'm missing , but how do multiple actionscripts at the same time work?
Any thanks would be greatly appreciated
Here's the code
/*Start*/
import flash.events.MouseEvent;
stop();
btn1.addEventListener(MouseEvent.CLICK,buttonClickHandler);
function buttonClickHandler(event:MouseEvent):void{
gotoAndPlay(2);
}
/*Drive*/
function hearKey(yourEvent:KeyboardEvent):void{
if (yourEvent.keyCode==Keyboard.RIGHT){
LionOne_mc.x += 8;
};
if (yourEvent.keyCode==Keyboard.LEFT){
LionOne_mc.x -= 8;
};
if (yourEvent.keyCode==Keyboard.UP){
LionOne_mc.y -= 8;
};
if (yourEvent.keyCode==Keyboard.DOWN){
LionOne_mc.y += 8;
};
};
stage.addEventListener(KeyboardEvent.KEY_DOWN,hearKey);
/*Colision*/
kangaTwo.addEventListener(Event.ENTER_FRAME,LionHit2);
function LionHit2(event:Event):void {
if (kangaTwo.hitTestObject(LionOne_mc)) {
tackle_mc.visible = true;
} else {
tackle_mc.visible = false;
}
}
You can have scripts across multiple layers in a frame. There is no problem with that. They will just run from top most layer, to the bottom.
Although it is technically possible, I would not recommend it. Timeline code is messy at the best of times, so it is best to keep it all in one layer. It is also best practice for this layer to be at the top, with no visual element on it, and for the layer to be named "Actions".
If you are calling gotoAndStop(2);, then all the code on frame one will stop running.
When you get the chance you should definitely look at using external ActionScript classes, rather than writing timeline code. There is a great tutorial here: active.tutsplus.com - AS3 101: OOP Introduction – Basix

Is my class-less AS2 programming close to OOP in spirit?

So I'm a flash game developer trying to make the transition from AS2 to AS3+OOP, only 3 years or so after everybody else did. There's a plethora of free, very helpful material to go through and I've been spending 2-3 days wrapping my head around some of it, but by now I feel like I just want to start and try it out and learn the harder stuff as I go (just like I did with AS2).
I get the benefits of (most aspects of) OOP and I was once forced to learn to do a couple of games in Processing which had me write a few classes and I really liked the whole inheritance thing, which is the biggest reason I'm keen to move on, I think.
I just wanted to ask about game structure - is my current way of AS2 programming (see the example below, with some pseudo code) close to the way you'd organize things in OOP, or are there some big flaws in my game logic/structure that I can't see? The way I understand I would have to do differently in AS3/OOP is to have a class for moving stuff such as the player, hero, missiles etc, then have an enemy class that extends that class, then have classes for each enemy that extends the enemy class, unlike now where each "class" is instead an object and a function called from the main game loop, and sub-classes are instead "if"-clauses in each function. But except for that, is my programming style on the right track or do I need to re-think the logic behind my code for it to work effectively in an AS3/OOP setting?
Any advice will be much appreciated!
function initializeF() {
initializeVariablesF();
startGameF();
}
function initializeVariablesF() {
enemyO = new Object(); //which will contain each enemy instance
enemyA = new Array(); //which will be a list of all the enemies, maybe superfluous?
playerShotsA=new Array();
//and so on...
enemyDataO = new Object();
enemyDataO.goblin = new Object();
//and then some vars relating to the goblin, sort of a class without methods, right?
}
function startGameF() {
this.onEnterFrame = function() { //my game loop
checkKeysF(); //checks which keys are pressed, saves it to a global object
playerMovementF(); //moves the player about depending on which keys are pressed
playerShotsF(); //deals with the missiles/shots/lasers the player has shot
enemyCreatorF(); //decides when to create a new enemy
enemyF(); //deals with all enemies in the enemyA
enemyShotsF(); //deals with the missiles/etc the enemies have created
};
}
function enemyCreatorF(){
//randomly creates an enemy through a "factory" function:
if (random(20)==1){
attachEnemyF(enemyDataO.goblin, ...and some values like position etc)
}
}
function attachEnemyF(a_enemyType, ... a bunch of values like position){
//create a new enemy object
var enemy=enemyO[new unique enemy name]
enemy.enemyType=a_enemyType
enemy.clip=attachMovie(a_enemyType,"clip", [values like x and y passed on])
enemyA.push(enemy)
}
function playerShotsF(){
for (every shot in playerShotsA){
//move it about
for (every enemy in enemyA){
//if it hits an enemy, add damage to the enemy
}
}
}
function enemyF() {
for (every enemy in enemyA) {
//check if it's dead/less health than zero, if so remove it from the array, remove it's clip, null it's object
//if it's not, move it about, maybe have it shoot
//if it touches the player, decrease the player's health
//different behavior depending on the enemy's type by "if" or "switch" statements
}
}
I'm not sure the question is a good fit for SO as it's mostly asking for opinions, but anyway:
Having a base class with basic functions such as "move", "hitTest", "render", etc. is indeed what you should do. Then have the player's avatar, enemies, etc. inherit from this class.
The F suffix (and even O and A suffixes) are quite superfluous, since any good AS3 editor will already tell you whether the class member is a function, or an array, object, etc.
You don't need to store your enemies in both an array and an object, it's going to make it unnecessary complicated to remove or add an enemy. Instead, just store them all in an array and use simple loops to inspect their properties.

Game logic and game loops in ActionScript 3

I am making a Shooting game in flash actionscript 3 and have some questions about the flow of logic and how to smartly use the OOPs concepts.
There are mainly 3 classes:
Main Class: Initializes the objects on the screen.
Enemy Class: For moving the enemies around on the screen.
Bullet Class: For shooting.
What I want to do is find out if the Enemy has been hit by a bullet and do things which must be done as a result ...
What I am doing right now is that I have a ENTER_FRAME event in which i check collision detection of each enemy unit (saved in an array) with the bullet instance created, and if it collides then perform all the necessary actions in the Main class .. clogging the Main class in the process ..
Is this the right technique ? or are there better solutions possible ?
Try to think more OOP, what is every object responsible for?
We have the enemies wich we can hit:
class Enemy : extends NPC implements IHittable {
. . .
function update(delta) {
// move, shoot, etc.
}
function handleHit(bullet) {
// die
}
}
A hittable object:
interface IHittable {
function handleHit(bullet);
}
The bullet is suppose to move and hit things:
class Bullet : {
function update(delta) {
// update position
}
function checkHits(world:World) {
for each(var hittable:IHittable in world.objects) { // might want to cluster objects by location if you're handling lots of objects / bullets)
if (isColidingWith(hittable))
o.handleHit(bullet);
}
}
}
And then we have the world with everything inside:
class World {
var npcs: Array ...
var bullets: Array ...
var hittables: Array ...
function update(delta) {
foreach(var c:NPC in npcs)
c.update(delta);
foreach(var b:Bullet in bullets) {
b.update(delta);
b.checkCollisions(world);
}
}
}
And your main loop is just simple as that:
var lastTime:int;
function onEnterFrame(...) {
var now:int = getTimer(); // FlashPlayer utility function to get the time since start (in ms)
world.update(now - lastTime);
lastTime = now;
}
A few other notes:
try to do all the computation based on a delta of time, otherwise the game's speed will vary with the framefrate.
what happens when a character dies? bullet disappear? Well, you could do it several ways:
fire an event, like EnemyDied and remove it from the world
implement an interface CanDie that has a (get dead():Boolean property) and use that to cleanup the world at every update.
but don't write the code to remove the enemy in the Enemy class, because then you will be polluting the class with code that should be handled by the World, and that will be hard to maintain later.
Sorry for the long answer, but I couldn't help myself :)
Was clogging the Main class the problem, or finding out what bullet hit what enemy the problem? If it was the bullet, you need to describe the bullet behavior - can it hit multiple enemies, how fast does it move (is it possible that when testing using "enterFrame" the bullet will first appear in front of the enemy, and, on the second frame, it will appear behind the enemy?). May enemy be simplified to some basic geometrical shape like circle or rectangle, or do you need pixel-perfect precision? Finally, how many bullets and how many enemies are you planning to have at any one time? It could be too expensive to have a display object per bullet, if you are going to have hundreds of them, and then it could make more sense to draw them into single shape / bitmapdata.
If the problem is that the Main class is too long, there are several possibilities here.
A nobrainer answer to this problem - use inheritance to simply put parts of the code in separate files. Not the best way, but a lot of people do it.
If you did the first, then you'd realize that there are certain groups of functions you put into superclass and subclasses - this will help you split the "clogged" class into several smaller independent pieces that have more particular specialization.
After you did the second, you may find out that there is certain dependency between how you split the big class into smaller classes, so you can try generating those smaller classes by a certain pattern.
And then you write the clogged code that generalizes those parts you just managed to split.
Above is basically the cycle from more concrete to more generic code. In the process of perfecting the last step, you'll write some concrete code again. And that will move you to the step 1. Lather, rinse, repeat :) In fact, you don't want to write OO code, or procedure code or anything that fashion of the day tells you to do. You want to write good code :) And you do it by moving from more generic to more specific and back to more generic, until it's perfect :P
Probably not the best answer, but you must admit, you didn't give much info to give you more precise answer.