QB64.org Forum

Active Forums => Programs => Topic started by: dajan on January 03, 2020, 03:37:13 am

Title: Hello physics
Post by: dajan on January 03, 2020, 03:37:13 am
This is kind of hello world program for some basic 2D ball physics (acceleration, friction, gravity, inelastic collision) implemented with the aim of using the fewest code lines and variables possible. This of course limits it's fidelity.

Hit W, S, A, D keys to accelerate the ball.

Code: QB64: [Select]
  1.     CLS
  2.     vx = ((x < 20 OR x > 620) * 1.9 + 1) * (vx - _KEYDOWN(ASC("d")) + _KEYDOWN(ASC("a"))) * 0.99
  3.     vy = ((y < 20 OR y > 460) * 1.9 + 1) * (vy - _KEYDOWN(ASC("s")) + _KEYDOWN(ASC("w"))) * 0.99 + 10 / 60
  4.     x = x + vx - (x < 20) + (x > 620)
  5.     y = y + vy - (y < 20) + (y > 460)
  6.     CIRCLE (x, y), 20, 7
  7.     _DISPLAY
  8.     _LIMIT 60
  9.  

/Edit: further code enhancements collected

Let's keep on concise coding, now sacrificing 5 more lines to build some game logic into the "engine":

Code: QB64: [Select]
  1. t = TIMER + 90
  2.     CLS
  3.     vx = ((x < 20 OR x > 620) * 1.9 + 1) * (vx + (x < 200 AND y > 250) * _KEYDOWN(ASC("d")) / 2 - (y > 250) * _KEYDOWN(ASC("a")) / 2) * 0.99
  4.     vy = ((y > 460) * 1.9 + 1) * (vy + (x < 200 AND y > 250) * _KEYDOWN(ASC("s")) / 2 - (x < 200 AND y > 250) * _KEYDOWN(ASC("w")) / 2) * 0.99 + 0.17
  5.     x = x + vx - (x < 20) + (x > 620)
  6.     y = y + vy + (y > 460)
  7.     p = ((p = 0) + 2 * ((p = 1 OR p = 2))) * (y > 200 AND y < 250 AND ABS(580 - (x - vx / vy * (y - 200))) < 30 AND vy > 0)
  8.     s = s - (p = 1)
  9.     PRINT "Time:"; _ROUND(t - TIMER), "Score: "; s
  10.     DRAW "BM0,250C2dR200D230BM530,200C4R100C" + STR$(7 + p) + "TA-15D100H15D20H15D20H15D20TA15U100"
  11.     CIRCLE (x, y), 20, 6
  12.     _DISPLAY
  13.     _LIMIT 60
  14. LOOP UNTIL _KEYDOWN(27) OR (TIMER > t AND y > 250)
  15.  

Time to add some bit more advanced features. Ball-rim collisions would be nice:

