java.util.ConcurrentModificationException with iterator (character movement) - java

I'm coding a game so that when you hold D the character moves right and when you hold S the character moves left. The program works just as it should, with one exception. As I'm moving the character (and the character moves perfectly fine), java keeps throwing the error "java.util.ConcurrentModificationException". I did some research and learned that I cannot be adding to the ArrayList "keys" and be iterating it at the same time. With that said, how do I edit the code to still have the character move seamlessly as he is now? This is the only way I know of to make sure the character moves at the same steady pace the second you hold a key down, not take a quick movement, pause, and then continue with the motion.
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);
}
}
}

Using an Iterator is the wrong model here: you aren't actually iterating through the list, you are just looking to see if you have an element, and then processing it if you have something.
A better fit is to use a queue - particularly, some sort of concurrent queue, e.g. java.util.concurrent.BlockingQueue, since you are modifying it and reading it in different threads.
You can add key codes into this using queue.add(e.getKeyCode()), and remove them using queue.poll() (or queue.peek()), which returns a null value if there is nothing in the queue (akin to itr.hasNext() being false).

Related

My Rectangle moves up despite what key I press with key Listener in Java

I am generally a very bad programmer but have been trying to learn game development for a school project. My problem is that I have a draw method that draws a white rectangle and have a key Listener for movement but for some reason it moves upward despite what key I press not just W A S and D.
If you could help with this I would appreciate.
thanks
package Main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable{
final int screenHeight = 600;
final int screenWidth = 800;
final int playerSize = 48;
int fps = 60;
KeyHandler keyH = new KeyHandler();
Thread gameThread;
//player default position
int playerX = 100;
int playerY = 100;
int playerSpeed = 1;
public GamePanel() {
this.setPreferredSize(new Dimension (screenWidth, screenHeight));
this.setBackground(Color.black);
this.setDoubleBuffered(true);
this.addKeyListener(keyH);
this.setFocusable(true);
}
public void startGameThread() {
gameThread = new Thread (this);
gameThread.start();
}
public void run() {
double drawInterval = 1000000000/fps; // 0.01666 seconds = 60 times per seconds
double nextDrawTime = System.nanoTime() + drawInterval;
while(gameThread != null) {
System.out.println("this gmae is runing");
// update information such as character positions
// draw the screen with the updated information
update();
repaint();
try {
double remainingTime = nextDrawTime - System.nanoTime();
remainingTime = remainingTime/1000000;
if(remainingTime<0) {
remainingTime = 0;
}
Thread.sleep ((long) remainingTime);
nextDrawTime += drawInterval;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void update() {
if(keyH.upPressed ==true) {
playerY = playerY - playerSpeed;
}
else if (keyH.downPressed ==true){
playerY = playerY + playerSpeed;
}
else if (keyH.leftPressed== true){
playerX = playerX - playerSpeed;
}
else if (keyH.rightPressed == true) {
playerX = playerX +playerSpeed;
}
}
public void paintComponent(Graphics g) {
// to draw something
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.white);
g2.fillRect(playerX, playerY, playerSize, playerSize);
g2.dispose();
}
}
package game;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyHandler implements KeyListener {
public boolean leftPressed;
public boolean rightPressed;
public boolean upPressed;
public boolean downPressed;
public boolean spacePressed;
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if(code == KeyEvent.VK_D);{
rightPressed = true;
}
if(code == KeyEvent.VK_A);{
leftPressed = true;
}
if(code == KeyEvent.VK_W);{
upPressed = true;
}
if(code == KeyEvent.VK_S);{
downPressed = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
int code = e.getExtendedKeyCode();
if(code == KeyEvent.VK_D);{
rightPressed = false;
}
if(code == KeyEvent.VK_A);{
leftPressed = false;
}
if(code == KeyEvent.VK_W);{
upPressed = false;
}
if(code == KeyEvent.VK_S);{
downPressed = false;
}
}
}

I made it so that the player is facing the mouse direction, but because of that there is a problem

So basically I wanted to create zombies to interact with them later on, but when I drew them I noticed that all of them are turning to the same direction as the player (to mouse) it happened with everything I drew. How do I fix that? (give each zombie it's own position independent from the mouse direction)
Screen.java
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
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.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
public class Screen extends JPanel implements KeyListener, MouseListener, MouseMotionListener {
private Enemy[] enemy;
private Bullet bullet;
private Player player;
boolean collisionBetweenBnZ = false;
private int mX, mY, key;
private List<Bullet> firedBullets = new ArrayList<Bullet>();
public Screen() {
player = new Player(400, 500);
enemy = new Enemy[10];
for (int i = 0; i < enemy.length; i++) {
enemy[i] = new Enemy();
}
setFocusable(true);
addKeyListener(this);
addMouseMotionListener(this);
addMouseListener(this);
this.requestFocusInWindow();
}
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
//an obstacle for zombies
g.fillRect(0, 400, 800, 4);
//drawing each bullet as soon as they are added to the list (when pressing mouse button)
for (int i = 0; i < firedBullets.size(); i++) {
firedBullets.get(i).drawBullet(g);
}
//drawing sprites
player.drawPlayer(g);
for (int i = 0; i < enemy.length; i++) {
enemy[i].drawEnemy(g);
}
}
public static int clamp(int num, int min, int max) { //method that prevents you from going beyond the window
if (num >= max) return num = max;
else if (num <= min) return num = min;
else return num;
}
public void fire() {
bullet = new Bullet(player.playerX(), player.playerY());
bullet.updateAngle(mX, mY, player.playerX(), player.playerY());
firedBullets.add(bullet);
}
public void animate() {
while (true) {
try {
Thread.sleep(10); //in milliseconds
}
catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
player.tick();
/*for (int i = 0; i < )
enemy.tick();*/
//System.out.println("X: " + mX + "\n" + "Y: " + mY);
for (int i = 0; i < firedBullets.size(); i++) {
firedBullets.get(i).launch();
}
//if () getbounds
repaint();
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
key = e.getKeyCode();
if (key == KeyEvent.VK_A) {
player.setVelX(-2);
}
else if (key == KeyEvent.VK_D) {
player.setVelX(2);
}
else if (key == KeyEvent.VK_S) {
player.setVelY(2);
}
else if (key == KeyEvent.VK_W) {
player.setVelY(-2);
}
else if (key == KeyEvent.VK_SPACE) {
//bullet.shootBullet = true;
}
else if (key == KeyEvent.VK_A && key == KeyEvent.VK_D) {
player.setVelX(0);
}
else if (key == KeyEvent.VK_W && key == KeyEvent.VK_S) {
player.setVelY(0);
}
}
public void keyReleased(KeyEvent e) {
key = e.getKeyCode();
if (key == KeyEvent.VK_A) {
player.setVelX(0);
}
else if (key == KeyEvent.VK_D) {
player.setVelX(0);
}
else if (key == KeyEvent.VK_S) {
player.setVelY(0);
}
else if (key == KeyEvent.VK_W) {
player.setVelY(0);
}
else if (key == KeyEvent.VK_SPACE) {
//bullet.shootBullet = false;
}
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
mX = e.getX();
mY = e.getY();
player.updateAngle(mX, mY);
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
fire();
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(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
}
}
Enemy.java
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.util.concurrent.ThreadLocalRandom;
public class Enemy {
private int health, width, height;
private int enemyX, enemyY, velY;
private BufferedImage img;
public Enemy() {
try {
img = ImageIO.read(new File("/Users/david/Desktop/Enemy_Sprite.png"));
} catch (IOException e) {
e.printStackTrace();
}
health = 100;
width = img.getWidth();
height = img.getHeight();
enemyX = ThreadLocalRandom.current().nextInt(50, 750);
enemyY = ThreadLocalRandom.current().nextInt(0, 200);
}
public Rectangle getBounds() {
return new Rectangle(enemyX, enemyY, width, height);
}
public void setVelY(int y) {
velY = y;
}
public void tick() {
enemyY += velY;
}
public boolean obstacleInteraction() {
//if (getBounds() == )
return true;
}
public void drawEnemy(Graphics g) {
g.drawImage(img, enemyX, enemyY, null);
}
}
I figured it out thanks to this person. So basically at the end of my code where I draw player and make him rotate to the mouse position put the saved original plane position
g.setTransform(oldAT);

Java Pong Game, Paddle is not moving [duplicate]

This question already has answers here:
How to use Key Bindings instead of Key Listeners
(4 answers)
Closed 5 years ago.
When VK_UP or VK_DOWN is pressed the Graphic g I created is not changing its position whatsoever. If someone could look and see if there is something wrong with my move method etc. Would really appreciate it.
Here is all my code so far:
package ping2;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Ping2 extends Applet implements Runnable, KeyListener{
final int WIDTH = 700, HEIGHT = 500;
Thread thread;
UserPaddle user1;
public void init() {
this.resize(WIDTH, HEIGHT);
this.addKeyListener(this);
user1 = new UserPaddle(1);
thread = new Thread(this);
thread.start();
}
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
user1.draw(g);
}
public void update(Graphics g) {
paint(g);
}
public void run() {
for(;;) {
user1.move();
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP) {
user1.setUpAccel(true);
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN) {
user1.setDownAccel(true);
}
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP) {
user1.setUpAccel(false);
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN) {
user1.setDownAccel(false);
}
}
public void keyTyped(KeyEvent arg0) {
}
}
package ping2;
import java.awt.*;
public class UserPaddle implements InterfaceBar{
double y, yVelocity;
boolean upAccel, downAccel;
int player1, x;
final double FRICTION = 0.90;
public UserPaddle(int player1) {
upAccel = false;
downAccel = false;
y = 210;
yVelocity = 0;
if(player1 == 1)
x = 20;
else
x = 660;
}
public void draw(Graphics g) {
g.setColor(Color.white);
g.fillRect(x, (int)y, 20, 80);
}
public void move() {
if(upAccel) {
yVelocity -= 2;
}else if(downAccel) {
yVelocity += 2;
}
//Automatically slows bar down if key not being pressed.
else if(!upAccel && !downAccel) {
yVelocity *= FRICTION;
}
}
public void setUpAccel(boolean input) {
upAccel = input;
}
public void setDownAccel(boolean input) {
downAccel = input;
}
public int getY() {
return (int)y;
}
}
package ping2;
import java.awt.Graphics;
public interface InterfaceBar {
public void draw(Graphics g);
public void move();
public int getY();
}
I have modified your move() a bit give it a try
move()
public void move() {
if(upAccel) {
yVelocity -= 2;
y = yVelocity;
}else if(downAccel) {
yVelocity += 2;
y = yVelocity;
}
}

Want to move my object vertically and horizontal, my code move in angles

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Game extends JPanel {
Ball ball = new Ball(this);
Number123 num123 = new Number123(this);
public Game(){
addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
ball.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
ball.keyPressed(e);
}
});
setFocusable(true);
}
private void move() {
ball.move();
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
num123.paintComponent(g2d);
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Two sprites");
Game game = new Game();
frame.add(game);
frame.setSize(600, 800);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
game.move();
game.repaint();
Thread.sleep(10);
}
}
}
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Ball implements ActionListener, KeyListener{
int x = 0;
int y = 0;
int xa = 0;
int ya = 0;
private Game game;
public Ball(Game game){
this.game= game;
}
void move(){
if (x + xa > 0 && x + xa < game.getWidth()-60)
x = x + xa;
if (y + ya > 0 && y + ya < game.getHeight()-60)
y = y + ya;
}
public void paint(Graphics2D g){
g.fillOval(x, y, 30, 30);
}
public void keyReleased(KeyEvent e) {
if (xa == 1){
xa = 1;}
if (xa == -1){
xa = -1;
}
if (ya == 1){
ya = 1;}
if (ya == -1){
ya = -1;
}
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT)
xa = -1;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
xa = 1;
if (e.getKeyCode() == KeyEvent.VK_UP)
ya = -1;
if (e.getKeyCode() == KeyEvent.VK_DOWN)
ya = 1;
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
new to java so sorry if its a simple answer.
when i run program my circle object moves in angles not vertically and horizontal.
You need to set xa to 0 when you want to move vertically, and ya to 0 when you want to move horizontally. They get initialized that way, but never get reset.

Pause/Resume java applet

two balls from left and bottom colliding with each other as they meet at a certain coordinate. I have already did what I searched on the internet and it worked perfectly, but I need a start, pause and resume buttons. Look at what I finished :
import java.applet.Applet;
import java.awt.Button;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class train extends Applet implements Runnable,ActionListener {
private volatile boolean runs = true;
private Image i;
private Graphics doubleG;
Ball b, b2;
Button x,y,z;
Thread thread = new Thread(this);
#Override
public void init(){
setSize(800, 600);
x = new Button("Action!");
y = new Button("Stop");
z = new Button("Resume!");
add(x);
add(y);
add(z);
y.addActionListener(new ActionListener() {
#SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent e)
{
runs = false;
repaint();
}
});
z.addActionListener(new ActionListener() {
#SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent e)
{
try {
runs = true;
b.update(this);
repaint();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
b2.update2(this);
repaint();
}
});
}
#Override
public void start(){
x.addActionListener(this);
b = new Ball(100, 100);
b2 = new Ball(500, 500);
}
#Override
public void run(){
while(runs){
b.update(this);
b2.update2(this);
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
//TODO Auto-generated catch block
// e.printStackTrace();
}
}
}
#Override
public void stop(){
}
#Override
public void destroy(){
}
#Override
public void update(Graphics g) {
// TODO Auto-generated method stub
if(i == null){
i = createImage(this.getSize().width, this.getSize().height);
doubleG = i.getGraphics();
}
doubleG.setColor(getBackground());
doubleG.fillRect(0, 0, this.getSize().width, this.getSize().height);
doubleG.setColor(getForeground());
paint(doubleG);
g.drawImage(i, 0, 0, this);
}
#Override
public void paint(Graphics g){
b.paint(g);
b2.paint(g);
}
public void actionPerformed(ActionEvent e) {
thread.start();
}
}
for the main train.class and :
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
public class Ball {
private int x;
private int y;
private double dx = 7.9;
private double dy = 7;
private int radius = 20;
public Ball() {
// TODO Auto-generated constructor stub
}
public Ball(int i, int j) {
// TODO Auto-generated constructor stub
x = i;
y = j;
}
public void update(train sp){
x += dx;
// if(x + dx > sp.getSize().width - 300){
// dx=0;
// }
}
public void paint(Graphics g){
g.setColor(Color.GREEN);
g.fillOval(x-radius, y-radius, radius * 2, radius * 2);
}
public void update2(train sp){
y -= dy;
if(y - dy < sp.getSize().height - 470){
x += dx;
y -= dy;
// if(y < sp.getSize().height - 470){
// y = sp.getSize().height -470;
// dy *= energyloss;
// dy = -dy;
// }else{
// dy += gravity * dt;
// y += dy*dt + .5 * gravity * dt * dt;
}
//}
}
public void update(ActionListener actionListener) throws InterruptedException {
x += dx;
}
public void update2(ActionListener actionListener) {
train tr = new train();
if(y - dy < tr.getSize().height - 470){
x += dx;
y -= dy;
}else{
y-=dy;
}
}
}
What I want to do is I want to make a resume button. I already finished the start and pause, but when I click the resume button, it just moves 1 coordinate at a time. I need it to just like Start , pause and play normally. Please help. T_T
An easy fix is to not have "runs" control the loop, but just determine whether or not the update method is called. That way you don't break the loop and have to restart.

Categories