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

2015/1/25

Interactive block

1
2
Jellyfish Jellyfish

2015/1/25

#
I am new to Greenfoot and i am trying to make a block that the player can't move past and a floor he/she can't go through and gravity. If someone could explain this to me that would be great and i don't just want to copy and paste and not know what I did. Thanks in advance! :D
danpost danpost

2015/1/25

#
First, you need a field to track the vertical speed of your actor. Then, each step of its movement (or during each act cycle) would involve the following (1) for acceleration due to gravity, a constant value is added to the speed field; and (2) for the vertical movement of your actor, the y-coordinate of its location must be adjusted by the current value of the speed field. Those are the basic things needed to apply gravity to your actor. Notice that if the speed field had a negative value, the actor would slow down as it moves up; and, with a positive value, it would speed up as it moves down. For collision detection, you are really just asking if the actor is touching an obstacle after being moved or relocated. When a collision occurs, you want your actor to stop at the point of contact (moved back off the object) and its speed in the direction it was moving to be zeroed (if being tracked in that direction). I prefer to keep the vertical and horizontal movement separate. By doing so, I can easily determine what needs done in all cases (which way to move when backing off an obstacle and what fields need adjusting). The Who class of my Jump and Run Demo w/Moving Platform can be used as an example of how all this can be done.
Jellyfish Jellyfish

2015/1/27

#
Here's what i have in my Explorer class: import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class explorer here. * * @author (your name) * @version (a version number or a date) */ public class explorer extends players { final int jSpeed = 20; //jump speed int ySpeed = 0, xSpeed = 0; boolean aboutFace; boolean onGround; /** * Act - do whatever the explorer wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { ySpeed++; //gravity if (xSpeed != 0 && onGround) xSpeed+=aboutFace?1:-1; //adds friction setLocation(getX()+xSpeed/10, getY()+ySpeed/2); //check for change in horizontal direction if((xSpeed>0 && aboutFace) || (xSpeed<0 && !aboutFace)) { aboutFace = !aboutFace; } //check for obstacles onGround=false; //initialize value //check below the actor while(getOneObjectAtOffset(0, getImage().getHeight()/2+1, null)!=null) { setLocation(getX(), getY()-1); onGround=true; ySpeed=0; } // check above the actor while(getOneObjectAtOffset(0, -getImage().getHeight()/2-1, null)!=null) { setLocation(getX(), getY()+1); ySpeed = 0; } // check to right of actor while(getOneObjectAtOffset(getImage().getWidth()/2+1, 0, null)!=null) { setLocation(getX()-1, getY()); xSpeed = 0; } // check to left of actor while(getOneObjectAtOffset(-getImage().getWidth()/2-1, 0, null)!=null) { setLocation(getX()+1, getY()); xSpeed = 0; } } /** * Determines any changes in horizontal and vertical speeds for the actor. */ private void getDirection() { //if (!onGround) return; // if not mid-air changes allowed // sets requested direction of move, or continues in current direction if (Greenfoot.isKeyDown("left") && xSpeed>-50) xSpeed-=2; // check left if (Greenfoot.isKeyDown("right") && xSpeed<50) xSpeed+=2; // check right if (Greenfoot.isKeyDown("up") && onGround) // check jump { ySpeed -= jSpeed; // add jump speed } } } but when I compile and run, the explorer just falls through the floor here's my floor class code: import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class floortiles here. * * @author (your name) * @version (a version number or a date) */ public class floortiles extends Actor { /** * Act - do whatever the floortiles wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { GreenfootImage road = new GreenfootImage("castle_walls.png"); GreenfootImage image = new GreenfootImage(1040, road.getHeight()); int w=road.getWidth(); for(int offset=0; offset<1040; offset+=w) image.drawImage(road, offset, 0); setImage(image); } }
Jellyfish Jellyfish

2015/1/28

#
Also sorry about the new discussion I forgot i had already made one
danpost danpost

2015/1/28

#
Using 'getOneObjectAtOffset', you are checking just one location for an obstacle. This means that if your player is moving faster than the width or height of the obstacle, it could pass right by it. If you used 'getOneIntersectingObjects, the player would have to be moving an addition speed of the width or height of its own image as well. btw, '50' is quite a large speed for a player. Most shooting games do not have their bullets or projectiles moving that fast. To have a player move that fast seems quite strange.
Jellyfish Jellyfish

2015/1/28

#
So what would that code be?
Jellyfish Jellyfish

2015/1/28

#
For floortiles class I erased the code so I could redo it, so thats the code I need, and for the player I need to know what to change from this: public class explorer extends players { // The following field will be controlled by a bar that will tell the world to change it private int speed = 1; /** * Method act: * checks for keypresses and moves the robot the appropriate speed until it comes upon a barrier */ public void act() { for (int i = 0; i < speed; i++) move(); } /** * Method move: * checks for keypresses and moves the robot one unit unless a barrier is present; * will be called multiple times when the speed is increased */ private void move() { int dx = 0, dy = 0; if (Greenfoot.isKeyDown("a")) dx--; if (Greenfoot.isKeyDown("d")) dx++; setLocation(getX() + dx, getY()); if (getOneIntersectingObject(floortiles.class) != null) { if (dy == 0) { setLocation(getX(), getY() + 1); if (getOneIntersectingObject(floortiles.class) == null) return; setLocation(getX(), getY() - 2); if (getOneIntersectingObject(floortiles.class) == null) return; setLocation(getX() - dx, getY() + 1); return; } setLocation(getX() - dx, getY()); } setLocation(getX(), getY() + dy); if (getOneIntersectingObject(floortiles.class) != null) { if (dx == 0) { setLocation(getX() + 1, getY()); if (getOneIntersectingObject(floortiles.class) == null) return; setLocation(getX() - 2, getY()); if (getOneIntersectingObject(floortiles.class) == null) return; setLocation(getX() + 1, getY() - dy); return; } setLocation(getX(), getY() - dy); } } /** * Method setSpeed: * recieves and sets a new speed value; * called by the world whenever a value of a bar class object changes; * * @param newSpeed A parameter to set the speed to */ public void setSpeed(int newSpeed) { speed = newSpeed; } }
danpost danpost

