所以你可以在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;
}
}
任何人都可以帮我解决这个问题吗?
答案 0 :(得分:0)
在地面上,你的角色似乎没有零垂直速度。他的终点速度仍在下降。如果你的代码低于地面,你的代码会自动将他带到地面,所以你看不到这一点。他试图跳跃,由此产生的垂直速度变化克服了这一点,但几乎没有。
但是如果你在一次小跳跃之后立即跳到地面时,他还没有以最终速度向下跳 - 他此时正以相对较低的速度下降。因为他的跳前下移速度较小,他的跳跃很容易克服它,并且他更高。