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

2019/4/12

Powerup Problem

1
2
3
AdiBak AdiBak

2019/4/12

#
Hello, I'm re-creating the Atari Centipede game. I'm adding my own powerups, like a laser that gives 2x points and also a power laser, which can destroy mushrooms in just one hit. Both powerups are intended to work on mushrooms, for now. But when I added them, they didn't seem to work accordingly. I'm not sure why, can someone please help me? Thank you. Here's the code for the Mushroom class: import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.util.ArrayList; public class Mushroom extends MultiHittable { //public static ArrayList <Particle> explos = new ArrayList(10); //public static List <Particle> explos; public Mushroom(){ getImage().scale(MyWorld.GRIDSIZE, MyWorld.GRIDSIZE); } public void goToGrid(){ int gs = MyWorld.GRIDSIZE; int gx = getX() / gs * gs + gs/2; int gy = getY() / gs * gs + gs/2; setLocation(gx, gy); } public void act(){ if (isTouching(Laser.class)){ removeTouching(Laser.class); onLaserHit(); return; } if (isTouching(PointsLaser.class)){ removeTouching(PointsLaser.class); onPointsLaserHit(); } if (isTouching(PowerLaser.class)){ removeTouching(PowerLaser.class); onPowerLaserHit(); } } public void onLaserHit(){ super.onHit(); MyWorld d = (MyWorld) getWorld(); Score scTxt = getWorld().getObjects(Score.class).get(0); if (getHits() < 4){ getImage().setTransparency(getImage().getTransparency() - getImage().getTransparency()/4); d.setScore(d.getScore() + d.getPPM()); scTxt.setText("Score: " + d.getScore()); } else { d.setScore(d.getScore() + d.getPPM() * 4); scTxt.setText("Score: " + d.getScore()); Particle p = new Particle(); getWorld().addObject(p, getX(), getY()); destroy(); } } public void onPointsLaserHit(){ super.onHit(); MyWorld d = (MyWorld) getWorld(); Score scTxt = getWorld().getObjects(Score.class).get(0); if (getHits() < 4){ getImage().setTransparency(getImage().getTransparency() - getImage().getTransparency()/4); d.setScore(d.getScore() + d.getPPM() * 2); scTxt.setText("Score: " + d.getScore()); } else { d.setScore(d.getScore() + d.getPPM() * 8); scTxt.setText("Score: " + d.getScore()); Particle p = new Particle(); getWorld().addObject(p, getX(), getY()); destroy(); } } public void onPowerLaserHit(){ //super.onHit(); MyWorld s = (MyWorld)getWorld(); Score scTxt = getWorld().getObjects(Score.class).get(0); //if (getHits() == 1){ s.setScore(s.getScore() + s.getPPM() * 3); scTxt.setText("Score: " + s.getScore()); destroy(); //} } public void destroy(){ MyWorld h = (MyWorld)getWorld(); h.setDestroyed(h.getDestroyed() + 1); getWorld().removeObject(this); } } And here's the MyWorld class: import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.util.List; //import java.lang.String; /** * Write a description of class MyWorld here. * * @author (Aditya Bakshi) * @version (a version number or a date) */ public class MyWorld extends World { public static final int GRIDSIZE = 20; public int yPos = getHeight() * 4/5; private int numDestroyed; private State state; private boolean pDown = false; private boolean isPaused = false; private boolean isGameOver = false; private int numLives = 3; private int points; private int level = 1; private int multiplier = 50; private boolean hasPointPowerup = false; private boolean hasPowerUp = false; private int ppC = 100; private int ppF = 200; private int ppM = 1; private int ppS = 500; private int ppSp = 200; //private boolean has /** * Constructor for objects of class MyWorld. * */ public MyWorld() { // Create a new world with 600x400 cells with a cell size of 1x1 pixels. super(400, 600, 1, false); setState(new TitleState(this)); points = 0; numDestroyed = 0; } public void setState(State s){ if (state != null){ state.onRemove(); } state = s; s.onSet(); } public void act(){ state.onAct(); if (Greenfoot.isKeyDown("p")){ //pDown = true; //Greenfoot.stop(); isPaused = true; } if (Greenfoot.isKeyDown("escape")){ // pDown = false; //Greenfoot.start(); isPaused = false; } } public boolean getPaused(){ return isPaused; } public void setPaused(boolean v){ isPaused = v; } public boolean getGameOver(){ return isGameOver; } public void setGameOver(boolean b){ isGameOver = b; } public int getDestroyed(){ return numDestroyed; } public void setDestroyed(int val){ numDestroyed = val; } public int getScore(){ return points; } public void setScore(int num){ points = num; } public int getLvl(){ return level; } public void setLvl(int m){ level = m; } public int getMulti(){ return multiplier; } public void setMulti(int q){ multiplier = q; } public void setPointPowerup(boolean m){ hasPointPowerup = m; } public boolean getPointPowerup(){ return hasPointPowerup; } public boolean hasPower(){ return hasPowerUp; } public void setPower(boolean bool){ hasPowerUp = bool; } public int getPPC(){ return ppC; } public void setPPC(int well){ ppC = well; } public int getPPF(){ return ppF; } public void setPPF(int nice){ ppC = nice; } public int getPPM(){ return ppM; } public void setPPM(int good){ ppM = good; } public int getPPS(){ return ppS; } public void setPPS(int jod){ ppS = jod; } public int getPPSP(){ return ppSp; } public void setPPSP(int will){ ppSp = will; } }
danpost danpost

