This site requires JavaScript, please enable it in your browser!
Greenfoot back
Roshan123
Roshan123 wrote ...

2020/10/6

Lag

Roshan123 Roshan123

2020/10/6

#
Is their anyway to check scenario lag before uploading it in the website I m telling this because sometimes when i upload a scenario, that starts lagging in the website but it doesn't lag in Greenfoot app Will It help me to check game lag....
RcCookie RcCookie

2020/10/6

#
You can try my FPS counter. Usually (this will probably differ from pc to pc) I get like 10% of the FPS I get offline on the website. This is the scenario. It features all kinds of UI.
RcCookie RcCookie

2020/10/6

#
You can use Danpost‘s too, but I know how my works and it’s really simple to use
Roshan123 Roshan123

2020/10/6

#
Does it needs a surplus code or a small amount of code If its a small code then will u write it for me becaz due to some reason i won't be able to download it If its a long code then let it be I will download it later on.....
Roshan123 Roshan123

2020/10/6

#
And also answer me that, will it help me to know that it will lag on website or not
RcCookie RcCookie

2020/10/6

#
The raw FPS measurement code is pretty short, but the code for the visuals is pretty big (For example that you can click on it to switch the mode). Also, I correctly do not have access to the code. If you really need it a can post it here later
RcCookie RcCookie

2020/10/6

#
Here is all the code: Time class (does the core fps calculations):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public class Time extends greenfoot.Actor{
    public static double MAX_DELTA_TIME = 0.08;
    public static double AVERAGE_DELTA_TIME = 0.01;
    long lastMillis;
    double deltaTime = AVERAGE_DELTA_TIME;
    public double timeScale = 1;
    public boolean useStaticFramelength = false;
    public double staticFramelength = 0.001;
    long frameIndex = 0;
 
    double timeSinceFpsUpdate = 0;
    int frameNum;
    int frameCount;
    int stableFps;
     
    public Time(){
        setImage(new greenfoot.GreenfootImage(1, 1));
    }
    public void act(){
        //TODO: Use System.nanoTime()
        long currentMillis = System.currentTimeMillis();
        deltaTime = (currentMillis - lastMillis) / 1000.0;
        lastMillis = currentMillis;
        deltaTime %= 1;
 
 
        timeSinceFpsUpdate += deltaTime;
        frameNum++;
        frameCount += fps();
        if(timeSinceFpsUpdate >= 1){
            timeSinceFpsUpdate %= 1;
            stableFps = (int)(frameCount / (double)frameNum);
            frameNum = frameCount = 0;
        }
        frameIndex++;
    }
     
    /**
     * Fraction of time since the last frame
     */
    public double deltaTime(){
        if(useStaticFramelength) return staticFramelength;
        if(deltaTime < MAX_DELTA_TIME) return deltaTime * timeScale;
        return MAX_DELTA_TIME * timeScale;
    }
 
    public void setTimeScale(double scale){
        timeScale = scale;
    }
     
    /**
     * Updated once per frame
     */
    public int fps(){
        if(deltaTime == 0) return 2000;
        return (int)(1 / deltaTime);
    }
     
    /**
     * Updated once per second
     */
    public int stableFps(){
        return stableFps;
    }
     
    public long frameIndex(){
        return frameIndex;
    }
     
    public void resetFrameIndex(){
        frameIndex = 0;
    }
}
Button class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
import greenfoot.*;
/**
 * This is a Button class. Use it for interfaces. The Button works completly
 * automaticly, you do not have to feed it any information after the
 * construction. It offers selveral methods to get information about
 * the users interactions with it. It may also go to a certain world when clicked
 * to move through menus.
 *
 * @author RcCookie
 * @version 1.2
 */
public class Button extends Actor
{
    /**
     * The number of times this button has been clicked.
     */
    protected int clickCount;
 
    /**
     * The number of frames this button was held down.
     */
    protected int pressTime;
 
