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

2019/1/24

Limiting the spawning/creation of objects or classes based on ints

1
2
Notted Notted

2019/1/24

#
Basically, I want to create some sort of limit that limits the creation of an object. Here, it's bomberMoveSpot. It works in the sense that it spawns the moveSpot, but it's not limiting the number moveSpots. The limit is supposed to be limited by spawnLimitMoveSpot, but I think it's not even being used in the correct way. Here is my code so far:
 Actor moveSpot = getOneObjectAtOffset(0, 0, bomberMoveSpot.class);
     boolean hasHitSpot = isTouching(bomberMoveSpot.class);
     int spawnLimitMoveSpot = 1;
if (this != null && moveSpot != null )
     {
        getWorld().removeObject(moveSpot);
        spawnLimitMoveSpot = spawnLimitMoveSpot - 1;
     }
     if (spawnLimitMoveSpot == 1)
     {
         getWorld().addObject(new bomberMoveSpot(), Greenfoot.getRandomNumber(320), getY());
     }
     else
     {
         getWorld().removeObject(moveSpot);
     }
     return hasHitSpot;
I think
Actor moveSpot = getOneObjectAtOffset(0, 0, bomberMoveSpot.class);
and
boolean hasHitSpot = isTouching(bomberMoveSpot.class);
are redundent, I think.
danpost danpost

2019/1/24

#
Notted wrote...
Basically, I want to create some sort of limit that limits the creation of an object. Here, it's bomberMoveSpot. It works in the sense that it spawns the moveSpot, but it's not limiting the number moveSpots. The limit is supposed to be limited by spawnLimitMoveSpot, but I think it's not even being used in the correct way. << Code Omitted >>
Apparently you only want one bomberMoveSpot object in the world at a time (as the limit is set to one and only decreased to zero if an object of that type is already in the world). Another thing is, as your code appears now, if a bomberMoveSpot is removed from the world, then one will be added right back in on the next act cycle. One act cycle usually takes about 1/60th of a second. That being said, it would not matter if you just relocated, instead of removing, the one that was already in the world:
Actor spot = getOneIntersectingObject(bomberMoveSpot.class)
if (spot != null) while (intersects(spot)) spot.setLocation(GreenfootgetRandomNumber(320), getY());
return spot != null;
I think << Code Omitted >> and << Code Omitted >> are redundent, I think.
Yes -- and no. They are a bit different. With getOneObjectAtOffset(0, 0, Actor.class), the image of the intersecting object must touch the center of the image of the calling object, and with isTouching(Actor.class), which uses getIntersectingObject(Actor.class), the images of both only need to be touching (regardless of center location of the calling object).
Notted Notted

2019/1/25

#
So this?
private boolean setMoveSpot()
    {
     Actor moveSpot = getOneIntersectingObject(bomberMoveSpot.class);
     int spawnLimitMoveSpot = 1;
     if (this != null && moveSpot != null )
     {
        moveSpot.setLocation(Greenfoot.getRandomNumber(320), getY());
        spawnLimitMoveSpot = spawnLimitMoveSpot - 1;
     }
     if (spawnLimitMoveSpot == 1)
     {
         getWorld().addObject(new bomberMoveSpot(), Greenfoot.getRandomNumber(320), getY());
     }
     else
     {
         moveSpot.setLocation(Greenfoot.getRandomNumber(320), getY());
     }
     return moveSpot != null;
    }
I think I may have to remove getWorld().addObject(new bomberMoveSpot(), Greenfoot.getRandomNumber(320), getY());, line in order to stop it from spawning. But then, it will never get into the world. I may have to set it in the myWorld class in order for it to be acted on.
danpost danpost

2019/1/25

#
Notted wrote...
So this? << Code Omitted >> I think I may have to remove getWorld().addObject(new bomberMoveSpot(), Greenfoot.getRandomNumber(320), getY());, line in order to stop it from spawning. But then, it will never get into the world. I may have to set it in the myWorld class in order for it to be acted on.
Yes, add a bomberMoveSpot object into the world in your MyWorld constructor or prepare method. Then simply use:
private boolean setMoveSpot()
{
    Actor spot = getOneIntersectingObject(bomberMoveSpot.class);
    if (spot != null) while (intersects(spot)) spot.setLocation(GreenfootgetRandomNumber(320), getY());
    return spot != null;
}
Notted Notted

2019/1/25

#
Ok. Now our problem is getting the bombSpawner to move back every time he intersects moveSpot. Here is the code (as of now):
private int movingBomber(int bomberSpeed)
    {
        setLocation(getX() + bomberSpeed, getY());
        setMoveSpot();
        if (setMoveSpot() || getX() > 570)
        {
           setLocation(getX() - bomberSpeed, getY());
           setRotation(180);
        }
        else
        {
            setRotation(0);
        }
        return bomberSpeed;
    }
I'm pretty sure this does not work. bombSpawner does not move backward whenever he hits a moveSpot.
danpost danpost

2019/1/25

#
Notted wrote...
Ok. Now our problem is getting the bombSpawner to move back every time he intersects moveSpot. << Code Omitted >> I'm pretty sure this does not work. bombSpawner does not move backward whenever he hits a moveSpot.
Remove line 4.
Notted Notted

2019/1/25