2019/4/12

#
What is your class tree structure like for the different lasers? are they all basic extensions of Actor or something else? if something else, describe please.
AdiBak AdiBak

2019/4/12

#
There's a subclass of Actor, called Laser, that the player is equipped with until the score reaches 2000. If the score gets to 2000, the player now has a PointsLaser, which, when used, should double the amount of points you get when hitting an object. You have the PointsLaser until the score reaches 4000, at which point you now have a PowerLaser, which is intended to destroy any mushroom in one hit. Both PointsLaser and PowerLaser are subclasses of Laser. Here's the code for Laser class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
/**
 * Write a description of class Laser here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Laser extends Actor
{
    public Laser(){
        getImage().scale(MyWorld.GRIDSIZE * 2, MyWorld.GRIDSIZE * 2);
    }
    int speed = 5;

    /**
     * Act - do whatever the Laser wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        // Add your action code here.
        MyWorld k = (MyWorld)getWorld();

        Score scTxt = k.getObjects(Score.class).get(0);

        /*Hittable c = (Centipede)getOneIntersectingObject(Centipede.class);

        if (c != null){
        c.onHit();
        k.setScore(k.getScore() + 100);
        scTxt.setText("Score: " + k.getScore());
        onHitTarget();

        }
         */

        move();
        if (inWorld()){
            if (inWorld() && shouldBeRemoved()){
                remove();
            }
        }

    }    

    public void move(){
        setLocation(getX(), getY() - speed);
    }

    public boolean inWorld(){

        if (getWorld() != null){
            return true;
        } 
        return false;
    }

    public void onHitTarget(){
        getWorld().removeObject(this);
        return;
    }

    public void remove(){
        getWorld().removeObject(this);
        return;
    }

    public boolean shouldBeRemoved(){
        boolean shouldRemove = false;
        if (getY() - getImage().getHeight()/2 < 0){
            shouldRemove = true;
        }
        return shouldRemove;
    }
}
Here's the code for PointsLaser and PowerLaser subclasses (both have same code): import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class PowerLaser here. * * @author (your name) * @version (a version number or a date) */ public class PowerLaser extends Laser { public PowerLaser(){ getImage().scale(MyWorld.GRIDSIZE * 2, MyWorld.GRIDSIZE * 2); } /** * Act - do whatever the PowerLaser wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { // Add your action code here. super.act(); } }
danpost danpost

2019/4/12

#
Do all your lasers use the same image?
Super_Hippo Super_Hippo

2019/4/12

#
Since the Laser subclasses are the same, you could have all of it in one class and save in a variable with type it is. For example:
private int type; //0=Laser, 1=PointsLaser, 2=PowerLaser

public Laser(int type)
{
    this.type = type;
    //only needed if different images are used
    switch (type)
    {
        case 0: setImage("Laser.png"); break;
        case 1: setImage("PointsLaser.png"); break;
        case 2: setImage("PowerLaser.png"); break;
    }
}