    /**
     * Weather the button is touched by the mouse right now.
     */
    protected boolean touched;
 
    /**
     * Weather the button is pressed down by the mouse right now.
     */
    protected boolean pressed;
 
    /**
     * The text on the button.
     */
    protected String name;
 
    /**
     * The image given as input, or null if a color was chosen.
     */
    protected GreenfootImage inputImage;
 
    protected Text inputText;
 
    /**
     * The x and y size of the button.
     */
    protected int x, y;
 
    /**
     * The color used to fill the background if inputImage is null.
     */
    protected Color color;
 
    /**
     * The font size for the buttons text.
     */
    protected int fontSize;
 
    /**
     * Weather there should be an outline around the button.
     */
    protected boolean drawFrame;
 
    /**
     * The world to switch to after the button was clicked, or null.
     */
    protected World onClick;
 
    /**
     * The standart image of the button.
     */
    protected GreenfootImage image;
 
    /**
     * The buttons image when hovered over it with the mouse.
     */
    protected GreenfootImage hoveredImage;
 
    /**
     * The buttons image when it is being clicked.
     */
    protected GreenfootImage clickedImage;
 
 
 
 
    public boolean enabled = true;
     
 
    /**
     * Constructs a new grey Button with the given title and a default size
     * of at least 90 times 35 pixels.
     *
     * @param title The text printed onto the button
     */
    public Button(String title){
        inputText = new Text(title, 25, Color.BLACK, Color.LIGHT_GRAY);
        x = 90;
        y = 35;
        drawFrame = true;
        onClick = null;
        setup();
    }
 
    /**
     * Constructs a new grey Button with the given title and a default size
     * of at least 90 times 35 pixels. It will switch to the given world when clicked.
     *
     * @param title The text printed onto the button
     * @param onClick The world to switch to when clicked
     */
    public Button(String title, World onClick){
        inputText = new Text(title, 25, Color.BLACK, Color.LIGHT_GRAY);
        x = 90;
        y = 35;
        drawFrame = true;
        this.onClick = onClick;
        setup();
    }
     
    /**
     * Constructs a new grey Button with the given title and a the given width
     * and height.
     *
     * @param x The width of the button
     * @param y The height of the button
     * @param title The text printed onto the button
     */
    public Button(int x, int y, String title){
        name = title;
        inputImage = null;
        this.x = x;
        this.y = y;
        color = Color.LIGHT_GRAY;
        fontSize = 25;
        drawFrame = true;
        onClick = null;
        setup();
    }
 
    /**
     * Constructs a new grey Button with the given title and a the given width
     * and height. It will switch to the given world when clicked.
     *
     * @param x The width of the button
     * @param y The height of the button
     * @param title The text printed onto the button
     * @param onClick The world to switch to when clicked
     */
    public Button(int x, int y, String title, World onClick){
        name = title;
        inputImage = null;
        this.x = x;
        this.y = y;
        color = Color.LIGHT_GRAY;
        fontSize = 25;
        drawFrame = true;
        this.onClick = onClick;
        setup();
    }
     
    /**
     * Constructs a new Button with the given title in the given size and
     * the given width and height using the given background colour. Unless
     * onClick is null if will switch to that world when clicked on.
     *
     * @param x The width of the button
     * @param y The height of the button
     * @param title The text printed onto the button
     * @param fontSize The font size for the text on the button
     * @param colour The background colour of the button
     * @param onClick The world to switch to when clicked
     */
    public Button(int x, int y, String title, int fontSize, Color colour, World onClick){
        name = title;
        inputImage = null;
        this.x = x;
        this.y = y;
        color = colour;
        this.fontSize = fontSize;
        drawFrame = true;
        this.onClick = onClick;
        setup();
    }
     
