Jump to content
IGNORED

using $0080 (aka DOUBLEY) in SPRITE


Recommended Posts

Ok, this should be an easy one.

 

I'm trying to figure out exactly how this works.

 

I am assuming it takes the first defined BITMAP you specify and then automatically uses the next one after it?  

 

I have it working, I am just wondering how it works and whether or not I can have it use different colors.

 

my code:

 

    SPRITE 7, HIT + VISIBLE + sx, DOUBLEY + sy, $0801 + 36 * 8
 

This sprite uses DEFINED  BITMAPS 36 and 37.   However, I want 36 to use blue ($0801) but the bottom white ($0807).  Can this be done? 

 

Obviously, the SPRITE displays in all BLUE on the screen because that was the color I used to test it.

 

I am going to look forward to getting some good tips on graphics once this is ready to demo.  I am terrible at using colors.

 

Link to comment
Share on other sites

1 hour ago, Mik's Arcade said:

I am assuming it takes the first defined BITMAP you specify and then automatically uses the next one after it?  

Correct.

1 hour ago, Mik's Arcade said:

I have it working, I am just wondering how it works and whether or not I can have it use different colors.

Different colors are not possible, can only have only one color per sprite.

Link to comment
Share on other sites

17 minutes ago, cmadruga said:

Correct.

Different colors are not possible, can only have only one color per sprite.

 

Interesting. Once I get this game fully working, I am definitely going to need to learn all the tips and tricks to make better graphics. I know I have to make use of overlaying BITMAPS and using the color square mode and whatnot.  For now, I'm just going to have to accept that I am making an ugly game....haha

Link to comment
Share on other sites

I think if the CPU was allowed to change register on the fly, then we could do scanline trick like change sprite color midway down, more than 8 MOBs on screen.

2 hours ago, Mik's Arcade said:

I am assuming it takes the first defined BITMAP you specify and then automatically uses the next one after it?  

Make sure that it is an even number and not odd when using DOUBLEY.  SPRITE36 is fine, but SPRITE33 is not. Found that out very early learning intybasic. 

  • Like 1
Link to comment
Share on other sites

17 hours ago, Kiwi said:

I think if the CPU was allowed to change register on the fly, then we could do scanline trick like change sprite color midway down, more than 8 MOBs on screen.

 

Unfortunately, the STIC does not offer any access to the horizontal blanking interrupt (HBLANK) or any other part of the underlying video hardware on the Intellivision, which is what prevents it from being able to perform video tricks like the Atari VCS, etc.  All it offers is access to graphics memory and internal registers that influence the video display, but no access at all to the actual mechanisms that generate it.

 

The reason we are able to access the vertical blanking interrupt (VBLANK) is because the STIC is "hardwired" to trip an EXEC routine to handle it.  Lucky for us, the designers had the presence of mind to have this low-level routine, in turn, look up an "Interrupt Service Routine" at a predefined memory address in RAM, rather than hard-code it itself.  Changing the pointer in that address during start-up is what allows home-brews to take over the system and bypass the EXEC.  Without that, we would have been stuck writing "EXEC games," with all the constraints and limitations implied in that.

 

Is it possible to modify the hardware to give access to the vertical blanking interrupt?  I do not know, but I suspect it is not.  To my understanding, the STIC was designed to handle the entire video frame generation, and only provides access to VBLANK in order to allow the CPU to prepare all buffers for the next frame.  Once all elements of graphics memory and motion objects are updated, the STIC takes up the job and does its thing without any further input from the CPU.

 

The STIC does interrupt the CPU periodically during active display to gain access to the system memory bus and fetch BACKTAB data as it composes the next frame, but again, we have no control over that.

 

   -dZ.

 

Edited by DZ-Jay
  • Like 2
Link to comment
Share on other sites

8 hours ago, DZ-Jay said:

 

Unfortunately, the STIC does not offer any access to the horizontal blanking interrupt (HBLANK) or any other part of the underlying video hardware on the Intellivision, which is what prevents it from being able to perform video tricks like the Atari VCS, etc.  All it offers is access to graphics memory and internal registers that influence the video display, but no access at all to the actual mechanisms that generate it.

 