Code: QB64: [Select]
  1. t = TIMER + 90
  2.     CLS
  3.     vx = ((x < 25 OR x > 615) * 1.9 + 1) * (vx + (x < 200 AND y > 250) * _KEYDOWN(ASC("d")) - (y > 250) * _KEYDOWN(ASC("a"))) * 0.987
  4.     vy = ((y > 455) * 1.9 + 1) * (vy + (x < 200 AND y > 250) * _KEYDOWN(ASC("s")) - (x < 200 AND y > 250) * _KEYDOWN(ASC("w"))) * 0.987 + 0.327
  5.     vd = SQR(vx ^ 2 + vy ^ 2)
  6.     rx(1) = 520: ry(1) = 200: rx(2) = 620: ry(2) = 200 'rim position
  7.     FOR i = 1 TO 2
  8.         dd = SQR((rx(i) - x) ^ 2 + (ry(i) - y) ^ 2)
  9.         nx = ((vx * (rx(i) - x) + vy * (ry(i) - y)) * -vx - (vx * (ry(i) - y) - vy * (rx(i) - x)) * -vy) / vd / dd * 0.9
  10.         ny = ((vx * (ry(i) - y) - vy * (rx(i) - x)) * -vx + (vx * (rx(i) - x) + vy * (ry(i) - y)) * -vy) / vd / dd * 0.9
  11.         vx = (dd < 25) * -nx + (dd >= 25) * -vx
  12.         vy = (dd < 25) * -ny + (dd >= 25) * -vy
  13.     NEXT i
  14.     x = x + vx - (x < 25) * 2 + (x > 615) * 2
  15.     y = y + vy + (y > 455) * 2
  16.     p = ((p = 0) + 2 * (p <> 0)) * (y > 210 AND y < 240 AND ABS(570 - (x - vx / vy * (y - 200))) < 25) * ((vy < 0) * 2 + 1)
  17.     s = s - (p = 1) + (p = -1)
  18.     net = -((x > 500 AND x < 620 AND y > 200 AND y < 300) AND (p > 0 OR ABS(net) > 0)) * _ROUND((x - 570) - ((x > 570) * 2 + 1) * (y - 250) * 0.3) * 0.9
  19.     PRINT "Time:"; _ROUND(t - TIMER), "Score: "; s
  20.     FOR i = 1 TO 20: CIRCLE (x, y), i * 25 / 20, 6: NEXT
  21.     DRAW "BM0,250C2R200D230BM520,200C4R119D1L119D1R119D20H20C7M-" + STR$(30 - net) + ",100M-10,-15M-10,15M-10,-15M-10,15M-" + STR$(30 + net) + ",-100"
  22.     _DISPLAY
  23.     _LIMIT 60
  24. LOOP UNTIL _KEYDOWN(27) OR (TIMER > t AND y > 250)
  25.  
Title: Re: Hello physics
Post by: romichess on January 03, 2020, 05:37:43 pm
Thank you. This is the perfect example to get started!
Title: Re: Hello physics
Post by: OldMoses on January 03, 2020, 08:41:26 pm
That was fun, who knew you could get so much amusement out of 11 lines of code?
Title: Re: Hello physics
Post by: bplus on January 03, 2020, 08:51:18 pm
I am betting the ball is accelerated more than once with each key press.
Title: Re: Hello physics
Post by: dajan on January 04, 2020, 03:11:24 am
Bplus, indeed, the ball keeps accelerating as long as you hold the key.

OldMoses,  I wondered if it can be squeezed under 10 lines, without chaining commands of course, but probbably not.
Title: Re: Hello physics
Post by: DANILIN on January 04, 2020, 07:27:59 am
Code: [Select]
CIRCLE (x, y), 20, 7
powerful washer

Code: [Select]
FOR i = 1 TO 10: CIRCLE (x, y), 10 + i, 5: NEXT
Title: Re: Hello physics
Post by: STxAxTIC on January 04, 2020, 09:22:07 am
I really liked this demo. Crammed to pounds of physics in a 5 pound bag, no doubt.
Title: Re: Hello physics
Post by: Qwerkey on January 04, 2020, 11:07:27 am
I am in agreement.  Rather pleasing for seemingly concise code.
Title: Re: Hello physics
Post by: TempodiBasic on January 04, 2020, 12:50:08 pm
yeah!
welcome physics, where are  you form?
This fine example let me remember this  https://en.wikipedia.org/wiki/La_Linea_(TV_series) (https://en.wikipedia.org/wiki/La_Linea_(TV_series))
Title: Re: Hello physics
Post by: dajan on January 04, 2020, 01:01:54 pm
Ok guys, glad you liked it. Let's keep on concise coding, now sacrificing 5 more lines to build some game logic into the "engine":

Try to guess the game rules on your own :o)

Code: QB64: [Select]
  1. t = TIMER + 90
  2.     CLS
  3.     vx = ((x < 20 OR x > 620) * 1.9 + 1) * (vx + (x < 200 AND y > 250) * _KEYDOWN(ASC("d")) / 2 - (y > 250) * _KEYDOWN(ASC("a")) / 2) * 0.99
  4.     vy = ((y > 460) * 1.9 + 1) * (vy + (x < 200 AND y > 250) * _KEYDOWN(ASC("s")) / 2 - (x < 200 AND y > 250) * _KEYDOWN(ASC("w")) / 2) * 0.99 + 0.17
  5.     x = x + vx - (x < 20) + (x > 620)
  6.     y = y + vy + (y > 460)
  7.     p = ((p = 0) + 2 * ((p = 1 OR p = 2))) * (y > 200 AND y < 250 AND ABS(580 - (x - vx / vy * (y - 200))) < 30 AND vy > 0)
  8.     s = s - (p = 1)
  9.     PRINT "Time:"; _ROUND(t - TIMER), "Score: "; s
  10.     DRAW "BM0,250C2dR200D230BM530,200C4R100C" + STR$(7 + p) + "TA-15D100H15D20H15D20H15D20TA15U100"
  11.     CIRCLE (x, y), 20, 6
  12.     _DISPLAY
  13.     _LIMIT 60
  14. LOOP UNTIL _KEYDOWN(27) OR (TIMER > t AND y > 250)
  15.  
