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

2019/6/15

Shooting actor. NEED HELP!

rtrout rtrout

2019/6/15

#
I'm creating a remake of plants vz zombies game and I want my plants to shoot at the zombies only when they're present in the same row. Right now I currently, can make the plants shoot but the bullets shoot even when the zombies are not on the screen. How do I get the bullets to shoot only when there is a zombie in the same row as the plant? this is my current code:
public void shoot()
    {
            long current  = System.currentTimeMillis();
        
            
            if (current >= lastAdded + 2000) 
            {
                lastAdded  = current;
                seed Seed = new seed();
// seeds are bullets
                World world = getWorld();
                if(world.getObjectsAt(getX() +10, getY()+0, seed.class).isEmpty()) 
                // inserts bullet
                {
                    world.addObject(Seed, getX() + 10, getY());
                }
            }
        
    }
Super_Hippo Super_Hippo

2019/6/16

#
I would probably keep the Zombies (each row separately) in a ArrayList in the world. So whenever a Zombie is added to a row, it is also added to the ArrayList of the row in which it is added. When it is killed, it is removed from the ArrayList again. Then you can check if the ArrayList contains any elements and if so, the plant shoots.
rtrout rtrout

2019/6/17

#
is it possible for you to show me what you mean?
Super_Hippo Super_Hippo

2019/6/17

#
//import the ArrayList class
import java.util.ArrayList;


//in world class

//create an array of ArrayLists, one for each row
private ArrayList<Zombie>[] zombies =
{
    new ArrayList<Zombie>(0),
    new ArrayList<Zombie>(0),
    new ArrayList<Zombie>(0),
    new ArrayList<Zombie>(0),
    new ArrayList<Zombie>(0),
    new ArrayList<Zombie>(0),
    new ArrayList<Zombie>(0) //as many rows as you have
};

//when adding a zombie
int randomRow = Greenfoot.getRandomNumber(zombies.length);
Zombie zombie = new Zombie(randomRow); //creating a new zombie (probably with parameter for type, not done here, maybe with the row, see below)
addObject(zombie, getWidth()+50, 50+100*randomRow);
zombies[randomRow].add(zombie);

//method to remove a zombie from the list
//well… depends. You need the zombie object to remove and the row in which it was in. Maybe you save the row in the zombie object, see above
public void removeZombie(Zombie zombie)
{
    zombies[zombie.getRow()].remove(zombie);
    removeObject(zombie); //either here or in the zombie class after calling this method here
}

//method to check if any zombie is in a certain row
public boolean zombieInRow(int row)
{
    return zombies[row].isEmpty();
}
//shooting
if (/*time condition &&*/ ((MyWorld) getWorld()).zombieInRow(myRow))
{
    getWorld().addObject(new Bullet(), getX(), getY());
}
//bullet hitting Zombie
Zombie zombie = (Zombie) getOneIntersectingObject(Zombie.class);
if (zombie != null)
{
    zombie.loseHealth(damage);
    getWorld().removeObject(this);
}
//Zombie saves its row
private int myRow;

public Zombie(int row)
{
    myRow = row;
}

//bullet hits zombie
public void loseHealth(int amount)
{
    health -= amount;
    if (health < 1)
    {
        ((MyWorld) getWorld()).removeZombie(this);
    }
}

//method to get the row (world's removeZombie method needs it)
public int getRow()
{
    return myRow;
}
Chances are there are a few mistakes in it. I hope you get the idea though. The alternative would be to check if any zombie is on a specific Y coordinate. So if the plants and the zombie uses the same Y-coordinate in the same row, then it would be like this when shooting:
if (/*time condition*/)
{
    for (Actor zombie : getWorld().getObjects(Zombie.class))
    {
        if (zombie.getY() == getY())
        {
            getWorld().addObject(new Bullet(), getX(), getY());
            break;
        }
    }
}
Or if you save the row in the objects when creating them as shown above: (coordinates don't matter)
if (/*time condition*/)
{
    for (Zombie zombie : getWorld().getObjects(Zombie.class))
    {
        if (zombie.getRow() == myRow())
        {
            getWorld().addObject(new Bullet(), getX(), getY());
            break;
        }
    }
}
This is far less code. It is probably less efficient. But maybe that doesn't matter in your project anyway.
rtrout rtrout

2019/6/17

#
thanks a million
rtrout rtrout

2019/6/17

#
also I have multiple subclasses under my zombie class so it gives me a generic array creation error. How should I fix that?
rtrout rtrout

2019/6/17

#
never mind. I got it. Thanks for the code. You're a lifesaver!
You need to login to post a reply.