The reason we are able to access the vertical blanking interrupt (VBLANK) is because the STIC is "hardwired" to trip an EXEC routine to handle it.  Lucky for us, the designers had the presence of mind to have this low-level routine, in turn, look up an "Interrupt Service Routine" at a predefined memory address in RAM, rather than hard-code it itself.  Changing the pointer in that address during start-up is what allows home-brews to take over the system and bypass the EXEC.  Without that, we would have been stuck writing "EXEC games," with all the constraints and limitations implied in that.

 

Is it possible to modify the hardware to give access to the vertical blanking interrupt?  I do not know, but I suspect it is not.  To my understanding, the STIC was designed to handle the entire video frame generation, and only provides access to VBLANK in order to allow the CPU to prepare all buffers for the next frame.  Once all elements of graphics memory and motion objects are updated, the STIC takes up the job and does its thing without any further input from the CPU.

 

The STIC does interrupt the CPU periodically during active display to gain access to the system memory bus and fetch BACKTAB data as it composes the next frame, but again, we have no control over that.

 

   -dZ.

 

Well, this has gone over my head...haha.

 

But, that's ok. All I know is that there are plenty of people making some great looking games, so it CAN be done.  Right now, I just need to get over the growing pains of actually completing something.

 

I'm almost there. I've got the player able to move and shoot, I've got collision with enemy sprites working and score is being properly recorded. I am just working on getting a bunch of randomized waves of up to 6 enemies at once working and I can call this a working demo for everyone to see.

 

If you guys think it is ok, then I will work on the bonus stages and end game programming and call it a wrap.

 

 

 

 

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hi  all -

 

It's been a while. Had a very busy June and July, but now I'm starting to get back on track with programming.

 

I've got a generic question that I can provide more details (or a video) if needed, but I think an explanation will suffice.

 

I've programmed a bullet and when it collides with an enemy spirte, rather that just have the enemy explode and disappear,  I instead have it plummet from the sky straight down until it hits the bottom of stage, and THEN it splats and disappears.

 

I have this working great but with one major issue:  when this code (a procedure I call using GOSUB) executes, it causes everything else on the screen to wait (ie, freeze).

 

What am I missing to have this piece of code operate independently of everything else around it?

 

let me know if you need more info....

 

thanks all!

 

 

Edited by Mik's Arcade
Link to comment
Share on other sites

I've never done it, but check the ON FRAME GOSUB syntax. I think you could do something like this:

 

  ON FRAME GOSUB bulletmove : REM must only be used once in the program
  [ .. main loop goes here .. ]

bulletmove: PROCEDURE
  IF bulletcounter>0 THEN
    [ move bullet downwards one frame ]
    bulletcounter = bulletcounter - 1
  END IF
  END
Edited by carlsson
Link to comment
Share on other sites

27 minutes ago, carlsson said:

I've never done it, but check the ON FRAME GOSUB syntax. I think you could do something like this:

 


  ON FRAME GOSUB bulletmove : REM must only be used once in the program
  [ .. main loop goes here .. ]

bulletmove: PROCEDURE
  IF bulletcounter>0 THEN
    [ move bullet downwards one frame ]
    bulletcounter = bulletcounter - 1
  END IF
  END

Ok, this is good.....I had a feeling it had to be done during the "ON FRAME" event, but I will have to add additional logic because of course this happens when a bullet collides with a sprite. Should be easy enough to move that logic up to "ON FRAME"..it is something like

 

IF COL6 AND $003F THEN    ' check if bullet hits any enemy sprites

 

thanks!

 

I will give this a go later when I am not stuck at work...lol

Link to comment
Share on other sites

You probably want to use the main loop for all collision detection etc, and whenever it has happened, set some variable/flag that will indicate for the frame routine that it should update the sprite until it has reached its target. In that way, you prevent the entire machine from slowing down as well as the interrupt routine doesn't take more time than it should.

 

I suppose you never programmed "scene demos", but the raster effects on e.g. C64 follow the same principles when it comes to a big text scroll: The main loop waits for a counter to reach 0 before it does the rough scrolling of text, plotting graphics etc. The raster interrupt only shifts the screen position at certain raster rows and reduces the counter for the main loop to pick up. Trying to cram the entire scroller into the raster interrupt would cause tearing and be highly inefficient.

