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

2011/11/14

turnAtLeftWall() Got a question! I know the answer is probably simple and I'm just not seeing it but I'm just starting and I'm lost. So here is my instructions and here is what I have so far. I can't figure out how to get the "orb" to bounce off the top a

keiko1dog keiko1dog

2011/11/14

#
Your next step is to account for a collision with the walls. You will accomplish this within a method called turnIfNeeded(), which will be called from the act() method of Orb. The turnIfNeeded() method may call four seperate methods, which you will write within this step. Here iis the code for turnAtFloor(). Use it as a model to create the other three methods. public void turnAtFloor() { if (getY() + getImage().getHeight()/2 >= getWorld().getHeight() ) { vel.reverseY(); I got the code for turnAtRightWall(), its the rest I'm stumped on. Anyone with some help would be greatly appreaciated /** * makes the Orb bounce off the edge of the world on all four sides, * not just hit the edge and turn. */ public void turnAtFloor() { if (getY() + getImage().getHeight()/2>=getWorld().getHeight() ) { vel.reverseY(); } } public void turnAtRightWall() { if (getX() + getImage().getWidth()/2>=getWorld().getWidth() ) { vel.reverseX(); } } public void turnAtRoof() { if (getY() + getImage().getHeight()/2<=getWorld().getHeight() ) { vel.reverseY(); } } public void turnAtLeftWall() { if (getX() + getImage().getWidth()/2<=getWorld().getWidth() ) { vel.reverseX(); } }
nccb nccb

2011/11/14

#
The code for the turnAtFloor and turnAtRightWall are very similar. They are taking your X (or Y) coordinate, which is the centre of your actor, adding half the width (or height) to get the coordinate of the right-hand side (or bottom) of the actor, then comparing it to the X (or Y) coordinate of the whole world; since the world begins at 0 on the left, its width is equivalent to the right-hand side (and since 0 is the top of the world, the height is equivalent to the Y coordinate of the bottom). So you need to adapt this logic to do the left/top. You'll need to take your X or Y coordinate, subtract half the width or height to get the left or top, and then compare this to zero, which is the coordinate of the edge of the world (using the opposite comparison, less than or equal to: you've already done this much in your attempt above).
keiko1dog keiko1dog

2011/11/14

#
Ok I had done that before but the orbs go righr to the top left corner and move a little back and forth. And I don't know how to call these mothods from the turnIfNeeded() method. This is all my code for my Orb class. It is supposed to have a constructor Orb(int xSpeed, int ySpeed) with a single line of code which creates a new Velocity object with the specified xSpeed and ySpeed and assigns it to the instance variable vel. Then I'm supposed to account for collision with the walls and call them(roof,floor,left,right)from turnIfNeeded. private Velocity vel; private int exactX; private int exactY; private int xSpeed; private int ySpeed; private GreenfootImage getImage; /** * Create the constructors for Orb */ public Orb(int xSpeed, int ySpeed) { vel= new Velocity(xSpeed, ySpeed); this.vel=vel; getImage = new GreenfootImage("gold-ball.png"); } /** * Act - do whatever the Orb wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { move(); turnAtFloor(); turnAtRoof(); turnAtRightWall(); turnAtLeftWall(); } public void move() { exactX = exactX + vel.getXSpeed(); exactY = exactY + vel.getYSpeed(); super.setLocation( (int) exactX, (int) exactY); } /** * makes the Orb bounce off the edge of the world on all four sides, * not just hit the edge and turn. */ public void turnAtFloor() { if (getY() + getImage().getHeight()/2>=getWorld().getHeight() ) { vel.reverseY(); } } public void turnAtRightWall() { if (getX() + getImage().getWidth()/2>=getWorld().getWidth() ) { vel.reverseX(); } } public void turnAtRoof() { if (getY() - getImage().getHeight()/2<= 0 ) { vel.reverseY(); } } public void turnAtLeftWall() { if (getX() - getImage().getWidth()/2<= 0 ) { vel.reverseX(); } } /** * get the x location */ public int getExactX() { return exactX; } /** * get the y location */ public int getExactY() { return exactY; } /** * get x speed */ public void getXSpeed() { xSpeed = -xSpeed; } /** * get y speed */ public void getYSpeed() { ySpeed = -ySpeed; } } Thanks for your help!!
nccb nccb

