Hello :)

(Forever) Beginner level programmer here!

I have been trying to make a top down driving game, and rather than reinvent the wheel I figured I could take some existing carts and use the code to make a player that uses a sprite that can rotate, and move forward and backward.

I found this post for the sprite rotation, which works exactly as I would like, although I can't really grasp how the function is working: https://www.lexaloffle.com/bbs/?pid=52525 (example1)

Then I found a cart of Asteroids by @mccolgst: https://www.lexaloffle.com/bbs/?tid=29903, stripped out all the stuff I didn't need (example2), and have been going between these 2 carts to try and combine the sprite rotation function with the desired movement.

Unfortunately I hit a wall and my latest effort was example3, but I'm quite lost honestly.

Can anyone shed some light on how these carts work and how I could go about applying a forward movement to a rotated sprite?

Cart #example1-0 | 2022-01-18 | Code ▽ | No License

Cart #example2-0 | 2022-01-18 | Code ▽ | No License

Cart #example3-0 | 2022-01-18 | Code ▽ | No License

P#105335 2022-01-18 18:25

In the third cart in update_p(), your value for the change of angle is 0.1 (a tenth of one), whereas your value for the change of p.a is p.rotspeed, which is 30 (a twelfth of 360). As such these are not in sync.

This addresses that issue by calculating the change to angle by calculation from p.rotspeed. For example in the line ' angle+=p.rotspeed/360'

 ```function update_p() if btn(0) then p.a-=p.rotspeed angle+=p.rotspeed/360 end if btn(1) then p.a+=p.rotspeed angle-=p.rotspeed/360 end p.a%=360 angle%=1 if(angle<0.005 or angle>0.995)angle=0 if btn(2) then p.x+=cos(angle) p.y+=sin(angle) --p.acc=true else --p.acc=false end --p.a=p.a%360 p.x+=p.dx p.y+=p.dy --p.dx*=p.friction --p.dy*=p.friction end```

There are also three extra lines in there:

 ``` p.a%=360 angle%=1 if(angle<0.005 or angle>0.995)angle=0 ```

These just reset the angles to 0.

The first two use modular arithmetic; see: https://en.wikipedia.org/wiki/Modular_arithmetic

For example: 'p.a%=360' makes p.a wrap from 359 to 0.

The third line 'if(angle<0.005 or angle>0.995)angle=0' waits until angle is near 0, then corrects for any errors introduced from dealing with fractions.

P#105344 2022-01-18 21:55

Hey @remcode!

Thank you so much for your very timely and detailed response!!

Thanks a bunch for the explanation and link; lots more to learn here.

Bonus question - I was trying to emulate the movement in the second cart example (the one based on Asteroids), but again I cannot understand what the code is doing. It seems this is what controls the ships forward movement:

if btn(2) then
player.dx+=-sin(player.aim-1).15
player.dy+=cos(player.aim-1).15
end

Again I am not totally clued on why you would interchange sin and cos functions to the x/y values, or what the additional values at the end are affecting. I pasted this snippet into the below cart, and I also tried swapping out p.x and p.y to p.dx and p.dy, but then the ship goes very fast:

``````p.dx+=cos(angle)
p.dy+=sin(angle)``````

So I tried giving a max value for dx/dy but something is off with the direction of movement again.

What could be the simplest way of applying the feeling of accelerated movement to the ship?

Many thanks again!

Cart #tobuzanora-0 | 2022-01-19 | Code ▽ | No License

P#105382 2022-01-19 20:55

By the way, completely amazed by this forums willingness to help newbies like myself. Great community :)

P#105383 2022-01-19 20:57

btw that rotation code is slow/outdated now.
suggest to switch to: https://www.lexaloffle.com/bbs/?tid=38548

P#105404 2022-01-20 06:56

 ```function update_p() --turn ship if btn(0) then p.a-=p.rotspeed angle+=p.rotspeed/360 end if btn(1) then p.a+=p.rotspeed angle-=p.rotspeed/360 end --wrap angle p.a%=360 angle%=1 if (angle<0.005 or angle>0.995) angle=0 if btn(2) then p.dx+=cos(angle)*.15 p.dy+=sin(angle)*.15 end --move ship p.x+=p.dx p.y+=p.dy --wrap to screen local width=32 if p.x<0-width then p.x=127 end if p.y<0-width then p.y=127 end if p.x>127 then p.x=0-width end if p.y>127 then p.y=0-width end --decrease acceleration p.dx*=p.friction p.dy*=p.friction end ```

