我对游戏进行编码,这样当你按住D时,角色向右移动,当你按住S时,角色向左移动。程序正常运行,但有一个例外。当我移动角色(并且角色移动得很好)时,java会不断抛出错误" java.util.ConcurrentModificationException"。我做了一些研究,并了解到我无法添加到ArrayList" keys"并在同一时间迭代它。话虽如此,我如何编辑代码仍然让角色像现在一样无缝移动?这是我所知道的唯一方法,以确保角色在按住键的同时以相同的稳定速度移动,而不是快速移动,暂停,然后继续运动。
package LevelEditor;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import java.util.Iterator;
public class LevelEditor extends Canvas implements KeyListener, Runnable, MouseListener, MouseMotionListener{
private Object[][] grid = new Object[50][50];
private Graphics bufferGraphics = null; //The graphics for the back buffer
private BufferStrategy bufferStrategy = null;
private Thread thread;
private boolean running;
private int selectedBlock = 0;
private int mouseX;
private int mouseY;
private int playerX;
private int playerY;
private ArrayList<Integer> keys = new ArrayList<Integer>();
Iterator itr;
Player player1;
public LevelEditor(Dimension size){
//Constructor
this.setPreferredSize(size);
this.addKeyListener(this);
this.thread = new Thread(this);
this.addMouseListener(this);
this.addMouseMotionListener(this);
running = true;
mouseX = 0;
mouseY = 0;
playerX = 0;
playerY = 0;
itr = keys.iterator();
}
public void paint(Graphics g){
if (bufferStrategy == null){
this.createBufferStrategy(2);
bufferStrategy = this.getBufferStrategy();
bufferGraphics = bufferStrategy.getDrawGraphics();
player1 = new Player(playerX, playerY);
this.thread.start();
}
}
@Override
public void run() {
//This is what runs when level editor is running
while (running){
//Program's logic
DoLogic();
Draw();
DrawBackbufferToScreen();
Thread.currentThread();
try{
Thread.sleep(10);
}
catch(Exception e){
e.printStackTrace();
}
}
}
public void DoLogic(){
}
public void Draw(){
//clear secondary screen
bufferGraphics = bufferStrategy.getDrawGraphics();
try{
bufferGraphics.clearRect(0, 0, this.getSize().width, this.getSize().height);
//this is where everything will be drawn to back buffer
for (int x = 0; x < grid.length; x++){
for(int y = 0; y < grid[x].length; y++){
Object o = grid[x][y];
if (o instanceof Block){
Block blocktoDraw = (Block)o;
blocktoDraw.draw(bufferGraphics);
}
}
}
Block.getBlock(selectedBlock, mouseX, mouseY).draw(bufferGraphics);
player1.draw(bufferGraphics);
for (Integer x : keys){
if(x == 68 && itr.hasNext()){
playerX += 5;
player1.updatePlayer(playerX, playerY);
player1.draw(bufferGraphics);
itr.next();
itr.remove();
}
if (x == 65 && itr.hasNext()){
playerX -= 5;
player1.updatePlayer(playerX, playerY);
player1.draw(bufferGraphics);
itr.next();
itr.remove();
}
}
}
catch(Exception e){
e.printStackTrace();
}
finally{
bufferGraphics.dispose();
}
}
public void DrawBackbufferToScreen(){
bufferStrategy.show();
Toolkit.getDefaultToolkit().sync();
}
@Override
public void mouseReleased(MouseEvent e) {
int mouseX = e.getX();
int mouseY = e.getY();
mouseX = (mouseX / 25);
mouseY = (mouseY / 25);
if (e.getModifiers() == 16){
grid[mouseX][mouseY] = Block.getBlock(selectedBlock, mouseX, mouseY);
}
else if (e.getModifiers() == 4){
grid[mouseX][mouseY] = Block.getBlock(100, mouseX, mouseY);
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
keys.clear();
}
@Override
public void keyPressed(KeyEvent e) {
keys.add(e.getKeyCode());
}
public void mouseMoved(MouseEvent e) {
this.mouseX = e.getX() / 25;
this.mouseY = e.getY() / 25;
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseDragged(MouseEvent e) {
int mouseX = e.getX();
int mouseY = e.getY();
mouseX = (mouseX / 25);
mouseY = (mouseY / 25);
if(e.MOUSE_DRAGGED == 506 && e.getModifiers() == 16){
grid[mouseX][mouseY] = Block.getBlock(selectedBlock, mouseX, mouseY);
}
else if (e.MOUSE_DRAGGED == 506 && e.getModifiers() == 4){
grid[mouseX][mouseY] = Block.getBlock(100, mouseX, mouseY);
}
}
}
答案 0 :(得分:1)
在这里使用Iterator
是错误的模型:你实际上并没有遍历列表,你只是想看看你是否有一个元素,然后如果你有东西就处理它。
更合适的是使用队列 - 特别是某种并发队列,例如java.util.concurrent.BlockingQueue
,因为您正在修改它并在不同的线程中读取它。
您可以使用queue.add(e.getKeyCode())
将密钥代码添加到其中,然后使用queue.poll()
(或queue.peek()
)将其删除,如果队列中没有任何内容,则会返回空值(类似于itr.hasNext()
是假的。