    /**
     * Constructs a new Button with the given title in the given size and
     * the given width and height using the given background colour. Unless
     * onClick is null if will switch to that world when clicked on.
     *
     * @param x The width of the button
     * @param y The height of the button
     * @param title The text printed onto the button
     * @param fontSize The font size for the text on the button
     * @param colour The background colour of the button
     * @param drawFrame if a black outline should be drawed around the image
     * @param onClick The world to switch to when clicked
     */
    public Button(int x, int y, String title, int fontSize, Color colour, boolean drawFrame, World onClick){
        name = title;
        inputImage = null;
        this.x = x;
        this.y = y;
        color = colour;
        this.fontSize = fontSize;
        this.drawFrame = drawFrame;
        this.onClick = onClick;
        setup();
    }
 
    /**
     * Constructs a new Button with the given image as background and
     * optional with a title and a black outline. Unless
     * onClick is null if will switch to that world when clicked on.
     *
     * @param theImage the background image
     * @param title the title written centered onto the image, or null
     * @param fontSize the font size of the title. Ignore if there is no title
     * @param drawFrame if a black outline should be drawed around the image
     * @param onClick The world to switch to when clicked
     */
    public Button(GreenfootImage theImage, String title, int fontSize, boolean drawFrame, World onClick){
        name = title;
        inputImage = theImage;
        x = theImage.getWidth();
        y = theImage.getHeight();
        color = Color.LIGHT_GRAY;
        this.fontSize = fontSize;
        this.drawFrame = drawFrame;
        this.onClick = onClick;
        setup();
    }
 
    /**
     * Constructs a new button from the given text. Content and size
     * are updated every frame.
     *
     * @param text The text object the button should be based on
     */
    public Button(Text text){
        inputText = text;
        x = y = 10;
        drawFrame = true;
        onClick = null;
        setup();
    }
     
    /**
     * Constructs a new button from the given text that is at least
     * as big as inputed. Content and size are updated every frame.
     *
     * @param text The text object the button should be based on
     * @param minX The minimum width of the button
     * @param minY The minimum height of the button
     */
    public Button(Text text, int minX, int minY){
        inputText = text;
        if(minX < inputText.getImage().getWidth()) minX = inputText.getImage().getWidth();
        if(minY < inputText.getImage().getHeight()) minY = inputText.getImage().getHeight();
        x = minX;
        y = minY;
        drawFrame = true;
        onClick = null;
        setup();
    }
     
