Jump to content
IGNORED

DoubleBack: open participation contest entry thread


Recommended Posts

aka. VBXE for Beginners, Redux
   alternate title: PL65 ftw.

 

Practice makes perfect.  My plan is to do another VBXE for Beginners discussion.
And it might just be me, if so, that's OK - but there is an incentive to join the conversation.

 

This time, the tutorial will center on creating game that will be submitted to ABBUC 2023.
And anyone that wishes to join in on the effort, will be a co-author of the game.  Anyone that posts in the thread is an automatic co-author.   Just jump in - there will be tasks, no experience required.
If you find this thread later and think it is a pity, I'm late.  Unless the contest is over, you aren't late, just jump in.

 

In the first tutorial, I used BASIC.  I did so because BASIC is still a very popular language in the Atari world.  However, BASIC is slow, and that slowness presents a challenge for doing a contest submission. In the first tutorial I worked on a game called Runway 180, and while it was largely written in BASIC, even for that example ultimately assembler will be required to do a version of the game with smooth animations.

 

This time, a new game and a new language.   The language, PL65.  The concern some might have with this choice, is they don't want to learn PL65.  You won't have to!  By this I mean, it doesn't have any particular learning curve. The PL in PL65 stands for "Programming Language".  How apropos!  If you know BASIC, you know most of PL65 already.

 

For example, in basic you learned the concept of a FOR-NEXT Loop.

 

BASIC:

100 FOR A=1 TO 100:NEXT A

 

In PL65, the loop is written like this:

 

FOR A=l TO 100 DO 
NEXT

 

You already understand the PL65 FOR statement, and this feeling of already knowing it, won't change.

Now, if I'm being intellectually honest, perhaps there is some learning involved in taking up PL65.
However, I think you'll understand why I chose it.  That is, it will actually be easier to write the game in PL65, than BASIC.  PL65 compiles to machine code, it creates executables about the speed of "Action" language, and when some assembler is needed, it makes that trivial.

 

Enough! What game?

 

So, the game this time, is a game released for the TRS-80 Coco: Doubleback

 

image.thumb.png.e2a8a4175b75bb01423cd5e40a6e42a6.png


Doubleback may look somewhat like snake, but you can run over your own tail.  
What you cannot do in doubleback is run into the objects on the screen.
And you score points by connecting a loop around an object.

 

See it in action here:

 


VBXE concepts:

 

The new VBXE concepts that will be learned - detecting collisions, using multiple "sprites", drawing overlapping "sprites".  I put "sprites" in quotes, because it isn't really a hardware sprite, but software, we will be using features of the blitter to accomplish these tasks.

 

Homework
--------
I'm not using any source code to do this port.  So - the tasks will be - for those good with sound, what background music will the game have?  For those good with graphics, what 256 color - appropriately sized objects do we need on the screen, any angles on obtaining artwork?  For those good with programming what algorithm or logic should we choose to understand an object has been encircled by any arbitrary closed loop?  For now, the language doesn't matter, just an efficient algo.  Another algo, tracking the tail.

My homework, I will put together a PL65 disk - since not everyone has or likes SDX, I will not choose SDX. I'm also going to make sure chosen will work with OS XL 1.3 ROMS and Altirra OS and I'm going to think about a path for writing code in your favorite Mac or PC text editor and then compiling on PL65 in the emulator.
 

  • Like 2
Link to comment
Share on other sites

First thought:

 

For the tail I would maintain 2 ordered lists:

- the first list would contain the points (coordinates) in which the head changes direction

- the second list would contain the ordered list of direction changes

 

This way we can "play back" the movement of the head: 

1. the tail starts from the last point (and removes it from the list)

2. and starts moving in the direction that is at the last position of the directions' list (and removes it)

3. it moves till it reaches the last coordinates in the points' list (or reaches the head's position if nothing in the list) and go back to step one

 

Seems simple, but needs a buffer management with the length of the buffer, first and last position. We can use the list of points (with the position of the head and tail) to check which is inside the polygon or is it a closed polygon at all.

Edited by jvas
Link to comment
Share on other sites

5 hours ago, jvas said:

First thought:

 

For the tail I would maintain 2 ordered lists:

- the first list would contain the points (coordinates) in which the head changes direction

- the second list would contain the ordered list of direction changes

 

This way we can "play back" the movement of the head: 

1. the tail starts from the last point (and removes it from the list)

2. and starts moving in the direction that is at the last position of the directions' list (and removes it)

3. it moves till it reaches the last coordinates in the points' list (or reaches the head's position if nothing in the list) and go back to step one

 