Title: Re: Hello physics
Post by: dajan on January 04, 2020, 01:23:04 pm
TempodiBasic I'm from Slovakia, if you are asking me. I remember LaLinea, liked to watch it on TV, it has its cool minimalistic style and was pretty funny.
Title: Re: Hello physics
Post by: bplus on January 04, 2020, 01:25:55 pm
Hi dajan,

Is the game of HORSE known in Slovakia?
Title: Re: Hello physics
Post by: FellippeHeitor on January 04, 2020, 01:35:54 pm
That's SO cool!
Title: Re: Hello physics
Post by: dajan on January 04, 2020, 03:48:34 pm
Hi bplus, no, I didn't know of HORSE bsaketball mod. Actually it took me 1 wikipedia and 2 YT videos to understand what is that about :o)
Title: Re: Hello physics
Post by: dajan on January 04, 2020, 04:04:10 pm
FellippeHeitor, thanks!
Title: Re: Hello physics
Post by: johnno56 on January 04, 2020, 04:12:51 pm
Just a quick question. When the "ball" is "at rest" on the bottom of the screen, is there a way to prevent the ball from "jittering"? Maybe not the right word... The ball seem to be moving up and down ever so slightly... I'm hoping the problem is with the program. If not then I am left with the obvious conclusion that my already failing eyesight is getting worse... lol
Title: Re: Hello physics
Post by: SierraKen on January 04, 2020, 04:34:58 pm
Dajan, I hope you don't mind but I took your first code example and made the screen larger, made the circle smaller, filled in the circle, and added a graphical trail to the ball. This is an awesome gravity example, thanks!

Code: QB64: [Select]
  1. _TITLE "Bouncy Ball Demo"
  2. SCREEN _NEWIMAGE(800, 600, 32)
  3.     vx = ((x < 5 OR x > 795) * 1.9 + 1) * (vx - _KEYDOWN(ASC("d")) + _KEYDOWN(ASC("a"))) * 0.99
  4.     vy = ((y < 5 OR y > 595) * 1.9 + 1) * (vy - _KEYDOWN(ASC("s")) + _KEYDOWN(ASC("w"))) * 0.99 + 10 / 60
  5.     x = x + vx - (x < 5) + (x > 795)
  6.     y = y + vy - (y < 5) + (y > 595)
  7.     CIRCLE (x, y), 5, _RGB32(255, 255, 255)
  8.     PAINT (x, y), _RGB32(255, 255, 255)
  9.     _DISPLAY
  10.     LINE (0, 0)-(800, 600), _RGBA(0, 0, 0, 40), BF
  11.     _LIMIT 60
  12.  
Title: Re: Hello physics
Post by: TempodiBasic on January 04, 2020, 05:14:27 pm
Hello Dajan
Welcome to the QB64forum
fine basket game!
Well Lalinea join us. :-)
Title: Re: Hello physics
Post by: dajan on January 04, 2020, 06:12:47 pm
johnno56, good point. This is the result of sparse coding, all boundary conditions are not treated properly in code. Normally, there should be some test for the ball being under the floor and align it with floor then.