Link to comment
Share on other sites

4 hours ago, carlsson said:

You probably want to use the main loop for all collision detection etc, and whenever it has happened, set some variable/flag that will indicate for the frame routine that it should update the sprite until it has reached its target. In that way, you prevent the entire machine from slowing down as well as the interrupt routine doesn't take more time than it should.

 

I suppose you never programmed "scene demos", but the raster effects on e.g. C64 follow the same principles when it comes to a big text scroll: The main loop waits for a counter to reach 0 before it does the rough scrolling of text, plotting graphics etc. The raster interrupt only shifts the screen position at certain raster rows and reduces the counter for the main loop to pick up. Trying to cram the entire scroller into the raster interrupt would cause tearing and be highly inefficient.

you read my mind.  That is what I am planning to do - use a flag during ON FRAME that only launches the code to move the sprite down to the screen until it hits the bottom.  Then set the flag back to off.   I'm going to try this tomorrow and will report back.  If I can't get it right that I will probably just destroy the sprite without the extra drama.....

 

And no, I never programmed 'scene demos.'

 

I have not done serious programming since the 1990's.  INTYBASIC is my first attempt at getting back into it....lol

Link to comment
Share on other sites

18 minutes ago, Mik's Arcade said:

you read my mind.  That is what I am planning to do - use a flag during ON FRAME that only launches the code to move the sprite down to the screen until it hits the bottom.  Then set the flag back to off.   I'm going to try this tomorrow and will report back.  If I can't get it right that I will probably just destroy the sprite without the extra drama.....

 

This is called a state machine, and it is an elegant way of handling complex behaviour of objects.

 

Rather than treating this as a one-off special case, you should see how to handle your enemy behaviour as an entity that goes through various states, such as "attack," "retreat," "follow," "dying," etc.  Your game loop then can do any necessary action depending on the current state of the object at any given time.

 

Other parts of your game can work in similar ways.  In general, any time that you have something that can change its behaviour over time, you can model it as a state machine.

 

18 minutes ago, Mik's Arcade said:

And no, I never programmed 'scene demos.'

 

I have not done serious programming since the 1990's.  INTYBASIC is my first attempt at getting back into it....lol

 

Link to comment
Share on other sites

50 minutes ago, DZ-Jay said:

 

This is called a state machine, and it is an elegant way of handling complex behaviour of objects.

 

Rather than treating this as a one-off special case, you should see how to handle your enemy behaviour as an entity that goes through various states, such as "attack," "retreat," "follow," "dying," etc.  Your game loop then can do any necessary action depending on the current state of the object at any given time.

 

Other parts of your game can work in similar ways.  In general, any time that you have something that can change its behaviour over time, you can model it as a state machine.

 

 

I think I kinda, sorta do this.....but this is good advice that I will make sure I follow.

Link to comment
Share on other sites

7 hours ago, Mik's Arcade said:

I think I kinda, sorta do this.....but this is good advice that I will make sure I follow.

It's kind of straightforward to implement.  If there is only one state change, you use a Boolean flag, and an If/Else to decide when to execute the special state.

 

If you have more states (e.g., an enemy that has multiple states with different behaviours, a level that can go through multiple phases, etc.), you define your states as a set of numeric values, and test them simply in an ON x GOSUB statement.

 

One very useful aspect that can be driven by a state machine is the sprite animation: your sprite may not only move differently, but may also have a different animation for, say, running vs. walking, vs. shooting, vs. jumping.

 

The important thing to consider is to treat these as different behaviours for different object states, rather than a bunch of unrelated things.

 

In other words, rather than use a flag to know when to shoot, and another unrelated flag that tells you that you need to play a shot sound effect, and have yet another way to know that the player animation needs to change; you treat these all as part of the same behaviour:  The player is shooting, so his animation must change, his movement must adapt, and the game world environment should be affected (e.g., by creating a bullet object, and playing a particular sound effect, etc.).

 

These are all aspects of the same event:  The player entered the "shooting" state.

 

