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

2015/5/27

sword move

1
2
craeXD craeXD

2015/5/27

#
Hello, i have a problem with the sword in my game. At first the player should hold the sword at -90 degrees (vertical) when "v" is pressed. Then the sword should go from -90 to +80, when v is released or after a amount of time (maybe half a second. But this doesn´t work quite good with turn or rotation commands, the sword moves to fast.
public void switchImage_attack1()
{
if(Greenfoot.isKeyDown("v"))
        {
            move(-115);
            turn(-90);
            move(95);
        }
}
The move commands align the sword, that it sticks to the player. mfg, crae
danpost danpost

2015/5/27

#
All method calls are executed straight through. That is to say that only the end result of the method will be apparent to the user. The above is equivalent to this:
public void switchImage_attack1()
{
    if (Greenfoot.isKeyDown("v"))
    {
        move(-20);
        turn(-90);
    }
}
and what is seen by the user is a single change in both position and rotation at the same time (if executed once). I presume this method is called by the act method of the class; in which case, the actor will be seen by the user to frantically revolve at about 12 to 15 complete circuits per second (and it would not look very esthetic) as long as the key is pressed. To animate something, you need to track the act cycles and perform specific actions along the way (moving and turning part of the way each act cycle). In other words, what you should be programming are the actions that need to occur during each act cycle. Some states that may need to be tracked are (1) is the sword being used (has the trigger been detected and has the actions of the sword not yet been completed); (2) where, currently, is the sword in its animation (is it on its down-swing, up-swing, changing directions or done moving).
craeXD craeXD

2015/5/27

#
If i use the move(-20) the sword rotates on the false side. And to be honest, i´m not sure that i understand what you mean. I tried to seperate the rotation with this:
if(Greenfoot.isKeyDown("v"))
        {
            
            counter2=0;
            move(-115);
            turn(-90);
            move(95);
        }
        else if( counter2=1)
        {
            move(-115);
            turn(-80);
            move(95);
        }
        else if( counter2=2)
        {
            move(-115);
            turn(-70);
            move(95);
        } 
        //and so on until ~75 degrees
The problem with this was, that when it got smooth it also got to lame...i mean its an sword hit an as this it sould be fast. Obviously its very long, too. mfg, crae
Super_Hippo Super_Hippo

2015/5/27

#
danpost wrote...
The above is equivalent to this: (...)
move(-115);
turn(-90);
move(95);
is not the same as
move(-20);
turn(-90);
To give you an idea how to start:
private boolean animation = false;

public void act()
{
    if (animation)
    {
        //animate moving
    }
    else if (Greenfoot.isKeyDown("v"))
    {
        //start the animation
        animation = true;
        move(-115);
        turn(-90);
        move(95);
    }
}
danpost danpost

2015/5/27

#
Super_Hippo wrote...
danpost wrote...
The above is equivalent to this: (...)
move(-115);
turn(-90);
move(95);
is not the same as
move(-20);
turn(-90);
To give you an idea how to start:
private boolean animation = false;

public void act()
{
    if (animation)
    {
        //animate moving
    }
    else if (Greenfoot.isKeyDown("v"))
    {
        //start the animation
        animation = true;
        move(-115);
        turn(-90);
        move(95);
    }
}
You are so right. I did not think it through (that the turn changes the direction of movement). At any rate, the full change in location and rotation would still occur instantaneously unless broken down into smaller steps.
craeXD craeXD

2015/5/28

#
This code doesn´t work, sorry. If i click "v" it makes an attack, but only one time and the sword doesn´t go back (i suppose it should, because animation is false then). Second thing is: How can i use double numbers? With this i could put more part steps in one second. I tried this:
public class Schwert extends SmoothMover
{
public int i1 = 0.1;
    public int i2 = 0.2;
    //and so on

public void switchImage_attack1()
     {
if(Greenfoot.isKeyDown("v"))
        {
            move(-115);
            turn(-90);
            move(95);
            counter2=0;
        }
        else if(counter2 == 0.1)
        {
            move(-115);
            turn(-75);
            move(95);
        }
         
        else if(counter2 == 0.2)
        {
            move(-115);
            turn(-45);
            move(95);
        }
         
        else if(counter2 == 0)
        {
            move(-115);
            turn(-15);
            move(95);
        }
         
        else if(counter2 == i4)
        {
            move(-115);
            turn(15);
            move(95);
        }
         
        else if(counter2 == i5)
        {
            move(-115);
            turn(45);
            move(95);
        }
         
        
        
   }
        
mfg, crae
Super_Hippo Super_Hippo

2015/5/28

#
To use doubles, you have to write 'double' instead of 'int' in lines 3 and 4. Show the code which you tried when using my version. I still don't understand how you are trying to use this 'counter2' field. You aren't increasing it somewhere (or at least it isn't shown), you only set it to 0 when v is pressed.
craeXD craeXD

2015/5/28

#
Oh sorry, its not shown there. I use "counter2++;" in the act method. The integers were a mistake, i already wrote this with double - with the result that it doesn´t work. Well here´s the whole class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.lang.Math;


public class Schwert extends SmoothMover
{
  
    private GreenfootImage image1;
    private GreenfootImage image2;
    private GreenfootImage image3;
    private GreenfootImage image4;
    private GreenfootImage image5;
    private GreenfootImage image6;
    private GreenfootImage image7;
    
    private int runnerEaten;
    int counter = 0;
    int counter2 = 0;
    int i = 0;
    int z = 0;
    
    public double i1 = 0.1;
    public double i2 = 0.2;
    //and so on
    
    public Schwert()
    {
        super();
        image1 = new GreenfootImage("sword.png");
        image2 = new GreenfootImage("sword2.png");
        image3 = new GreenfootImage("sword3.png");
        image4 = new GreenfootImage("sword4.png");
        image5 = new GreenfootImage("sword5.png");
        image6 = new GreenfootImage("sword6.png");
        image7 = new GreenfootImage("sword7.png");
        
         
        runnerEaten = 0;
         
        
    }
    public void act() 
    {
      move(0);
      
      lookForRunner();
      java.util.List<Player>
      playersInWorld = getWorld().getObjects(Player.class);
      if (!playersInWorld.isEmpty()) 
      {
            Player variabelplayer = playersInWorld.get(0);
            StaybyPlayer(variabelplayer);
            SchauzuMaus();
             
      }
      
      
      switchImage_attack1();
      counter++;
      counter2++;
       
     
     
      
    }   
     public void StaybyPlayer(Player/**<-Klasse   erfundene Variabel->**/ varplayer)
   {
   int PlayerX = varplayer.getX();
   int PlayerY = varplayer.getY();
   setLocation(PlayerX,PlayerY);
   }
   
    /**public void SetzeNeueKoordinaten()
    {
            setLocation(getX(), getY()-40);
    }**/
   
    public void SchauzuMaus()
  
    {
         greenfoot.MouseInfo Maus = Greenfoot.getMouseInfo();
         if(Maus != null)
         {
         int MausX;
         int MausY;
         MausX = Maus.getX();
         MausY = Maus.getY();
         turnTowards(MausX,MausY);   
         //move(2);
        }

        }
    public void switchImage_attack1()
     {
        
        if(getImage().equals(image1))
        {
            move(135);
        }
        else if(getImage().equals(image2))
        {
            move(135);
        }
        if ("space".equals(Greenfoot.getKey()))
        {
            setImage(image2);
            counter=0;
        }
        else if(counter == 6)
        {
             
            //setImage(image1);
            
        } 
        
        if(Greenfoot.isKeyDown("v"))
        {
            move(-115);
            turn(-90);
            move(95);
            counter2=0;
        }
        else if(counter2 == i1)
        {
            move(-115);
            turn(-75);
            move(95);
        }
         
        else if(counter2 == i2)
        {
            move(-115);
            turn(-45);
            move(95);
        }

   }

   
    public void lookForRunner()
    {
        if (canSee(Runner.class) ) 
        {
            eat(Runner.class);
            Greenfoot.playSound("slurp.wav");
            
            runnerEaten = runnerEaten + 1;
            
        }
    }
    
     public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;        
    }
    
    public void eat(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        if(actor != null) {
            getWorld().removeObject(actor);
        }
    }
    
}
Ignore the sword images, i try to make it with "turn", and therefore i need the doubles...to put about, well i dont know maybe 15 turn commands in one second, so that it looks smooth, when "v" is pressed. mfg, crae
Super_Hippo Super_Hippo

2015/5/28

#
I think you misunderstand what 'counter2++' does. It is the same as 'counter2 = counter2 + 1'. In other words, it starts with 0 and will be 1 after the first act cycle, then 2 and so on. It will never be a number between 0 and 1.
craeXD craeXD

2015/5/28

#
Is there a way to get a counter or something like that with numbers between 0-1, 2-3, 3-4, ...?
Super_Hippo Super_Hippo

2015/5/28

#
Yes, but you won't need it. Just use 1, 2, 3 and so on.
craeXD craeXD

2015/5/28

#
I need it^^ With 1, 2, 3, ...i can only put a few turns in a second. So i can make it fast, but it looks crappy or i can make it lame and good-looking (smooth). The thing is i want both: a good looking movement, within 5-6 seconds. I mean if i make it with 1, 2, 3....8 i can put maybe 20 degrees in one act cycle, but this is too much. So if i go for well 1 to 16 i can reduce the degrees per act cycle to 10, but it takes twice the time.
Super_Hippo Super_Hippo

2015/5/28

#
Okay, again. If you have a counter which gets increased by 1 every act cycle, you can use 1, 2, 3, ... . It is the same if you do that or if you increase it by 0.1 every act cycle and use 0.1, 0.2, 0.3, ... . If the speed slider is in the middle (50), there are about 55 act cycles per second. So what would doubles change there? A counter doesn't need doubles, maybe the rotation/position needs it for smooth moving. What exactly should the sword do? A normal "swing" maybe takes 1 or less seconds. 5-6 seconds seem to be a long time.
craeXD craeXD

2015/5/28

#
Yep the rotation needs it. It should swing about 160 degrees. With every increase of the counter the sword should turn a part of this 160 degrees. If i take for example 8 act cycles, the sword have to turn 20 degrees per cycle (160/8=20). I tested this and the result is that this is too fast, it doesnt look smooth. So i tested 16 act cycles, which results in 10 degrees per cycle. This is ok, it looks good, but it slows down the attack, because there are more part steps. And now i try to find a solution. I thougt if i use doubles instead of integers for the counter and as a result for the amount of time, which is needed for the animation, i can make 16 turns in the same time as 8 with integers. For example: - integer 16 turns: 1=10°, 2=20°, 3=30°, ... , 16=160° (~55 act cycles-->16/55 seconds) - doubles 16 turns: 0.5=10°, 1=20°, 1.5=30°, ... , 8=160° (~55 act cycles-->8/55 seconds with the same amount of turns, but in the half of the time-->fast and! smooth attack) I hope i explained it understandable now :D mfg, crae
Super_Hippo Super_Hippo

2015/5/28

#
Ah ok, so you don't really want the movement in 5-6 seconds. 16/55 seconds is too slow? Well, there is no good way to make something show up in between act cycles and there aren't "half" act cycles. You can use the 'repaint' method and do like two act cycles in one, but your eye can't notice 110 images a second anyway. What you can do is, change the speed to 60 maybe. (Add 'Greenfoot.setSpeed(60);' in the constructor of the world subclass.) Then the whole scenario goes faster though.
There are more replies on the next page.
1
2