If the ship is slowing too fast, you might also want to change your value for friction to 0.99 or 0.999, so more of the speed is preserved.

P#105414 2022-01-20 14:52
1

@simonwilson

If you're looking to gain a deeper understanding of what's going on, so you can more easily make such changes, try the following links:

mathsisfun: unit circle

mathsisfun: vectors

Some things will be more or less relevant with Pico-8 (see the Pico-8 manual: Quirks); particularly:

Pico-8 cos and sin expect/use angles from 0 to 1 (the 'Coding Math' channel mentions radians).

Pico-8 inverts the result of the sin function, with the y-axis already inverted, the effect is that the result it gives is in the rotation direction you might expect (anti-clockwise). (In episode 2, the 'Coding Math' channel presenter says that you will find rotation going the other way.)

Many coding channels will be looking at languages other than Lua, and other than Pico-8's altered subset.

P#105464 2022-01-21 09:29 ( Edited 2022-01-22 07:24)

These tutos are great and made for pico-8: https://demoman.net/

P#105470 2022-01-21 16:10

@remcode Many thanks again for the altered code and resources. Its now behaving exactly as I was hoping for, but yes I definitely need to study how this is working.

@merwok Also thanks a bunch for the great resource!

P#105995 2022-01-30 18:51

I realize Pico-8 has limited resolution, however is there any way to get around these jaggies, @simonwilson ?

P#106000 2022-01-30 19:31

@dw817 I'm not the expert on this but I think since the sprite is such a low resolution already, the function is doing its best to make it look correct at all angles, but there is a limit...

If you want something with less jagged pixels then try drawing a larger sprite and that should reduce the effect. Otherwise try the alternative rotation function in the link above from @freds72.

P#106054 2022-01-31 18:24

Hi @simonwilson. I tried his program, still getting jaggies. i guess what I'm looking for which likely hasn't been done yet is something to DITHER the rotation. That is give them softer edges based upon how sharp they appear in rotation.

https://www.lexaloffle.com/bbs/?pid=106060#p

. . .

Just now thinking, how about a program to do a clean rotation every 22.5 degrees ? Does not need fine 0-359.

So it could rotate from 0 to 22.5, 45, 67.5, 90, 112.5, 135, 157.5, 180, 202.5, 225, 247.5, 270, 292.5,315, 337.5 and back to 0 again. 16 total rotation states.

P#106062 2022-01-31 18:48 ( Edited 2022-01-31 19:46)

Back again!

So.... Movement is ok, sprite rotation is ok... But now I cannot make the background pixels transparent.

I checked the spr_r function and I see that it uses a for loop to set the pixels in each frame, so when it comes to the Pset function,
I made the colour a local variable, and tried to set the colour 14 to transparent.

if (xx>=0 and xx<sw and yy>=0 and yy<=sh) then

`````` local colour = sget(sx+xx,sy+yy)

pset(x+ix,y+iy,colour)

if colour == 14 then
palt(14,true)
palt(0,false)
end

print(colour,10,40)``````

end

This didn't work, so I checked the value of Colour by printing it, and sure enough it was the correct value. But then if I set Colour to another value, the numeric value changes, but not the colour it had been set to.... What?!

I thought this would solve the issue but I cannot see why the number can change, but not the colour...

Cart #transparency-0 | 2022-02-05 | Code ▽ | No License

P#106388 2022-02-05 17:11

see my answer, you are not using the ‘right’ rotation function.

P#106389 2022-02-05 17:47

@freds72

I was just about to give up on this but I followed your link with the new function and have managed to implement it to my cart... so finally it is working as I had hoped for. Many thanks!

Cart #car_rotate_transparency-0 | 2022-02-06 | Code ▽ | No License

P#106428 2022-02-06 11:45

@dw817 As you can see in the latest for my cart above, I used the same rotation function but the jaggies are definitely present and I don't have a way around it. The dithering would be nice, but do you think it could be achieved with the limited colours?

I like your idea with the preset 16 rotation states - hope to hear if you decide to develop it more.

P#106429 2022-02-06 11:50 ( Edited 2022-02-06 11:51)