question about movement

See the image below:

http://howler.f2g.net/game.png

I am trying to remake an old game called FuzzBall that I used to play in MSX…ok long time ago… :wink: If u have interest in it:http://www.juegomania.org/msx/38

I need to move that blue oval to the square below. I wanna create the illusion that when the player moves down it seems that he is going downstairs, the same when the player is going up in the playfield.

I was trying to make the movement based on Math.sin(). Do u have a tip? Should I use the sin funcition or pre-calculate the movement?

Tks

Well, for one the game is called Q*Bert. Fuzzball was one of many Q*Bert clones.

[quote]I was trying to make the movement based on Math.sin(). Do u have a tip? Should I use the sin funcition or pre-calculate the movement?
[/quote]
I probably would be try to be so clever about it. A simple parabolic arc would probably give more than acceptable results. All you need is a starting point, an end point, how high you want to jump, and for how long. Basically, it would break down into the following variables:

yvelocity = the direction and speed Q*Bert is traveling along the y axis. Negative is up, positive is down. 
xvelocity = the direction and speed Q*Bert is traveling along the x axis
gravity = the rate at which gravity pulls Q*Bert down.

yvelocity and xvelocity get added to QBert’s position every frame. While xvelocity may remain constant (until QBert comes to a full and complete stop), yvelocity is adjusted by gravity every frame. gravity should be positive so that Q*Bert jumps up, slows to a halt, then falls back down.

In psuedo-code:

int xvelocity = 2;
int yvelocity = -5;
int gravity = 1;

int x;
int y;

[...]

while(jumping)
{
    x += xvelocity;
    y += yvelocity;
    yvelocity += gravity;
}

I have the middle point of each cube. The middle point is the middle of each yellow square. In the screenshot example, I am on the first square at (x,y) and then I wanna move to the square at down right for example at (x2,y2). I wanna make a curve movement from (x,y) to (x2,y2). How can I do that? A parabolic movement would be nice…I don’t remeber the maths for this…it has been long time away from the books. Any tip?

ok I think that I understand… but about your pseudo-code: when should I stop jumping and where is the start point and the end point?

[quote]ok I think that I understand… but about your pseudo-code: when should I stop jumping and where is the start point and the end point?
[/quote]
You can use whatever you want for the start and end points. You said you had the center points of each square, so use those. FYI, you’ll need to play with the initial values until they work correctly.

could u please post some code? or point me where can I find more about this subject?Tks

here is what I have…moving down is ok, but moving up is jerky…could someone help me with this code?