Object states can also influence each other.  For example, an enemy can block a player shot.  You can treat this as another aspect of the same event.  Rather than testing if the action button has been pressed to see if the enemy must defend himself, you have the enemy react to the player state:  The player is in "shooting" state, therefore the enemy should change to "defensive" state.

 

This is closer to how the real world works, where events affect the behaviour of things and they in turn influence or elicit actions and reactions from others.  Your game world is a simulation of some "real" world (imaginary as it may be), after all.


Structuring behaviours this way makes them easier to manage.  It makes the game world more stable, which makes it easier to troubleshoot.  It also makes it consistent, which allows the player to learn the rules and adapt easily, and gives a sense of fairness.

 

   dZ.

Edited by DZ-Jay
  • Like 1
Link to comment
Share on other sites

If you are interested, here are a few resources on the topic:

 

The official, "computer sciency" name is Deterministic Finite State Machine, or just Finite State Machine (FSM); and it is the core of video game engines and the basis of gameplay AI.


Do not be scared by the technical name, its meaning is actually quite straightforward:

  • It is a state machine because it is a machine (i.e., a thing that does work) that can have multiple states that influence its behaviour;
  • It is "finite" because it has a limited and known number of states, and can only change between them;
  • It is "deterministic" because it can be in exactly one state at a time, and at any time you can tell which state the machine is in.

 

So, an object, agent, or environment (machine) that can change to any one of a limited number (finite) of known behaviors or phases (states), and whose current state is always known or can be inferred from its behaviour (deterministic) — hence a Deterministic Finite State Machine.

 

You don't have to worry too much about all that, but it is useful to understand because you will see them called FSM or DFSM around the Interwebz.

 

   dZ.

Edited by DZ-Jay
  • Like 1
Link to comment
Share on other sites

thanks for all the tips. This all makes sense and it good programming habits in general.  I think it is always easy to start out with everything organized, but the code can quickly spiral out of control if you don't keep these items in mind.

 

I still have not had time to really dig into the code.....I swear tomorrow will be the day!  Work has been very busy so I have no been in the mood to code after.

Link to comment
Share on other sites

well, trying to get this working during "ON FRAME" was a disaster....lol.

 

I think for now I will shelve this code and just get the rest of the game done first. For now, the enemies will just explode and disappear when hit...

 

I'm almost done with the base game loop, so I'd rather focus on getting this to work from game start to game over first.  

 

Then I can add bells and whistles like sound, music, and extra effects.

 

I will come back to this eventually....I want it to work just like the coin-op.

Link to comment
Share on other sites

How are the enemy programmed?  You can probably change the behavior by branching to another behavior. I usually use several arrays for enemy attribute.  objectID(4), objectx(4),objecty(4), objectb(4)
Oh don't use 'on frame' btw. Create a new procedure, and name it ObjectBehavior:procedure.  Then do for i=0 to 4.  Then on objectID(i) goto KO,Normal,Fall . I think if I remember correctly, KO(kickout[Do nothing]) is 0, then Normal is 1, your enemy routine, Fall would be the enemy falling would be 2. Don't forget to add next i.  Then add gosub ObjectBehavior to your main game loop.  When colliding, then do objectID(1)=2 to change it to be falling, and turn off interact bit for the sprite so it won't retrigger repeatly.

The structure should look like this,

ObjectBehavior:procedure
for i=0 to 4
on objectID(i) goto KO,Normal,Fall
Normal:
enemy routine etc.
goto KO 'so it doesn't run the Fall routine, and it's ok to use a goto jump in a procedure.
Fall:
objecty(i)=objecty(i)+1
if objecty(i)>=100 then objecty(i)=0;objectx(i)=0;objectID(i)=0;
KO:
next i
return
end

I have made a game sample that uses the code I use for my games. It's old and hopefully it's useful.

 

  • Like 1
Link to comment
Share on other sites

2 hours ago, Kiwi said:

