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

2014/10/8

Drawing a line from one object to another

jshallow86 jshallow86

2014/10/8

#
Create a fishing game. A boat sits on top the water and has a hook that can move up or down. I want to draw a single line from the hook to the boat, that will move along with the boat. Basically I need to draw a line that starts at the X and Y position of the boat, and draws to the X and Y position of the hook. I've been experiment for an hour and can't figure it out, any help would be appreciated.
NikZ NikZ

2014/10/8

#
You can use drawLine() or just have an image of the line. To make it longer get do scale(x, y + more). These methods are in GreenfootImage.
jshallow86 jshallow86

2014/10/8

#
under my hook class (the hook that is supposed to be on the end of the line) public void act() { getWorld().getBackground().drawLine(getX(),getY(), 150, 150); } does nothing. eventually I need to replace the 150, 150 with the X and Y position of the boat. How would I do that as well. Thanks a lot for your time
NikZ NikZ

2014/10/8

#
Just remember that 150 is a coordinate for the image, not the whole window. How tall is the image? For your image to work I believe it must be 150 tall. Also with your code given, it would have to be 150 thick.
NikZ NikZ

2014/10/8

#
How about scaling it to 1, 151 then doing draw line 0, 0, 0, 150?
jshallow86 jshallow86

2014/10/9

#
ok making progress: created public static variables boatX and boatY (taking getX() and getY() respectively) in the boat class in the hook class did the same naming them wormX and wormY. getWorld().getBackground().drawLine(wormX, wormY, boat.boatX, boat.boatY); the line is drawn as planned, the only problem is that it continues to be drawn leaving the prior lines. the result is a bunch of black lines drawn across the background. I just need a single one from the hook to the boat. thanks for the help
NikZ NikZ

2014/10/9

#
Oh. Do clear() before drawing. And have a separate class for the line so that the line isn't in the background and is separate.
jshallow86 jshallow86

2014/10/9

#
public void drawMeALine(){ getWorld().getBackground().drawLine(hook.wormX, hook.wormY, boat.boatX, boat.boatY); } with drawMeALine() called in the act method of the seperate line class doesnt draw anything
danpost danpost

2014/10/9

#
With the line as an actor, to keep it with the boat, the boat object will have to control its location. The variable length of the line can be controlled either by the boat or by the line itself (not talking image here). You would have a choice of having the boat also control the location of the hook or have the line control that. It would probably be best to do that in the same place you control the length of the line. No matter what you decide in the above, it would be best NOT to have act methods in either the line or the hook classes, but to call methods in those classes from the boat class, otherwise you may end up with some synchronization problems. Probably the easiest way to set it up is with a line image that is the length of the maximum line length and have the line location at exactly the same location as the boat plus a y-offset of half the maximum line length. That way, you can clear and refill the image with black up to the current length of the line and relocate the hook at that time.
jshallow86 jshallow86

2014/10/12

#
here is the source for my HookLine class, the class that I want to use to draw a line from the boat to the hook. import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.awt.Color; public class HookLine extends Animal { public void act() { drawMeALine(); } public void drawMeALine(){ Ocean oceanWorld = (Ocean)getWorld(); Boat boat = oceanWorld.getBoat(); Hook hook = oceanWorld.getHook(); GreenfootImage img = new GreenfootImage(2,100); img.drawLine(boat.getX(), boat.getY(), hook.getX(), hook.getY()); setImage(img); img.clear(); img.setColor(Color.BLACK); img.fill(); setImage(img); } } I add it the world in the world subclass Ocean using this: theLine = new HookLine(); addObject(theLine, 200,250); the line is drawn, but is a static image (that does move around with the boat along the X axis) that doesn't do anything. It is simply a black line in the middle the screen that move left or right with the boat and doesn't connect the boat to the hook or get bigger or smaller.
danpost danpost

2014/10/12