    /**
     * Constructs a new button from the given text that is at least
     * as big as inputed. It will switch to the given world unless it
     * is null. Content and size are updated every frame.
     *
     * @param text The text object the button should be based on
     * @param minX The minimum width of the button
     * @param minY The minimum height of the button
     * @param drawFrame If a black outline should be drawed around the button
     * @param onClick The world to switch to when clicked
     */
    public Button(Text text, int minX, int minY, boolean drawFrame, World onClick){
        inputText = text;
        x = minX;
        y = minY;
        this.drawFrame = drawFrame;
        this.onClick = onClick;
        setup();
    }
 
 
    /**
     * Creates the image, hoveredImage and clickedImage for the button using
     * the latest settings and aplies the matching image to the button.
     */
    public void createImages(){
        if(inputText != null){
            name = inputText.getContent();
            int x = this.x;
            int y = this.y;
            if(x < inputText.getImage().getWidth() + 6) x = inputText.getImage().getWidth() + 6;
            if(y < inputText.getImage().getHeight()) y = inputText.getImage().getHeight();
 
            image = new GreenfootImage(x, y);
            if(inputText.getBackgroundColor() != null){
                image.setColor(inputText.getBackgroundColor());
                if(x > inputText.getImage().getWidth()){
                    int delta = x - inputText.getImage().getWidth();
                    image.fillRect(0, 0, delta / 2, image.getHeight());
                    image.fillRect(image.getWidth() - (delta - delta / 2), 0, delta / 2, image.getHeight());
                }
                if(y > inputText.getImage().getHeight()){
                    int deltaX = x - inputText.getImage().getWidth();
                    int deltaY = y - inputText.getImage().getHeight();
                    image.fillRect(deltaX / 2, 0, inputText.getImage().getWidth(), deltaY / 2);
                    image.fillRect(deltaX / 2, image.getHeight() - (deltaY - deltaY / 2), inputText.getImage().getWidth(), deltaY / 2);
                }
            }
            image.drawImage(inputText.getImage(), (x - inputText.getImage().getWidth()) / 2, (y - inputText.getImage().getHeight()) / 2);
             
        }
        else{
            if(inputImage != null){
                image = new GreenfootImage(inputImage);
            }
            else{
                image = new GreenfootImage(x, y);
                image.setColor(color);
                image.fill();
            }
            if(name!=null){
                GreenfootImage temp1 = new GreenfootImage(name, fontSize, Color.BLACK, null);
                image.drawImage(temp1, image.getWidth()/2-temp1.getWidth()/2, image.getHeight()/2-temp1.getHeight()/2);
            }
        }
 
        image.setColor(Color.BLACK);
        if(drawFrame)image.drawRect(0,0,image.getWidth()-1,image.getHeight()-1);
 
        hoveredImage = new GreenfootImage(image);
        hoveredImage.scale((int)(image.getWidth() * 1.1), (int)(image.getHeight() * 1.1));
 
        GreenfootImage temp = new GreenfootImage(image.getWidth(), image.getHeight());
        temp.setColor(Color.BLACK);
        temp.fill();
        temp.setTransparency(80);
        clickedImage = new GreenfootImage(image);
        clickedImage.drawImage(temp, 0, 0);
 
        if(touched){
            if(pressed) setImage(clickedImage);
            else setImage(hoveredImage);
        }
        else setImage(image);
    }
 
 
    /**
     * Applies default settings to the button
     */
    private void setup(){
        createImages();
        touched = false;
        pressed = false;
        clickCount = 0;
        pressTime = 0;
    }
     
 
    /**
     * Analyses the mouse interactions each frame. Do not remove
     * any code here! Use the run method instead!
     */
    public void act()
    {
        touched = touching();
        if(touched&&Greenfoot.mousePressed(null)){
            pressed=true;
            if(enabled) onPress();
        }
        else if(Greenfoot.mouseClicked(null)){
            if(pressed&&touched){
                clickCount++;
                if(enabled) onClick();
                if(enabled) onRelease();
                pressed = false;
                if(onClick!=null)Greenfoot.setWorld(onClick);
            }
            else if(pressed){
                pressed = false;
                if(enabled) onRelease();
 
            }
        }
 
         
        if(inputText != null) createImages();
        else if(touched){
            if(pressed) setImage(clickedImage);
            else setImage(hoveredImage);
        }
        else setImage(image);
         
        if(pressed)pressTime++;
        run();
    }
 
 
    /**
     * Simulates clicking the button for the given time. The button will not
     * actually animate the click, however, click count and press time will
     * be updated and {@code onPress()}, {@code onClick()} and {@code onRelease()}
     * will be executed.
     *
     * @param time The number of frames the button should (virtually) be pressed down.
     */
    public void click(int time){
        if(enabled) onPress();
        pressTime += time >= 0 ? time : 1;
        clickCount++;
        if(enabled) onClick();
        if(enabled) onRelease();
    }
 
    /**
     * Simulates clicking the button for a single frame. The button will not
     * actually animate the click, however, click count and press time will
     * be updated and {@code onPress()}, {@code onClick()} and {@code onRelease()}
     * will be executed.
     */
    public void click(){
        click(1);
    }
 
 
    /**
     * Checkes weather the mouse is touching the button right now. Is rather
     * cpu-intense so don't use it more than once per frame.
     *
     * @return Wheather the mouse is touching the button
     */
    public boolean touching(){
        try{
            MouseInfo mouse = Greenfoot.getMouseInfo();
            Sensor sensor = new Sensor();
            getWorld().addObject(sensor, mouse.getX(), mouse.getY());
            return sensor.touching(this);
            //return ActorVisitor.containsPoint(this, mouse.getX(), mouse.getY());
        }catch(Exception e){}
        return false;
    }
 
 
    /**
     * A simple class to test if it is touching the button.
     */
    class Sensor extends Actor{
        /**
         * Creates a new sensor with an transparent one pixel big image.
         */
        public Sensor(){
            setImage(new GreenfootImage(1, 1));
        }
 