How are the enemy programmed?  You can probably change the behavior by branching to another behavior. I usually use several arrays for enemy attribute.  objectID(4), objectx(4),objecty(4), objectb(4)
Oh don't use 'on frame' btw. Create a new procedure, and name it ObjectBehavior:procedure.  Then do for i=0 to 4.  Then on objectID(i) goto KO,Normal,Fall . I think if I remember correctly, KO(kickout[Do nothing]) is 0, then Normal is 1, your enemy routine, Fall would be the enemy falling would be 2. Don't forget to add next i.  Then add gosub ObjectBehavior to your main game loop.  When colliding, then do objectID(1)=2 to change it to be falling, and turn off interact bit for the sprite so it won't retrigger repeatly.

The structure should look like this,

ObjectBehavior:procedure
for i=0 to 4
on objectID(i) goto KO,Normal,Fall
Normal:
enemy routine etc.
goto KO 'so it doesn't run the Fall routine, and it's ok to use a goto jump in a procedure.
Fall:
objecty(i)=objecty(i)+1
if objecty(i)>=100 then objecty(i)=0;objectx(i)=0;objectID(i)=0;
KO:
next i
return
end

I have made a game sample that uses the code I use for my games. It's old and hopefully it's useful.

 

Wow.....this is a great sample. thanks for putting it together.

 

I'm not going to lie, I think I am in a bit over my head with this programming, but I will keep at it.  I've been leaning on Oscar's code for Pumpkins because the enemy behavior is similar to what I am making.

 

I do like the idea of creating small programs like this to test out specific techniques to help you flesh out a full game.

Link to comment
Share on other sites

  • 1 month later...

it's nice to see the board is still active and there are lots of new programmers. I love reading their questions and the answers everyone provides.

 

I have not been programming as much as I would like lately, but I will say that I have been making slow progress.

 

I'm ALMOST ready to show off some work.  Soon I plan on releasing I would say is an alpha version of my game for some feedback, constructive criticism and some pity....haha. The game will be playable from start to finish and will only be missing the bonus stages. Of course, I'll have some questions on how to improve things.

 

maybe in a week or 2....

Link to comment
Share on other sites

  • 4 weeks later...

YES!

 

I finally figured out how to make the ninja plummet from the sky to their deaths.

 

I took a deep dive into Oscar's Pumpkin Master code and now I fully understand how it makes an array of SPRITES move about in a defined pattern.  I just needed to create a new 'state' for the Spite to just stop moving along the X and just move straight down on the Y until it splats on bottom row before I wipe it out.

 

Fun stuff.

 

Is there any way to close a topic now that this is resolved?

Link to comment
Share on other sites

13 minutes ago, Mik's Arcade said:

YES!

 

I finally figured out how to make the ninja plummet from the sky to their deaths.

 

I took a deep dive into Oscar's Pumpkin Master code and now I fully understand how it makes an array of SPRITES move about in a defined pattern.  I just needed to create a new 'state' for the Spite to just stop moving along the X and just move straight down on the Y until it splats on bottom row before I wipe it out.

 

Fun stuff.

 

Is there any way to close a topic now that this is resolved?

Yes:  You just ... stop posting on it. :)

 

    -dZ.

Link to comment
Share on other sites

1 hour ago, Mik's Arcade said:

it just seems weird there is no option to close it.  It funny when I look at a topic that could be a couple of years old, and then one new random comment brings it back from the dead....haha

That's because it's a discussion forum, not a Q&A portal, like Quora or StackOverflow. ;)

 

All that said, it's an interesting point ... I wonder if @Albert would consider extending AA to include a Q&A system like those, or if something like that is even available for the current forum software.

 

It would be great for the technical areas, such as the many device-specific programming sections.

 

    -dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

50 minutes ago, DZ-Jay said:

That's because it's a discussion forum, not a Q&A portal, like Quora or StackOverflow. ;)

 

All that said, it's an interesting point ... I wonder if @Albert would consider extending AA to include a Q&A system like those, or if something like that is even available for the current forum software.

 

It would be great for the technical areas, such as the many device-specific programming sections.

 

    -dZ.

Yes, the forum does support Q&A type forums, and people can vote for the best answer(s) so they rise to the top. I think an admin/mod can then select the best answer so it is pinned directly under the question.  I haven't really seen a particular need for them, but I'd be happy to use them if there's a need.

 

image.png

 

 ..Al

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