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

2018/3/6

Removing multiple actors that are in a row

DrCrane DrCrane

2018/3/6

#
Hello, I've been working on a game in which you must remove all the balls. However, I cannot think of a way to remove multiple balls (of the same color!) in a line that has branches going up and down. TL;DR: How can I remove the balls that are connected to each other and have a chain of more than 3? All the necessary code is included for the level, and an image of what I want to remove (a chain of 3 or more) World class (Level4)
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.Random;

/**
 * Write a description of class Level4 here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Level4 extends World
{
    private int totalBallRows = 3;
    private int drawBallStop = 6;
    private int yPos;

    /**
     * Constructor for objects of class Level4.
     * 
     */
    public Level4()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(400, 600, 1); 

        createBackGround();
        loadGameAssets();
        generateBalls();
    }

    public void createBackGround() {
        addObject(new dropRow_Title(), 348, 69);
        addObject(new dropRow_playArea(), 123, 274);
    }

    public void loadGameAssets() {
        addObject(new dropRow_scoreboard(), 346, 204);
        addObject(new dropRow_scoreDisplay(0), 372, 251);
        addObject(new dropRow_ballStop(), 98, 546);
    }

    public void generateBalls() { //523
        for (int counter2 = 0; counter2 < totalBallRows; counter2=counter2+1) {
            if(counter2 == 0) yPos = 0;
            else if(counter2 == 1) yPos = 45;
            else if(counter2 == 2) yPos = 90;
            else yPos = 1;

            addObject(new dropRow_ball(ballType()), 22, yPos);
            addObject(new dropRow_ball(ballType()), 62, yPos);
            addObject(new dropRow_ball(ballType()), 102, yPos);
            addObject(new dropRow_ball(ballType()), 142, yPos);
            addObject(new dropRow_ball(ballType()), 182, yPos);
            addObject(new dropRow_ball(ballType()), 222, yPos);
        }
    }

    public int ballType() {
        int balltype;
        int bt_temp = getRandomNumber(0, 4);
        if(bt_temp == 1) { bt_temp = getRandomNumber(0, 4); }
        balltype = bt_temp;

        return balltype;
    }

    public int getRandomNumber(int min, int max)
    {
        Random random = new Random(); 
        int  n = random.nextInt(max-min) + min; 
        return n; 
    }
}
dropRow_ball
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Dropto y=544
 */
public class dropRow_ball extends dropRow
{
    public dropRow_ball(int type) {
        if(type == 1) { //Red 
            setImage("dropfun_redball.png");
        }
        else if(type == 2) { //Yellow
            setImage("dropfun_yellowball.png");
        }
        else if(type == 3) {//Green
            setImage("dropfun_greenball.png");
        }
    }

    public void act() {
        if(isTouching(dropRow_ball.class)) {} //Do nothing
        else if(isTouching(dropRow_ballStop.class)) {} //Do nothing
        else setLocation(getX(), getY()+5);

    }
    public boolean checkMovePossible() {
        return true;
    }
}
Vercility Vercility

2018/3/6

#
Edit: Come to think of it, in greenfoot this might be easier than I thought initially Make every ball check their surroundings with a method. If you find a matching one call the method on that ball too etc, and add those to a set, if it's size is >=3 at the end delete them all
DrCrane DrCrane

2018/3/6

#
I've figured out another way, which I am currently coding in. I can give the code that detects the row (only horizontal for now. will add vertical and diagonal later). Class: dropRow_chainChecker
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.*;

/**
 * in checkForBalls() the filename that is written in writeFile() is based on logic. The file is in
 * data/droprowMap/***.txt
 * The *** is df_rowpos_linepos.txt
 */
public class dropRow_chainChecker extends dropRow
{
    int wait = 0;
    
    public dropRow_chainChecker() {

    }

    public void act() 
    {
        checkForBalls();
    }    

