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

2011/10/20

How to get and use Actors from an Array list..

nikko nikko

2011/10/20

#
Hi everyone! Having BIG time problem producing an Snake game in Greenfoot. The problem is that I want to expand and take the snakes body segments from an Array and I have no clue where to start or who to ask. --------------------------------- I have this in my world: SnakeHead snakeExtension = new SnakeHead ; snakeExtension = new SnakeHead(); And I wrote this in my constructor for my SnakeHead class. public SnakeHead() { } What kind of parameters do the Constructor for the SnakeHEad class want? ------------------------------------------------------------------ WORLD CLASS: import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class SnakeWorld here. * * @author (your name) * @version (a version number or a date) */ public class SnakeWorld extends World { SnakeHead snakeExtension = new SnakeHead ; /** * Constructor for objects of class SnakeWorld. * */ public SnakeWorld() { // Create a new world with 600x400 cells with a cell size of 1x1 pixels. super(80, 80, 10); addObject( new SnakeHead(), 10, 10); addObject( new Food(), 16, 16); GreenfootImage gi = new GreenfootImage(this.getWidth(),this.getHeight()); for (int i = 0; i < gi.getWidth(); i += 10) { gi.drawLine(i,0,i,gi.getHeight()); } for (int i = 0; i < gi.getHeight(); i += 10) { gi.drawLine(0, i, gi.getWidth(),i); } snakeExtension = new SnakeHead(); snakeExtension = new SnakeHead(); snakeExtension = new SnakeHead(); this.setBackground(gi); getSnakeExtension(); } public Actor getSnakeExtension() { return snakeExtension; } } CLASS SNAKE: public class SnakeHead extends Actor { int location = 1; int foodOnScreen = 1; int score = 0; //HIGHSCOREN /** * Act - do whatever the SnakeHead wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public SnakeHead() { } public void act() { Actor snakeExtension = ((SnakeWorld)getWorld()).getSnakeExtension(); //dead(); checkForFoodCollide(); foodSpawn(); if(location == 1) //Right { setLocation(getX() + 3, getY()); if(Greenfoot.isKeyDown("up")) { location = 2; setLocation(getX() -3, getY()); } else if(Greenfoot.isKeyDown("down")) { location = 3; setLocation(getX() -3, getY()); } } if(location == 2) //Up { setLocation(getX(), getY() - 3); if(Greenfoot.isKeyDown("left")) { location = 4; setLocation(getX(), getY() + 3); } else if(Greenfoot.isKeyDown("right")) { location = 1; setLocation(getX(), getY() + 3); } } if(location == 3) //down { setLocation(getX(), getY()+ 3); if(Greenfoot.isKeyDown("left")) { location = 4; setLocation(getX(), getY()-3); } else if(Greenfoot.isKeyDown("right")) { location = 1; setLocation(getX(), getY()-3); } } if(location == 4) //left { setLocation(getX() - 3, getY()); if(Greenfoot.isKeyDown("up")) { location = 2; setLocation(getX() + 3, getY()); } else if(Greenfoot.isKeyDown("down")) { location = 3; setLocation(getX() + 3, getY()); } } } public void mover() { } public void dead() { if(getY() <= 0) { Greenfoot.stop(); setLocation(getX(), 1); } else if(getY() > 29) { Greenfoot.stop(); setLocation(getX(), 28); } else if(getX() < 0) { Greenfoot.stop(); setLocation(1, getY()); } else if(getX() > 29) { Greenfoot.stop(); setLocation(28, getY()); } } //Det här metodanropet betyder att ormen hela tiden skall leta efter en pizza bit public void checkForFoodCollide() { if ( whenCollide(Food.class) ) { eat(Food.class); } } //Det här är metoden för vad som händer när ormen hittar en pizza bit och för vad som händer just då. //Samt vad just den här metoden skall retunera. Hade jag inte haft denna metoden här så hade jag aldrig fått //Ut värdet som jag använder i metoden under denna. public boolean whenCollide(Class eatStuff) { Actor pizza = getOneObjectAtOffset(0, 0, eatStuff); return pizza != null; } //Det här är metoden för vad som sak hända med pizza biten såfort den äts upp. public void eat(Class eatStuff) { Actor pizza = getOneObjectAtOffset(0, 0, eatStuff); if(pizza != null) { getWorld().removeObject(pizza); foodOnScreen = foodOnScreen - 1; score++; //snakeExtension = new Body(); } } //Här spawnar jag maten till en random location.. Inte mycket att beskriva egentligen. public void foodSpawn() { int spawnTheFoodX = Greenfoot.getRandomNumber(60); int spawnTheFoodY = Greenfoot.getRandomNumber(60); if(foodOnScreen == 0) { getWorld().addObject(new Food(), spawnTheFoodX + 3 , spawnTheFoodY + 3); foodOnScreen ++; } } }
danpost danpost

2011/10/20

#
A reference to the previous head would be ideal (an instance SnakeHead variable 'headFollowed') and can be passed to the constructor (use 'null' for the first head). Also helpful would be two instance variables (not passed to the constructor) for the x and y coordinates of its last position ('lastX' and 'lastY'; use 'lastX = getX()' and 'lastY = getY()' in the move() method before the actual move. Set up methods to retrieve these values publicly (getHeadFollowed(), getLastX(), and getLastY()). The x and y values can be used to make sure all the heads play follow the leader and the headFollowed can be checked to see if it is the lead snakeHead. If you are planning on having the snake split into multiple snakes, you can change 'headFollowed' to be 'null' for the new lead snakeHead.
bourne bourne

2011/10/20

#
Do you have a particular design plan in mind or is that what you are asking for? 1. If you are wanting to have your snake grow in size, the standard array will prove to be difficult. I suggest using java.util.ArrayList 2. A snake segment I suppose would need a position, although if it extends Actor, it's already taken care of. 3. You don't necessarily need an array of any sort if SnakeHead is an Actor and are placed in the World. Note: you don't have to move every SnakeHead a space to show movement of the snake. You can just keep track of the "head" position (where you add a new SnakeHead in a given direction, that which becomes the new "head"), and the "tail" where you remove the last SnakeHead object (segment). And to cause it to grow, you can do something like, so many steps - don't remove the "tail"
nikko nikko

2011/10/21

#
Hi again! And thanks for your time and hints! Im sitting here with a task that I got from school and since my teachers are NOT allowed to show me any code I have to "guess" my way trough this. My school gave me this task after knowing java for about 1.5 months.... Im a noob and I have to do everything from scratch! Wich means im not allowed to "copy" or "reuse" any code from the book. All I've got is a gridnet as a world and the eating stuff works and so does the random spawn of food but what now? If i need to use Array? That's the problem. I have read about Arrays but can't figure out how to draw stuff from it? Haven't start working on the "tail following" stuff yet since I really want to know how to add a new bodySegment (from Array) everytime im eating something with my snakeHead. I saw there was a severeal examples from people making snake games here on greenfoot but its just to much code and im not thinking about copy any stuff that i can't understand. Thanks for being understanding and not laughing at me :)))) Sec.... Gonna upgrade my code here
danpost danpost

2011/10/21

#
bourne, question: How would you get a reference to the new tail when you remove the last segment from the snake? nikko, if you decide on something like what I proposed, adding a new head segment would go something like this: a world boolean variable 'addSegment' (or 'hasEaten') will be set to true when the snake eats; the lead snake segment or head (with headFollowed = null) checks to see if addSegment is true; if so, create a new segment and set it to a reference variable; set its headFollowed instance variable to null; add it to the world at the next head movement location; change old head's headFollowed to the new reference and set old head's lastX and lastY to the new head's current coordinates; and, finally, reset the world addSegment variable to false.
danpost danpost

2011/10/21

#
Correction as to how 'lastX' and 'lastY' should be used: as you create each snake segment, set it to a reference variable before adding it to the world so you can send it to the Constructor for the next segment (null is used for the first segment created). In the segment class, the constructor saves the reference to 'headFollowed'; for all segments except the head save to 'lastX' and 'lastY' the current coordinates of the 'headFollowed' segment. In the act method if either coordinate for 'headFollowed' does not match its current location, then it has moved on and the current segment can now be moved to that location and 'lastX' and 'lastY' can be reset to the new 'headFollowed' coordinates. (Each subsequent segment will follow suit)
bourne bourne

2011/10/21

#
Sorry don't have time to read over everything, but to your question danpost: each segment can store a direction to the next, or a reference to the next (done so when creating each new segment, -when replacing the "head"). And simply do an update to how you store the "tail" accordingly, each time you remove the "tail".
danpost danpost

2011/10/22

#
I understand, you need both references to 'trailing' and 'leading' segments in each segment (except null for 'trailing' in last segment and null for 'leading' in first segment). Very good. I wrote a quick random movement snake program, nothing but the snake moving around the screen randomly; except that you can click on a segment and split the snake into separate snakes. Interesting :/
You need to login to post a reply.