import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class F extends JFrame {

    private boolean[] controls = new boolean[5];

    private int[][] grid = new int[7][13];
    private Color[] colors={Color.yellow,Color.blue,Color.green,Color.red};
    int ic=0;
    
    boolean movingDown;
    boolean movingUp;
    boolean movingLeft;
    boolean movingRight;
    int facing;
    
    // center position of the grid (screen x, screen y)
    //int cx,cy;
    // player position in the grid cy range:0..6 cx range:0..12
    int gx,gy;
    //
    private int x;
    private int y;
    
    private double xvel=0.1,yvel=-0.3,gravity=0.0019;

    private F() {
        super("F");

        setSize(800, 600);
        setResizable(false);
        show();

        enableEvents(56);

        createBufferStrategy(2);
        BufferStrategy strategy = getBufferStrategy();

        init();

        long lastLoopTime = System.currentTimeMillis();
        while (true) {
            int delta = (int) (System.currentTimeMillis() - lastLoopTime);
            logic(delta);
            lastLoopTime = System.currentTimeMillis();
            draw((Graphics2D) strategy.getDrawGraphics());
            strategy.show();
            try {
                Thread.sleep(1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void init() {
        restartGame();
        facing=0;
    }

    private void restartGame() {
        gx=6;
        gy=0;
        x = 100 + (gx * 50) - 25;
        y = 120 + (gy * 60) - 45;
        initLevel();
    }

    private void initLevel() {
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < 13; j++) {
                grid[i][j] = (j >= 6 - i && (j <= 2 * i + 6 - i) ? 1 : 0);
                if (i != 0
                        && j >= 6 - i
                        && (j <= 2 * i + 6 - i)
                        && ((j % 2 == 0 && i % 2 != 0) || (j % 2 != 0 && i % 2 == 0))) {
                    grid[i][j] = -1;
                }
            }
        }
    }

    private void logic(int delta) {
        if(controls[3] && !movingDown && !movingUp && !movingLeft && !movingRight) {
            movingDown=true;
            if(facing==0 || facing==1) {
                gx--;
                gy++;
                xvel=-0.1;
                yvel=-0.3;
                facing=0;
            }
            gravity=0.0019;
        } else if(controls[2] && !movingUp && !movingDown && !movingLeft && !movingRight) {
            movingUp=true;
            if(facing==0 || facing==1) {
                gx++;
                gy--;
                xvel=-0.1;
                yvel=0.3;
            } 
            gravity=-0.0019;//0.00059;
        } else if(controls[0] && !movingLeft && !movingDown && !movingUp && !movingRight) {
            movingLeft=true;
            if(facing==1 || facing==0) {
                gx--;
                gy--;
                xvel=0.1;
                yvel=0.3;
            } 
            gravity=-0.0019;//0.00059;
        } else if(controls[1] && !movingRight && !movingDown && !movingUp && !movingLeft) {
            movingRight=true;
            if(facing==0 || facing==1) {
                xvel=0.1;
                yvel=-0.3;
                gx++;
                gy++;
                facing=1;
            }
            gravity=0.0019;
        }
        
        
        if(movingUp || movingLeft) {
            x-=xvel*delta;
            y-=yvel*delta;
            yvel-=gravity*delta;
            if(y<120 + (gy * 60) - 45){
                y=120 + (gy * 60) - 45;
                x=100 + (gx * 50) - 25;
                movingUp=false;
                movingLeft=false;
                grid[gy][gx]++;
            }
        } else if(movingRight || movingDown) {
            x+=xvel*delta;
            y+=yvel*delta;
            yvel+=gravity*delta;
            if(y>120 + (gy * 60) -45){
                y=120 + (gy * 60) - 45;
                x=100 + (gx * 50) - 25;
                movingRight=false;
                movingDown=false;
                grid[gy][gx]++;
            }
        }
    }

    private void draw(Graphics2D g) {
        g.setColor(Color.black);
        g.fillRect(0, 0, 800, 600);
        this.renderField(g);
        this.drawFuzzer(g);
        
        g.setColor(Color.red);
        for(int i=50; i < 800; i+=50) {
            g.drawLine(i,120,i,560);
        }
        for(int i=120; i < 600; i+=20) {
  g.drawLine(50,i,750,i);
        }
        
        g.setColor(Color.white);
        g.drawLine(50,135,750,135);

        
    }

    private void drawFuzzer(Graphics2D g) {
        g.setColor(Color.blue);
        g.fillOval(x,y,50,65);

        g.setColor(Color.gray);
        g.fillOval(x,y,2,2);
        g.fillOval(x,y+30,2,2);
        
    }
    
    private void renderField(Graphics2D g) {
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < 13; j++) {
                if (grid[i][j] > 0) {
                    drawCube(g, i, j);
                }
            }
        }
    }

    private void drawCube(Graphics2D g, int i, int j) {
        int x = 100 + (j * 50);
        int y = 120 + (i * 60);

        
      g.setColor(colors[0]);
        int[] x3 = { x, x-50, x, x+50, x };
        int[] y3 = { y+40, y+20, y, y+20, y+40 };
        g.fillPolygon(x3, y3, 5);
        
        g.setColor(Color.green);
        g.fillOval(x-3,y+20-3,6,6);

        g.setColor(Color.white);
        int[] x1 = { x, x, x-50, x-50, x };
        int[] y1 = { y+40, y+80, y+60, y+20, y+40 };
        g.fillPolygon(x1, y1, 5);

        g.setColor(Color.lightGray);
        int[] x2 = { x, x, x+50, x+50, x };
        int[] y2 = { y+40, y+80, y+60, y+20, y+40 };
        g.fillPolygon(x2, y2, 5);

    }

    protected void processKeyEvent(KeyEvent e) {
        int[] keys = new int[] { KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
                KeyEvent.VK_UP, KeyEvent.VK_DOWN, KeyEvent.VK_SPACE };
        for (int i = 0; i < keys.length; i++) {
            if (e.getKeyCode() == keys[i]) {
                controls[i] = e.getID() == KeyEvent.KEY_PRESSED;
            }
        }
        if (e.getKeyCode() == 27) {
            System.exit(0);
        }
    }

    public static void main(String argv[]) {
        new F();
    }

}

