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

2012/11/28

Urgent help

1
2
lonely.girl lonely.girl

2012/11/28

#
Hey, I've downloaded a program with source code a while ago from this website, I was wondering if it is possible for anybody to help me understand some of the stuff in the code that I didn't really get? #ANY help or comment is really appreciated The program is the snake game If it is possible then first I would like to start with the world and the following questions regarding the code below: 1) why r we setting color in this statement / Color color1= new Color(255,250,250); if it is for the score then we didn't we do that in score actor 2) what is this part? from what I understood that we already added array in the part where we set the head and two other parts so what is the need of the following & what does it mean? public void addArray() { Snake newSnake = new Snake; System.arraycopy(snake, 0, newSnake, 0, snake.length); #don't seem 2 b able 2 wrap my head around this one snake = newSnake; } 3) here is almost same question, why do we have "add object/item" and then "add item" separately, what I understood is "public void add item" is to add an item to the world but "public void update" is to change & update what happens after the item is removed to add a new one?? is that correct can we say that r1 & r2 below are x,y for the item ?? private void update() { int r1, r2; r1 = Greenfoot.getRandomNumber(24); r2 = Greenfoot.getRandomNumber(24); addObject(new Item(), r1*20+10, r2*20+10); #don't get the multiplication here ---------------------------------------------------------------------------------------------- public class Bord extends World { public Snake snake; Color color1= new Color(255,250,250); int a,b; private Score thisScore; private Item item; public void act() { addItem(); } public bord() { super(500, 500, 1); Greenfoot.setSpeed(35); snake = new Snake; snake = new Snake("head"); snake = new Snake(); snake = new Snake(); addObject(snake, 110, 50); addObject(snake, 90, 50); addObject(snake, 70, 50); addObject(new Wall(), 150, 381); addObject(new Wall(), 350, 119 ); thisScore = new Score(); addObject(thisScore, 130, 5); } public void addArray() { Snake newSnake = new Snake; System.arraycopy(snake, 0, newSnake, 0, snake.length); snake = newSnake; } public void addItem() { List<Item> item = getObjects(Item.class); if (item.isEmpty()) { update(); } } public Score getScore() { return thisScore; } private void update() { int r1, r2; r1 = Greenfoot.getRandomNumber(24); r2 = Greenfoot.getRandomNumber(24); addObject(new Item(), r1*20+10, r2*20+10); } } ------------------------------------------------------------------------------------------ Sorry for being annoying with too many questions & thanks in advance
danpost danpost

2012/11/28

#
(1) If that is the whole listing of the world class, then I see know reason for the Color color1 assignment in this class. Maybe it was accidentally left there after changing some of the code. Maybe it was a bit of poor programming. Who knows? (2) It is true that the array was already added; but its length is only as long as the snake itself. When the snake grows, the array needs to be adjusted in length (adding one to the length of the array) to hold the next segment. This is what the method does. The first line create a temporary array of length one greater than the main array. The second statement copy the data from the main array to the temporary one. The final statement creates a new main array set with the data from the temporary array. After the call to this method, a new segment will be assigned to the new (end) location in the array. (3) The 'addItem' method called from the 'act' method only checks to see if the 'item' is not in the world; and if not, calls the 'update' method to add the 'item' back into the world. 'r1' and 'r2' are short for 'randomOne' and 'randomTwo'. Giving names like 'r1' and 'r2' are discouraged, but oftentimes, especially for common usages, that standard is not applied. I believe that the maximum value for 'r1' and 'r2' could have been raised by one (to 25) since the dimensions of the world are 500x500. The calculation of the 'x' and 'y' in the last statement ensures the 'item' is placed within world bounds and exactly at locations that the snake may occupy (the snake moves horizontally and vertically at a speed of 20 pixels per move; and is also placed in the world with offsets of 10). Hope these explanations were to your satisfaction.
lonely.girl lonely.girl

2012/11/28

#
Hey danpost that was amazingly helpful, I wish I would be able to know all this myself in the future :) So this means int a, b also no need for them coz they are not used anywhere else in the class !!! It was more than great so thank you very much, last question before I put the snake class * if the dimensions of the world are (1000, 700) what could the max value for r1 and r2 be???? Thanks a million for your help it really clarified alot :)
Malmotri Malmotri

2012/11/28

