This site requires JavaScript, please enable it in your browser!
Greenfoot back
Johnny567
Johnny567 wrote ...

2016/12/13

Enemy Projectile...Kinda

Johnny567 Johnny567

2016/12/13

#
I'm trying to make it so the asteroid (my enemy ship for rn) shoots down a bomb at my ship. I've already put in place the damage that it does and where it's supposed to come from, but there's some problems. 1. I don't know an If statement that will make the bomb shoot every few seconds instead of every time it hits the edge. 2. I don't know how to make the bomb shoot down instead of to the right/left 3. Side note: If you could also help, I don't know how to make my ship bounce back and forth across the top without changing the rotation so it messes up the image and the direction of the shot. Enemy:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Enemy here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Enemy extends Actor
{
    /**
     * Act - do whatever the Asteriod wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    private GreenfootImage image1;
    private GreenfootImage image2;
    EnemyBeam enemybeam = new EnemyBeam();
    MyWorld world = (MyWorld) getWorld();

    public void act() 
    {
        move(1);
        image1 = new GreenfootImage("rock.png");
        image2 = new GreenfootImage("explosion.jpg");
        setImage(image1);  
         if (isAtEdge()) {
            turn(180); 
            World myWorld = getWorld();
            myWorld.addObject(enemybeam,0,0);
            enemybeam.setLocation(getX(), getY());
        }
      }
    }
Enemy Beam:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class EnemyBeam here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class EnemyBeam extends Actor
{
    /**
     * Act - do whatever the EnemyBeam wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        move(10);
        Actor ship = getOneIntersectingObject(CopyOfShip.class);
    if(ship!=null)
        {
            World myWorld = getWorld();
            MyWorld world = (MyWorld) getWorld();
            Lives lives = world.getLives();
            lives.loseLife();
            myWorld.removeObject(this);
    }  
    else if(isAtEdge())
        {
            World myWorld = getWorld();
            Actor mySelf = this;
            myWorld.removeObject(mySelf);
        }
}
}
Super_Hippo Super_Hippo

2016/12/13

#
For 1, you need a counter.
private int shootCounter = 0;

//in act
shootCounter++;
if (shootCounter == 200)
{
    shootCounter = 0;
    //add bomb
}
2.
//instead of move
setLocation(getX(), getY()+5);
3. Show what you have tried.
Johnny567 Johnny567

2016/12/13

#
Super_Hippo wrote...
For 1, you need a counter.
private int shootCounter = 0;

//in act
shootCounter++;
if (shootCounter == 200)
{
    shootCounter = 0;
    //add bomb
}
2.
//instead of move
setLocation(getX(), getY()+5);
3. Show what you have tried.
I meant my enemy and the only thing I've tried is the if (isAtEdge()) { turn(180); statement
danpost danpost

2016/12/13

#
Instead of turning 180 in the class of the enemy, just change the move value. Use 1 for right and -1 for left. You just need to add a field to track the move direction value:
private int dir = 1;
Then when at edge:
dir = -dir;
To allow multiple beams, you must create a new beam each time. Remove line 17 of the Enemy class and replace line 29 with the following two lines:
EnemyBeam enemybeam = new EnemyBeam();
enemybeam.turn(90);
Now, we can add an int timer field to control the production of EnemyBeam objects. All changes result in the following:
// instance fields
private int dir = 1;
private int beamTimer;

// in act
if (isAtEdge()) dir = -dir;
if (++beamTimer%170 == 0) 
{
    EnemyBeam enemybeam = new EnemyBeam();
    enemybeam.turn(90);
    getWorld().addObject(enemybeam, getX(), getY());
}
Oh, and remove line 18 of the Enemy class. It will never be set to any world there.
Johnny567 Johnny567

2016/12/13

#
danpost wrote...
Instead of turning 180 in the class of the enemy, just change the move value. Use 1 for right and -1 for left. You just need to add a field to track the move direction value:
private int dir = 1;
Then when at edge:
dir = -dir;
To allow multiple beams, you must create a new beam each time. Remove line 17 of the Enemy class and replace line 29 with the following two lines:
EnemyBeam enemybeam = new EnemyBeam();
enemybeam.turn(90);
Now, we can add an int timer field to control the production of EnemyBeam objects. All changes result in the following:
// instance fields
private int dir = 1;
private int beamTimer;

// in act
if (isAtEdge()) dir = -dir;
if (++beamTimer%170 == 0) 
{
    EnemyBeam enemybeam = new EnemyBeam();
    enemybeam.turn(90);
    getWorld().addObject(enemybeam, getX(), getY());
}
Oh, and remove line 18 of the Enemy class. It will never be set to any world there.
I understand what most of this does, but how you use the dir?
Super_Hippo Super_Hippo

2016/12/13

#
move(dir*speed);
With speed being the speed of the actor, for example 5.
Johnny567 Johnny567

2016/12/13

#
Super_Hippo wrote...
move(dir*speed);
With speed being the speed of the actor, for example 5.
Ok but that doesn't change the direction
Super_Hippo Super_Hippo

2016/12/13

#
Line 6 in danpost's code does that.
if (isAtEdge()) dir = -dir;
Johnny567 Johnny567

2016/12/13

#
Wait now it hits one edge and then get stuck at the other
Johnny567 Johnny567

2016/12/13

#
Johnny567 wrote...
Wait now it hits one edge and then get stuck at the other
Nevermind I fixed it thank you so much
You need to login to post a reply.