nobody? is the source too big?

I could not make this thing work… :stuck_out_tongue: Don’t you wanna give a try to help me? :wink:

when I get home, I’ll look to it!
(in about three hours)

Rafael.-

These have been my longest three hours… ;D

I saw your code, and I found the problem.
The condition

  if(y<120 + (gy * 60) - 45){

is true before the ball has raisen to the top of the jump. (The ball is in the square and is below the floor)
To correct, you must ask for the velocity(on y)… it must be positive (is falling).

Also these seems to me wrong…

...
   if(movingUp || movingLeft) { 
  x-=xvel*delta; 
  y-=yvel*delta; 
  yvel-=gravity*delta;
...
 else if(movingRight || movingDown) { 
  x+=xvel*delta; 
  y+=yvel*delta; 
  yvel+=gravity*delta;
...

The gravity must not change… is constant(always positive). Also, to jump you must set the yvel to a negative number(when going down is -0.3 but when going up is -0.55 to get upper with the jump).
With all the corrections, the final code is:

  private void logic(int delta) {
    if (controls[3] && !movingDown && !movingUp && !movingLeft && !movingRight) {
      movingDown = true;
      if (facing == 0 || facing == 1) {
        gx--;
        gy++;
        xvel = -0.1;
        yvel = -0.3;
        facing = 0;
      }
    }
    else if (controls[2] && !movingUp && !movingDown && !movingLeft && !movingRight) {
      movingUp = true;
      if (facing == 0 || facing == 1) {
        gx++;
        gy--;
        xvel = 0.1;
        yvel = -0.55;
      }
    }
    else if (controls[0] && !movingLeft && !movingDown && !movingUp && !movingRight) {
      movingLeft = true;
      if (facing == 1 || facing == 0) {
        gx--;
        gy--;
        xvel = -0.1;
        yvel = -0.55;
      }
    }
    else if (controls[1] && !movingRight && !movingDown && !movingUp && !movingLeft) {
      movingRight = true;
      if (facing == 0 || facing == 1) {
        xvel = 0.1;
        yvel = -0.3;
        gx++;
        gy++;
        facing = 1;
      }
    }
    if (movingUp || movingLeft) {
      x += xvel * delta;
      y += yvel * delta;
      yvel += gravity * delta;
      if (yvel> 0.2 && y < 120 + (gy * 60) - 45) {
        y = 120 + (gy * 60) - 45;
        x = 100 + (gx * 50) - 25;
        movingUp = false;
        movingLeft = false;
        grid[gy][gx]++;
      }
    }
    else if (movingRight || movingDown) {
      x += xvel * delta;
      y += yvel * delta;
      yvel += gravity * delta;
      if (y > 120 + (gy * 60) - 45) {
        y = 120 + (gy * 60) - 45;
        x = 100 + (gx * 50) - 25;
        movingRight = false;
        movingDown = false;
        grid[gy][gx]++;
      }
    }
  }

It seems a bit better, but you can try values for yvel to get better results.

Rafael.-

thank you very much!!! ;D :smiley: 8) It much better! I will try to change the values to get it more precise.