Jump to content



0

2 frames(sprites) moving around


10 replies to this topic

#1 freehabitat OFFLINE  

freehabitat

    Chopper Commander

  • 113 posts
  • Location:Vienna, AUSTRIA

Posted Sun Jan 20, 2008 8:02 AM

Hello,...

so far i solved my problem with the size of playersprites. one thing i did not solved is that what i called beaming...

if i move my sprite in any directions out of the playfield it sould appear on the opposite side, very common for some games.
as you can see if you try my code, it works in 3 directions very well. if i move my sprite to the bottom it moves "to fast" to the top.

can you see?!



by the way,.. what other possibilitys are to do big frames moveing around by useing joystick ?


thanks,
Thomas

Attached Files


Edited by freehabitat, Sun Jan 20, 2008 8:12 AM.


#2 SeaGtGruff OFFLINE  

SeaGtGruff

    River Patroller

  • 4,543 posts
  • Location:Georgia, USA

Posted Mon Jan 21, 2008 1:57 AM

I'm going to answer your last question first...

View Postfreehabitat, on Sun Jan 20, 2008 9:02 AM, said:

what other possibilitys are to do big frames moveing around by useing joystick ?
As I see it, you have only three to five options-- use sprites, use the playfield, use color changes, or maybe you could use video blanking. The fifth option would be to use some combination of the first four options.

The best option would be to use sprites, since they're movable objects, anyway. For a frame or box, you'd probably want to use the players, since they're the only sprites that are more than 1 bit (or pixel) wide. The problem is, the players can be set to only three different sizes-- single width (each bit or pixel is 1 color clock wide), double width (each bit or pixel is 2 color clocks wide), or quadruple width (each bit or pixel is 4 color clocks wide). That puts a limit on how wide of a frame you can draw with a player, unless you use one or more tricks. For example, you could create a larger 48-pixel wide frame using the "score" trick, but that would mean you'd have only one frame, since both players would need to be used to create just the one frame. Or you could draw two frames, each with one player, and use flickering to make bigger frames.

You could also use the missiles and the ball, but since they're each just 1 pixel wide, you'd have to use some tricks to try to create a frame with them, and even then, the frame might not be as wide as you'd like.

Or you could use the players and the missiles together, which could give you slightly wider frames than if you'd used just the players by themselves.

The second option would be to use the playfield to draw a frame. The advantage would be that you could draw the frame as wide as the screen, and/or as tall as the screen. The disadvantage is that the playfield resolution is much lower that the sprites' resolution, so a frame drawn with the playfield could be moved horizontally only 4 color clocks at a time-- it would not move around as smoothely as a sprite could.

The third option would be to draw a frame by changing colors while the scan line is being drawn. For example, you could draw a frame using just the background color register. Color changes can occur every 3 color clocks-- or rather, they can occur on boundaries that are spaced 3 color clocks apart, whereas two consecutive color changes cannot be closer that 9 color clocks apart. That culd give you a horizontal motion that's just a tiny bit better than using the playfield, but it would probably be very tricky to write a kernel to draw a frame this way and yet be able to move it around on the screen.

The fourth option-- using video blanking-- is basically like a variation of using the color-changing option, so it has all the problems of that method, except it's actually more restrictive, because you'd be stuck with drawing a black frame (since video blanking is actually where you "turn off" the scanning beam, hence no colors can be drawn in the area where video blanking is being used).

The fifth option is to use some combination of the other methods. For example, you could draw the horizontal sides of a frame using the playfeld, and use 2 copies of a player or missile to draw the vertical sides, and then you'd need to carefully move the horizontal playfield lines around while you're moving the vertical player lines around.

Or you could draw the horizontal lines using color changes, and draw the vertical lines using 2 copies of a player or missile.

You should be aware, though, that many of the techniques I described above would require writing a custom kernel in assembly language-- you couldn't do them in batari Basic using the canned kernels.

View Postfreehabitat, on Sun Jan 20, 2008 9:02 AM, said:

if i move my sprite in any directions out of the playfield it sould appear on the opposite side, very common for some games.
as you can see if you try my code, it works in 3 directions very well. if i move my sprite to the bottom it moves "to fast" to the top.
This is because of the way the video display and the TIA work. When you position a sprite near the right edge of the screen so that part of it extends past the right edge of the screen, the TIA draws the rest of the sprite at the left side of the screen. This is automatic, and requires no extra programming on your part. In fact, if you want an object to slide into view at the side of the screen, or slide off the side of the screen, without part of it wrapping around to the other side of the screen as it's sliding onto or off of the screen, then you have to do something special, like change its shape to make the "offscreen" portion be "turned off" (i.e., replace the 1 bits with 0 bits).