        /**
         * Weather the sensor is touching the given button.
         *
         * @param button The button to check for
         * @return Weather the given button is touched
         */
        public boolean touching(Button button){
            boolean out = getOneIntersectingObject(Button.class) == button;
            getWorld().removeObject(this);
            return out;
        }
    }
 
 
    /**
     * Executed once per frame as a replacement of the act method. Override
     * it to use.
     */
    public void run(){}
 
    /**
     * Executed whenever the mouse is first pressed onto the button
     */
    public void onPress(){}
 
    /**
     * Executed whenever the mouse is released after holding down the button,
     * also if is is not on it no more.
     */
    public void onRelease(){}
 
    /**
     * Executed ehenever the mouse is released after holding down the button,
     * but only when the mouse touched the button while being released.
     */
    public void onClick(){}
     
 
    /**
     * Resets the stats of the button.
     */
    public void reset(){
        clickCount = 0;
        pressTime = 0;
    }
     
    /**
     * Sets the count of the button to the given value.
     *
     * @param n The new value
     */
    public void setCount(int n){
        clickCount = n;
    }
     
    /**
     * Returns the number of times the button was clicked since the last
     * reset.
     *
     * The Button is considered to be clicked when the mouse was pressed on
     * the button and then released on it again. It still counts as a click
     * if the mouse was dragged outside of the button while being pressed
     * but is released on the button.
     *
     * @return The number of clicks
     */
    public int getClickCount(){
        return clickCount;
    }
     
    /**
     * Returns true if the button was clicked since the last reset.
     *
     * The Button is considered to be clicked when the mouse was pressed on
     * the button and then released on it again. It still counts as a click
     * if the mouse was dragged outside of the button while being pressed
     * but is released on the button.
     *
     * @return A boolean if the button was ever clicked at least one time
     */
    public boolean clicked(){
        return clickCount>0;
    }
     
    /**
     * Returns if the button is being pressed right now.
     *
     * The Button is considered to be pressed when the mouse was pressed on
     * the buttonand since than holded down. It still counts as pressed
     * if the mouse was dragged outside of the button while being pressed.
     *
     * @return If the button is pressed right now
     */
    public boolean pressed(){
        return pressed;
    }
     
    /**
     * Returns if the button is being touched by the mouse right now.
     *
     * @return If the button is touched right now
     */
    public boolean touched(){
        return touched;
    }
     
    /**
     * Returns the number of frames the button was pressed since the last
     * reset.
     *
     * It is considered as pressed if the boolean pressed() is true.
     *
     * @return the time the button was pressed
     */
    public int getTimePressed(){
        return pressTime;
    }
     
    /**
     * Returns the title written onto the button.
     *
     * @return The buttons text
     */
    public String getTitle(){
        return name;
    }
 
    /**
     * Returns the text object used in this button
     *
     * @return The text object of this button
     */
    public Text getText(){
        return inputText;
    }
 
 
    /**
     * Override the title of the button.
     *
     * @param name The new title
     */
    public void setTitle(String name){
        this.name = name;
        createImages();
    }
 
    /**
     * Sets the image of the button to the given one. If image is null,
     * the latest color will be used.
     *
     * @param image The new image
     */
    public void setBackgroundImage(GreenfootImage image){
        inputImage = image;
        createImages();
    }
 
    /**
     * Sets the background of the button to the given color.
     *
     * @param color the new color
     */
    public void setColor(Color color){
        inputImage = null;
        this.color = color;
        createImages();
    }
 
