Skip to content

Commit abe79c6

Browse files
author
Mike Barkmin
committed
better timer and timed dot example
1 parent f5e7054 commit abe79c6

File tree

8 files changed

+105
-14
lines changed

8 files changed

+105
-14
lines changed

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,27 @@ You can access the timer objects throught `stage.getTimer()` or
202202
| `boolean everyMillis(int)` | `stage.everyMillis(2000)` | Returns true **roughly** every 2000 Milliseconds |
203203
| `void reset()` | `dog.reset()` | Resets a timer back to 0 |
204204

205+
If you want that a sprite should do something every 2000ms and every 1000ms,
206+
you need two timers. To add a timer you simply call
207+
`sprite.addTimer("timerForMe")`. The timer is than accessable with `sprite.getTimer("timerForMe")`.
208+
209+
Unfortunatly the timer are not on point. Sometimes they are lacking behind.
210+
This happens when the frame rate drops. This can lead to a unwanted rendering
211+
order. For example the pattern which was tried to achive in the example
212+
[TimedDot](#TimeDot) should look like this:
213+
214+
Lila, Lila, Green, Lila, Lila, Green, Clear.
215+
216+
Especially at the beginning of the sketch the frame rate increases slowly to
217+
the desired one. Therefore there are some missing frames in the beginning and
218+
the pattern is messed up. To achive a better result you should use a multiple
219+
of the frame rate for millis. (If not set the standard frame rate is 60). You
220+
can see the difference below.
221+
222+
223+
| Millis multipe of 100 | Millis multiple of 60 |
224+
| :-: | :-: |
225+
| ![timed dot normal](web/assets/timed_dot_100.gif) | ![timed dot 60](web/assets/timed_dot_60.gif) |
205226

206227
### ScratchSound (internally)
207228

@@ -273,6 +294,15 @@ An example which makes use of timers.
273294

274295
![random dot](web/assets/random_dot.gif)
275296

297+
298+
### TimedDot
299+
300+
Source Code: https://github.com/mikebarkmin/processing-library-scratch/tree/master/examples/RandomDot
301+
302+
An example which makes use of timers.
303+
304+
![timed dot](web/assets/timed_dot_60.gif)
305+
276306
## Missing
277307

278308
* blocks which are not listed above are currently missing

examples/TimedDot/TimedDot.pde

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import eu.barkmin.processing.scratch.*;
2+
3+
ScratchStage stage;
4+
DotSprite dot;
5+
6+
void setup() {
7+
size(400, 200);
8+
frameRate(60);
9+
ScratchStage.init(this);
10+
stage = ScratchStage.getInstance();
11+
dot = new DotSprite();
12+
}
13+
14+
void draw() {
15+
dot.draw();
16+
if (stage.getTimer().everyMillis(2400)) {
17+
stage.eraseAll();
18+
}
19+
}
20+
21+
class DotSprite extends ScratchSprite {
22+
DotSprite() {
23+
super();
24+
this.addTimer("timer2");
25+
this.addTimer("timer1");
26+
this.getPen().setSize(20);
27+
this.setOnEdgeBounce(true);
28+
this.setRotation(65);
29+
}
30+
31+
void draw() {
32+
super.draw();
33+
if(this.getTimer("timer2").everyMillis(600)) {
34+
this.getPen().down();
35+
this.getPen().setColor(200);
36+
this.move(20);
37+
this.getPen().up();
38+
}
39+
if(this.getTimer("timer1").everyMillis(1200)) {
40+
this.getPen().down();
41+
this.getPen().setColor(100);
42+
this.move(20);
43+
this.getPen().up();
44+
}
45+
}
46+
}

src/eu/barkmin/processing/scratch/ScratchPen.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
import processing.core.PGraphics;
44

55
import java.util.ArrayList;
6+
import java.util.Stack;
67

78
public class ScratchPen {
89

910
private ScratchColor color = new ScratchColor(120);
1011
private float opacity = 255;
1112
private float size = 1;
12-
private ArrayList<ArrayList<Point>> pointsBuffer = new ArrayList<>();
13+
private Stack<ArrayList<Point>> pointsBuffer = new Stack<>();
1314
private boolean down = false;
1415

1516
public ScratchPen() {
@@ -23,7 +24,7 @@ public ScratchPen(ScratchPen p) {
2324
this.color = new ScratchColor(p.color);
2425
this.size = p.size;
2526
this.opacity = p.opacity;
26-
this.pointsBuffer = new ArrayList<>();
27+
this.pointsBuffer = new Stack<>();
2728
this.pointsBuffer.add(new ArrayList<>());
2829
this.down = p.down;
2930
}
@@ -134,7 +135,7 @@ public void draw() {
134135
int pointsBufferSize = this.pointsBuffer.size();
135136
if (pointsBufferSize <= 0) return;
136137

137-
ArrayList<Point> points = this.pointsBuffer.get(pointsBufferSize - 1);
138+
ArrayList<Point> points = this.pointsBuffer.peek();
138139
int pointsSize = points.size();
139140

140141
buffer.beginDraw();
@@ -144,11 +145,19 @@ public void draw() {
144145
buffer.stroke(point.color.getRed(), point.color.getGreen(), point.color.getBlue(), point.opacity);
145146
buffer.strokeWeight(point.size);
146147
buffer.line(previousPoint.x, previousPoint.y, point.x, point.y);
148+
// remove rendered points
149+
if (this.down == false) {
150+
this.pointsBuffer.pop();
151+
}
147152
} else if (pointsSize == 1) {
148153
Point point = points.get(pointsSize - 1);
149154
buffer.stroke(point.color.getRed(), point.color.getGreen(), point.color.getBlue(), point.opacity);
150155
buffer.strokeWeight(point.size);
151156
buffer.point(point.x, point.y);
157+
// remove rendered points
158+
if (this.down == false) {
159+
this.pointsBuffer.pop();
160+
}
152161
}
153162
buffer.endDraw();
154163
}

src/eu/barkmin/processing/scratch/ScratchSprite.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,11 @@ public void move(float steps) {
356356
if(this.costumes.size() > 0) {
357357
currentCostume = this.costumes.get(this.currentCostume);
358358
}
359-
float costumeWidht = currentCostume != null ? currentCostume.getImage().width : this.pen.getSize();
359+
float costumeWidth = currentCostume != null ? currentCostume.getImage().width : this.pen.getSize();
360360
float costumeHeight = currentCostume != null ? currentCostume.getImage().height : this.pen.getSize();
361361

362362
if (this.onEdgeBounce) {
363-
float spriteWidth = this.show ? costumeWidht : this.pen.getSize();
363+
float spriteWidth = this.show ? costumeWidth : this.pen.getSize();
364364
if (newX > parent.width - spriteWidth / 2 || newX < spriteWidth / 2) {
365365
this.rotation = this.calculateAngleOfReflection(this.rotation, false);
366366
}

src/eu/barkmin/processing/scratch/ScratchStage.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public int getCurrentBackdropIndex() {
103103
*/
104104
public void eraseAll() {
105105
this.penBuffer = parent.createGraphics(parent.width, parent.height);
106+
this.pre();
106107
}
107108

108109

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,33 @@
11
package eu.barkmin.processing.scratch;
22

33
public class Timer {
4-
private int start;
5-
private int lastTime;
4+
private int nextFrame;
65

76
public Timer () {
8-
this.start = ScratchStage.parent.millis();
9-
this.lastTime = this.start;
7+
this.nextFrame = -1;
108
}
119

1210
public int getMillis() {
13-
return ScratchStage.parent.millis() - start;
11+
return Math.round(ScratchStage.parent.frameCount / ScratchStage.parent.frameRate * 1000);
1412
}
1513

1614
public boolean everyMillis(int millis) {
17-
if (ScratchStage.parent.millis() - lastTime > millis) {
18-
lastTime = ScratchStage.parent.millis();
15+
int frameSkip = this.getFrameFromMillis(millis);
16+
if (nextFrame < 0) {
17+
nextFrame = ScratchStage.parent.frameCount + frameSkip;
18+
}
19+
if (ScratchStage.parent.frameCount >= nextFrame) {
20+
nextFrame = ScratchStage.parent.frameCount + frameSkip;
1921
return true;
2022
}
2123
return false;
2224
}
2325

26+
private int getFrameFromMillis(int millis) {
27+
return (int) Math.round(millis * ScratchStage.parent.frameRate / 1000.0);
28+
}
29+
2430
public void reset() {
25-
this.start = ScratchStage.parent.millis();
26-
this.lastTime = this.start;
31+
this.nextFrame = -1;
2732
}
2833
}

web/assets/timed_dot_100.gif

26.4 KB
Loading

web/assets/timed_dot_60.gif

21.5 KB
Loading

0 commit comments

Comments
 (0)