SierraKen - be my guest! I put it here firstly to see if others can make it into something interesting. And that trailing fireball is awesome effect indeed. I noticed the firebal leaves the last dark shaded circle unerased, is that indtended?
Title: Re: Hello physics
Post by: SierraKen on January 04, 2020, 08:07:56 pm
Thanks Dajan! I don't exactly know why the fireball does that, or why that code even does what it does. I've been using it for about half a year now myself and got it from Bplus. It has something to do with making it transparent for using the number 40. You can experiment with different numbers if you wish and read the QB64 Wiki page here, But this page doesn't mention the trailing effect itself.  https://www.qb64.org/wiki/RGBA (https://www.qb64.org/wiki/RGBA)
Title: Re: Hello physics
Post by: dajan on January 05, 2020, 06:25:13 pm
Time to add some bit more advanced features. Ball-rim collisions would be nice, but it also means giving up my original code minimalism idea. Never mind, I think it is woth it.
What do you think:

Code: QB64: [Select]
  1. t = TIMER + 90
  2.     CLS
  3.     vx = ((x < 25 OR x > 615) * 1.9 + 1) * (vx + (x < 200 AND y > 250) * _KEYDOWN(ASC("d")) - (y > 250) * _KEYDOWN(ASC("a"))) * 0.987
  4.     vy = ((y > 455) * 1.9 + 1) * (vy + (x < 200 AND y > 250) * _KEYDOWN(ASC("s")) - (x < 200 AND y > 250) * _KEYDOWN(ASC("w"))) * 0.987 + 0.327
  5.     vd = SQR(vx ^ 2 + vy ^ 2)
  6.     rx(1) = 520: ry(1) = 200: rx(2) = 620: ry(2) = 200 'rim position
  7.     FOR i = 1 TO 2
  8.         dd = SQR((rx(i) - x) ^ 2 + (ry(i) - y) ^ 2)
  9.         nx = ((vx * (rx(i) - x) + vy * (ry(i) - y)) * -vx - (vx * (ry(i) - y) - vy * (rx(i) - x)) * -vy) / vd / dd * 0.9
  10.         ny = ((vx * (ry(i) - y) - vy * (rx(i) - x)) * -vx + (vx * (rx(i) - x) + vy * (ry(i) - y)) * -vy) / vd / dd * 0.9
  11.         vx = (dd < 25) * -nx + (dd >= 25) * -vx
  12.         vy = (dd < 25) * -ny + (dd >= 25) * -vy
  13.     NEXT i
  14.     x = x + vx - (x < 25) * 2 + (x > 615) * 2
  15.     y = y + vy + (y > 455) * 2
  16.     p = ((p = 0) + 2 * (p <> 0)) * (y > 210 AND y < 240 AND ABS(570 - (x - vx / vy * (y - 200))) < 25) * ((vy < 0) * 2 + 1)
  17.     s = s - (p = 1) + (p = -1)
  18.     net = -((x > 500 AND x < 620 AND y > 200 AND y < 300) AND (p > 0 OR ABS(net) > 0)) * _ROUND((x - 570) - ((x > 570) * 2 + 1) * (y - 250) * 0.3) * 0.9
  19.     PRINT "Time:"; _ROUND(t - TIMER), "Score: "; s
  20.     FOR i = 1 TO 20: CIRCLE (x, y), i * 25 / 20, 6: NEXT
  21.     DRAW "BM0,250C2R200D230BM520,200C4R119D1L119D1R119D20H20C7M-" + STR$(30 - net) + ",100M-10,-15M-10,15M-10,-15M-10,15M-" + STR$(30 + net) + ",-100"
  22.     _DISPLAY
  23.     _LIMIT 60
  24. LOOP UNTIL _KEYDOWN(27) OR (TIMER > t AND y > 250)
  25.  

Edit: Prevented double score detection and added some mass to ball and rim.

Edit2: If you found rim bounces weird, you were right. Formulas were messed up, now it is correct (I hope).

Edit3: Made code even shorter removing 13 unnecesery lines
Title: Re: Hello physics
Post by: Qbee on January 05, 2020, 07:46:42 pm
Time to add some bit more advanced features. Ball-rim collisions would be nice, but it also means giving up my original code minimalism idea. Never mind, I think it is woth it.
What do you think:

Was fun :)

I added "a$ = INKEY$" as last line to make a screenshot: 10 Points isn't bad, or ?

Title: Re: Hello physics
Post by: dajan on January 06, 2020, 04:06:47 am
10 is not bad at all, I had to beat that :o)
Crucial is not to look at the time at the end.
Title: Re: Hello physics
Post by: DANILIN on January 06, 2020, 04:47:21 am
powerful ball

