Jump to content

Recommended Posts

A question on timing of sprite movement in 7800Basic, I traditionally use decimal for controlling speed. 7800Basic supports this, but is it better to use a frame counter to trigger a move? Recommendations welcome! Thanks.

Speed = 0.2
X = X + Speed

Share this post


Link to post
Share on other sites

I'm still in the 2600 camp but it should still apply ..

 

I usually increment a counter variable at the beginning of the main loop. Using bitwse operations I can decided when to move:

 

Basically, the code below moves the player every other frame.

 

main

counter = counter + 1

if counter{0} then player0x = player0x + 1

Share this post


Link to post
Share on other sites

When you add numbers with fixed point mathematics what's actually happening is that the system adds up the factions first (which represent the number of 256ths), then if the number rolls over past 256 the processor sets the carry flag, then when the integer parts of the number are added up it'll add an extra 1 if the carry flag is set.

If you want to try it yourself I've added the assembly for 16 bit addition below.

 

asm

clc

lda lowByte1

adc lowByte2

sta newLowByte

lda highByte1

adc highByte2

sta newHighByte

End

Share this post


Link to post
Share on other sites

Frame counters might be a bit more complicated to handle manually. Doing fixed point variables lets the math keep track of the frame counting for you.

Share this post


Link to post
Share on other sites

I've done it both ways. There are pros and cons. A frame counter lets you easily balance your routines, if you find you need to split your routines across frames for CPU reasons, and uses less memory than sub-pixel. Using sub-pixel movement allows for smoother speed transitions, which provides an easy way to ramp up difficulty.

 

With Salvo, I took a bit of a mixed approach. There are 11 enemies to move, so every other frame the enemy movement routine is called, and this bit of code is at the top of that routine...

 

    if paldetected=0 then enemytick=enemytick+levelspeed[temp1]:if !CARRY then return
    if paldetected=1 then enemytick=enemytick+levelspeedpal[temp1]:if !CARRY then return
    [...]
    data levelspeed
        $a0,$a0,$b0,$b0,$c0,$c0,$d0,$d0
        $d0,$e0,$e0,$e0,$f0,$f0,$f0,$ff
end
    data levelspeedpal
        $c0,$c0,$d3,$d3,$E6,$E6,$F9,$F9
        $F9,$FF,$FF,$FF,$FF,$FF,$FF,$ff
end

This is pretty much a sub-pixel "speed" routine, but lacking the top 8 bits. The maximum speed allowed is nearly "1". (technically nearly 0.5, since it's called every other frame)

 

You might notice the game's pal speed tops out around level 10. In practice it seems to be a non-issue, because I don't believe anybody has ever reached double-digit levels before.

  • Like 1

Share this post


Link to post
Share on other sites

I believe you can though I've not tried it myself.

There is a roughly 128 byte limit to what you can do after a THEN statement due to how branching works on the 6502, so unless you're not doing much in the loop you may be better off using a gosub or goto to jump to your loop elsewhere.

Share this post


Link to post
Share on other sites

Works for me. I did a quick sanity check...

 

 a=5
 b=0
 if a=5 then for x = 0 to 3:b=b+2:next

        displaymode 320A
main
        clearscreen
        plotchars 'b=' 0 5 0
        plotvalue ascii 0 b 1 16 0
        drawscreen
        goto main

Which spits out "b=8" if a=5, and "b=0" otherwise, as expected.

Share this post


Link to post
Share on other sites

Works for me. I did a quick sanity check...

 

 a=5
 b=0
 if a=5 then for x = 0 to 3:b=b+2:next

        displaymode 320A
main
        clearscreen
        plotchars 'b=' 0 5 0
        plotvalue ascii 0 b 1 16 0
        drawscreen
        goto main
Which spits out "b=8" if a=5, and "b=0" otherwise, as expected.

 

 

 

Thanks for checking :)

 

 

Also with sprites I have made an assumption that maybe wrong....

 For num_enemy = 0 to 4
   plotsprite enemy 0 x y frame
 next
 

Can you only use the image once? The guide doesn't specify this. cheers.

Share this post


Link to post
Share on other sites

You can use plot any given sprite image as many times as you like.

 

In your example you don't modify the x and y in the loop, which would result in 5 "enemy" images at the exact same location. Maybe that's your issue?

Share this post


Link to post
Share on other sites

You can use plot any given sprite image as many times as you like.

 

In your example you don't modify the x and y in the loop, which would result in 5 "enemy" images at the exact same location. Maybe that's your issue?

 

 

Thanks was just a quick type up, i'm not seeing any turn up at this point.

 

code is:

 for check = 0 to rats
 tempX = ratX[check] : tempY = ratY[check]
 tempFrame = ratFrame[check]
 plotsprite rat1 4 tempX tempY tempFrame
 next

Share this post


Link to post
Share on other sites

Have you imported multiple 'rat' images? The frame parameter is optional but depending on what's in the ratFrame array it might be drawing an empty image.

Also keep in mind that large x and y values will 'draw'the sprite outside of the visible screen area

  • Like 1

Share this post


Link to post
Share on other sites

Have you imported multiple 'rat' images? The frame parameter is optional but depending on what's in the ratFrame array it might be drawing an empty image.

Also keep in mind that large x and y values will 'draw'the sprite outside of the visible screen area

 

 

Its a bit weird, yes has multiple images, I only briefly looked at it last night, Ill do some more troubleshooting over the weekend.

 incgraphic rat1.png
 incgraphic rat2.png
 incgraphic rat3.png

Share this post


Link to post
Share on other sites

resolved my missing rat issue :)

 