On the other hand, the video screen doesn't have wraparound in the vertical direction; if something starts to move off of the top or bottom of the screen, it doesn't simultaneously start to appear at the bottom or top of the screen. You *can* make a sprite do a "vertical wraparound" that way, but the way you have to do it is by drawing part of the sprite at the top of the screen, and drawing the other part of the sprite at the bottom of the screen, so that it *appears* to be wrapping around. That isn't too difficult to do in assembly language, as long as you've written your kernel to let you do that, but it's trickier to do in batari Basic, since batari Basic uses a "canned" kernel that doesn't lend itself to those kinds of techniques.

However, you *can* do it in batari Basic, and it isn't all that difficult, but you have to be clever-- and careful. Basically, you must define the player so it has two copies-- a top one and a bottom one-- with a lot of blank lines between them, spaced apart so that the extra copy doesn't start to appear at the top or bottom of the screen until the main copy has started to slide off of the screen. And then you have to manipulate the player's lo pointer, the player's height, and the player's y position to draw it just right depending on which vertical position you want it to have.

I've modified your "frames" program to allow the larger frame to wraparound from top to bottom, or vice versa, using this technique, but I remarked out the code for moving the smaller frame around, because I haven't made the modification for the smaller frame yet. I'm going to post the modified code now, but I'm not going to try to explain it tonight-- I'm going to wait until another night, when I've had time to fix the smaller frame to work the same way.

Michael

frame1.png

frame2.png

frame3.png

frame4.png

frame5.png

Attached Files



#3 freehabitat OFFLINE  

freehabitat

    Chopper Commander

  • 113 posts
  • Location:Vienna, AUSTRIA

Posted Mon Jan 21, 2008 6:09 AM

Hello Michael,...

so far i trye coding on a simple way,.. without using multikernel hacks. this will be used for later programms whan i am more into it.


Quote

I've modified your "frames" program to allow the larger frame to wraparound from top to bottom, or vice versa, using this technique

thats brilliant! more effectfull than i thought.


Quote

The best option would be to use sprites, since they're movable objects, anyway

jep, iīll try to do a animated sprite in 3 size,.. every time you press fire-button the size change to the next shape.

i will post the code later in the evening (MEZ-time :) )



thank for advice!!!

tom

#4 freehabitat OFFLINE  

freehabitat

    Chopper Commander

  • 113 posts
  • Location:Vienna, AUSTRIA

Posted Mon Jan 21, 2008 5:51 PM

Hello again,..

i was checking the code now,... and i am burning to know more about your trix :)

so i tried to use the modification also for the second frame but i did not got that following line:

const p0lo=#<playerL017_0


thatīs the first thing i dont exactly know,... const is called p0lo or p1lo= and what is the rest?! anyway,...


but i think i got some other parts of the modification.
you made the playersprite so large that only one full frame can be showen in the playfield, if you go out of the playfield you can see the second frame comeing in on the opposite side. very clever... itīs just about conting lines and keeping everysing symetric, isnīt it ?

well,... i am excited to know more,...

bye Tom

#5 freehabitat OFFLINE  

freehabitat

    Chopper Commander

  • 113 posts
  • Location:Vienna, AUSTRIA

Posted Tue Jan 29, 2008 8:22 AM

Hello,...

i tried a little but did not come to a positiv conclution.

so how can i use this constante with the second playersprite :| ??

const p0lo=#<playerL017_0

i tried tu use a second constante:
const p1lo=#<playerL017_0
and tried with settings of the playerL017 ....
it was not possible to compile.


please let me kow ..


tom

Attached Files


Edited by freehabitat, Tue Jan 29, 2008 9:24 AM.


#6 SeaGtGruff OFFLINE  

SeaGtGruff

    River Patroller

  • 4,543 posts
  • Location:Georgia, USA

Posted Tue Jan 29, 2008 10:18 PM

View Postfreehabitat, on Tue Jan 29, 2008 9:22 AM, said:

Hello,...

i tried a little but did not come to a positiv conclution.
Eeep, sorry that I never posted anything further! First, I'm going to give some preliminary discussion.

There are basically three ways to move an object off the side of the screen:

(1) You can let the sprite wrap around to the opposite side of the screen, such that part of the sprite is visible at one edge of the screen, and the rest of the sprite is visible at the opposite edge of the screen. In other words, as the sprite begins to move off of one side of the screen, it simultaneously begins to move onto the opposite side of the screen. Due to the way the Atari 2600 draws the sprites on the scan line, this type of transition occurs automatically when moving left-to-right or right-to-left, although you *do* need to adjust the sprite's x coordinate appropriately as its leftmost edge leaves one side of the screen and reenters on the opposite side of the screen. But this type of "wraparound" transition does *not* occur automatically when moving top-to-bottom or bottom-to-top. If you want *that* to happen, you must do some special programming to make it happen-- or *appear* to happen.