#
You can see it like this. Something times 20 + 10 should be you size in x or y. And result is your dimensions in x or y - 10 in both. in super(500,500,1) 24*20+10=490 So for super(1000,700,1) It would be x: 49*20+10=990 y: 34*20+10=690 And it would look like this:
private void update()
    {
        int r1, r2;
        r1 = Greenfoot.getRandomNumber(49);
        r2 = Greenfoot.getRandomNumber(34);
        addObject(new Item(), r1*20+10, r2*20+10);
    }
danpost danpost

2012/11/28

#
Let me generalize the answer to your 'last question'. If the dimensions of the world are (xDimension, yDimension), then r1 = Greenfoot.getRandomNumber(xDimension/20); r2 = Greenfoot.getRandomNumber(yDimension/20); Of course, it would be best to have the dimensions be multiples of 20.
Malmotri Malmotri

2012/11/28

#
or you can right it direct without variable.
 
private void update()
    {
        addObject(new Item(),Greenfoot.getRandomNumber(49)*20+10,Greenfoot.getRandomNumber(34)*20+10);    
    }
Malmotri Malmotri

2012/11/28

#
Yes thats better a explanation danpost. Easy to understand!
danpost danpost

2012/11/28

#
@Malmotri, 'getRandomNumber' never returns the limit value supplied. For a limit of four, 'getRandomNumber(4)', the four possible return values are 0, 1, 2, and 3. Therefore, in your example above, where you limit 'r1' to 49 and 'r2' to 34, the highest x and y would only be 970 and 670.
Malmotri Malmotri

2012/11/28

#
Ohh i didn't know that. Thank you! Then i would be 50 in x and 35 in y.
lonely.girl lonely.girl

2012/11/28

#
Danpost thanks a lot for the explanation it is such a good help..... Malmotri It was a very good example better than variables & so simple I'll change the code then :) Thank you very much this really helps big time.... I'm just finishing my question about the snake class, hopefully I'll post it soon Appreciate your help so much
lonely.girl lonely.girl

2012/11/28

#
import greenfoot.*;
import java.awt.Color;
public class Snake extends Actor {
    private String segment, direction;
    private int speed, speedX, speedY, length;
    public Color color;
   
    public Snake(String segment)
    {
        this.segment = segment;
        direction = "right";
        speedX = speed = 20;
        speedY = 0;
        length = 3;
        setImage("black-ball3.png");
    }

    public Snake()

    {
         setImage("steel-ball2.png");
    }
    

    public void act()
    {
        if (segment == "head") {
            Board board = (Board)getWorld();
            for (int i = length - 1; i > 0; i--)
                board.snake[i].setLocation(board.snake[i - 1].getX(), board.snake[i - 1].getY());

            keyboardControl();
            move();
            eat();
        
        }
    }

    private void keyboardControl()
    {
        if (Greenfoot.isKeyDown("left") && direction != "right") {
            speedX = -20;
            speedY = 0;
            direction = "left";

        } else if (Greenfoot.isKeyDown("right") && direction != "left") {
            speedX = 20;
            speedY = 0;
            direction = "right";

        } else if (Greenfoot.isKeyDown("up") && direction != "down") {
            speedX = 0;
            speedY = -20;  
            direction = "up";

        } else if (Greenfoot.isKeyDown("down") && direction != "up") {
            speedX = 0;
            speedY = 20;
            direction = "down";

        }
    }

    private void move()
    {

        if (getX() + speedX < 0 || getX() + speedX >= 500
        || getY() + speedY < 0 || getY() + speedY >= 500)
            end();


        Actor wall = getOneObjectAtOffset(speedX, speedY, Wall.class);
        if (wall != null)
            end();


        Actor body = getOneObjectAtOffset(speedX * 2, speedY * 2, Snake.class);
        if (body != null)
            end();

        setLocation(getX() + speedX, getY() + speedY);
    }

    private void eat()
    {
        Actor item = getOneObjectAtOffset(0, 0, Item.class);
        if (item != null) {
            
            Board board = (Board)getWorld();
            board.addArray();
            board.removeObject(item);
            board.snake[length] = new Snake();
            board.addObject(board.snake[length], getX(), getY());
            
          
            length++;
           
            Score score = board.getScore();
            score.addScore(1);
        }
    }
    
    
    
    
      private void end()
    {
        Greenfoot.stop();
    }
}

