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

2018/1/8

No object image

ImAndrew ImAndrew

2018/1/8

#
I have this method which should shoot a "fireball" to my character from the enemy but it only does damage and skip the movement from the enemy to player and I can't get the problem.
    public void shoot(RangeEnemy enemy, Character character)
    {
        World world = enemy.getWorld();
        RangeFire shoot = new RangeFire();
        world.addObject(shoot, enemy.getX(), enemy.getY());
        shoot.turnTowards(character.getX(), character.getY());
        shoot.move(speed);
        if(shoot.isTouching(Character.class))
        {
            character.setHealth(character.getHealth() - damage);
            world.removeObject(shoot);
        }
        else if (shoot.isTouching(null) || shoot.isAtEdge())
        {
            world.removeObject(shoot);
        }
    }
Yehuda Yehuda

2018/1/9

#
What is the object 'shoot'? Why is the fireball not its own class, then every time you want to shoot you add a fireball and it will be referred to as 'this' inside itself.
ImAndrew ImAndrew

2018/1/9

#
This is the entire class of my fireball and shoot is an object from it.
public class RangeFire extends Actor
{
    private int speed = 1;
    private int damage = 15;
     
    public void shoot(RangeEnemy enemy, Character character)
    {
        World world = enemy.getWorld();
        RangeFire shoot = new RangeFire();
        world.addObject(shoot, enemy.getX(), enemy.getY());
        shoot.turnTowards(character.getX(), character.getY());
        shoot.move(speed);
        if(shoot.isTouching(Character.class))
        {
            character.setHealth(character.getHealth() - damage);
            world.removeObject(shoot);
        }
        else if (shoot.isTouching(null) || shoot.isAtEdge())
        {
            world.removeObject(shoot);
        }
    }
}
danpost danpost

2018/1/9

#
The creating and the behavior of a RangeFire object need to be in two separate places. You create a fireball once, but its behavior is that which can happen after its creation. Any specific behavior may or may not happen throughout the existence of the object and could even be a constantly repeated behavior. I must conjecture that you create one fireball to create another (or the rest), which is not recommended. The only reason I can see for you to do this is to have access to the 'shoot' method in the class. Using 'static' (class) content, you can gain access without having to create the first fireball object:
public class RangeFire extends Actor
{
    private int speed = 1;
    private int damage = 15;
    private Character character;
      
    public static void shoot(RangeEnemy enemy, Character character)
    {
        World world = enemy.getWorld();
        RangeFire shoot = new RangeFire();
        world.addObject(shoot, enemy.getX(), enemy.getY());
        shoot.turnTowards(character.getX(), character.getY());
        this.character = character ;
    }
    
    public void act()
    {
        move(speed);
        if(isTouching(Character.class))
        {
            character.setHealth(character.getHealth() - damage);
            getWorld().removeObject(this);
        }
        else if (isTouching(null) || isAtEdge())
        {
            getWorld().removeObject(this);
        }
    }
}
With the above, you can create a fireball with
RangeFire.shoot(enemy, character);
Only the beginning is what I am pointing out. The parameters will/should be exactly what you were already using.
ImAndrew ImAndrew

2018/1/10

#
danpost wrote...
The creating and the behavior of a RangeFire object need to be in two separate places. You create a fireball once, but its behavior is that which can happen after its creation. Any specific behavior may or may not happen throughout the existence of the object and could even be a constantly repeated behavior. I must conjecture that you create one fireball to create another (or the rest), which is not recommended. The only reason I can see for you to do this is to have access to the 'shoot' method in the class. Using 'static' (class) content, you can gain access without having to create the first fireball object:
public class RangeFire extends Actor
{
    private int speed = 1;
    private int damage = 15;
    private Character character;
      
    public static void shoot(RangeEnemy enemy, Character character)
    {
        World world = enemy.getWorld();
        RangeFire shoot = new RangeFire();
        world.addObject(shoot, enemy.getX(), enemy.getY());
        shoot.turnTowards(character.getX(), character.getY());
        this.character = character ;
    }
    
