[英]java arrayList treating different elements differently
So, I'm trying to make a simple platformer, here is the code: 因此,我正在尝试制作一个简单的平台游戏,代码如下:
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
}
}
The problem is that when the player jumps on the platforms, the platforms act differently depending on the platform. 问题在于,当玩家跳上平台时,平台的行为会因平台而异。 If I jump on the last drawn one, it acts how I want (jumping is set to
false
, the player.intersects(plat)
prints true to screen and the platform's bounds are printed both to the screen and the console). 如果我跳到最后绘制的一个,它将按照我想要的方式运行(跳转设置为
false
, player.intersects(plat)
在屏幕上显示为true,平台的边界在屏幕和控制台上都显示)。 Then, when I jump on a different platform, jumping stays true, player.intersects(plat)
prints false to screen and the platform's bounds are only printed to the console, not the screen. 然后,当我跳到另一个平台上时,跳动保持为true,
player.intersects(plat)
在屏幕上打印false,并且平台的边界仅打印到控制台,而不是屏幕。
I think I've narrowed it down to being something to do with having more than one element in the arrayList, but I don't know the specific issue. 我想我已将其范围缩小到与arrayList中具有多个元素有关的事情,但是我不知道具体问题。
there is a simple reason why jump is always true - in the last line of your complex logic you write 跳转始终为真有一个简单的原因-在您编写的复杂逻辑的最后一行中
if (!player.intersects(plat) && !player.intersects(ground)) jumping = true;
This will overwrite the jumping=false
you set in a loop run before. 这将覆盖您之前在循环运行中设置的
jumping=false
。
If you intersect with a platform which is not the last then you will not intersect with the last platform in the ArrayList - but the logic code above will set jump to true in the last loop run. 如果您与不是最后一个平台的平台相交,那么您将不会与ArrayList中的最后一个平台相交-但上面的逻辑代码将在最后一次循环运行中将jump设置为true。
I assume your player is only intersecting one platform at once - so your code should work if you insert a break
statement after the last operation in the if(player.intersects(plat)) { ... }
code block. 我假设您的播放器一次仅与一个平台相交-因此,如果您在
if(player.intersects(plat)) { ... }
代码块中的最后一个操作之后插入break
语句,则您的代码应该可以工作。
You should reengineer your logic part and write JUnit tests for it - but anyway you should refactor your code. 您应该重新设计逻辑部分并为其编写JUnit测试-但是无论如何,您都应该重构代码。 If your game is getting more complex you will get problems with adapting new features.
如果您的游戏变得越来越复杂,那么使用新功能会遇到问题。 Please use constants for the key codes so that it is more easy for readers to understand what you are doing.
请使用常数作为键码,以使读者更容易理解自己在做什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.