Seems simple, but needs a buffer management with the length of the buffer, first and last position. We can use the list of points (with the position of the head and tail) to check which is inside the polygon or is it a closed polygon at all.

cool!  When I get off work tonight,  I will setup an environment in order to test the tail.  I will copy an initial setup from another project - so that we have playfield, a player to visualize the head, joystick routine and have the player movement bounded within the edges of the playfield.   That will allow for implementation and testing/finalizing details of the described tail logic.   

 

 

Link to comment
Share on other sites

After today, i'll switch to updates going to github, because otherwise I'll be spamming the thread with uninteresting incremental builds.

 

What we have here is a DOS 2.5 disk with PL65 on it.  Configured for 7 open files, so it'll run.

 

I have a lot of starter code - well I even have the music player that I got from some Atari magazine, I'll look that up layer.

 

But, I had in mind to do a quick little playground for testing the tail using the PLOT command, but spamming the PLOT command seems to crash the atari every time.

 

So, I did a quick FPLOT routine.  Now, to correctly implement FPLOT, I have to read the byte that I want to write too, and flip the bits within the byte.  I know taht - I just haven't done it yet.

 

Becuase - out of time for today.  But I'll work on it again before the weekend.

 

Meanwhile if anyone is interested in checking out PL65 environment.

 

It's DOS 2.5, so from the menu type "L" for Load and then PL65.COM

 

image.thumb.png.66b1e81f0a41c3d2fe5576b3636264be.png

 

In the PL65 program type "1 Compiler"

 

Then here are some choices:

 

image.thumb.png.9041ec00ccc48c24772651b9b494610e.png

 

 

Then you will have compiled it.

 

 

Then you can type "L again and this time load

 

BACK.XEX

 

If you go through all that, all you will see today is, because basically I have a stub for FPLOT (fast plot), and not actually implemented the correct code today, because no time.

 

 

 

image.thumb.png.a8fedf9c7977750d90f147524c03ea5b.png

 

The song is Monkey's spinning Monkey's.

 

After I get the playground setup, will test the tail logic.

 


 

Dos 2.5.atr

Link to comment
Share on other sites

The files have moved to:

 

RobertDupuy/vbxe-fun: Atari VBXE card (github.com)

 

And the download for this project is now called DBACK.ATR

 

I knocked out finishing the "test" code base, which at least needed joystick routines to record movement, and a working fast plot to show the tail.

 

This is a great example of why I like PL65.  Just type in BASIC style syntax, but when it comes to bit manipulation it's assembler that is easier, not basic.

 

PL65 doesn't care if you go in and out of both environments at will:

 

PROC FPLOT(BYTE X,Y)
!fast plot-in dev
BYTE BFLG,RDR,NSCRVAL
BEGIN
 Y=Y-32
 X=X-40
 RDR=X-((X/4)*4)
 CASE RDR
  OF 3 DO BFLG=2 ENDOF
  OF 2 DO BFLG=8 ENDOF
  OF 1 DO BFLG=32 ENDOF
  OF 0 DO BFLG=128 ENDOF
 ENDCASE

 SCRADR=(Y/2)*40+(X/4)+SAVMSC
 NSCRVAL=SCRVAL
 LDA NSCRVAL
 ORA BFLG
 STA BFLG
 SCRVAL=BFLG
END

 

OK, so now that the test environment is setup, the next step will be implementing the suggested tail logic.


 

  • Like 1
Link to comment
Share on other sites

@jvas

 

Uploaded to github, the DBACK.ATR contains both source and xex,  now the most basic tail handling.

PROC MOVEPLAYER(BYTE X,Y)
BEGIN
 EPLOT[TAILX[TAILP],TAILY[TAILP])
 TAILX[TAILP] = X
 TAILY[TAILP] = Y
 FPLOT(X,Y)
 PPLOT(0,X,Y)
 TAILP=TAILP+1
 IF TAILP=172 THEN TAILP=0 ENDIF
END

 

EPLOT is "erase plot" - erase the last entry in the tail

FPLOT is "Fast plot"    - draw the front of the tail

It's just round robin around an array.  Well just for ease, two arrays, one for X points, one for Y points.

 

I read your post, and what I'm reading is a replay of direction and moments in which the player changed direction.  The benefit would be a saving on tracking individual points.   Still there is a need to plot the points to be visible on the screen.

 

The second thought I'm having is about analog input.  Obviously I'm just using the Atari joystick, so far, and indeed that may not change.  I hope as a stretch goal, if time allows, to add support for analog - either a scheme to use a paddle, or something original.  With analog input there would be not just turns of 45 or 90 degrees but a range of arbitrary inputs.

 