I think now i put the code the right way :D let's start with color assignment which I believe it's not necessary here either? right? ok here we go: 1) a\ are we using the "this" keyword here because we want to refer to the current object? and because "segment" is called somewhere else in the class so we needed to distinguish it in the constructor ? b\ why did we put "string segment" in parameters?
  public Snake(String segment)
    {
        this.segment = segment;
        direction = "right";
        speedX = speed = 20;
        speedY = 0;
        length = 3;
        setImage("snake.png");
    }
c\ here are we adding the image of the newly added segment? after the snake is eating the item 2) in the code below first what I understood is that it is responsible for moving the snake and making the body follow the head the questions are a/ why are we using field.snake? is it because we have the coding in the world already so we have to refer to it there because we created the array in that class? b/ why i-- ?? not incremental aren't we like moving ? the for loop is kind of hard to understand ikd :( c/ then we are updating the current location but why writing ??
public void act()
    {
        if (segment == "head") {
            Field field = (Field)getWorld();
            for (int i = length - 1; i > 0; i--)
                field.snake[i].setLocation(field.snake[i - 1].getX(), field.snake[i - 1].getY());

            keyboardControl();
            move();
            eat();
        
        }
3) The keyboard control is obvious & easy to get thankfully so in this quetstion just wanna double check my understanding for the "if"s in the move first "if" is to make sure the snake is inside the world not hitting edges second "if" is to check if the snake hits the wall third "if" if it hits part of the body or tale is that pretty much it ?? 4) the code below is also easy to understand what's going on here the snake becoming longer, the score is increasing and the item is being removed but the only thing I couldn't get is Actor item = getOneObjectAtOffset(0, 0, Item.class); I mean I know it's to call the item from the item class but what are these two zeros stand for?
 private void eat()
    {
        Actor item = getOneObjectAtOffset(0, 0, Item.class);
        if (item != null) {
            
            Field field = (Field)getWorld();
            field.addArray();
            field.removeObject(item);
            field.snake[length] = new Snake();
            field.addObject(field.snake[length], getX(), getY());
            
          
            length++;
           
            Score score = field.getScore();
            score.addScore(1);
        }
    }
    
Appreciate your help very much and hoping for these questions above to be my last :)
danpost danpost

2012/11/28

#
(Pre) Color color: as it is not assigned any value in the class, I would think that it can be removed. (1)(a) Since the method is being intoduced a local field by way of a parameter variable called 'segment', the only way to refer to the instance field already defined in the class with the same name is with the 'this' keyword. (b) the 'act' method needs a way to distinguish between the 'head' segment and any 'body' segments; therefore an instance field must be used to perform exactly that. And that information is recieved through the constructor's parameter. (c) actually, the constructor with the parameter was written solely for the 'head' of the snake; while the one without it was written solely for any 'body' segment. (2)(a) because the snake array is located in the Field world class, accessing the array can only be accomplished by getting a reference to that world as a 'Field' world. (b) the loop counter is being used as the index in the snake array. It starts at the back end of the snake (length-1) and works its way forward (by decrementing the index using i--) until the segment behind the 'head is reached (index of 1). (c) hopefully explained in (2)(b) above. (3) you seem to understand the 'if's in the 'move' method. (4) think of 'getOneObjectAtOffset(dx, dy, class)' as equivalent to (if there was such a method) 'getOneObjectIntersectingThePoint(this.getX()+dx, this.getY()+dy, class)' So, with dx=0 and dy=0, this becomes 'getOneObjectIntersectingThePoint(this.getX(), this.getY(), class)' What that would do is return one 'class' type objects whose image contains the point at which the actor ('this') is located (if there is one; if not, returns 'null').
lonely.girl lonely.girl

2012/11/28

#
I can't thank you enough, this was very kind of you & very helpful Thank you so much
lonely.girl lonely.girl

2012/11/28

#
Do you think it would be easy to add obstacles in the world ? which should have the same effect as the wall ?
danpost danpost

2012/11/28

#
My original draft of the previous was much more detailed. But after my sensitive mousepad corrupted it to smitherines and I had to start over, I had to be a little more abbreviated in what I was to say. I was going to mention, however, that I did not like the way that the 'keyboardControl' method was written. The reason being that it is biased to certain keys over others (or more precisely, biased to vertical movement over horizontal movement). For example, one could press the 'up' key while holding down the 'right' key and the direction of movement for the snake will change from right to up; but if one was to press the 'right' key while holding down the 'up' key, the snake will continue going up. This kind of performance tends to ruin the 'feel' of play of the scenario.
There are more replies on the next page.
1
2