Thread Question (12 posts)

  • Profile picture of ogerlord ogerlord7p said 3 months, 3 weeks ago:

    Hi, at the moment i have different gameplay questions.
    For example I thought about 2 units attacking each other automaticly. If I would use the normal update loop to trigger the attack cooldown the gameplay would become very crazy when you have only a few FPS. Because of this I think i need to seperate the gameplay in an own thread (or use many timer).
    What do you think about this? And is there already a way to update the animations etc. easily when you work in another thread?

  • Profile picture of Tr3kk3r Tr3kk3r2p said 3 months, 3 weeks ago:

    if you want to have “cooldowns”. why dont you just save the time of the last attack, and then compare, it with the current time minus the saved time? if thats greater then the cooldown, the next attack can be made, otherwise it can not.

    Some pseudo code:

    if(current_time – last_attack > cooldown) {
    attack = get_attack_from_attack_queue();
    cooldown = attack.getCooldown()
    last_attack = current_time;
    attack.execute();
    }
    else {
    ; //still on cooldown => do nothing
    }

  • Profile picture of WASD WASD21p said 3 months, 3 weeks ago:

    As @Tr3kker says, checking the time every loop is often a better solution than creating threads.

  • Profile picture of normen normen1290p said 3 months, 3 weeks ago:

    Yes, it might seem like a lot of work but a check for null or comparison is something your computer can do millions of times a second, having an event-based system or even worse separate threads means much more overhead in the end. Also its the most consistent programming scheme really, applications and especially games have been done like this for ages really.

  • Profile picture of ogerlord ogerlord7p said 3 months, 3 weeks ago:

    Okay, but I dont want to create many variables that save the time and check it. (I think it would be confusing)
    Does JME have a “timer” class which could count the time for me?

  • Profile picture of normen normen1290p said 3 months, 3 weeks ago:

    Well normally you only need a few timers max per class (e.g. AppState or Control). I don’t know whats the issue with having one variable and adding tpf instead of having a whole class and the variable.

  • Profile picture of Tr3kk3r Tr3kk3r2p said 3 months, 3 weeks ago:

    @ogerlord said:
    Okay, but I dont want to create many variables that save the time and check it. (I think it would be confusing)

    Then use an array instead of multiple variables?

  • Profile picture of androlo androlo323p said 3 months, 2 weeks ago:

    An array, or maybe in its very own class. :o

    If it’s well made, perhaps it can be used in other classes as well.

  • Profile picture of ogerlord ogerlord7p said 3 months, 2 weeks ago:

    Maybe something like this:

    import java.util.PriorityQueue;
    
    public interface MyRunnable
    {
        public void run(Object value);
    }
    
    public class MyTimer implements Comparable{
    
        private static PriorityQueue heap
        private static long myTime;
    
        private MyRunnable runnable;
        private Object value;
        private long time;
        private boolean loop;
        private long loopDuration;
    
        public static void init()
        {
            myTime=0;
            heap = new PriorityQueue();
        }
    
        public static void update(float tpf)
        {
            if(heap.isEmpty()==false)
            {
                myTime += (long)(tpf*1000);
                while(heap.isEmpty()==false && ((MyTimer)heap.peek()).time < myTime )
                {
                    MyTimer t = (MyTimer)heap.peek();
                    heap.remove();
                    t.execute();
                }
            }
        }
    
        public MyTimer(MyRunnable runnable, Object value, int time, boolean loop )
        {
            this.runnable=runnable;
            this.value=value;
            this.time = myTime+(long)time;
            this.loop=loop;
            if(loop)
            {
                loopDuration = (long)time;
            }
            heap.add(this);
        }
    
        private void execute()
        {
            if(runnable != null)
            {
                runnable.run(value);
                if(loop)
                {
                    time = time + loopDuration;
                    heap.add(this);
                }else{
                    value=null;
                    runnable=null;
                }
            }
        }
    
        public void cancel()
        {
            value=null;
            runnable=null;
            heap.remove(this);
        }
    
        public int compareTo(Object o)
        {
            return (int)(time -((MyTimer)o).time);
        }
    
    }

    Example:

    
      public void simpleInitApp() {
            MyTimer.init();
    
            new MyTimer(new PrintMessage(),"loop",1000,true);
            new MyTimer(new PrintMessage(),"first",500,false);
            new MyTimer(new PrintMessage(),"third",5000,false);
            new MyTimer(new PrintMessage(),"second",2000,false);
    
        }
    
        public void simpleUpdate(float tpf){
            MyTimer.update(tpf);
        }
    
       private class PrintMessage implements MyRunnable
        {
            public void run(Object o)
            {
                System.out.println("Test:"+o);
            }
        }
  • Profile picture of normen normen1290p said 3 months, 2 weeks ago:

    For something like that you can rather use the app.enqueue method.. I think it was mainly about the counter itself.

  • Profile picture of ogerlord ogerlord7p said 3 months, 2 weeks ago:

    Hm? I cant follow you. Why should be the app.enqueue method better?

  • Profile picture of normen normen1290p said 3 months, 2 weeks ago:

    I mean the whole runnable logic.. I guess its possible to do it this way but it kind of requires you to encapsulate everything in runnables instead of checking some timer in an update() call or something.