Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6711191
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T08:06:37+00:00 2026-05-26T08:06:37+00:00

Currently, I’m elaborating with game development, and have created (with help of some online

  • 0

Currently, I’m elaborating with game development, and have created (with help of some online tutorials) following sample game. The goal is to touch the sprites on the screen and thus killing them (i.e. they are removed from the screen). Screenshot is following

screenshot

When I kill few of them, I get following exception

E/AndroidRuntime(  277): FATAL EXCEPTION: Thread-8
E/AndroidRuntime(  277): java.util.ConcurrentModificationException
E/AndroidRuntime(  277):        at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
E/AndroidRuntime(  277):        at cz.trada.gd101.GameView.draw(GameView.java:65)
E/AndroidRuntime(  277):        at cz.trada.gd101.GameLoopThread.run(GameLoopThread.java:32)

The source code is shown bellow. Unfortunately, I don’t know how to highlight the exact lines of codes here on SO, so I put following comment in front of them: //ERROR COMING
So, you can easily locate those lines.

Please, help me to understand the cause of the concurrency error and find a solution.

P.S. The picture resources my_sprite_girl and my_sprite_boy used in the game are attached at the end of this post.

Main.java

package cz.trada.gd101;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class Main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(new GameView(this));
    }
}

GameView.java

package cz.trada.gd101;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class GameView extends SurfaceView {
    private static final String TAG = "GameView";
    SurfaceHolder holder;   

    GameLoopThread gameLoopThread;
    List<Sprite> sprites = new ArrayList<Sprite>();

    long lastClick;

    public GameView(Context context) {
        super(context);

        gameLoopThread = new GameLoopThread(this);
        holder = getHolder();
        holder.addCallback(new Callback() {

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                boolean retry = true;
                gameLoopThread.setRunning(false);
                while (retry) {
                    try {
                        gameLoopThread.join();
                        retry = false;
                    } catch (InterruptedException e) {
                        Log.d(TAG, e.getMessage());
                    }
                }   
            }

            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                createSprites();
                gameLoopThread.setRunning(true);
                gameLoopThread.start();             
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width,
                    int height) {
            }
        }); 

    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);
        for (Sprite sprite : sprites) {
//ERROR COMING
                sprite.draw(canvas);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
          if (System.currentTimeMillis() - lastClick > 500) {
                 lastClick = System.currentTimeMillis();
                 float x = event.getX();
                 float y = event.getY();
                 synchronized (getHolder()) {
                     for (int i = sprites.size() - 1; i >= 0; i--) {
                         Sprite sprite = sprites.get(i);
                         if (sprite.isCollision(x, y)) {
                             sprites.remove(sprite);
                             break;
                         }
                     }
                 }
          }
          return true;
    }

    private void createSprites() {
        for (int i = 0; i < 10; i++) {
            sprites.add(createSprite(R.drawable.my_sprite_girl));
            sprites.add(createSprite(R.drawable.my_sprite_boy));
        }
    }

    private Sprite createSprite(int resource) {
        Bitmap bmp = BitmapFactory.decodeResource(getResources(), resource);
        return new Sprite(this, bmp);
    }
}

GameLoopThread.java

package cz.trada.gd101;
import android.graphics.Canvas;
import android.util.Log;

public class GameLoopThread extends Thread {
    private static final String TAG = "GameLoopThread";
    private static final int FPS = 10;

    private GameView view;
    private boolean running = false;

    public GameLoopThread(GameView view) {
        this.view = view;       
    }

    public void setRunning(boolean run) {
        running = run;
    }

    @Override
    public void run() {
        long ticksPS = 1000 / FPS;
        long startTime;
        long sleepTime;
        while (running) {
            Canvas c = null;
            startTime = System.currentTimeMillis();                 
            try {
                c = view.getHolder().lockCanvas();
                synchronized (view.getHandler()) {
//ERROR COMING
                    view.draw(c);                   
                }
            } 
            finally {
                if (c != null) {
                    view.getHolder().unlockCanvasAndPost(c);
                }
            }

            sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
            try {
                if (sleepTime > 0)
                    sleep(sleepTime);
                else
                    sleep(10);
            } catch (Exception e) {
                Log.d(TAG, e.getMessage());
            }
        }
    }
}

Resources

my_sprite_girl

my_sprite_boy

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T08:06:38+00:00Added an answer on May 26, 2026 at 8:06 am

    Your error probably comes from the call to remove() in onTouchEvent() while the loop in draw() is iterating over the sprites.

    If your Sprite class already has equals() and hashCode() (or you add them), you could use ConcurrentSkipListSet instead which gives you lock-free contains, remove and add operations in log(n).

    CopyOnWriteArrayList would probably also solve the problem but not be very performant (due to copy-on-write part).

    As a style note, you could also use an Iterator and its remove() method in the onTouchEvent() loop:

    Iterator<Sprite> it = sprites.iterator();
    while (it.hasNext()) {
        Sprite sprite = sprites.next();
        if (sprite.isCollision(x, y)) {
            it.remove();
            break;
            }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Currently i have a node.js and socket.io application in development on my local machine
Currently I have the following code to update the NSLevelindicator: [self.headerIndicator selfFloatValue:heightValue] Is there
Currently I am making a console game (a rougelike) and I needed some advice
Currently, I'm working on a project where I have a server - client relationship
Currently I have 2 ways of displaying images in a cell, which way will
Currently I have this code: <?php echo '<meta name=robots content=noindex>'; $arr = json_decode(file_get_contents(http://media1.clubpenguin.com/play/en/web_service/game_configs/ paper_items.json),true);
Currently working on a multi-tenant application, have an issue in generating identifier in a
Currently, I have this selector: .form .mid td p:last-child:not(:only-child) { margin-bottom: 0; } It's
Currently I have two projects that are separate from one another. The first is
Currently I have a pure silverlight website with navigation. Im worried about the customers

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.