奇怪的跳跃 - 基本的Java游戏开发

时间:2017-01-25 19:08:06

标签: java keylistener

gif of the problem at hand

所以你可以在gif中看到,当我的角色第一次跳跃时它是一个非常短暂的跳跃,但是如果你让他在着陆后立即跳跃,他会跳到天空。

这是游戏代码:

package com.game.src.main;
import java.awt.*;
import java.util.*;
import javax.swing.JFrame;
import java.awt.image.*;
import java.io.IOException;
import java.awt.event.*;
public class Game extends Canvas implements Runnable {
private Player p;
private Controller c;
private Player p2;

private boolean running = false;
private Thread thread;
long timeOfLastProjectile = 0;
long timeOfLastProjectile2 = 0;

public static final int WIDTH  = 940;
public static final int HEIGHT =  400;
public static final int SCALE = 1;
public final String TITLE = "1v1";

private BufferedImage image = new BufferedImage(WIDTH,HEIGHT*2,BufferedImage.TYPE_INT_RGB);
private BufferedImage spriteSheet = null;
private BufferedImage background  = null;

private boolean is_shooting = false;
private boolean is_shooting2 = false;

public void init()
{
    BufferedImageLoader loader = new BufferedImageLoader();
    try
    {
        spriteSheet = loader.loadImage("/spritesheet.png");
        background = loader.loadImage("/background.gif");
    }catch(IOException e)
    {
        e.printStackTrace();
    }

    addKeyListener(new KeyInput(this));
    this.requestFocus();
    p = new Player(200,(370-64),this);
    p2 = new Player((740-64),(370-64),this);
    c = new Controller(this);
}

private synchronized void start()
{
    if (running)
        return;

    running = true;
    thread = new Thread(this);
    thread.start();
}

private synchronized void stop()
{
    if (!running)
        return;

    running = false;
    try{
        thread.join();
    } catch (InterruptedException e){
        e.printStackTrace();
    }
    System.exit(1);
}

public void run()
{
    init();
    long lastTime = System.nanoTime();
    final double amountOfTicks = 60.0;
    double ns = 1000000000 / amountOfTicks;
    double delta = 0;
    int updates = 0;
    int frames = 0;
    long timer = System.currentTimeMillis();
    while(running)
    {
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;
        if(delta >= 1)
        {
            tick();
            updates++;
            delta--;
        }
        render();
        frames++;

        if(System.currentTimeMillis() - timer > 1000)
        {
            timer += 1000;
            System.out.println(updates + " Ticks, Fps " + frames);
            updates = 0;
            frames = 0;
        }
    }
    stop();
}

private void tick()
{
    p.tick();
    p2.tick();
    c.tick();
}

private void render()
{
    BufferStrategy bs = this.getBufferStrategy();

    if(bs == null)
    {
        createBufferStrategy(3);
        return;
    }

    Graphics g = bs.getDrawGraphics();
    ////////////////////////////////////

    g.drawImage(image, 0, 0, getWidth(), getHeight(), this);

    g.drawImage(background, 0, 0, null);

    p2.render(g);
    p.render(g);
    c.render(g);
    ////////////////////////////////////

    g.dispose();
    bs.show();
}

public void keyPressed(KeyEvent e) {

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_D) {
        p.setVelX(-3);
    }

    else if (key == KeyEvent.VK_G) {
         p.setVelX(3);
    }

    else if (key == KeyEvent.VK_R) {
        p.jump(7);
    }

    else if (key == KeyEvent.VK_F)
    {
        p.setVelY(3);
    }
    else if (key == KeyEvent.VK_Q && !is_shooting)
    {
        long timeNow = System.currentTimeMillis();
        long time = timeNow - timeOfLastProjectile;
        if (time < 0 || time > 1000) {
            timeOfLastProjectile = timeNow;
            is_shooting = true;
            c.addBullet(new Bullet(p.getX(), p.getY(), this, 1));
        }
    }
    //-------------------------------------------------------
    if (key == KeyEvent.VK_LEFT)
    {
        p2.setVelX(-3);
    }

    else if (key == KeyEvent.VK_RIGHT) {
        p2.setVelX(3);
   }

    else if (key == KeyEvent.VK_UP) {
        p2.setVelY(-3);
    }        

    else if (key == KeyEvent.VK_DOWN)
    {
        p2.setVelY(3);
    }