2011/11/15

#
The code looks right to me from what I can see. (Did it change? I swear there was an erroneous minus yesterday which I was going to reply about this morning, but I can't see it now.) If you're still getting odd behaviour with it not bouncing properly, can you upload the whole scenario to the site (with source) so I can take a look?
keiko1dog keiko1dog

2011/11/15

#
posted my scenario but forgot to pit in my comments!!! In the OrbWorld class, I'm supposed to put in 5 orbs every time you run the simulation and they all have to be in the world plus they all have to have their own random velocity. In the Orb class, they have to bounce off each wall, making a sound and this has to be called within the method turnIfNeeded(), from the act() method. The turnIfNeeded() method may call four separate methods which are turnAtLeftWall, turnAtRightWall,TurnAtRoof,turnAtFloor. Some of this seems to come so easy and some seems to just get me lost!!!!! Thanks again for any help!
nccb nccb

2011/11/15

#
Ok, I've found the problem. You are keeping track of the position in exactX and exactY (more on that in a sec). These start as 0 and 0, and you're never setting them differently. So although you start by placing the Orbs into the world at various locations, the first time you call move(), the position gets set to exactX, exactY plus your velocity -- pretty much the top-left hand corner. And once the orbs get outside the bounds they should stay in like this, they'll get stuck and glitched. A quick fix is to implement the addedToWorld method and set exactX and exactY to be the current position just after you get put into the world for the first time -- put this in Orb:
    public void addedToWorld(World world)
    {
        exactX = getX();
        exactY = getY();
    }
As for exactX and exactY: usually, the reason for having variables like this is when exactX and exactY are float or double, i.e. more precise than integers. At the moment in your code, exactX and exactY are ints, so they are just mirroring Greenfoot's inbuilt position-tracking (getX, getY and setLocation), for no benefit and at the added expense of introducing confusing bugs like that. If you plan to change exactX/exactY to be floating point then fine, but otherwise I'd remove them and just use getX/getY. It will shorten and simplify your code, both of which are good things :-)
keiko1dog keiko1dog

2011/11/16

#
ok changed the code, took out exactX and exactY, replaced with getX, getY. Still have the same problem! the Orb will not "bounce" off the walls. If I remove the code to place 5 orbs into the world, the 1 orb will bounce off the floor and the right wall, but not the roof or the left wall. If I replace the code for placing 5 orbs into the world, one orb goes into the upper left corner and stays there, the rest slam around the world, never really bouncing off the walls. My other problem is with placing the orbs inside the world without any of the graphics being cut off by the edge of the world. HELP!!!!!
danpost danpost

2011/11/16

#
Your getXSpeed() and getYSpeed() methods should probably have return xSpeed and return ySpeed as the codes. Aside from that, your turnAtRoof() and turnAtLeftWall() methods should have setLocation(int, int) statements in them to ensure that the Orbs are in the World. Better, would be to check, before moving, whether the Orb is going past the edges of the world. (If you check after moving the orb, and just reverse the direction without moving it back into the world, it will keep reversing its direction on each act(), and appeaer to be locked in place at the edge of the world). I will look at your code and see what I can find.
danpost danpost

2011/11/17

