所以,我试图制作一个简单的平台游戏,这里是代码:
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();
//for background scrolling
private int worldShift;
//sprites
Rectangle2D player = new Rectangle2D.Double(rectX, rectY, 10, 10);
Rectangle2D ground = new Rectangle2D.Double(0, 420, 800, 150);
int[][] platforms = { {300 + worldShift, 300, 100, 20}, { 450 + worldShift, 200, 100, 20 }, { 500 + worldShift, 250, 100, 20 }, { 100 + worldShift, 200, 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(0, 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;
g2.setColor(Color.white);
g2.draw(player);
g2.fill(player);
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);
}
//debug printouts
g.drawString(inter, 400, 30);
g.drawString(coords, 20, 150);
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);
}
}
@Override
public void run() {
while (running) {
update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void update() {
worldShift = 0;
rectX += dx;
rectY += dy + 1;
// set sprite coords
player.setRect(rectX, rectY, 10, 10);
ground.setRect(0, 420, 800, 480);
// stops player running off screen
if (rectX < 1) rectX = 0;
if (rectX > 790) rectX = 790;
// 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 = " " + player.intersects(plat);
//for moving the world
if (rectX > 700 && dx == 5)
worldShift = -5;
if (rectX < 100 && dx == -5)
worldShift = 5;
//collision detection
if (player.intersects(plat)) {
System.out.println(plat);
jumping = false;
dy = 0;
coords = " " + plat.getBounds();
System.out.println(platformList.indexOf(plat));
// if player coming from top
if (rectY < plat.getY())
rectY = (int) (plat.getY() - player.getHeight());
// if player coming from bottom
else if (rectY > plat.getY() + plat.getHeight())
rectY = (int) (plat.getY() + plat.getHeight());
}
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
dy -= 20; // 38 is up
jumping = true;
System.out.println("Jumping");
}
}
//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
}
}
问题在于,当玩家跳上平台时,平台的行为会因平台而异。如果我跳到最后绘制的那个,它会按照我想要的方式行动(跳转设置为false
,player.intersects(plat)
将true打印到屏幕,并且平台的边界将打印到屏幕和控制台)。然后,当我跳到另一个平台上时,跳跃保持为真,player.intersects(plat)
将屏幕打印为false,平台的界限仅打印到控制台,而不是屏幕。
我认为我已经将其缩小到与在arrayList中拥有多个元素有关,但我不知道具体问题。
答案 0 :(得分:0)
有一个简单的原因,为什么跳总是如此 - 在复杂逻辑的最后一行 你写的
if (!player.intersects(plat) && !player.intersects(ground)) jumping = true;
这将覆盖您之前在循环运行中设置的jumping=false
。
如果你与一个不是最后一个的平台相交,你就不会 与ArrayList中的最后一个平台相交 - 但是上面的逻辑代码 将在上一次循环运行中将跳转设置为true。
我认为你的播放器只是一次交叉一个平台 -
因此,如果在最后一个之后插入break
语句,则代码应该可以正常工作
if(player.intersects(plat)) { ... }
代码块中的操作。
你应该重新设计你的逻辑部分并为它编写JUnit测试 - 但是 无论如何你应该重构你的代码。如果你的游戏正在进行中 更复杂的是,您将遇到调整新功能的问题。 请使用常量作为密钥代码,以便更容易 让读者了解你在做什么。