    /**
     * Sets the images displayed to custom ones to allow more customisation.
     *
     * @param image The image to be showm normally
     * @param hoveredImage The image to be showm when the mouse hovers over the button
     * @param clickedImage The image to be shown when the button is pressed down
     */
    public void setCustomImages(GreenfootImage image, GreenfootImage hoveredImage, GreenfootImage clickedImage){
        this.image = image;
        this.hoveredImage = hoveredImage;
        this.clickedImage = clickedImage;
        if(touched){
            if(pressed) setImage(this.clickedImage);
            else setImage(this.hoveredImage);
        }
        else setImage(this.image);
 
    }
 
    /**
     * Sets the text object the button is based on to the given one.
     *
     * @param text The text object to set to
     */
    public void setText(Text text){
        inputText = text;
        createImages();
    }
 
    /**
     * Sets weather the outline should be drawn or not
     *
     * @param drawFrame Weather the outline should be drawn
     */
    public void drawFrame(boolean drawFrame){
        this.drawFrame = drawFrame;
        createImages();
    }
 
    /**
     * Sets the world to switch to on click to the given one. If onClick is
     * null, the world will not be swiched.
     *
     * @param onClick The world to switch to, or null
     */
    public void setNextWorld(World onClick){
        this.onClick = onClick;
    }
}
Text class (used to display text by the button):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import greenfoot.*;
 
/**
 * The text class is used to store and display some text and to input
 * and modify the text in other objects.
 *
 * @author RcCookie
 * @version 1.0
 */
public class Text extends Actor{
 
    /**
     * The text of the text.
     */
    protected String content = "";
 
    /**
     * The fontSize of the dext drawn.
     */
    private int fontSize = 20;
 
    /**
     * The color of the letters of the text.
     */
    private Color color = Color.BLACK;
 
    /**
     * The color of the background image of the text.
     */
    private Color background = null;
     
 
    /**
     * Constructs an empty text with default settings.
     */
    public Text(){}
 
    /**
     * Constructs a new text with the given content.
     *
     * @param content The text of the text
     */
    public Text(String content){
        this.content = content;
        update();
    }
 
    /**
     * Constructs a new text with the given content written in the given
     * font size.
     *
     * @param content The text of the text
     * @param fontSize The font size of the text
     */
    public Text(String content, int fontSize){
        this.content = content;
        this.fontSize = fontSize;
        update();
    }
 
    /**
     * Constructs a new text with the given content written in the given
     * color.
     *
     * @param content The text of the text
     * @param color The color of the text
     */
    public Text(String content, Color color){
        this.content = content;
        this.color = color;
        update();
    }
 
    /**
     * Constructs a new text with the given content written in the given
     * color and font size.
     *
     * @param content The text of the text
     * @param fontSize The font size of the text
     * @param color The color of the text
     */
    public Text(String content, int fontSize, Color color){
        this.content = content;
        this.fontSize = fontSize;
        this.color = color;
        update();
    }
 
    /**
     * Constructs a new text with the given content written in the given
     * color and font size. The background will be filled with the given
     * backgound color.
     *
     * @param content The text of the text
     * @param fontSize The font size of the text
     * @param color The color of the text
     * @param background The color of the background
     */
    public Text(String content, int fontSize, Color color, Color background){
        this.content = content;
        this.fontSize = fontSize;
        this.color = color;
        this.background = background;
        update();
    }
     
     
    /**
     * Updates the image of the text according to the current settings.
     */
    protected void update(){
        setImage(new GreenfootImage(content, fontSize, color, background));
    }
     
     
    /**
     * Sets the text of the text to the given string.
     *
     * @param content The new text
     */
    public void setContent(String content){
        this.content = content;
        update();
    }
     