#
But bombSpawner is not moving against the moveSpot. He's not changing his direction. I may also want him to move towards the moveSpot, but that's much later.
danpost danpost

2019/1/25

#
Notted wrote...
But bombSpawner is not moving against the moveSpot. He's not changing his direction. I may also want him to move towards the moveSpot, but that's much later.
If possible, please provide the entire bomber class code.
Notted Notted

2019/1/25

#
public class bombSpawner extends Actor
{
    /**
     * This is a bomb spawner. Spawns bombs and moves around.
     * 
     */
    int bombSpawnTimer = 30;
    public void act() 
    {
        spawnBomb();
        movingBomber(4);
    }  
    private void spawnBomb()
    {
        bombSpawnTimer = bombSpawnTimer - 1;
        if (bombSpawnTimer == 0)
        {
        getWorld().addObject(new Bomb(), getX(), getY());
        bombSpawnTimer = 30;
        }
    }
    private int movingBomber(int bomberSpeed)
    {
        setLocation(getX() + bomberSpeed, getY());
        if (setMoveSpot() || getX() > 570)
        {
           setLocation(getX() - bomberSpeed, getY());
        }
        return bomberSpeed;
    }
    private boolean setMoveSpot()
    {
     Actor moveSpot = getOneIntersectingObject(bomberMoveSpot.class);
     if (moveSpot != null) while (intersects(moveSpot)) moveSpot.setLocation(Greenfoot.getRandomNumber(320), getY());
     return moveSpot != null;
    }
}
danpost danpost

2019/1/25

#
Okay, it looks like you just want it to move back and forth to randomly chosen locations, which is what you are using the bomberMoveSpot object for. You can delete the bomberMoveSpot class altogether as all it is doing is choosing a new y-coordinate value for the bombSpawner object to move to. Just add a field in the bombSpawner class to hold a random y-coordinate value:
private int gotoY = 500; // use the y-coordinate value you initially placed the bomberMoveSpot object at
There are multiple ways to reassign a value to the field. The following will ensure the spawner crosses the middle, horizontally, on all moves (ensuring it will always turn around) with a minimum of a 100-pixel move (avoiding quick turn-arounds):
import greenfoot.*;

public class bombSpawner extends Actor
{
    private int speed = 4;
    private int timer;
    private int gotoX = 500;
    
    public void act()
    {
        move();
        spawnBomb();
    }
    
    private void move()
    {
        move(speed);
        if ((getX()-gotoX >= 0 && speed > 0) || (getX()-gotoX <= 0 && speed < 0))
        {
            speed = -speed;
            int width = getWorld().getWidth();
            gotoX = width/2+(50+Greenfoot.getRandomNumber(width/2-80))*speed/4;
        }
    }
    
    private void spawnBomb()
    {
        timer = (timer+1)%30;
        if (timer == 0) getWorld().addObject(new Bomb(), getX(), getY());
    }
}
Notted Notted

2019/1/28

#
This does not seem to solve the problem; the bomber simply moves to the edge of the screen and does not turn around when he reaches the edge. He also does not randomly choose a location. He only moves left and never deviates.
danpost danpost

2019/1/28

#
Notted wrote...
This does not seem to solve the problem; the bomber simply moves to the edge of the screen and does not turn around when he reaches the edge. He also does not randomly choose a location. He only moves left and never deviates.
I tested the class in a new scenario with a Bomb class that has bombs move down the screen. Everything seemed to work as intended. The bomber moved back and forth, turning around at different places.
danpost danpost

2019/1/28

#
Please show your revised bomber class codes.
Notted Notted

2019/1/28

#
Would it be better if I uploaded my scenario here for testing and debug proposes?
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * This is a bomb spawner. Spawns bombs and moves around.
 * 
 * OTerry
 * Alpha v0.2
 */
public class bombSpawner extends Actor
{
    /**
     * This is a bomb spawner. Spawns bombs and moves around.
     * 
     */
    private int bombSpawnTimer = 30;
    private int bomberSpeed;
    private int gotoY = 96;
    private int gotoX = 319;
    public void act() 
    {
        spawnBomb();
        movingBomber();
    }  
    private void spawnBomb()
    {
        bombSpawnTimer = bombSpawnTimer - 1;
        if (bombSpawnTimer == 0)
        {
        getWorld().addObject(new Bomb(), getX(), getY());
        bombSpawnTimer = 30;
        }
    }
    private void movingBomber()
    {
        bomberSpeed = 4;
        move(bomberSpeed);
        if ((getX()-gotoX >= 0 && bomberSpeed > 0) || (getX()-gotoX <= 0 && bomberSpeed < 0))
        {
            bomberSpeed = -bomberSpeed;
            int width = getWorld().getWidth();
            gotoX = width/2+(50+Greenfoot.getRandomNumber(width/2-80))*bomberSpeed/4;
        }
    }
}
myWorld is 320x480, by the way. Maybe that's causing the problem?
danpost danpost

2019/1/28

#
Notted wrote...
Would it be better if I uploaded my scenario here for testing and debug proposes?
Not necessary.
<< Code Omitted >> myWorld is 320x480, by the way. Maybe that's causing the problem?
Not the problem. The problem is line 35. Remove it and change line 16 to:
private int bomberSpeed = 4;
It does no good to negate a value (when attempting to reverse directions -- line 39) if you are to change it right back.
There are more replies on the next page.
1
2