    public void checkForBalls() {
        int line = linePos();
        int row = rowPos();
        if(wait != 60) wait++;
        else {
            wait = 0;
            if((row == 1) && (line == 1)) {
                if(isTouching(dropRow_ballRed.class)) {
                    writeFile("data/droprowMap/df-1-1.txt", "red");
                }
                else if(isTouching(dropRow_ballYellow.class)) {
                    writeFile("data/droprowMap/df-1-1.txt", "yellow");
                }
                else if(isTouching(dropRow_ballGreen.class)) {
                    writeFile("data/droprowMap/df-1-1.txt", "green");
                }
            }
            else if((row == 1) && (line == 2)) {
                if(isTouching(dropRow_ballRed.class)) {
                    writeFile("data/droprowMap/df-1-2.txt", "red");
                }
                else if(isTouching(dropRow_ballYellow.class)) {
                    writeFile("data/droprowMap/df-1-2.txt", "yellow");
                }
                else if(isTouching(dropRow_ballGreen.class)) {
                    writeFile("data/droprowMap/df-1-2.txt", "green");
                }
            }
            else if((row == 1) && (line == 3)) {
                if(isTouching(dropRow_ballRed.class)) {
                    writeFile("data/droprowMap/df-1-3.txt", "red");
                }
                else if(isTouching(dropRow_ballYellow.class)) {
                    writeFile("data/droprowMap/df-1-3.txt", "yellow");
                }
                else if(isTouching(dropRow_ballGreen.class)) {
                    writeFile("data/droprowMap/df-1-3.txt", "green");
                }
            }
            else if((row == 1) && (line == 4)) {
                if(isTouching(dropRow_ballRed.class)) {
                    writeFile("data/droprowMap/df-1-4.txt", "red");
                }
                else if(isTouching(dropRow_ballYellow.class)) {
                    writeFile("data/droprowMap/df-1-4.txt", "yellow");
                }
                else if(isTouching(dropRow_ballGreen.class)) {
                    writeFile("data/droprowMap/df-1-4.txt", "green");
                }
            }
            else if((row == 1) && (line == 5)) {
                if(isTouching(dropRow_ballRed.class)) {
                    writeFile("data/droprowMap/df-1-5.txt", "red");
                }
                else if(isTouching(dropRow_ballYellow.class)) {
                    writeFile("data/droprowMap/df-1-5.txt", "yellow");
                }
                else if(isTouching(dropRow_ballGreen.class)) {
                    writeFile("data/droprowMap/df-1-5.txt", "green");
                }
            }
            else if((row == 1) && (line == 6)) {
                if(isTouching(dropRow_ballRed.class)) {
                    writeFile("data/droprowMap/df-1-6.txt", "red");
                }
                else if(isTouching(dropRow_ballYellow.class)) {
                    writeFile("data/droprowMap/df-1-6.txt", "yellow");
                }
                else if(isTouching(dropRow_ballGreen.class)) {
                    writeFile("data/droprowMap/df-1-6.txt", "green");
                }
            }
        }
    }

    public int linePos() {
        int line;
        int rawX = getX();
        if(rawX == 22) { line = 1; }
        else if(rawX == 62) { line = 2; }
        else if(rawX == 102) { line = 3; }
        else if(rawX == 142) { line = 4; }
        else if(rawX == 182) { line = 5; }
        else if(rawX == 222) { line = 6; }
        else line = 0;

        return line;
    }

    public int rowPos() {
        int row;
        int rawY = getY();
        if(rawY == 525) { row = 1; }
        else row = 0;

        return row;
    }

    public void writeFile(String filename, String writeLine)
    {
        FileOutputStream fos = null;
        File file;

        try {
            //Specify the file path here
            file = new File(filename);
            fos = new FileOutputStream(file);

            /* This logic will check whether the file
             * exists or not. If the file is not found
             * at the specified location it would create
             * a new file*/
            if (!file.exists()) {
                file.createNewFile();
            }

            /*String content cannot be directly written into
             * a file. It needs to be converted into bytes
             */
            byte[] bytesArray = writeLine.getBytes();

            fos.write(bytesArray);
            fos.flush();
            System.out.println("File Written Successfully");
        } 
        catch (IOException ioe) {
            ioe.printStackTrace();
        } 
        finally {
            try {
                if (fos != null) 
                {
                    fos.close();
                }
            } 
            catch (IOException ioe) {
                System.out.println("Error in closing the Stream");
            }
        }
    }
}
Class: dropRow_chainWreckerController
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.*;