public void act()
{
    move(5);
    Mushroom m = (Mushroom) getOneIntersectingObject(Mushroom.class);
    if (m != null)
    {
        switch (type)
        {
            case 0:
            m.takeDamage(); //create a method which damages the Mushroom and removes it if necessary
            //add points to the score – I got a bit lost about how you calculate your points.
            //You can also add the score in the takeDamage method or have the method return a boolean depending on the life state of the mushroom after the hit to see how many points to add
            break;
            
            case 1:
            m.takeDamage();
            //add twice as much to the score as above
            break;
            
            case 2:
            getWorld().removeObject(m); //PowerLaser destroys it in one shot
            //add score – if handled in takeDamage method, make sure you use it here, too. For example with passing a parameter how much damage it should deal. Then you can either use a very high number for a safe kill or you use something like -1 and check for -1 in the method and kill it then
            break;
        }
    }
}

//only needed if you keep the checks for intersection in the mushroom class (see below) – otherwise, use what is in the act method here
public int getType()
{
    return type;
}
(Btw, please use code-tags in the future.)
AdiBak AdiBak

2019/4/12

#
How do I switch the laser?
AdiBak AdiBak

2019/4/12

#
And how do I get a reference of the type of laser in other classes?
Super_Hippo Super_Hippo

2019/4/13

#
By the way, I forgot to add the following line after line 38:
getWorld().removeObject(this);
You switch the type of the Laser from the character who shoots it. So instead of "new Laser()", you will have "new Laser(type)". type is the variable in the character class which decides which laser type should be shot. To get the type of the Laser, you can use the getType method. So if you don't use the act method I showed and keep it in the Mushroom class, it could look like this:
Laser l = (Laser) getOneIntersectingObject(Laser.class);
if (l != null)
{
    switch (l.getType())
    {
        case 0: //Mushroom touches Laser
        //<insert code here>
        break;

        case 1: //Mushroom touches PointsLaser
        //<insert code here>
        break;

        case 2: //Mushroom touches PowerLaser
        //<insert code here>
        break;
    }
}
AdiBak AdiBak

2019/4/13

#
Thanks, it worked! I have another question -- how do you ask for user input? What I want to do is that once the score reaches a certain amount, the player will get to choose their powerup and play with that. I want to call something similar to that of "readLine()" used in Javascript. Can someone please help? Thank you.
danpost danpost

2019/4/13

#
AdiBak wrote...
how do you ask for user input? What I want to do is that once the score reaches a certain amount, the player will get to choose their powerup and play with that. I want to call something similar to that of "readLine()" used in Javascript. Can someone please help? Thank you.
You could use the ask method of the Greenfoot class.
AdiBak AdiBak

2019/4/13

#
I used the ask method, which did work, but after typing in the answer and clicking "OK", the prompt wouldn't go away. Should I have a "break" statement?
danpost danpost

2019/4/13

#
AdiBak wrote...
I used the ask method, which did work, but after typing in the answer and clicking "OK", the prompt wouldn't go away. Should I have a "break" statement?
A "break" statement? I do not see why you would need one. Please provide attempted codes.
AdiBak AdiBak

2019/4/13

#
Here's the part:
if (w.getScore() > 0 && w.getScore() <= 2000){
            w.setNormal(true);
        }
        
        if (w.getScore() > 2000 && w.getScore() <= 4000){
            w.setNormal(false);
            w.setPointPowerup(true);
        } 
        if (w.getScore() > 4000 && w.getScore() <= 6000){
            w.setPointPowerup(false);
            w.setPower(true);
        }
        if (w.getScore() > 6000){
            w.setPower(false);
            String question = Greenfoot.ask("What powerup would you like (normal, points, power)?");
            if (question == "normal"){
                w.setNormal(true);
               
            } else if (question == "points"){
                w.setPointPowerup(true);
                
            } else if (question == "power"){
                w.setPower(true);
               
            }
        //    break;
        }
danpost danpost

2019/4/13

#
Okay. I was thinking you could upgrade the question variable to a field:
private String question = null;
and add the condition that it be null at line 13:
if (question == null && w.getScore() > 6000)
to control the asking of the question. You would need to remove the type 'String' from line 15.
AdiBak AdiBak

2019/4/13

#
I understand, but how would I ask the question if it's null?
There are more replies on the next page.
1
2
3