Jump to content

8x16 player?

Recommended Posts

If those will be the same color and stacked vertically, just use DOUBLEY. That way you can use a single MOB.


If not, just position the mobs with a coordinate offset. You will need to use 2 MOBs then.

If you don’t have 2 MOBs available, you can still use a single one and multiplex it, but the resulting flickering effect will not look great.

Edited by cmadruga
  • Like 3
Link to comment
Share on other sites

Although Auto Racing uses the EXEC, it uses 4 sprites per car.  Two of those sprites are "stitched together" to create a 16x16 image, and the other two are also "stitched" to the first two for the car's shadow.


In the EXEC, you can define one sprite to always be a certain pixel offset from the one before it, and every time you move the first sprite, they move together.  That may or may not be duplicatable in IntyBASIC, but I'd like to know either way.  It's doable in ECS BASIC, which uses the EXEC as well.

  • Like 1
Link to comment
Share on other sites

I wonder  how you would do that with IntyBASIC. Perhaps if you define an ON FRAME routine that knows which variables you use for sprite coordinates and position the additional/shadow sprites accordingly. It would in theory let you only manage the master sprite, but I don't know if that is a good usage of that mechanism. Of course another way would be to define a subroutine "moveSprites" that handles all sprite movement in one place, though you would still have to offset sprites by hand.


Generally speaking, I think you'd figure it out quite soon. If your logic and code are structured enough so you don't scatter things around, it would be easy to achieve lining sprites next to or onto each other. State machines surely would help as opposed to knee jerk actions across the code.

  • Like 2
Link to comment
Share on other sites


The sprite engine in Christmas Carol uses a similar mechanism.  What the EXEC calls "linked" sprites, I called "overlay objects," because they were used primarily to add secondary colors or details to a sprite.


It works something like this:  When you define your logical sprites, the framework creates a record structure in RAM that includes fields for velocity, animation, position, etc.  Some of it is in 8-bit RAM and some of it in 16-bit RAM, so a look-up table is then constructed with static information such as the memory pointers for the record structure, along with a hard-coded assignment to a MOB.


I called each entry in that table an "Object Record" (OBJ).  In terms of IntyBASIC, it would look like this:

' Define new obeject
Dim #SystemRamVariables(m)
Dim ScratchRamVariables(n)

' Define Object Record
' Data <sysram-pointer>, <scrram-pointer>, <mob-number>
Data VarPtr #SystemRamVariables(0), VarPtr ScratchRamVariables(0), 0

Among the 8-bit RAM fields is a "Status" register, where each bit indicates something about a sprite.  These are flags that indicate such things as whether the object is active, if it should be tested for collisions, if it just entered a new tile in the virtual map and is allowed to change directions, etc. -- and importantly, whether it is linked to a "parent object."

For "overlays" you do a similar thing, except that the memory structures are slightly different (in an effort to conserve RAM, since overlays lack their own velocity and position, etc.).  However, this need not be so, and in fact, I believe that the EXEC allows any object to be linked with every other, so their memory commitments are uniform for all sprites.


The key is that the overlays include a field with the "Object Record" index of their parent object, and an optional X and Y position offset from it.  The offsets are encoded as two nybbles in a single byte (again, to conserve RAM).


The overlays are then added to a similar table with static pointers, following the one for the regular objects, forming essentially one long table for both kinds of objects.  These entries I called "Non-Interactive Object Records" (NIOBJ), which in my head I pronounce just like the name "Niobe."


Fun Fact:  I called them "non-interactive" because they are the same objects I used for software sprites and other elements that do not move on the screen.  Apart from the overlays of the regular sprites, they are also mostly used for static graphical animation elements like snowflakes, droplets, presents, the jack-in-the-box, etc.  In any case, their link to a parent is therefore optional, dynamic, and depends on the need at the moment.


Ultimately, these records are used by the sprite motion and animation engines, which run on every frame.  Because the OBJ and NIOBJ record structures are identical, and because the RAM layout is similar (a NIOBJ has a subset of the fields of an OBJ) the animation engine can just iterate through both tables as one, deference the pointers as necessary, and perform the animation accordingly.


The sprite motion engine is a bit more discriminating.  It too runs through both tables as one, but it tests the "is linked to parent" flag, and if it is true (and assuming that the object is an NIOBJ), it will dereference the parent index and use its current position as the position of the NIOBJ, adjusted by the offset accordingly.


In terms of IntyBASIC, it would look something like this:

' Move all objects
For I = 0 to TotalObjectCount
  ' Get Object Record
  Obj = ObjectTable(I)

  ' Get 8-Bit RAM memory structure

  ' Get parent position if its linked
    ' Get parent object
    ParentObj = ObjectTable( Rec(FLD_PARENT) )

    ' Get parent record
    ParentRec = ParentObject(FLD_SCRATCH_RAM)

    X = ParentRec(X_POS) + Rec(X_OFFSET)
    Y = ParentRec(Y_POS) + Rec(Y_OFFSET)
   X = Rec(X_POS)
   Y = Rec(Y_POS)
  End If

  ' Update MOB with new position
  #MobShadow(X_REGISTER + Rec(MOB_NUMBER)) = X
  #MobShadow(Y_REGISTER + Rec(MOB_NUMBER)) = Y


(Note that this is untested code, straight out of my head, so consider it like pseudo-code.)


All that indirection was necessary in my game to abstract the sub-systems and allow for a flexible framework.  It was also hyper-optimized in tight assembly language in order to reduce memory access and expensive computations.


For an IntyBASIC game all that abstraction may not be needed, so a more straightforward solution could be employed.  Lookup tables and tight memory structures may still apply.



Edited by DZ-Jay
  • Like 1
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...