#
Would it not be easier to create a simple line and scale it to length as needed? If you initially create an image, lets say 2 by 4, and fill just the lower half with black (the default drawing color for a new GreenfootImage object), then scaling the height by multiples of two should lengthen and shorten the line image appropriately. Then the Hook object can be relocated to the same coordinates as the line plus half the height of the image of the line to keep it at the end of the line. The initial image should be created in a 'public HookLine()' constructor. The act method would rescale the image and relocate the hook. ODD! Why do you have the HookLine class extend the Animal class?
jshallow86 jshallow86

2014/10/12

#
I was just being lazy and wanted the HookLine to inherit some methods from the Animal class without having to re-do the code. I had previously drawn a line, well see 2pixels wide by 200 pixels. I added the objects when the world was created, which placed the line at a Y offset from the boat, and the hook at the end of the line. Everything seemed to look fine. When I ran it (using scale() to attempt to change the line) the entire image would scale, not just the bottom. So if I wanted to lower the hook, which would require the line to increase, both the top and the bottom of the line would increase in length, as opposed to the just the bottom. Hopefully that makes sense. I'll give it another go making HookLine an Actor, and using the constructor to draw the line, and the act method to resize it. It's just seem crazy I'm having so much trouble with this. I'm new to programming for sure, but I have added multiple levels, different types of fish worth different points, fish that spawn other fish, a system to buy upgrades for the ship (increasing ship speed and increasing the hook speed), but I can't figure out how to draw a simple line....
Super_Hippo Super_Hippo

2014/10/12

#
I guess your boat stays at the surface and can only move left and right. So for example, you move your boat with left and right and move the hook with up and down. Then I would do something like this in the boat class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
private Line line;
private Hook hook;
 
protected void addedToWorld(World world)
{
    line = new Line(10); //create the line with a start-length of 10. You can adjust this of course
    getWorld().addObject(line, getX(), getY()); //add the line to the world
    hook = new Hook(); //create the hook
    getWorld().addObject(hook, getX(), getY()+10); //add the hook to the world
}
 
public void act()
{
    checkKeypress();
}
 
public void checkKeypress()
{
    if (Greenfoot.isKeyDown("left")) //move boat, line and hook to the left side
    {
        setLocation(getX()-2);
        line.setLocation(line.getX()-2,line.getY());
        hook.setLocation(hook.getX()-2,hook.getY());
    }
    if (Greenfoot.isKeyDown("right")) //move boat and hook to the right side
    {
        setLocation(getX()+2);
        line.setLocation(line.getX()-2,line.getY());
        hook.setLocation(hook.getX()+2,hook.getY());
    }
 
 
    if (Greenfoot.isKeyDown("up") && hook.height > 5) //move hook up
    {
        hook.setLocation(hook.getX(),hook.getY()-2);
        line.changeHeight(-2);
}
    if (Greenfoot.isKeyDown("down") && hook.height < getWorld().getHeight()-getY()-5) //move hook down
    {
        hook.setLocation(hook.getX(),hook.getY()+2);
        line.changeHeight(2);
    }
}
In the Line class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public height = 0;
 
public Line(int height)
{
    changeHeight(height);
}
 
public changeHeight(int dh)
{
    height += dh;
    GreenfootImage image = new GreenfootImage(2,height);
    image.fill();
    setImage(image);
    setLocation(getX(),getY()+(int)(dh/2));
}
And in the Hook class you don't need moving code:
1
2
3
4
public Hook()
{
    setImage("hook.png");
}
Maybe it doesn't work (not tested), but maybe you can see the idea of how to control the hook from the boat class.
danpost danpost

2014/10/12

#
jshallow86 wrote...
So if I wanted to lower the hook, which would require the line to increase, both the top and the bottom of the line would increase in length, as opposed to the just the bottom. Hopefully that makes sense.
That makes perfect sense; and, that is why I only filled the lower half of the image with black and kept the upper half transparent. So scaling would make the line drop and rise properly with the added benefit of not having to adjust the location of the line actor when changing its length.
Super_Hippo Super_Hippo

2014/10/12

#
Edit last post: Line 28 should be the following of course:
1
line.setLocation(line.getX()+2,line.getY());
You need to login to post a reply.