    public void act()
    {
        move(speed);
        if(isTouching(Character.class))
        {
            character.setHealth(character.getHealth() - damage);
            getWorld().removeObject(this);
        }
        else if (isTouching(null) || isAtEdge())
        {
            getWorld().removeObject(this);
        }
    }
}
With the above, you can create a fireball with
RangeFire.shoot(enemy, character);
Only the beginning is what I am pointing out. The parameters will/should be exactly what you were already using.
Ok, thanks, with your tip I solved the problem and made the class more simpler with a new algorithm but now I have the same problem with another class(arrow) and I don't understand why because it's almost the same code used in FireBall class but it's for hero.Actually, it's not just the object image but the object is not added in the world at all. I added the arrow in world in the hero class and then programmed the behavior of the arrow in its class.
danpost danpost

2018/1/10

#
ImAndrew wrote...
I added the arrow in world in the hero class and then programmed the behavior of the arrow in its class.
Cannot help with code that is not supplied.
ImAndrew ImAndrew

2018/1/10

#
danpost wrote...
ImAndrew wrote...
I added the arrow in world in the hero class and then programmed the behavior of the arrow in its class.
Cannot help with code that is not supplied.
This is the class Hero method:
void rangeAttack()
    {
        if(Greenfoot.getKey() == "x")
        {
            Arrow arrow = new Arrow();
            getWorld().addObject(arrow, getX(), getY());
            arrow.turnTowards(this.getX(), this.getY());
        }
    }
This is the act method in Arrow class:
    public void act()
    {
        checkForEnemy();
        move(speed);
        System.out.println("ARROW"); // testing
    }
danpost danpost

2018/1/10

#
Are you using 'getKey' elsewhere in your codes in such a way that you are checking for two keys simultaneously? I ask because 'getKey' only returns a key once, after which it returns a distinctly different keystroke, or 'null' if no more keys have yet been detected.
ImAndrew ImAndrew

2018/1/10

#
danpost wrote...
Are you using 'getKey' elsewhere in your codes in such a way that you are checking for two keys simultaneously? I ask because 'getKey' only returns a key once, after which it returns a distinctly different keystroke, or 'null' if no more keys have yet been detected.
I do in another method with a different key.Should I get rid of one of them? Edit: I tried but it doesn't work.
danpost danpost

2018/1/10

#
ImAndrew wrote...
I do in another method with a different key.Should I get rid of one of them?
I would reserve the 'getKey' method for text input or GUI objects that place focus on one object at a time. For game actions, I stick with using the 'isKeyDown' method. Usually, it will require that a boolean field be set up to track the state of each key to be detected. For example
// field for state of key
private boolean xDown;

// code detecting key
if (xDown != Greenfoot.isKeyDown("x")) // detect change in state of key
{
    xDown = ! xDown; // save new state
    if (xDown) // is key now down
    {
        // action to perform
    }
}
ImAndrew ImAndrew

2018/1/10

#
danpost wrote...
ImAndrew wrote...
I do in another method with a different key.Should I get rid of one of them?
I would reserve the 'getKey' method for text input or GUI object that place focus on one object at a time. For game actions, I stick with using the 'isKeyDown' method. Usually, it will require that a boolean field be set up to track the state of each key to be detected. For example
// field for state of key
private boolean xDown;

// code detecting key
if (xDown != Greenfoot.isKeyDown("x")) // detect change in state of key
{
    xDown = ! xDown; // save new state
    if (xDown) // is key now down
    {
        // action to perform
    }
}
Oh ,Thanks I tried something where I used frames(Every x frames do that or after x frames you can do that again and then reset frames timer) before using getKey but with bool it is more clean. But I don't get why using two getKey will not work.
danpost danpost

2018/1/10

#
ImAndrew wrote...
I don't get why using two getKey will not work.
You would have to understand the way the keyboard buffer works. Keystrokes are placed in an array with a pointer to the next key to be retrieved. When getting a key, the pointer is adjusted so the next key is ready to be returned on the next get. If this did not happen, the same key would be returned indefinitely.
ImAndrew ImAndrew

2018/1/10

#
danpost wrote...
ImAndrew wrote...
I don't get why using two getKey will not work.
You would have to understand the way the keyboard buffer works. Keystrokes are placed in an array with a pointer to the next key to be retrieved. When getting a key, the pointer is adjusted so the next key is ready to be returned on the next get. If this did not happen, the same key would be returned indefinitely.
Okay, now it's a little more clear, thanks, you saved my game a few times and learned me a lot of things xD
You need to login to post a reply.