|
Post by hydrophilic on Sept 3, 2014 8:46:01 GMT
There was a really cool thread on the old C128 forum... well for me, because I'm a programming NERD. It was about mirror copy (i.e., reverse the bits in a byte). There were several responses by forum members... and each one was (arguably) better than the last. And when it seemed all the best (debatable) ones had been published by regular forum members, some guy from out of nowhere (sorry don't remember who) came along and posted an excellent (superior?) method.
Well hopefully I can spark that kind of discussion again. With this thread on something simple yet practical.
So what is the best way (in BASIC) to translate a joystick direction into a vector (X,Y values) ? Here is my response...
0 REM INIT 10 FOR I = 1 TO 8 : J = I - 2 20 : DX(I) = (I>1)*(I<5)+(I>5) 30 : DY(I) = (J>1)*(J<5)+(J>5)+(I<3) 40 NEXT 90 SPRITE 2,1,2: REM DEMO 100 DO: J=JOY(2) AND 127 110 : MOVSPR 2,+DX(J),+DY(J) 120 LOOP That simple code lets you move Sprite#2 around the screen with a joystick plugged into port #2. It runs acceptably fast (for BASIC)... although at 1 pixel increments (as coded above) it is not "really" fast... just multiply the DX and DY values by some constant for faster speed (more pixels per LOOP) if you need it.
Maybe YOU know of a better way already? Or maybe you are programming wizard and can create something better in a few seconds? Otherwise, play around for a while (with any/all BASIC methods) until you get something better... and then post your superior response!
|
|
witzo
Windows User
Posts: 19
|
Post by witzo on Sept 27, 2014 21:20:26 GMT
I found that this works quite nicely. Not sure if it's as fast as yours, Hydrophilic. I just set the speed to 5 in the movspr command, could be anything from 1 to 15.
10 scnclr:print"witzo for c-128.freeforums.net" 20 sprite 2,1,2 30 do 40 j=joy(2) and 127 50 movspr 2, (j-1)*45 #abs(j>0)*5 60 loop
|
|
|
Post by hydrophilic on Sept 28, 2014 7:54:56 GMT
Awesome! It is much simpler... no arrays and only a single line:
movspr 2, (j-1)*45 # abs(j>0) * 5
I think it would need to be * 1 to be comparable to my original post, but your method seems superior in any case. Thanks!!
|
|
|
Post by gsteemso on Sept 29, 2014 5:06:13 GMT
This may seem a silly question, but what on Earth is achieved by having an unattached number sign in the middle of the expression like that? I’ve never seen that anywhere else, and there’s no mention of it in Hydrophilic’s BASIC reference pages. Actually, while I’m on the subject, how does that expression even work?
|
|
witzo
Windows User
Posts: 19
|
Post by witzo on Sept 29, 2014 12:41:28 GMT
I remembered that MOVSPR had a way of indicating angle of movement, and looked up the various syntaxes. MOVSPR has a whole range of parameter sets. The one I used is MOVSPR number, angle #speed. So the # indicates speed (from 0 to 15). See the C128D System Guide page on it below. movspr 2, (j-1)*45 #abs(j>0)*5 (j-1)*45 J is a number from 0 through to 8 with 1 being up, subtract 1 for -1..7, multiply by 45 for a compass direction that is the same as the direction pushed. Only now do I realise the direction can become -1*45 for joystick in the middle. But it turns out that that is not a problem, since speed is set to 0 (see below) when that value comes up. #abs(j>0)*5 # indicates that the speed follows. I learned on the VIC20 Denial forum that comparisons could be used mid-code in place of a number, and evaluate to 0 (false) or -1 (true). When j=0 (joystick in the middle), the expression is false (0), *5=0 for speed zero. Any other direction 1..8 gives true (-1), of which the absolute is 1, *5=5 for speed 5.
|
|
|
Post by gsteemso on Sept 30, 2014 3:19:47 GMT
Huh. Learn something new every day. Thanks for explaining that. That actually works out so neatly that I half-suspect the ANGLE # SPEED syntax was meant for this use, or some other closely-related use.
You could fix the -1*45° for joystick sitting still with a second use of the (j>0) comparison. Don’t even need to use ABS() — just multiply the expression by -45 instead of +45.
|
|
|
Post by hydrophilic on Sept 30, 2014 4:08:39 GMT
Gsteemso, you had me really worried when you wrote the # syntax was not documented! I pulled up my MOVSPR page, and the # syntax is documented. Then I was worried that the # syntax was only listed, but not explained how it works. But there is an explanation for the 3 forms of MOVSPR... the third explaining the angle # speed syntax.
Umm, maybe the explanation wasn't clear? (The syntax is obviously messy, but blame CBM for that)
Ah... I did not include an EXAMPLE of the # form. OK, I can fix that.
Um, I noticed from CBM System Guide quoted above that they show 4 forms (note I said here and on my web page there are 3 forms). Well the first 2 that CBM are the same - both are rectangular co-ordinates... one form is relative and the other form is absolute. I guess I should make that clear in my documentation too. Thanks for the feedback guys!
---------
When the joystick is in the middle, the angle may be negative, but nobody cares!! Because the speed will be zero and thus no movement... just like you would expect when not moving the joystick.
The main difference with witzo's code is you loose some control due to the IRQ animation; whereas with the original code you always move in well-defined steps. Both methods have advantages, but witzo's code is much easier to understand... if you know how the # format works. Heck even if you don't understand it, it is easier to type and faster to run
It seems like CBM just hacked the normal polar co-ordinate processing (the distance ; angle format) and changed the distance to a speed... really it is just a distance to move each IRQ.
(Umm, by that logic, the last 2 forms that CBM shows are also the same! So there is really only 2 forms: rectangular and polar. Err... now my head hurts thinking how to explain all this concisely on a web page.)
Edit If anyone cares, I updated my MOVSPR page to include all 6 forms: X absolute, Y absolute (instant) X relative, Y absolute (instant) X absolute, Y relative (instant) X relative, Y relative (instant) Magnitude; Angle (instant) Angle # Speed (temporal)
And like I said above, example for # format added.
I really just want this topic to focus on BASIC sprite movement (any method) so I'll shut up about my webpage now... but thanks for the feedack!! Hopefully the changes will benefit all CBM programmers.
|
|
witzo
Windows User
Posts: 19
|
Post by witzo on Oct 1, 2014 18:58:29 GMT
Huh. Learn something new every day. Thanks for explaining that. That actually works out so neatly that I half-suspect the ANGLE # SPEED syntax was meant for this use, or some other closely-related use. You could fix the -1*45° for joystick sitting still with a second use of the (j>0) comparison. Don’t even need to use ABS() — just multiply the expression by -45 instead of +45. I don't quite understand how to use (j>0) times the angle, but you did point out to me that ABS() was superfluous. Turns out this runs visibly faster!: movspr 2, (j-1)*45 #j>0*-5 Thanks.
|
|
|
Post by hydrophilic on Oct 2, 2014 6:33:24 GMT
Yeah, the ABS is not needed. MOVSPR will accept negative angles. And as stated before, a negative angle with zero magnitude results in no movement (as desired). So Witzo's most recent post seems to be the 'most effecient'.... that is faster to run and simpler to code... COOL
|
|
|
Post by gsteemso on Oct 15, 2014 2:38:25 GMT
When I wrote that the # syntax wasn’t included in the BASIC reference, I hadn’t actually checked the MOVSPR entry, because I was operating under the mistaken assumption that the hash mark was acting as a BASIC operator or something of that sort. I had never seen a hash mark used in Commodore BASIC at all, anywhere, and had no idea how to pick apart the syntax of the original expression.
EDIT: With the obvious exceptions of GET#, INPUT#, PRINT#, and RECORD#, of course, but it’s part of the keyword with those. Not the same thing at all.
|
|