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

2019/7/14

How do you get an actor to wrap all the way around the world?

puggo7 puggo7

2019/7/14

#
Hello! I'm a little bit new to Greenfoot and Java in general, but I'm attempting to create a "Crossy Road-ish" game that involves trains. I'm trying to wrap them around the world, but every time my train has only gone half way to the right, it suddenly teleports back to the left. Is there any way for the train to disappear COMPLETELY to the right, pause for a while, AND THEN appear from the left to start the process again? I will leave my code for my train below, thank you!
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Train extends Enemies
{
    
    public void act() 
    {
        move(4);
        
         int x = getX();
        int y = getY();
        int worldWidth = getWorld().getWidth() - 1; 
        int worldHeight = getWorld().getHeight() - 1;
        if(x >= worldWidth) 
        {
            setLocation(-1, y); 
        }
        if(x <= 0)
        {
            setLocation(worldWidth - 1, y); 
        }
        if(y > worldHeight)
        {
            setLocation(x, 1); 
        
        if(y <= 0) 
        {
            setLocation(0, worldHeight - 1); 
        }
    }    
}
Proprogrammer04 Proprogrammer04

2019/7/14

#
I can't see a problem… When I tries your Code, i went to the right edge, teleports to the left Edge and starts moving across the world again... It did not dissapear or anything like that...
danpost danpost

2019/7/15

#
puggo7 wrote...
I'm trying to wrap them around the world, but every time my train has only gone half way to the right, it suddenly teleports back to the left. Is there any way for the train to disappear COMPLETELY to the right, pause for a while, AND THEN appear from the left to start the process again? << Code Omitted
I do understand your issue. In your World subclass constructor, add a false parameter at the end of the super call:
public MyWorld()
{
    super(600, 400, 1, false); // here
This will "unbound" your world, allowing actors to go beyond the visible window limits. Then, in Train class act method, you can wrap with:
move(4);
int worldWidth = getWorld().getWidth();
int worldHeight = getWorld().getHeight();
int trainLength = getImage().getWidth();
if (getX() > worldWidth+trainLength/2+2) setLocation(-trainLength/2, getY());
if (getX() < -trainLength/2-2) setLocation(worldWidth+trainLength/2, getY());
if (getY() > worldHeight+trainLength/2+2) setLocation(getX(), -trainLength/2);
if (getY() < -trainLength/2-2) setLocation(getX(), worldHeight+trainLength/2);
puggo7 puggo7

2019/7/15

#
Ahhh I see! Thank you so much! It works :D!
puggo7 puggo7

2019/7/15

#
Wait, also how do you move an actor by blocks/pixels? I want my player to only be able to move one block every time they press the arrow keys (kind of like the actual game where you have to tap in order to move one block forward or swipe to move one block right/left). Is it possible to execute this kind of code? Also, thank you once again!
danpost danpost

2019/7/15

#
puggo7 wrote...
how do you move an actor by blocks/pixels? I want my player to only be able to move one block every time they press the arrow keys (kind of like the actual game where you have to tap in order to move one block forward or swipe to move one block right/left). Is it possible to execute this kind of code?
You will probably need to track the state of the arrow keys:
// fields for Player objects
private boolean leftDown;
private boolean rightDown;

// in Player class (same) act method
int dx = 0;
if (leftDown != Greenfoot.isKeyDown("left"))
{
    leftDown = !leftDown;
    if (leftDown) dx--;
}
if (rightDown != Greenfoot.isKeyDown("right"))
{
    rightDown = !rightDown;
    if (rightDown) dx++;
}
move(speed*dx); // int "speed" needs defined or replaced with a value
puggo7 puggo7

2019/7/15

#
Left and right work perfectly :D! As for Up and Down on the other hand... it seems my computer views dy and dx as the same (maybe that's not the right way to put it, but that's what popped in my head first)? I attempted what I thought would work, but perhaps it doesn't... Sorry if I'm bugging you a ton, but would you mind lending me a hand again? Thank you, and I'll leave my code below!
{
        int dx = 0;
        int dy = 0;
        if (leftDown != Greenfoot.isKeyDown("left"))
        {
            leftDown = !leftDown;
            if (leftDown) dx-=5;
        }
        if (rightDown != Greenfoot.isKeyDown("right"))
        {
            rightDown = !rightDown;
            if (rightDown) dx+=5;
        }
        if (upDown != Greenfoot.isKeyDown("up"))
        {
            upDown = !upDown;
            if (upDown) dy+=5;
        }
        if (downDown != Greenfoot.isKeyDown("down"))
        {
            downDown = !downDown;
            if (downDown) dy-=5;
        }
        move(4*dx);
        move(4*dy);
    }
Super_Hippo Super_Hippo

2019/7/15

#
Well, you pass an int to the „move“-method. It doesn't matter what name that variable has. Replace lines 24 and 25 with this line:
setLocation(getX()+4*dx, getY()+4*dy)
However, it doesn't seem very logical to me to increase/decrease those dx/dy by 5 and then multiply them with 4 again. By the way, you need to swap the +/- for the y-direction. y=0 is at the top.
puggo7 puggo7

2019/7/15

#
Thank you, Hippo! Also, it might look weird or illogical to do that, but in my game, it just makes the player "hop" at a greater distance. The original code that danpost wrote didn't make the player "hop" too much. Plus, I have a pretty large map that the player has to traverse. There might be a more efficient code (and if there is, might you mind if you could post it for me? Thank you :D), but I was just fiddling around with it, and it worked just how I wanted it to!
puggo7 puggo7

2019/7/15

#
OH wait, you're right... I tried another way and it works much better and keeps the "hopping" at a constant distance! My bad :P
You need to login to post a reply.