(2) You can let the sprite disappear gradually off of one side of the screen, *without* reappearing simultaneously at the opposite side of the screen. This type of transition does *not* occur automatically in either direction-- horizontally or vertically-- but it's easier to do in the vertical direction. In fact, depending on how the display kernel is written, it may occur automatically when moving off of the top or bottom of the screen, but probably not when moving off of the opposite side.

(3) You can have the sprite disappear all at once as soon as any part of it begins to move off the edge of the screen. Again, this does *not* occur automatically, at least not in general. But it *may* occur automatically when moving the sprite off of the top or bottom of the screen-- again, depending on how the display kernel has been written. On the other hand, this type of transition is the easiest one to program.

Obviously, the same three styles of moving a sprite *off* of the screen will also apply to moving a sprite *onto* the screen.

Anyway, the approach I took when modifying your original code was to use method #1, and let the frame (or sprite) wrap around automatically in the horizontal direction. Then the only thing left to do is figure out how to make the frame *appear* to wrap around in the vertical direction.

This would be fairly easy to do in assembly, using a custom-written display kernel, but it takes a little more effort in batari Basic with the "canned kernel." It's still pretty easy to do in batari Basic-- once you figure out the necessary logic-- but it takes more ROM for storing the sprite's shape, because you need to store it as a very tall sprite, consisting of two copies of the sprite which are separated by a lot of blank lines, as follows:

frames.gif

I need to take a break right now, so I'll post the rest of the explanation later tonight.

Michael

#7 SeaGtGruff OFFLINE  

SeaGtGruff

    River Patroller

  • 4,543 posts
  • Location:Georgia, USA

Posted Wed Jan 30, 2008 3:04 AM

frames.gif

As shown in the picture, the number of lines in the bottom copy of the player (P), plus the number of blank lines between the two copies of the player, should add up to the number of lines in the screen display (S). Thus, there should be S - P blank lines between the top and bottom copies of the player. That way, if the bottom line of the bottom copy is positioned at the bottommost line of the screen, the bottom line of the top copy will be just above the topmost line of the screen, such that it's just offscreen. And if, say, N lines of the bottom player have moved off of the bottom of the screen, then N lines of the top player will be visible at the top of the screen.

Note that we don't need all P lines for the top copy-- we need only P - 1 lines, because we can leave off the top line. That's because if we *were* to have all P lines for the top copy, and the top copy had slid down far enough for all P lines to be visible, then the bottom copy would have slid completely off the bottom of the screen. And whenever the whole shape is on the screen-- whether it's all at the bottom of the screen, or at the top of the screen, or anywhere in between-- then we can just use the bottom copy. In fact, we *want* to always use the bottom copy, because the sprite is drawn upside down, so the bottom copy is really at the beginning of our sprite bitmap.

Anyway, once we've defined the player as being two shapes, with a bunch of blank lines in between them, the only thing that's left for us to do is figure out what the player's pointerlo offset should be, what its height should be, and what it's y coordinate should be, to get the shape drawn just the way we want it to be. For this, we need to save the player's original pointerlo value, so we can restore it again as needed, and we also need a way to set a working y coordinate independently of the actual y coordinate. We can use a constant for the pointerlo value, assuming we know what value to set it to-- and we can let the assembler take care of that for us. So we really need only one user variable, for the working y coordinate.

Let's back up for a moment. When you define a player shape, batari Basic has five zero-page RAM locations that it uses to keep track of the player. These are some of what I call batari Basic's "system variables," because they're variables that batari Basic uses for its own purposes, as opposed to the 26 "user variables" that are available for *our* purposes. In particular, the system variables which batari Basic uses for player0 are as follows:

player0x -- The x coordinate of player0.
player0y -- The y coordinate of player0.
player0pointerlo -- The lo-byte of the address where player0's graphics data are located.
player0pointerhi -- The hi-byte of the address where player0's graphics data are located.
player0height -- The number of bytes for player0's graphics data, less 1.

There are also some other system variables that can be used for player0, depending on whether any kernel options are being used, but those five are the primary ones.

Now, batari Basic handles player0pointerlo, player0pointerhi, and player0height automatically whenever you define a new player0 shape, so the only ones we usually need to worry about are player0x and player0y. Let's consider a very simple bit of program code, one that won't even run after we compile it, because it isn't a complete program:

   rem * exploring player0 and player1

   player0:
   %11111111
   %01111110
   %00111100
   %00011000
end

   player1:
   %00011000
   %00111100
   %01111110
   %11111111
end
If we compile this code, and then look at the bB.asm file that the batari Basic compiler generates for it, we can see what the assembly code looks like:

game
.L00;  rem * exploring player0 and player1

.
; 