2015/1/28

#
First, by placing the loop in the act method, you are unnecessarily having to determine the direction of movement each step of the loop. Second, you set 'dy' to zero an never change it. By re-writing the code to account for this alone, we end up with this:
private void move()
{
   int dx = 0;
   if (Greenfoot.isKeyDown("a")) dx--;
   if (Greenfoot.isKeyDown("d")) dx++;
   setLocation(getX() + dx, getY());
   if (getOneIntersectingObject(floortiles.class) != null) 
   {
        setLocation(getX(), getY() + 1);
        if (getOneIntersectingObject(floortiles.class) == null) return;
        setLocation(getX(), getY() - 2);
        if (getOneIntersectingObject(floortiles.class) == null) return;
        setLocation(getX() - dx, getY() + 1);
    }
}
The first thing can be handled by changing the act method to this:
public void act()
{
    move();
}
and adjusting the move method to this:
private void move()
{
    int dx = 0;
    if (Greenfoot.isKeyDown("a")) dx--;
    if (Greenfoot.isKeyDown("d")) dx++;
    for (int i=0; i<speed; i++)
    {
        setLocation(getX() + dx, getY());
        if (getOneIntersectingObject(floortiles.class) == null) continue;
        setLocation(getX(), getY() + 1);
        if (getOneIntersectingObject(floortiles.class) == null) continue;
        setLocation(getX(), getY() - 2);
        if (getOneIntersectingObject(floortiles.class) == null) continue;
        setLocation(getX() - dx, getY() + 1);
        return;
    }
}
Jellyfish Jellyfish

2015/1/28

#
Ok so now when he comes within a distance of the block, he stops. Basically he stops before getting to the block
danpost danpost

2015/1/28

#
Is there excess transparency around the images of any of your actors? In other words, is it possible to reduce the size of any of the images involved without removing any non-transparent part of the image?
Jellyfish Jellyfish

2015/1/31

#
Yes I did that it works now thank you!
Jellyfish Jellyfish

2015/1/31

#
Yes there was I deleted it Thanks!
Jellyfish Jellyfish

2015/2/2

#
So I'm making a game like mario, and when I typed in that code above, it says "cannot find variable speed"
Jellyfish Jellyfish

2015/2/2

#
Never mind fixed it
Jellyfish Jellyfish

2015/2/8

#
Ok I'm on a different pc and I was wondering, whenever I compile that code, it says, "cannot find variable- variable speed"
There are more replies on the next page.
1
2