Another question the if you use the POKECHAR do you need to then re-plot the screen and save it again for the restore command? this is to change a tile.

pokechar map1 TileX TileY 20 12 $30 

Share this post


Link to post
Share on other sites

Assuming "map1" is a ram location, you don't have to re-plot. You can just restore the ram contents however you populated them in the first place. e.g. plotchars, memcpy, etc.

Share this post


Link to post
Share on other sites

When compiling the program and assembling. Is there a way to have DASM show what symbol it is not resolving. I keep running into "UNRESOLVED SYMBOL LIST" and spend hours trying to find the one misspelled label. I tried adding a "-l" parameter to the dasm in the .bat file, but did not help.

Share this post


Link to post
Share on other sites

Assuming "map1" is a ram location, you don't have to re-plot. You can just restore the ram contents however you populated them in the first place. e.g. plotchars, memcpy, etc.

 

This was with the plotmap map1 0 0 0 20 12 can i not use pokechar map1 TileX TileY 20 12 $30 to flip a tile?

Share this post


Link to post
Share on other sites

Depends on whether "map1" is a ROM data statement, or some bytes of RAM. plotmap works with both, so I can't tell what you're doing from just the plotmap command.

 

If it's ROM (ie. "map1" is the label from a data statement) then you can't pokechar. If it's RAM, then sure.

 

For a ram-based plotmap example, there's a "ramcharmap" in the 7800basic sample directory.

Share this post


Link to post
Share on other sites

Depends on whether "map1" is a ROM data statement, or some bytes of RAM. plotmap works with both, so I can't tell what you're doing from just the plotmap command.

 

If it's ROM (ie. "map1" is the label from a data statement) then you can't pokechar. If it's RAM, then sure.

 

For a ram-based plotmap example, there's a "ramcharmap" in the 7800basic sample directory.

 

I'm using the below is this RAM or ROM?

incmapfile level_1.tmx

Im thinking about swapping to using data statements so I can have colored tiles and tiles I can modify.

Share this post


Link to post
Share on other sites

That would be ROM. When you import a map or graphics you're essentially just defining the raw data for some part of the chip that gets burned, so where code is converted to a numerical representation, data is just copied across. As RAM is volatile you can't assume data will be there until you write it there. So if you have data representing tile values in a level, you can define that as data in the ROM, then when the game starts you can copy that data to a section of RAM that you've designated as being where the tiles are read from during the game. If you draw a tile-map that's pointing at the tiles in ROM it'll never change because you can't change ROM, but if you draw a tile-map pointing at your copy in RAM you can do all sorts of things with it and change it on the fly.

 

As the 7800 doesn't have a colour-map like machines with a more traditional tile based display when you plot your maps they will always have the same palette regardless of what you change your tiles to unless you clear and redraw your map.

 

I apologise for the rambling, I'm not sure if I've made any sense.

  • Like 1

Share this post


Link to post
Share on other sites

That would be ROM. When you import a map or graphics you're essentially just defining the raw data for some part of the chip that gets burned, so where code is converted to a numerical representation, data is just copied across. As RAM is volatile you can't assume data will be there until you write it there. So if you have data representing tile values in a level, you can define that as data in the ROM, then when the game starts you can copy that data to a section of RAM that you've designated as being where the tiles are read from during the game. If you draw a tile-map that's pointing at the tiles in ROM it'll never change because you can't change ROM, but if you draw a tile-map pointing at your copy in RAM you can do all sorts of things with it and change it on the fly.

 

As the 7800 doesn't have a colour-map like machines with a more traditional tile based display when you plot your maps they will always have the same palette regardless of what you change your tiles to unless you clear and redraw your map.

 

I apologise for the rambling, I'm not sure if I've made any sense.

 

Thanks heaps that makes things a lot clearer :) I need to re-look at maps and re-engineer my game, there was a PLOTMAPFILE.BAS sample that shows three tilesets being using for multiple colours which appeals. I saw that SCROLL.BAS too which is amazing and would match my platformer well.

Share this post


Link to post
Share on other sites

I'm having some trouble with boxcollision. I have drawn a very simple map with some 2-pixel high lines (plotted as sprites), then as I try to draw boxcollision boxes over them, it seems to work randomly. I check in four if statements first which way the player is moving (one if statement for each direction), then if they're colliding with the box, if both are true, I push the player back the way they came so they act like barriers. I'm aware this is far from efficient, I was just trying to get something up and running.

 

It may be coincidence, but it's mostly sprites on the left side of the screen that don't work, however I drew a box on the left side without checking the direction and it worked ok, but it seemed to have a small gap in it where the player should've been colliding but wasn't. I tried changing the x and y coords of this box and sometimes it would collide and sometimes not. There's also another line which is like this. Some sprites are exactly the same as another except, for example, the y axis of the collision box, but one works and one doesn't. I've even drawn the exact same line straight after another, just with something else after the 'then' of the if statement and the first one works but not the second. One line i drew directly across from another, so the only difference is the x value, I gradually pushed the x value back by 16 pixels at a time and after about x-value 20 or so, the player stopped colliding with it (but seemed to continue to collide with the further right side of the line). So I'm preety baffled as to what's going on. The code is just a modified version of the 'simple' file in the samples folder with the colliding added.

 

The sprites don't go outside the visible screen area and I doublechecked to make sure all the values, etc were correct. I put the debug collision boxes both before and after all the other collision if statements and they seemed to work the same.

 

Anyone know what I'm doing wrong?

Share this post


Link to post
Share on other sites

The only thing that comes to mind - if your game has one of the objects partially off-screen during collisions, you need to use the "set collisionwrap on" setting.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...