.L01;  player0:

	LDA #<playerL01_0

	STA player0pointerlo
	LDA #>playerL01_0

	STA player0pointerhi
	LDA #3
	STA player0height
.
; 

.L02;  player1:

	LDA #<playerL02_1

	STA player1pointerlo
	LDA #>playerL02_1

	STA player1pointerhi
	LDA #3
	STA player1height
 if (<*) > (<(*+4))
	repeat ($100-<*)
	.byte 0
	repend
	endif
playerL01_0

	.byte	%11111111
	.byte	%01111110
	.byte	%00111100
	.byte	%00011000
 if (<*) > (<(*+4))
	repeat ($100-<*)
	.byte 0
	repend
	endif
playerL02_1

	.byte	%00011000
	.byte	%00111100
	.byte	%01111110
	.byte	%11111111
	   echo "	",[(scoretable - *)]d , "bytes of ROM space left")
Notice that each line of batari Basic code will be assigned a sort of line number (or line label), beginning with ".L00" for the first line, then ".L01," ".L02," etc. Blank lines don't get numbered; they're just labelled as "." Also, if you use a "player0:" statement (or "player1:" or "playfield:"), only the line with the actual statement will be numbered; the lines with the data and with the "end" keyword" will *not* be numbered.

Whenever you use a "player0:" or "player1:" statement, batari Basic stores the actual graphics data at the *end* of the program code, and generates a unique label for the data, using the format "playerL0x_y," where "x" is the line number of the corresponding "player0:" or "player1:" statement, and "y" is the number of the player. Thus, since our example code has a "player0:" statement on line ".L01," and a "player1:" statement on line ".L02," the two labels that get generated will be "playerL01_0" and "playerL02_1."

I need to stop here to go to bed, so I'll resume from this point tomorrow! :)

Michael

#8 freehabitat OFFLINE  

freehabitat

    Chopper Commander

  • 113 posts
  • Location:Vienna, AUSTRIA

Posted Wed Jan 30, 2008 7:18 PM

hi,...

i am suprised that i understand more than befor. i go to bed as well and will read it again next morning.
it seems you bring me to the point where i learn about the assambly language and not only bB.

well,.. i am pretty excited about the solution for the second frame.

if we get this running i can start my 2nd testing phase for my art-project. surely iīll post some pictures or a little clip here as soon
have something,...

so far i can present this shot of lightsculptures made by atari 2600... its only testings...


Posted Image

Posted Image


now you might understand what the frames would become : )
tom

#9 freehabitat OFFLINE  

freehabitat

    Chopper Commander

  • 113 posts
  • Location:Vienna, AUSTRIA

Posted Thu Jan 31, 2008 3:46 PM

ok,.. somehow i am im lost in a maze...

1)
 const p0lo = #<playerL017_0
 const p1lo = #<playerL033_1

even if i write const
apple=123
instead of
const p1lo = #<playerL033_1
i get fatal assambly error...


2) player 1:

the sprite has as much lines than player0 (#111), the squares are different but the space between does the rest to have a amount of 111 lines,.. i understand this.

 rem 	-player1 beam-

  if y=255 then y=87
  if y=88 then y=0
  if y<15 then player1pointerlo=p1lo+y : player1height=86 : player1y=87
  if y>14 then player1pointerlo=p1lo : player1height=14 : player1y=y

player1height=14 is set because of the size of the single frame,... but is there any need to change the player1height=86 : player1y=87 and y=87 ? i am little lost here but i think this should fit to the smaller frame/spritesize...

player1x=player1x+x

  if player1x=255 then player1x=159 : goto main 
  if player1x=160 then player1x=0 : goto main

here is the same question,.. does the wide of the sprite changes anything on the values? (player1x=159 / player1x=160)


well,.. itīs still a mystery how to move the second frame but i really got lot more comprehension.

i wish to had more teacher like this in my past!

best

Tom

Attached Files



#10 freehabitat OFFLINE  

freehabitat

    Chopper Commander

  • 113 posts
  • Location:Vienna, AUSTRIA

Posted Sun Feb 3, 2008 2:58 PM

:lust:

wow,.. somehow i did it i can move both frames seperated. love it...

thanx SeaGtGruff ! this is for you:

frames play hide&seek



now iīll test it in the projection and later iīll bother you with my Bb-paint program....


best from vienna,

Tom

Attached Files


Edited by freehabitat, Sun Feb 3, 2008 4:23 PM.


#11 SeaGtGruff OFFLINE  

SeaGtGruff

    River Patroller

  • 4,543 posts
  • Location:Georgia, USA

Posted Sun Feb 3, 2008 9:16 PM

Try this instead. I just decreased the number of blank lines in player1, and adjusted some of the numbers in the "player1 beam" routine.

Michael

Attached Files






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users