File: RPS-Sim-2.swf-(33 KB, 800x600, Other)
[_] Rock Paper Scissors Anonymous 01/23/23(Mon)05:32:07 No.3491789
I just made this in Macromedia Flash 8. Curious to see if Ruffle will play it.
Marked for deletion (old).
>> [_] Anonymous 01/23/23(Mon)09:51:31 No.3491795
Neat! Unfortunately, after about 30 or so seconds, it starts to run unbearably slow.
>> [_] Anonymous 01/23/23(Mon)10:46:10 No.3491799
>>3491789
>Winner is scissors
neat
>> [_] Anonymous 01/24/23(Tue)04:07:58 No.3491824
This is really cool. A gaggle of rocks was on the left side of screen, a wide stripe of scissors
in the middle and a few papers on the right side. The scissors slew all of the papers, so there
was nothing protecting the scissors from the stones and they were all massacred.
>>3491795
It's trying to do 100*99 collision checks up to 30 times per second. That's every single object
on the stage doing hitTest() on every other clip on the stage regardless of how near or far they
are, no binning or other non-trivial optimizations.
>> [_] Anonymous 01/24/23(Tue)05:57:12 No.3491827
>>3491824
I added early outs for collision detection, but it only made the CPU use worse. Even in the
native player, CPU use almost doubled. Perhaps it's the String comparison. Maybe using Ints would
be a lot faster.
>> [_] Anonymous 01/24/23(Tue)06:29:52 No.3491828
i could already see where this was going when there was no more paper
>> [_] Anonymous 01/24/23(Tue)07:43:46 No.3491829
>paper has a 1% edge at spawn
>>3491824
>no binning or other non-trivial optimizations
Since there is nothing asymmetrical about the collisions, the number of checks could be very
trivially halved by only checking objects that come after the current object in the array. Which
forms a triangle:
A: B C D
B: C D
C: D
D:
Instead of a square:
A: B C D
B: A C D
C: A B D
D: A B C
I would also be concerned about 10000 array.length calls in a loop. Flash is too dumb to optimize
things like this so you must do it yourself. Store the length in a variable beforehand and
compare the counter to that. Or even better: set the counter to array.length(-1) and count
backwards towards zero so you're only dealing with primitives and constants rather than
repeatedly requesting a property (that stays the same anyway) from a class.
>>3491827
ActionScript 2 doesn't distinguish between ints and doubles. In fact it doesn't care at all.
Whatever type you declare a variable as in your code doesn't matter, the compiler scrubs it right
off and it's figured out at runtime.
>> [_] Anonymous 01/24/23(Tue)13:09:20 No.3491840
ROCK SUPERIOR CHOICE
>> [_] Anonymous 01/24/23(Tue)13:13:56 No.3491842
paper won for me
>> [_] Anonymous 01/25/23(Wed)09:07:04 No.3491863
>>3491829
>ActionScript 2 doesn't distinguish between ints and doubles. In fact it doesn't care at all.
Whatever type you declare a variable as in your code doesn't matter, the compiler scrubs it right
off and it's figured out at runtime.
I wasn't referring to that. I use "Rock" "Paper" "Scissors" to define what type each object is.
Flash has to perform string comparisons to figure out what type each object is. Instead I could
make Rock = 1, Paper = 2, Scissors = 3 and remove the need to compare strings.
Considering that adding a few extra string comparisons to optimise things actually made it
slower, I'm guessing string comparisons are really slow.
Simple additional logic like e.g.
If obj1.type == obj2.type
then don't hitTest
and if obj1.type == "Rock" && obj2.type == "Scissors"
then also don't hitTest (No point because the outcome will be the rock remains a rock), etc.
All while caching the result from calling obj1.type and obj2.type so that repeated method calls
weren't made
just made it much more computationally intensive rather than actually optimising things.
>> [_] Anonymous 01/25/23(Wed)10:11:46 No.3491864
>>3491863
>If obj1.type == obj2.type then don't hitTest
I see what you mean, doing preliminary checks here is slower than the amount of time it saves.
Especially since you're only doing rectangular hitTests which are very fast anyway.
>and if obj1.type == "Rock" && obj2.type == "Scissors"
>then also don't hitTest (No point because the outcome will be the rock remains a rock), etc.
Here I got lost. You have a winner and a loser, why not go through and see if they touch and
loser switches shape? This is where triangular loops come into play.
Here's an example of what I'm getting at, if I'm not completely mistaken this should be
multitudes faster than what you have:
var i, j, obj1
for (i = 0; i < len; i++) {
____obj1 = array[i] // cache
____for (j = i+1; j < len; j++) {
______if (obj1.hitTest(array[j])) {
__________hit(obj1, array[j])
________}
____}
}
function hit(mc1, mc2) {
____if (mc1.type == 0) {
________if (mc2.type == 1) mc1.type = 1
________if (mc2.type == 2) mc2.type = 0
____} else if (mc1.type == 2) {
________if (mc2.type == 2) mc1.type = 2
________if (mc2.type == 0) mc2.type = 1
____} else {
________if(mc2.type == 0) mc1.type = 0
________if(mc2.type == 1) mc2.type = 2
____}
}
Do you see what is going on here? Note how obj2 isn't cached, since caching itself takes time and
the vast majority of time it's not called more than once.
>> [_] Anonymous 01/25/23(Wed)10:58:46 No.3491866
[code]
Just a test
This should totally be enabled on /f/
[/code]
>> [_] Anonymous 01/25/23(Wed)12:43:05 No.3491870
>>3491866
You'd have to kill someone here to get a mods attention and even then I doubt they would do
anything
>> [_] Anonymous 01/25/23(Wed)19:28:53 No.3491881
>>3491864
>var i, j, obj1
>for (i = 0; i < len; i++) {
>____obj1 = array[i] // cache
>____for (j = i+1; j < len; j++) {
>______if (obj1.hitTest(array[j])) {
>__________hit(obj1, array[j])
>________}
>____}
>}
>
>function hit(mc1, mc2) {
>____if (mc1.type == 0) {
>________if (mc2.type == 1) mc1.type = 1
>________if (mc2.type == 2) mc2.type = 0
>____} else if (mc1.type == 2) {
>________if (mc2.type == 2) mc1.type = 2
>________if (mc2.type == 0) mc2.type = 1
>____} else {
>________if(mc2.type == 0) mc1.type = 0
>________if(mc2.type == 1) mc2.type = 2
>____}
>}
Again, I'm not referring to this. I'm referring to a different optimisation technique based on
the fact that by nature of the game rules optimisations can be made around the object types. I.E.
Rock vs Rock = Rock, so why bother checking their collisions if nothing would happen even if they
did collide? Same goes for Rock vs Scissors = Rock, Scissors vs Paper = Scissors, Paper vs Rock =
Paper. In all of these instances it doesn't make sense to hitTest because if they did collide,
nothing would happen. These are the early-outs I implemented after posting the SWF here. Instead
of making the game faster, just made it slower.
>> [_] Anonymous 01/25/23(Wed)20:20:49 No.3491884
Paper was about to win, there were only two scissors left and then paper would have beaten the
rest of the rock, but one scissor escaped, converted all the paper, then rock won.
>> [_] Anonymous 01/25/23(Wed)20:22:13 No.3491885
>>3491870
I want to know what the /f/ mass killing would even look like. Mowing down a street rave to
Infected Mushroom? Killing schoolgirls while screaming about beef stroganoff?
>> [_] Anonymous 01/25/23(Wed)21:38:21 No.3491887
op try this:
function checkCollision(movieClip, objects)
{
/**/var myframe = movieClip._currentframe; // NEW
/**/if (myframe === 1) myframe = -1; // NEW (ignore the check if our type is undecided, otherwise
it messes up spawning somehow)
/**/for (var i = 0; i < objects.length; i++)
/**/{
/**//**/if (objects[i]._currentframe !== myframe) // NEW
/**//**/{
/**//**//**/if (movieClip.hitTest(objects[i]))
/**//**//**/{
/**//**//**//**/return objects[i];
/**//**//**/}
/**//**/}
/**/}
}
removes the slowdown when there are many things colliding for me
>> [_] Anonymous 01/25/23(Wed)22:19:16 No.3491889
>>3491864
>____obj1 = array[i] // cache
don't micro-optimize when there are bigger things to fix!!!!!!!!!!!!!!!!! if you're comparing
enough objects that property lookup is what's slowing you down, then maybe try to reduce those
comparisons instead
i guess your array thing is doing that but i just wanted to say
>> [_] Anonymous 01/25/23(Wed)23:23:25 No.3491891
>>3491889
>i guess your array thing is doing that
Yep, that's why I was comfortable doing that little caching optimization; I assumed I had already
solved the "big problem" here, although I may have overlooked something as I wrote it hasty and
tired.
>>3491887
I wanted to check the metrics for this one but noticed that the more cramped up the place is, the
faster everything runs. Turns out the loop halts when it finds the first object to collide with,
ignoring all subsequent ones even if they might be "more relevant" hits. So if a scissor is
touching two rocks at once, there is 50% chance it won't register a hit until another one of the
rocks leaves from vicinity, or an even earlier rock comes in contact with it. Something like that.
Naturally it follows that the more rocks touch a scissor, the lesser the chance any single rock
will be the "first" one.
I thought it had something to do with "prefer 1 vs 1 fight situations" but now I think it might
be a bug.
OP, can you verify if this is the program's intended behavior?
>> [_] Anonymous 01/26/23(Thu)01:50:23 No.3491895
>>3491881
>I.E. Rock vs Rock = Rock, so why bother checking their collisions
Good point, that becomes even more relevant as the game goes on since more and more objects are
of the same shape and can ignore each other.
But setting aside more complex algos based on spatial data structures and the like, I still think
a refined bounds check procedure between two objects (hitTest() calls with shapeFlag=false are
already relatively fast!) wouldn't be significantly slower than the string comparisons, which I
assumed you were still doing as you told the optimisations you tried weren't that successful.
That's why I just put everything in the if-tree at the end.
>Rock vs Scissors = Rock, Scissors vs Paper = Scissors, Paper vs Rock = Paper
>In all of these instances it doesn't make sense to hitTest because if they did collide, nothing
would happen
This is precisely why I suggested only checking each pair once. All objects run the same
code/react the same way to collisions so it's symmetric. I don't know how to explain it better
but this meaningfully slows down the rising curve of required operations as you add more objects,
it's the best you'll get before moving onto more complicated algorithms.
https://en.wikipedia.org/wiki/Triangular_number