/**
 * Write a description of class dropRow_chainWrecker here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class dropRow_chainWreckerController extends dropRow_chainChecker
{
    /**
     * Act - do whatever the dropRow_chainWrecker wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        checkRedChainH();
        checkRedChainV();
    }    
    
    public void checkRedChainH() { //Check chains in Horizontal lines
        //Line 1 (Bottom)
        String df_1_1 = readFile("data/droprowMap/df-1-1.txt");
        String df_1_2 = readFile("data/droprowMap/df-1-2.txt");
        String df_1_3 = readFile("data/droprowMap/df-1-3.txt");
        String df_1_4 = readFile("data/droprowMap/df-1-4.txt");
        String df_1_5 = readFile("data/droprowMap/df-1-5.txt");
        String df_1_6 = readFile("data/droprowMap/df-1-6.txt");
        World world = getWorld();
        if(df_1_1.equals("red")) {
            if(df_1_2.equals("red")) {
                if(df_1_3.equals("red")) { //Chain in row 1, line 123
                    System.out.println("Line 123");
                    
                    world.addObject(new dropRow_chainWrecker(1), 22, 525);
                    world.addObject(new dropRow_chainWrecker(1), 62, 525);
                    world.addObject(new dropRow_chainWrecker(1), 102, 525);
                }
            }
        }
        if(df_1_2.equals("red")) {
            if(df_1_3.equals("red")) {
                if(df_1_4.equals("red")) { //Chain in row 1, line 234
                    System.out.println("Line 234");
                }
            }
        }
        if(df_1_3.equals("red")) {
            if(df_1_4.equals("red")) {
                if(df_1_5.equals("red")) { //Chain in row 1, line 345
                    System.out.println("Line 345");
                }
            }
        }
        if(df_1_4.equals("red")) {
            if(df_1_5.equals("red")) {
                if(df_1_6.equals("red")) { //Chain in row 1, line 456
                    System.out.println("Line 456");
                }
            }
        }
    }
    
    public void checkRedChainV() { //Check chains in Vertical lines
        
    }
    
    public String readFile(String filename)
    {
        BufferedReader br = null;
        List<String> lines = new ArrayList<String>();

        try
        {
            InputStream input = getClass().getClassLoader().getResourceAsStream(filename); // open input stream
            br = new BufferedReader(new InputStreamReader(input)); // wrap the stream within a BufferedReader object
        }
        catch (Exception e) { System.out.println("File not found: "+filename); return null; } // for failure to open stream
        // attempt to read in the lines of text
        try
        {
            String line = null; // sets up a local field for each line of text
            while ((line = br.readLine()) != null)  lines.add(line); // read each line and add them to the 'lines' list
            br.close(); // close the BufferedReader object
        }
        catch (Exception e) { try { br.close(); } catch (Exception f) {} } // close file if read error occurred

        String lines_joined = String.join(",", lines);

        String[] newStrings = lines_joined.split(",");
        String end = newStrings[0];

        return end;
    }
}
Class: dropRow_chainWrecker
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;

/**
 * Write a description of class dropRow_chainWrecker here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class dropRow_chainWrecker extends dropRow_chainWreckerController
{
    Actor wreckBall;
    
    /**
     * Act - do whatever the dropRow_chainWrecker wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public dropRow_chainWrecker(int balltype)
    {
        World world = getWorld();
        if(balltype == 1) {
            List<Actor> wreckBall = getIntersectingObjects(dropRow_ballRed.class);
        }
        else if(balltype == 2) {
            
        }

        else if(balltype == 3) {

        }
        
        world.removeObjects(wreckBall);
    }    
}
The dropRow_chainWrecker class has an error which I'm currently working on. Will update when I got it fixed, but I'm off for today (probably).
Vercility Vercility

2018/3/7

#
What the actual fuck. Why are you writing files and why are you hard coding every case
Yehuda Yehuda

2018/3/7

#
In this scenario we used a list. We got a list of all the intersecting Pops, every Pop has a public variable in it to get its color. All Pops in the list that are a different color (from this one) were removed from the list. If the list had a size of at least 2 after that then all the Pops in the list including this Pop had a boolean variable changed in them to true, which when this variable is true the Pop will remove itself. This Pop couldn't just remove the other Pops from the list because then three Pops will all be removing each other. (I'm not sure that reason actually makes a difference. I think the variable is also to know that it should be fading.) I'm saying all this without even being sure this is what you're trying to do. I didn't read your code, since it's too long.
danpost danpost

2018/3/7

#
I do not know if it is the best or anything, but I would put a method in the ball class to return a list of its immediate neighbors so their types can be compared. The world would then take any matching ball and place it into a list (if not already in it). Prior to calling the method on a ball, the world would start this list with that particular ball. Once all the neighbors of all the elements in the list are checked, it becomes the complete group to remove (if the size is greater than 2). On the broader side of things, I would have a list in the world to hold any ball that produces any change in the current layout. When all is settled, and the removal phase begins, each element is used to start a group as above. As matching groups are made, their elements can be immediately removed from this main list so no re-checking is done and also so there is no chance of checking a ball that may have already been removed from the world.
DrCrane DrCrane

2018/3/7

#
Yehuda wrote...
In this scenario we used a list. We got a list of all the intersecting Pops, every Pop has a public variable in it to get its color. All Pops in the list that are a different color (from this one) were removed from the list. If the list had a size of at least 2 after that then all the Pops in the list including this Pop had a boolean variable changed in them to true, which when this variable is true the Pop will remove itself. This Pop couldn't just remove the other Pops from the list because then three Pops will all be removing each other. (I'm not sure that reason actually makes a difference. I think the variable is also to know that it should be fading.) I'm saying all this without even being sure this is what you're trying to do. I didn't read your code, since it's too long.
That's about what I need yes, but the linked scenario it doesnt go past initializing and I cannot download the scenario. On another note, my bad workaround is currently working
Yehuda Yehuda

2018/3/8

#
You can View applet version (I think the updates were never uploaded but this version works), and anyway I explained how it was done: With a list of all the intersecting objects, and the code is in the Pop class (see previous post).
You need to login to post a reply.