    else if (key == KeyEvent.VK_P && !is_shooting2)
    {
        long timeNow2 = System.currentTimeMillis();
        long time2 = timeNow2 - timeOfLastProjectile2;
        if (time2 < 0 || time2 > 1000) {
            timeOfLastProjectile2 = timeNow2;
            is_shooting2 = true;
            c.addBullet(new Bullet(p2.getX(), p2.getY(), this, 0));
        }
    }
}

public void keyReleased(KeyEvent e) {

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_D) {
        p.setVelX(0);
    }

     else if (key == KeyEvent.VK_G) {
         p.setVelX(0);
    }

    else if (key == KeyEvent.VK_R) {
    }
    else if (key == KeyEvent.VK_F)
    {
        p.setVelY(0);
    }
    else if (key == KeyEvent.VK_Q)
    {    

        is_shooting = false;

    }
  //-------------------------------------------------------
    if (key == KeyEvent.VK_LEFT)
    {
        p2.setVelX(0);
    }

    else if (key == KeyEvent.VK_RIGHT) {
        p2.setVelX(0);
   }

    else if (key == KeyEvent.VK_UP) {
        p2.setVelY(0);
    }        

    else if (key == KeyEvent.VK_DOWN)
    {
        p2.setVelY(0);
    }

    else if (key == KeyEvent.VK_P )
    {
        is_shooting2 = false;
    }

}

public static void main(String args[])
{
    Game game = new Game();

    game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
    game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
    game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));

    JFrame frame = new JFrame(game.TITLE);
    frame.add(game);
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    game.start();
}

public BufferedImage getSpriteSheet()
{
    return spriteSheet;
}

}

这是播放器:

package com.game.src.main;
import java.awt.*;
import java.awt.image.BufferedImage;

public class Player {
private double x; 
private double y;
protected double maxDY;
protected double gravity;
protected boolean canJump;

private BufferedImage player;

private double velX = 0;
private double velY = 0;
public Player(double x, double y, Game game) {
    this.x = x;
    this.y = y;
    SpriteSheet ss =  new SpriteSheet(game.getSpriteSheet());
    player = ss.grabImage(1,1,32,32);
    gravity = 0.1;
    maxDY = 5;
}

private void initPlayer() {

}

public void tick()
{

    x+=velX;
    y+=velY;
    fall();
    if(x <= 0)
        x=0;

    if (x >= 940-32)
        x=940-32;

    if(y <= 0)
        y=0;

    if (y >= 370-64)
    {
        y=370-64;  
        canJump = true;
    }
    else
    {
        canJump = false;
    }
}

public void render(Graphics g)
{
    g.drawImage(resize(player,64,64), (int)x, (int)y, null);
}

public double getX() {
    return x;
}

public double getY() {
    return y;
}

public void setX(double x)
{
    this.x = x;
}

public void setY(double y)
{
    this.y = y;
}

public void setVelX(double velX)
{
    this.velX = velX;
}

public void setVelY(double velY)
{
    this.velY = velY;
}
public static BufferedImage resize(BufferedImage img, int newW, int newH) { 
    Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
    BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);

    Graphics2D g2d = dimg.createGraphics();
    g2d.drawImage(tmp, 0, 0, null);
    g2d.dispose();

    return dimg;
} 

public void fall()
{   
    if (y < 320)
    velY += gravity;
    if (velY > maxDY) velY = maxDY;
}

public void jump(double jumpHeight)
{       
    if (canJump)
        velY -= jumpHeight;
}
}

我很确定它与播放器中的这个特殊位有关,但我不确定:

public void tick()
{

    x+=velX;
    y+=velY;
    fall();
    if(x <= 0)
        x=0;

    if (x >= 940-32)
        x=940-32;

    if(y <= 0)
        y=0;

    if (y >= 370-64)
    {
        y=370-64;  
        canJump = true;
    }
    else
    {
        canJump = false;
    }
}

任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

在地面上,你的角色似乎没有零垂直速度。他的终点速度仍在下降。如果你的代码低于地面,你的代码会自动将他带到地面,所以你看不到这一点。他试图跳跃,由此产生的垂直速度变化克服了这一点,但几乎没有。

但是如果你在一次小跳跃之后立即跳到地面时,他还没有以最终速度向下跳 - 他此时正以相对较低的速度下降。因为他的跳前下移速度较小,他的跳跃很容易克服它,并且他更高。