Code: [Select]
'CIRCLE (x, y), 25, 6
FOR i = 1 TO 25: CIRCLE (x, y), i, 6: NEXT
Title: Re: Hello physics
Post by: TempodiBasic on January 06, 2020, 05:32:53 am
@Dainilin
Fine ball !

@dajan
it is the first time that I see embed on the same row of code  calculation and control of  conditions.
Is it an ancient tecnique of spaghetti code to shrink dimensions of source code?
Thanks to share
Title: Re: Hello physics
Post by: dajan on January 06, 2020, 05:50:25 am
DANILIN - Now, that seems to be a proper ball :o)

TempodiBasic - I guess you can call it that :o) It might have been preferred approach in ancient times, when each byte mattered, but my original idea was a challenge to squeeze entire game to fewest line codes and variables possible.
Title: Re: Hello physics
Post by: TempodiBasic on January 06, 2020, 01:36:13 pm
Hi Dajan
just to smile
I have tried to use your tecnique on the same row of calculation and valutation of conditions...
but I have got no good results, my ball stucked when it touched every edge ...
sigh! So I tryed to add IF THEN to see if I have made a bad control of conditions.... but nothing...
So next step I go to trace value of variable on the screen, (for a so little program I don't disturb vWatch) and i see that variables never pass trough the edges!.... Sigh!
then one of mine criticist neuron said me that I have forgotten to test the condition of equality so when variables gained the edge they are not more changed by routine and never went trough the edges so they never have been corrected! And so they stucked the ball.
Naturally I have tried to use condition in calculation and not to simulate physics so don't search for bouncing or gravity effects.
It has been a test to use this tecnique of shrinking.

This is the basic concept
Code: QB64: [Select]
  1. xC = 100: yC = 100: rC = 20: cC = 6
  2.  
  3.     CLS
  4.     CIRCLE (xC, yC), rC, cC: PAINT STEP(0, 0), cC, cC
  5.     a$ = INKEY$
  6.     yC = yC - 5 * (yC >= 20 AND yC <= 460) * (a$ = "W" OR a$ = "w") + 5 * (yC >= 20 AND yC <= 460) * (a$ = "S" OR a$ = "s") - 10 * (yC < 20) + 10 * (yC > 460)
  7.     xC = xC + 5 * (xC >= 20 AND xC <= 620) * (a$ = "D" OR a$ = "d") - 5 * (xC >= 20 AND xC < 620) * (a$ = "A" OR a$ = "a") + 10 * (xC > 620) - 10 * (xC < 20)
  8.     _DISPLAY
  9.     _LIMIT 30
  10. LOOP UNTIL a$ = CHR$(27)
  11.  

Thanks to share the idea
Title: Re: Hello physics
Post by: dajan on January 06, 2020, 03:23:36 pm
TempodiBasic, nice one, i see you're getting there :o)
Btw, why did you go with 10 * (...) for boundary correction, 5 * (...) works better there for me. Also INKEY$ has limits for only 1 movement at cycle, you cant go diagonal this way.

Edit: You can delete a lot of this code and it still works:

Code: QB64: [Select]
  1. xC = 100: yC = 100: rC = 20: cC = 6
  2.     CLS
  3.     CIRCLE (xC, yC), rC, cC: PAINT STEP(0, 0), cC, cC
  4.     a$ = INKEY$
  5.     yC = yC + 5 * (a$ = "W" OR a$ = "w") - 5 * (a$ = "S" OR a$ = "s") - 5 * (yC < 20) + 5 * (yC > 460)
  6.     xC = xC - 5 * (a$ = "D" OR a$ = "d") + 5 * (a$ = "A" OR a$ = "a") + 5 * (xC > 620) - 5 * (xC < 20)
  7.     _DISPLAY
  8.     _LIMIT 30
  9. LOOP UNTIL a$ = CHR$(27)
  10.  
Title: Re: Hello physics
Post by: TempodiBasic on January 06, 2020, 03:40:39 pm
I agree with all your feedback
1.
 to manage more keys  (key combo) better QB64 keywords _KEYHIT or _KEYDOWN than old QB45 methods INKEY$ or INP
2.
 10 has been a test for correction that I forgot there :-)
Thanks