所以,我要做一个简单的Java平台了,但是还有一个大问题,当玩家从下面跳转并与平台相撞时,玩家有时(如果他们靠近平台的话)跳过平台并降落在上面的平台上。以下是代码:
package Main;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
public class Platformer extends Applet implements Runnable, KeyListener {
// buffering variables
private Image dbImage;
private Graphics dbg;
// running boolean
private boolean running = true;
// Player coords
private int rectX = 100;
private int rectY = 420;
// initialise dx and dy at zero
private double dx = 0;
private double dy = 0;
private boolean jumping = false;
//debug Strings
private String inter = new String();
private String coords = new String();
private String debugX = "", debugY = "";
//for moving the player
private int worldShift = 0;
//sprites
Rectangle2D player = new Rectangle2D.Double();// = new Rectangle2D.Double(rectX, rectY, 10, 10);
Rectangle2D ground = new Rectangle2D.Double(0, 420, 800, 150);
int[][] platforms = { {300, 300, 100, 20}, { 450, 200, 100, 20 },
{ 500, 250, 100, 20 }, { 100, 200, 100, 20 }, { 600, 300, 100, 20 } };
ArrayList<Rectangle2D> platformList = new ArrayList<Rectangle2D>();
int level = 1;
@Override
public void init() {
setSize(800, 480);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Test");
setVisible(true);
for (int i = 0; i < platforms.length; i++){
// platforms
Rectangle2D platform = new Rectangle2D.Double();
platform.setRect(platforms[i][0] + worldShift, platforms[i][1],
platforms[i][2], platforms[i][3]);
platformList.add(platform);
}
}
@Override
public void start() {
Thread thread = new Thread(this);
thread.start();
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
public void paint(Graphics g) {
//Double Buffering
Graphics2D g2 = (Graphics2D) g;
dbImage = createImage(getWidth(), getHeight());
dbg = dbImage.getGraphics();
paintComponent(dbg);
g2.drawImage(dbImage, 0, 0, this);
}
// Paint objects
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
//draw platforms
if (level == 1) {
g2.setColor(Color.blue);
g2.draw(ground);
g2.fill(ground);
for (Rectangle2D plat : platformList){
g2.setColor(Color.red);
g2.draw(plat);
g2.fill(plat);
}
g2.setColor(Color.red);
//debug printouts
g.drawString(inter, 400, 30);
g.drawString(coords, 20, 150);
//draw player
g2.setColor(Color.white);
g2.draw(player);
g2.fill(player);
//print debug info to screen
Font bold = new Font("Liberation Sans", Font.BOLD, 36);
setFont(bold);
g.drawString("dx, dy: (" + dx + ", " + dy + ")", 30, 30);
g.drawString("x, y: (" + player.getX() + ", " + player.getY() + ")",
30, 60);
g.drawString("" + debugX + ", " + debugY + "", rectX, rectY);
}
}
@Override
public void run() {
while (running) {
update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void update() {
rectX += dx;
rectY += dy + 1;
// stops player running off screen
if (rectX < 1) rectX = 0;
if (rectX > 790) rectX = 790;
// set sprite coords
player.setRect(rectX, rectY, 10, 10);
ground.setRect(0, 420, 800, 480);
// collision detection
if (player.intersects(ground)) {
rectY = (int) (ground.getY() - player.getHeight());
jumping = false;
dy = 0;
}
for (int i = 0; i < platformList.size(); i++){
Rectangle2D plat = platformList.get(i);
//sets platform's coordinates
plat.setRect(plat.getX() + worldShift, plat.getY(), plat.getWidth(), plat.getHeight());
//sets debug Strings
coords = "Not on platform";
inter = " " + platformList.get(0).getX() + worldShift + ", " + worldShift;
debugX = "" + rectX;
debugY = "" + rectY;
//for scrolling the background
if (rectX > 700 && dx == 5){
worldShift = -5;}
else if (rectX < 100 && dx == -5){
worldShift = 5;}
else worldShift = 0;
//collision detection
if (player.intersects(plat)) {
jumping = false;
dy = 0;
coords = " " + plat.getBounds();
//if falling
if (rectY <= (int) (plat.getY() + (plat.getHeight()/2))){
rectY = (int) (plat.getY() - player.getHeight());
//if jumping
else if (rectY >= plat.getY() + (plat.getHeight()/2)){
rectY = (int) (plat.getY() + plat.getHeight());}
break;
}
else if (!player.intersects(plat) && !player.intersects(ground)) {
jumping = true;
}
}
//implements falling
if (jumping)
dy += 1;
}
//button presses
@Override
public void keyPressed(KeyEvent e) {
System.out.println("Key pressed code=" + e.getKeyCode() + ", char=" + e.getKeyChar());
if (e.getKeyCode() == 37)
dx -= 5; // 37 is left
if (e.getKeyCode() == 39)
dx += 5; // 39 is right
// if (e.getKeyCode() == 40) dy -= 5; //40 is down
if (e.getKeyCode() == 38 && jumping == false){
// if on the ground,
// i.e. only jump if on the ground
// 38 is up
dy -= 20;
jumping = true;
}
}
//key release
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == 37)
dx = 0; // 37 is left
if (e.getKeyCode() == 39)
dx = 0; // 39 is right
if (e.getKeyCode() == 40)
dy = 0; // 40 is down
// if (e.getKeyCode() == 38)
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}我确信update()的‘//冲突检测’部分没有什么问题,但我不知道问题是什么。除其他外,我尝试将跳转机制放置在update循环中,但是它也没有工作。
谢谢你的帮助。
发布于 2015-07-15 10:44:27
看看跳跃的大小,它是20:
public void keyPressed(KeyEvent e) {
System.out.println("Key pressed code=" + e.getKeyCode() + ", char=" + e.getKeyChar());
if (e.getKeyCode() == 37)
dx -= 5; // 37 is left
if (e.getKeyCode() == 39)
dx += 5; // 39 is right
// if (e.getKeyCode() == 40) dy -= 5; //40 is down
if (e.getKeyCode() == 38 && jumping == false){
// if on the ground,
// i.e. only jump if on the ground
// 38 is up
dy -= 20; // <- jump size 20
jumping = true;
}
}但是你的平台高度也是20,你是根据平台的中心来决定的,这意味着它只有10个像素才能达到中心,跳台的大小应该小于平台的一半高。
编辑良好配置:
尝试以下配置:
设置增量下降到+0.25,跳转增量降到-9
删除注释,使其更短
if (jumping)
dy += 0.25;和
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 37)
dx -= 5; // 37 is left
if (e.getKeyCode() == 39)
dx += 5; // 39 is right
if (e.getKeyCode() == 38 && jumping == false){
dy -= 9; // <- jump size set to 9 (half is 10)
jumping = true;
}
}注意:闪烁是可怕的,我解决了将paint(Graphics)方法重命名为update(Graphics)的问题。
https://stackoverflow.com/questions/31427902
复制相似问题