    /**
     * Sets the font size of the text (also of the already written stuff) to
     * the given one.
     *
     * @param fontSize The new font size
     */
    public void setFontSize(int fontSize){
        this.fontSize = fontSize;
        update();
    }
     
    /**
     * Sets the color of the text (also of the already written stuff) to the
     * given one.
     *
     * @param color The new text color
     */
    public void setColor(Color color){
        this.color = color;
        update();
    }
     
    /**
     * Sets the background color to the given one.
     *
     * @param background The new background color
     */
    public void setBackgroundColor(Color background){
        this.background = background;
        update();
    }
     
     
    /**
     * returns the text of the text.
     *
     * @return The text of the text
     */
    public String getContent(){
        return content;
    }
 
    /**
     * returns the color of the text.
     *
     * @return The color of the text
     */
    public Color getColor(){
        return color;
    }
 
    /**
     * Returns the background color of the text.
     *
     * @return The background color of the text
     */
    public Color getBackgroundColor(){
        return background;
    }
 
    /**
     * Returns the font size of the text.
     *
     * @return The font size of the text
     */
    public int getFontSize(){
        return fontSize;
    }
}
Fps-Counter class (combines fps with button functionallity):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
 * The fps display shows the current fps in one of two modes: either
 * in realtime (based on only the last frame) or the average (of the
 * last second) (as calculated in packages.tools.Time). When clicked
 * on it it switches modes.
 *
 * @see packages.tools.Time
 * @author RcCookie
 * @version 1.0
 */
public class FpsDisplay extends Button{
    /**
     * The time object that actually calculats the fps.
     */
    protected Time time;
 
    /**
     * Weather the output is the average(=true) or realtime (=false).
     */
    boolean stableMode;
 
 
    /**
     * Constructs a new fps display in stable mode.
     */
    public FpsDisplay(){
        super(new Text("FPS: --", null), 70, 20);
        time = new Time();
        stableMode = true;
    }
 
    /**
     * Constructs a new fps display in the given mode.
     *
     * @param stableMode Weather the display shows stable fps by default
     */
    public FpsDisplay(boolean stableMode){
        super(new Text("FPS: --", null), 70, 20);
        time = new Time();
        this.stableMode = stableMode;
    }
 
 
    /**
     * Runs the time object and updates the text output.
     */
    @Override
    public void run(){
        time.act();
        getText().setContent("FPS: " + currentModeFps());
    }
     
 
    /**
     * Returns the current realtime fps.
     *
     * @return The current realtime fps
     */
    public int fps(){
        return time.fps();
    }
 
    /**
     * Returns the current average fps.
     *
     * @return The current average fps
     */
    public int stableFps(){
        return time.stableFps();
    }
 
    /**
     * Returns the fps in the current mode.
     * @return The current fps in the current mode
     */
    public int currentModeFps(){
        if(stableMode) return stableFps();
        else return fps();
    }
 
 
    /**
     * Returns the duration of the last frame as a fraction of a second.
     *
     * @return The duration of the last frame as a fraction of a second
     * @see packages.tools.Time.deltaTime()
     */
    public double deltaTime(){
        return time.deltaTime();
    }
     
 
    /**
     * Switches modes. Called by the button class whenever the button was clicked.
     */
    @Override
    public void onClick(){
        stableMode = !stableMode;
    }
}
Especially the button class looks very long but it's mostly documentation. You may say now that some of the methods are never used, but that's because this is to be used in various cases not just for the fps counter. To use this, simply create a new class in greenfoot and copy in all the code. After all it is propably easier to download the scenario and grap the packages folder for your scenario.
Roshan123 Roshan123

2020/10/6

#
I can't express it...... Who r u ??? I think you r mad in coding It would be something around 10-20kb(just a guess) Thanks for sharing it But now i can't add it becaz i m much more concerned about my scenario storage after looking at the code I know its below 100kb(the maximum guess) but i want my scenario to work very smoothly
Roshan123 Roshan123

2020/10/6