#
OK, here goes. In the world class, all you need to do is create and add the 5 orbs into the world (do not worry about the velocities here). (Create the orbs without any parameters). In the orb class, the only instance variable you will need is Velocity vel, which can be created in the constructor of the orb (again, create the Velocity without any parameters). In the velocity class, you can set the xSpeed and ySpeed to Greenfoot.getRandomNumber(100) in the constructor of the velocity (make sure you have import greenfoot.*; as the first line above the class indentifier. Now, in the orb class, you can use getX() and getY() for the current location of the orb, and vel.xSpeed and vel.ySpeed for the speeds. The only methods you need in the orb class are the five called within the act() method (move() and the four turn methods). The only ones you need in the velocity class are the reverseX() and reverseY(). One more note: the prefixing of 'super' (for setLocation) and 'this' (I forget exactly where -- somewhere in the orb class) are unneccessary. Hope this helps. (It looked pretty good after I tweeked it).
danpost danpost

2011/11/17

#
By the way, the only way to prevent the edge of the world from cutting into your graphics is to have move() as the last call in act() and adjust the other methods called within act to reflect the next location of the orb (not the current one) by adding in the speeds. This will, unfortunately, have another side-effect -- the orbs may appear to bounce in mid-air (before actually reaching the edge of the world). I had previously created a simple bouncing ball. My fix involved breaking the move that involved the bounce into two distinct parts: (1) set the location of the object at the bounce-point (half its width or height from the edge of the object it bounces on) and update the world to repaint the screen showing the object actually bouncing, and (2) calculate its new position in the world after the bounce (at its current velocity) from its pre-bounce location and re-set the location to there. This actually made it look like it was bouncing off the object (or edge of the world).
keiko1dog keiko1dog

2011/11/17

#
Hey danpost!, I really appreciate all your help, and also the help from nccb. I am working on 2 computers, a mac and a windows based computer, trying to make this thing work. I'm going to implement what you have given me but the problem is my instruction are as follows:Create the class called Velocity and copy supplied code,paying attention to constructor and its parameters. Create new subclass of Actor called Orb-- The objects of class orb should move according to a set velocity so declare an instance variable called vel of type Velocity within the Orb class.--- Create the constructor Orb(int xSpeed, int ySpeed). Write a single line for the body of constructor which creates a new Velocity object with the specified xSpeed and ySpeed and assigns it to the instance variable vel.--Create a move() method for Orb. This will require several steps. In order to move the Orb object, you must first know where the object is. Then, you will need to know how far the object should move horizontally and vertically. Then, you need to set the new location of the object. You compute the new location by adding the distance by which the object should move to the object’s current location. • To know where the Orb object is: Identify methods inherited from the Actor class to identify the Orb’s current x- and y-coordinates. • To know how far to move the Orb object: Remember that vel is a Velocity object that is generated when an Orb object is constructed. The methods getXSpeed() and getYSpeed() are defined for Velocity objects. Call these methods on the vel object from within the move method of Orb. Hint: You will need to use dot notation. • To set the new location of the Orb object: Invoke the setLocation method on the Orb object. The new x-location of the Orb should be the sum of the current x-location and the value returned by getXSpeed(). Calculate the y-coordinate similarly. • Invoke the move() method within the act() method of Orb and compile. Instantiate an Orb, assigning it initial xSpeed and ySpeed values. When you run the program, the Orb should move until it reaches a corner. Explain what happens and why this breaks the realism of the simulation • Your next step is to account for a collision with the walls. You will accomplish this within a method called turnIfNeeded(), which will be called from the act() method of Orb. The turnIfNeeded() method may call four separate methods, which you write in this step. The four methods are: turnAtLeftWall(), turnAtRightWall(), turnAtFloor(), and turnAtRoof(). The code for one of the four methods, turnAtFloor(), is provided below. Use it as a model to create the three other methods. public void turnAtFloor() { if (getY() + getImage().getHeight()/2 >= getWorld().getHeight()) { vel.reverseY(); } } How would I go about doing something like you suggested? as far as the bounce?My professor thinks this should come easy!! lol I'm ready to pull my hair out! we've only been in class 3 weeks. Thanks again for any help!
danpost danpost

2011/11/17

#
Basically, you still need to remove the instance variables xSpeed and ySpeed from the orb class (you are accessing them via the Velocity class with dot notation (vel.xSpeed and vel.ySpeed). Those speed values can be created in the world class and passed down in the creation of orb and velocity via the parameters; though there is no need to do anything with them in your orb class except pass them down. Still, I suggest moving the move() in act() to be the last method called within act(). (this way, if the orb was off world's edge, it moves back before checking where it is and reversing its direction again still off world's edge).
KingDex62 KingDex62

2013/2/4

#
What's the code to allow the Orb to make noise when it hits the wall?
danpost danpost

2013/2/4

#
The format of any method call in OOP (object-oriented progamming) is object.action. If there is no object supplied, then it is assumed to be the 'this' keyword, which refers to the object created from that class the method is in. For a sound, a GreenfootSound object is the object and 'play' is the action you wish to have it do. So, create a GreenfootSound object using the GreenfootSound constructor call and save it in a GreenfootSound field. Then when you want to 'make noise', name the sound and action to perform.
You need to login to post a reply.