If I've missed something, let me know....

 

thanks for the input.

 

I think what further I'm going to do, is setup github with a checklist of tasks to complete the game, and do the code check in, in the normal way - so that people can just view it on the website without a download, and then split out all the code into modules for easier editing in pl65 without a lot of scrolling.

 

I'll work more on the weekend.

 

 

 

 

 

Edited by Mark2008
  • Like 1
Link to comment
Share on other sites

I found these two articles:

1.  Check if a point is inside a polygon: https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/

2.  Which is based on  the algorythm of determinig of the intersection of two segments: https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/

 

  1. We treat the objects in the game as points. For example we can say, that if the center of an object is looped then the object itself is looped. 
  2. We can determine if a new loop is created. Only in this case we have to go on. In the video it seems that not only intersections but when two points next to each other also creates a loop:
    1. The coordinates of the head is the same as one of the other point of the snake
    2. Or the coordinates of the head is next to the one of the other point of the snake
  3. We can separate all points of the "snake" which are part of a loop (need to find out how, more than one loops are possible):
    These are all points from the head toward the tail till we reach the point determined in #2

The 1st algorithm becames simple them:

An object is in a loop, if there are odd number of snake points (determined in #3) whose x coordinate is bigger then the object's x coordinate and the y coordinate is the same as the object's y coordinate

 

There are some tough cases like this:

image.png.131f9b4d8647baafa13441fac9262ab5.png

Edited by jvas
Link to comment
Share on other sites

When counting points that are on the right of the object: if a point is next to the previous point we found in the list, then it it doesn't count. In the example above only the leftmost point of the horizontal green line counts only. Don't know whether I am clear or not :)

Link to comment
Share on other sites

@jvas  oh wow, I disappeared for a while....thansk for finding that. I'm going to read through that this weekend.  honestly I don't know if it helps to talk about my thoughts yet.

I was considering whether, I think they call it ray casting, would work.

 

lets say we are talking about the center of the object, then casting from there a ray in 4 direction to check for collision with the loop.  A surrounded object would meet the loop with all 4 checks. 

 

but nevermind that, I will wrap my mind around the suggestion....just checking in with this post, really, I hope to have time tomorrow to examine th is more closely.

 

Link to comment
Share on other sites

On 1/18/2023 at 9:46 AM, jvas said:

When counting points that are on the right of the object: if a point is next to the previous point we found in the list, then it it doesn't count. In the example above only the leftmost point of the horizontal green line counts only. Don't know whether I am clear or not :)

I found time to read it at lunch.

 

It sounds clear. 

 

1. center point treated as the object - agree

2.  checks on loop creation - agree

3. determine the points that are part of the loop, to me since we catch the loop immediately at is created the start of the loop is the point you just drew, and you trace it back to the overlap - that's the loop

There is no need to worry about more than one loop, previous loops were checked when they were created

 

You've mentioned difficult cases - agreed, some edge cases will have to be coded around....all looks great, I'm excited to try some code with it tomorrow

 

 

Link to comment
Share on other sites

starting work today, the goal:


Create an algorithm, to determine "is the point inside a closed loop" - I do not consider yet, that the loop must be a polygon created from straight lines.   However, it is 1 of 2 methods being considered.

The two concepts being considered:

 

Polygon created from lines method:

With a digital joystick you have 8 directions. If you are pressing up, and then press right, you can consider the time you were pressing up, to be a line.  The time you are pressing right, to be a line.  By recording directional changes, you are recording a list of line segments.

 

By creating a line modeled polygon, code has been written that determines whether a point is within a polygon and handles exceptions by checking whether lines are collinear.

I will implement this method initially PL65, even while I recognize it isn't exactly fair, such high level code will be too slow.   But it will help begin to understand where the CPU time may be spent.  


"just a bunch of pixels" method: 

In this method, you start with the point and cast a ray up, down, left and right.
If any ray fails to intersect with a point in the loop, then the loop hasn't enclosed the point.  Otherwise, it has enclosed the point.  It is possible to fool this method with a false encirclement.

 

image.png.0906d1f9e04390cea2ddb8ace0b8a043.png

 

Extending existing code that models input and loop drawing, i wish to check how many line segments are being created, real world, if considering directional changes as line segment markers.  Secondly, how possible is it to create the exception to the "just a bunch of pixels" false encirclement exception, shown above.


 My expectation is both methods will highly accurate.   The next thing to check is speed.  My expectation is both will be too slow, but optimization will be achieved - then the question becomes level of effort to implement in hand coded assembler.

 

anyway...this is verbose mode...now goign to see what some coding reveals.

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.

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...