#
Actually i m newbie in java so its pitty long for me And i wanted it to learn that how does it work and also wanted to add it. Now its not possible for a newbie to learn it
RcCookie RcCookie

2020/10/6

#
Button.java ~21kb ;-) If you want to learn how it works then take a look at the Time class. It does all the neccecary stuff to calculate the fps. This is the act and fps method of the time class simplified to everything that is neccecary for simple fps calculation:
1
2
3
4
5
6
7
8
9
10
11
12
13
long lastMillis;
double deltaTime;
 
public void act(){
    long currentMillis = System.currentTimeMillis();
    deltaTime = (currentMillis - lastMillis) / 1000.0;
    lastMillis = currentMillis;
}
 
public int fps(){
    if(deltaTime == 0) return 2000;
    return (int)(1 / deltaTime);
}
Let's take a look: First off all the current time (in milliseconds, 1000 milliseconds = 1 second) is saved:
1
long currentMillis = System.currentTimeMillis();
"deltaTime" represents the fraction of a second since the last frame. For example, with 10 fps the deltaTime would be 0.1 as the time between each frame is a tenth of a second. We calculate it by getting the defference in time between the last and the current frame. This is a value that represents the milliseconds since the last frame. Now we divide that number by 1000, the length of 1 second. There we have deltaTime.
1
deltaTime = (currentMillis - lastMillis) / 1000.0;
Finally we save the current time for the next frame.
1
lastMillis = currentMillis;
Now we have a value that describes the length of the last frame. Let's take a look at the fps method which calculates the fps from the current deltaTime: The first line checks weather the current deltaTime is 0. If this is the case, the time step since the last frame and the current frame is less than a millisecond. Might seem quick, but with little in the world this is totally possible (Remember, the fps in Greenfoot do not mean the fps that your screen draws but the frames executed per second. Some frames might not be drawn). In this case we simple return 2000 fps (1000 would be a stable 1 millisecond per frame, so it's twice the framerate of what we would notice).
1
if(deltaTime == 0) return 2000;
If however deltaTime is in a normal range, we return 1 divided by deltaTime (as an integer). This means that we essentially count how often a frame of the current length would fit into 1 second.
1
return (int)(1 / deltaTime);
There you go! Fps of the current frame. However, this fps method returns a very precise number for each frame but not a nice average. For that the other code in the time act method is used. But for some simple performance tests, this is totally enough. The problem is that while you can calculate the fps now, you can't output it yet. You may think that you could just print it to the console, but, unfortunatly, the console is pretty slow and itself will slow down your game to like 100 fps even if you could have 1000. So my recomentation would be to use getWorld.showText("FPS: " + fps(), 100, 100); which simply draws the fps onto the world background at the coordinates 100, 100. But that's why I am using the button to print it. Also, the button allowes to switch fps modes between average and precise. After all, "deltaTime" is not only useful for measuring fps. It's actually just a side product. The real purpose is that you can have fps-independent movement and similar. What you can do is for example say:
1
2
3
4
5
double speedPerSecond = 20;
 
public void act() {
    move(speedPerSecond * deltaTime);
}
Since the more often the method is executed per second the smaller deltaTime is, the actor will move 20 pixels per second, no matter if you have your speed slider at max or limiting to 10 fps. Also, this will for some degree smoothen out lag as it will accelerate objects more at lower framerates. Finally, I just wanted to mention that I'm 'only' coding java (and generally) for about 2 years now. I'm sure you can learn this really quickly, too!
Roshan123 Roshan123

2020/10/7

#
Thank u!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! U wasted a lot of ur time i teaching a newbie After looking at the code i knew that my basic is not strong and i have to strive more(actually i knew it already) I have not been taught java. I m learning on my own and my basic is not so strong to understand ur code. Lastly i would like to say u that; when i will be a genius like u then i shall look that how u made fps Initially i thought that fps would be easy and easy to learn but now its not easy for me or a beginner
You need to login to post a reply.