好吧,所以我正在尝试制作一个快速而肮脏的平台引擎,我在碰撞检测和移动平台方面遇到了一些问题。一方面,“玩家”似乎在移动平台上稍微反弹,当他击中右侧时,错误也会发生。我将上传一个jnlp演示,以便您可以尝试查找更多错误并查看发生了什么,但这里有来源:
import java.awt.Rectangle;
import java.util.Vector;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
public class Platformer extends BasicGame{
boolean keys[];
int ALL_KEYS = 0xFF;
Player player;
Vector<Vector<Thing> > things;
int level = 0;
public Platformer() {
super("You've met with a terrible fate, haven't you?");
}
public void init(GameContainer gc) throws SlickException {
keys = new boolean[ALL_KEYS];
for(int i = 0; i < ALL_KEYS; i++){
keys[i] = false;
}
player = new Player();
things = new Vector<Vector<Thing> >();
Vector<Thing> temp = new Vector<Thing>();
temp.add(new Thing(0, 440, 640, 40, 1));
temp.add(new Thing(200, 300, 240, 50, 1));
temp.add(new Thing(500, 200, 240, 50, 1));
things.add(temp);
}
public void update(GameContainer gc, int delta) throws SlickException{
if(keys[Input.KEY_UP]){
player.velo = player.maxJump;
keys[Input.KEY_UP] = false;
}
if(keys[Input.KEY_DOWN]){
keys[Input.KEY_DOWN] = false;
}
if(keys[Input.KEY_LEFT]){
player.delta -= player.speed;
if(player.delta < -player.maxSpeed)
player.delta = -player.maxSpeed;
}
else if(keys[Input.KEY_RIGHT]){
player.delta += player.speed;
if(player.delta > player.maxSpeed)
player.delta = player.maxSpeed;
}
else{
if(player.delta < -0.5){
player.delta += player.speed;
}
else if(player.delta > 0.5){
player.delta -= player.speed;
}
else if(player.delta > -0.5 && player.delta < 0.5){
player.delta = 0;
}
}
if(player.delta < 0)
player.moveLeft(things.get(level));
else if(player.delta > 0)
player.moveRight(things.get(level));
if(player.velo < 0)
player.moveUp(things.get(level));
else
player.moveDown(things.get(level));
things.get(level).get(1).moveRight(player, things.get(level));
}
public void render(GameContainer gc, Graphics g) throws SlickException{
g.setColor(new Color(0,55,55));
g.fillRect(0, 0, 640, 480);
g.setColor(new Color(255,0,0));
g.fillRect(player.x, player.y, player.width, player.height);
for(int i = 0; i < things.get(level).size(); i++){
if(things.get(level).get(i).type == 1)
g.setColor(new Color(0,100,100));
g.fillRect(things.get(level).get(i).x, things.get(level).get(i).y,things.get(level).get(i).width, things.get(level).get(i).height);
}
}
public void keyPressed(int key, char c) {
keys[key] = true;
}
public void keyReleased(int key, char c) {
keys[key] = false;
}
public static void main(String[] args) throws SlickException{
AppGameContainer app =
new AppGameContainer( new Platformer() );
app.setShowFPS(false);
app.setAlwaysRender(true);
app.setTargetFrameRate(60);
app.setDisplayMode(640, 480, false);
app.start();
}
class Player{
float x = 50;
float y = 50;
float delta = 0; // x momentum
float velo = 0;
int height = 50;
int width = 30;
float speed = 0.2f;
int maxSpeed = 6;
int maxFallSpeed = 5;
int maxJump = -8;
public void moveLeft(Vector<Thing> things){
x += delta;
if(x < 0)
x = 0;
for(int i = 0; i < things.size(); i++){
if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
x += (things.get(i).x + things.get(i).width) - x;
delta = 0;
}
}
}
public void moveRight(Vector<Thing> things){
x += delta;
if(x + width > 640)
x = (640 - width);
for(int i = 0; i < things.size(); i++){
if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
x -= (x + width) - things.get(i).x;
delta = 0;
}
}
}
public void moveLeftWithThing(Vector<Thing> things, float thingSpeed){
x -= thingSpeed;
if(x < 0)
x = 0;
for(int i = 0; i < things.size(); i++){
if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
x += (things.get(i).x + things.get(i).width) - x;
delta = 0;
}
}
}
public void moveRightWithThing(Vector<Thing> things, float thingSpeed){
x += thingSpeed;
if(x + width > 640)
x = (640 - width);
for(int i = 0; i < things.size(); i++){
if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
x -= (x + width) - things.get(i).x;
delta = 0;
}
}
}
public void moveUp(Vector<Thing> things){
y += velo;
velo += speed;
if(velo > maxFallSpeed)
velo = maxFallSpeed;
for(int i = 0; i < things.size(); i++){
if(new Rectangle((int) x, (int) y, width, height/2).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
y += (things.get(i).y + things.get(i).height) - y;
velo = 0;
}
}
}
public void moveDown(Vector<Thing> things){
y += velo;
velo += speed;
if(velo > maxFallSpeed)
velo = maxFallSpeed;
boolean b = false;
for(int i = 0; i < things.size(); i++){
if(!b && new Rectangle((int) x, (int) y + (height/2), width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
y -= (y + height) - things.get(i).y;
velo = 0;
}
}
}
}
class Thing{
float x = 50;
float y = 50;
int height = 50;
int width = 30;
int type = -1;
float speed = 0.5f;
public Thing(float x, float y, int width, int height, int type){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.type = type;
}
public void moveUp(Player player){
y -= 0.5f;
if(new Rectangle((int) x,(int) y, width, height).intersects(new Rectangle((int) player.x, (int) player.y, player.width, player.height))){
player.y -= (player.y + player.height) - y;
player.velo = 0;
}
}
public void moveRight(Player player, Vector<Thing> things){
x += speed;
if(new Rectangle((int) x,(int) y - 1, width, height).intersects(new Rectangle((int) player.x, (int) player.y, player.width, player.height))){
player.moveRightWithThing(things, speed);
}
}
}
}
以下是演示:http://prime.programming-designs.com/java/platformer_demo/platdemo.jnlp
答案 0 :(得分:7)
您无法找到错误的原因是代码可怕。
moveLeft
,moveRight
,moveUp
和moveDown
都非常相似。velo
表示速度向下,delta
表示速度向右(错误标记为“动量”):为什么不vy
和vx
?另外maxSpeed
表示最大水平速度,maxFallSpeed
表示最大垂直速度。speed
。new Rectangle
。重复代码会产生错误,因为当复制功能时,可能会在其中一个地方出错,并且还会隐藏错误,因为代码量使得发现它们变得更加困难。 / p>
无论如何,平台上的弹跳可能与Player:moveDown
中使用的矩形偏移了玩家身高的一半,而Thing:moveRight
中你正在与一个矩形相撞的事实有关。这不是抵消。 (但这只是猜测。)