It is currently Thu Jul 19, 2018 2:43 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 1451 posts ]  Go to page Previous  1 ... 48, 49, 50, 51, 52, 53, 54 ... 97  Next
Author Message
PostPosted: Sat Oct 06, 2012 11:12 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
tokumaru wrote:
Bregalad's formula is correct, for when there are 7 items per row.
... ...Yeay! :idea: :o Thanks tokumaru! :D

tokumaru wrote:
The formula for reading data from a 2D array which is stored in memory linearly is always Y * ElementsPerRow + X, that doesn't change. But you also have to take into consideration that the base unit is the type of element you are accessing, in this case, metatiles. If you have pixel coordinates, you have to first convert them to metatile coordinates, hence the need to divide both X and Y by the dimensions of your metatiles before applying that formula.

Another thing that will affect how you apply the formula is how your levels are stored in RAM/ROM. If you store it screen by screen, then ElementsPerRow will always be the same, because the number of metatiles per screen doesn't change. If you don't divide your level in screens, then ElementsPerRow will be the length of the entire level, and it will vary from level to level. IMO, things are easier if you divide the levels into screens, because the metatile offsets will always fit in 8 bits, and the multiplications/divisions can be easily done with shifts.
And cause it would be easy for my sister to edit the screens. The blue part below is almost how she did it! :) I never thought of not dividing the level into separate screens... that would be kind of insane :P I think. But it does sound like it would be easy scrolling beyond 2 screens; though I don't know how to... ...yet. :)



tokumaru wrote:
Here comes another (untested) example of data arrangement (and how to access it):

codeLevelMap:

;first screen:
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
;(another 12 rows here)
.db $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10

;second screen:
.db $00, $00, $00, $00, $00, $10, $10, $00, $00, $00, $00, $00, $00, $00, $00, $00
.db $00, $00, $00, $00, $00, $10, $10, $00, $00, $00, $00, $00, $00, $00, $00, $00
;(another 12 rows here)
.db $10, $10, $20, $20, $20, $20, $20, $20, $20, $21, $22, $23, $00, $00, $00, $00

;third screen:
.db $22, $00, $22, $00, $22, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
.db $22, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
;(another 12 rows here)
.db $20, $20, $20, $20, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10

;(keep going for as many screens as you want)


;Reads the index of the metatile at position (PointX, PointY) in the level map
ReadMetatile:

;get the index of the screen
ldy PointX+1

;multiply it by 240 (using a look-up table) and add it to the base
;address of the level to create a pointer to the screen we need
clc
lda ScreenOffsetLo, y
adc LevelMap+0
sta ScreenPointer+0
lda ScreenOffsetHi, y
adc LevelMap+1
sta ScreenPointer+1

;calculate the index of the metatile: (Y / 16) * 16 + (X / 16)
lda PointX+0
lsr
lsr
lsr
lsr
sta Temp
lda PointY+0
and #%11110000
ora Temp
tay

;read the metatile
lda (ScreenPointer), y

;return
rts
/code
Now you can do whatever you want with that information. Want to know if that metatile is solid? Do something like this:

Code:
   tax
   lda MetatileCollision, x
   and #BITTHATINDICATESWHETHERAMETATILEISSOLID
   beq +NotSolid
Swell... incredible! That takes less cycles. But it takes a bit more space no... memory. Fast is class! :D

tokumaru wrote:
Want to know what is the top left tile of that metatile?

Code:
   tax
   lda MetatileTopLeft, x
Aw yes faster code! :)

Ok I slowly changed my code to be just like your code all today. Time to sleep.
But, I haven't implemented any of this bit of your yellow code up there... I just tried to use my variables. :oops: I got the first part of my code to look like the first part of your code. Now the lady sprite falls just halfway down the screen and then pauses. She is susposed to fall to the bottom of the screen. :( My code at the end is still the same:
Code:
0C3DB                             
0C3DB                              ;GRAVITY
0C3DB C6 31                        dec tC
0C3DD 10 02                        bpl +skip
0C3DF                             
0C3DF B1 0C                        lda (rhombusCollision_low), y
0C3E1                           
0C3E1                                 ;if the metatile is not solid
0C3E1 0A                             asl a    ;<pushes bit #7 into carry.
0C3E2 90 09                          bcc +skip
0C3E4                           
0C3E4                                   ;then fall to the metatile below...
0C3E4                           
0C3E4 B1 1A                            ;lda (UCollision_low), y
0C3E6 A5 05                            lda oY
0C3E8 18                               clc
0C3E9 69 08                            adc #8
0C3EB 85 05                            sta oY
0C3ED                           +skip 
0C3ED                             
0C3ED E6 31                        ;inc tC
0C3EF                             
0C3EF 60                        rts ;end of unpack and end of daprg-collisionU

That line ;lda (UCollision_low), y is commented because it doesn't really work... should load accumulator with 0 for air or 1 for solid. But, I'm not working any more right now... haven't solved it yet... maybe you could? It's perfectly ok if yall don't. To sleep I go... goodnight. Ohhhh and thanks tokumaru, for all of the great help!! :D I'm almost done... will post some more tomorrow afternoon.

edit: Ok... I want to say that I know that the yellow text will help me to make my game... almost... to make our game more like a machiene. A machiene with parts that work flawlessly together... I remember that tokumaru. :)


Top
 Profile  
 
PostPosted: Sun Oct 07, 2012 12:51 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10609
Location: Rio de Janeiro - Brazil
unregistered wrote:
I haven't implemented any of this bit of your yellow code

That code is just a multiplication by 240, which is faster with a table, but this table needs 512 bytes, which you might not want to dedicate to this purpose. Another way to multiply X by 240 is to do (X * 256) - (X * 16). Here's a replacement for that calculation, without using tables:

Code:
   ;put (screen index * 16) into ScreenPointer
   lda PointX+1
   lsr
   lsr
   lsr
   lsr
   sta ScreenPointer+1
   lda PointX+1
   asl
   asl
   asl
   asl
   sta ScreenPointer+0

   ;subtract it from (screen index * 256)
   sec
   lda #$00
   sbc ScreenPointer+0
   sta ScreenPointer+0
   lda PointX+1
   sbc ScreenPointer+1
   sta ScreenPointer+1

   ;add the result to the base address of the level
   clc
   lda ScreenPointer+0
   adc #<LevelMap
   sta ScreenPointer+0
   lda ScreenPointer+1
   adc #>LevelMap
   sta ScreenPointer+1

It's much slower though. BTW, in my old code I used LevelMap+0 and LevelMap+1 by mistake, I should have used #<LevelMap and #>LevelMap instead.


Top
 Profile  
 
PostPosted: Fri Oct 12, 2012 3:03 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
My sprite has started out in the lower left corner all day today... I can't figure out why. :oops:
Is there something wrong in the code I've been trying to set?

Code:
0C3B3                           ;**********************************************************************************************
0C3B3                           unpack:
0C3B3                           
0C3B3                           ;**********************************************************************************************
0C3B3                           
0C3B3                           ;128  64  32  16   8   4   2   1   
0C3B3                           ;$80 $40 $20 $10 $08 $04 $02 $01
0C3B3 A9 3C                         lda #<MetatileRhombus
0C3B5 85 0C                        sta rhombusCollision_low
0C3B7 A9 C8                        lda #>MetatileRhombus
0C3B9 85 0D                        sta rhombusCollision_high
0C3BB                              
0C3BB A9 1B                        lda #<MetatileCollision
0C3BD 85 1A                        sta UCollision_low
0C3BF A9 C9                        lda #>MetatileCollision
0C3C1 85 1B                        sta UCollision_high
0C3C3                              
0C3C3                              
0C3C3                           ;   clc
0C3C3                           ;   lda ScreenOffsetLo, y
0C3C3                           ;   adc #<LevelMap
0C3C3                           ;   sta ScreenPointer+0
0C3C3                           ;   lda ScreenOffsetHi, y
0C3C3                           ;   adc #>LevelMap
0C3C3                           ;   sta ScreenPointer+1
0C3C3                              
0C3C3                           
0C3C3 A5 04                        lda oX
0C3C5 85 28                        sta PointX
0C3C7 A5 1C                        lda oY+23
0C3C9 85 2A                        sta PointY
0C3CB                              
0C3CB 20 F5 C3                     jsr linear_position ;y holds new linear position
0C3CE                                 
0C3CE                              
0C3CE                              ;GRAVITY
0C3CE                                 
0C3CE 85 FF                        sta $ff
0C3D0 B1 10                        lda (ten_low), y
0C3D2 A8                           tay
0C3D3 B1 0C                        lda (rhombusCollision_low), y
0C3D5                           
0C3D5                                 ;if the metatile is not all the same tile
0C3D5 0A                             asl a    ;<pushes bit #7 into carry.
0C3D6 90 1C                          bcc +skip
0C3D8                           
0C3D8                                 ; and if the ground below is not something solid to stand on...
0C3D8 A5 2C                          lda SomethingSolidtoStandon
0C3DA F0 18                          beq +skip
0C3DC                                   ;then fall to the metatile below...
0C3DC                                 
0C3DC A5 05                         -- lda oY
0C3DE 18                               clc
0C3DF 69 08                            adc #8
0C3E1 85 05                            sta oY
0C3E3                                 
0C3E3 85 2A                             sta PointY
0C3E5 20 F5 C3                        jsr linear_position
0C3E8                                 
0C3E8                                 ;and check the value of the block
0C3E8                           ;      tay
0C3E8 B1 10                           lda (ten_low), y
0C3EA A8                               tay
0C3EB B1 1A                           lda (UCollision_low), y
0C3ED 85 2C                             sta SomethingSolidtoStandon
0C3EF                                   ;if it is 00 it's air
0C3EF D0 03                             bne +notair
0C3F1                                     ;it is air!!!
0C3F1 4C DC C3                           jmp --
0C3F4                                   +notair
0C3F4                                   ;and if it is 01 it's solid. :)  So try to stop or move back to the previous tile?
0C3F4                                     
0C3F4                                     ;it's probably solid!!!
0C3F4                                      ;so stop falling
0C3F4                                    
0C3F4                           
0C3F4                           
0C3F4                           +skip
0C3F4                              
0C3F4                                 
0C3F4 60                        rts ;end of unpack
0C3F5                           
0C3F5                           linear_position:
0C3F5                              ; Calculate the index of the metatile: (Y / 16) * 16 + (X / 16) = LINEAR_POSITION  p.50
0C3F5 A5 28                        lda PointX+0
0C3F7 4A                           lsr a ;divide my X coordinate by (2 * 2 * 2 * 2) = 16
0C3F8 4A                           lsr a ;<----------------------------*
0C3F9 4A                           lsr a ;<--------------------------------*
0C3FA 4A                           lsr a ;<------------------------------------*
0C3FB AA                             tax
0C3FC 85 37                        sta tC+1
0C3FE A5 2A                        lda PointY+0
0C400 29 F0                        and #11110000b
0C402 05 37                        ora tC+1
0C404 A8                           tay
0C405                           
0C405 60                            rts


Top
 Profile  
 
PostPosted: Mon Oct 15, 2012 1:14 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
Yessss! :D

Ok it's fixed now... I found out this morning that the -- loop is too tiny! When you delete that loop part and let it end with storing the new value of SomethingSolidtoStandon... then it works!! :D She falls ............................................. down into the ground and sticks there. I would like to see her fall and stop with her feet on the ground. Is this a good method?: Calculate the block above her hand... she has her hands high in the air. Do I just subtract 16 inside each calculation? Or maybe I should add 16 to her height so that checks the block near her feet? :? I'm kind confused about what to do. I'll figure it out sometime. :oops:


Top
 Profile  
 
PostPosted: Mon Oct 15, 2012 2:05 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10609
Location: Rio de Janeiro - Brazil
The exact points that make contact with surfaces can be anything you want. I have no idea how you're handling object coordinates, but I assume you have the current coordinates of the girl characters stored somewhere, which you use to calculate the coordinates of the individual sprites. Similarly to how you calculate sprite coordinates from these "master coordinates", you can also calculate the collision points.

If the character is 16x32 pixels, and its coordinates indicate its top left corner, you can calculate a point of collision at the middle bottom of the character with X+8, Y+32. Once you know this point (PointX, PointY), you can call that routine that checks the metatile at that location. If it's not solid, the character should fall. If it is solid, you can't simply stop it from falling (because the character could be stuck into the ground if moving faster than 1 pixel per frame), you have to push it back up so that it's exactly on top of the floor.


Top
 Profile  
 
PostPosted: Mon Oct 15, 2012 2:32 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
Grand!!! Thlink I have it!!

edit: Well... now she starts way up high and falls a little bit...then stops... well above the ground. It's kind of exciting!!!!!!!!!!!!!! ALMOST THERE... SHE JUST NEEDS TO FALL FOR A LITTLE BIT LONGER!! :D

edit2: Now she falls to the ground and sticks inside it a little!


Top
 Profile  
 
PostPosted: Mon Oct 15, 2012 6:37 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
tokumaru wrote:
The exact points that make contact with surfaces can be anything you want. I have no idea how you're handling object coordinates, but I assume you have the current coordinates of the girl characters stored somewhere, which you use to calculate the coordinates of the individual sprites. Similarly to how you calculate sprite coordinates from these "master coordinates", you can also calculate the collision points.

If the character is 16x32 pixels, and its coordinates indicate its top left corner, you can calculate a point of collision at the middle bottom of the character with X+8, Y+32. Once you know this point (PointX, PointY), you can call that routine that checks the metatile at that location. If it's not solid, the character should fall. If it is solid, you can't simply stop it from falling (because the character could be stuck into the ground if moving faster than 1 pixel per frame), you have to push it back up so that it's exactly on top of the floor.


HOW?? I get that it is time to add eight... but where ever I put the
Code:
          sec
          lda oY
          sbc #8
          sta oY

it makes our girl character not move at all... every time my function subtracts 8 right after it added 8... and so she doesn't fall... ever! :( How would you make this work correctly? My logic has it check the block below and add eight if it's air and then quit after reading the type of block below. That happens every time. :?


Top
 Profile  
 
PostPosted: Mon Oct 15, 2012 6:54 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1154
You can't subtract by a fixed amount. If she's one pixel in the floor and you subtract eight, she's flying. If she's 9 pixels in the floor and you subtract 8 she's still in the floor.

You have to figure out how far she needs to be ejected, and then eject her.

If you've got 16x16 metatiles, only the lowest four bits of her lowest coordinate byte matter. You check if she's in a collision enabled tile.

Now think. If the lowest bits of her position are $0, how many pixels does she need to move up? How about when she's at $F? Once you figure that out, figure out some math to make it always eject her immediately out the tile.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Mon Oct 15, 2012 7:22 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10609
Location: Rio de Janeiro - Brazil
unregistered wrote:
it makes our girl character not move at all... every time my function subtracts 8 right after it added 8... and so she doesn't fall... ever!

Pushing her back up is something you should do only if her feet are into the floor, not all the time. And like Kasumi said, you can't just push her a fixed amount of pixels.

The math should be quite simple really, since your solid metatiles are always 16x16 pixels... Say that you checked point X + 8, Y + 32 of a 16x32 character, and you found the metatile at that position to be solid. This means you have to make the character "snap" to the metatile that's above this one. You can ignore how far into the floor the character is with PointY AND #%f0, which is the pixel coordinate of the very top (first row) of the solid metatile. Then, it's just a matter of subtracting the character's height to find the new Y coordinate that will place it right above the floor.

Quote:
My logic has it check the block below and add eight if it's air and then quit after reading the type of block below. That happens every time. :?

And if the block below is solid, you must push the character back up. You can do it that way, but you'll have no acceleration at all (because you always add 8), and that looks very bad. The speed of falling objects increases with time, so it would be better that you added a variable instead of a constant number, and every frame that the character is in the air the value of that variable increases. However, if you increase the speed by whole pixels every frame it will grow too fast and you'll barely notice it, so you should probably look into fixed point math, so that you can add fractional numbers to the character's speed to make it more smooth.


Last edited by tokumaru on Mon Oct 15, 2012 10:17 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Mon Oct 15, 2012 8:27 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 3090
Location: Tampere, Finland
tokumaru wrote:
(because you always add 8)

Can we get rid of that smiley on the forum? Way more often I see it used accidentally rather than intentionally. Or maybe the accidental uses just stick out...

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi


Top
 Profile  
 
PostPosted: Mon Oct 15, 2012 10:18 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10609
Location: Rio de Janeiro - Brazil
Yeah, I always get screwed by that stupid smiley...


Top
 Profile  
 
PostPosted: Mon Oct 15, 2012 10:45 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
tokumaru wrote:
unregistered wrote:
My logic has it check the block below and add eight if it's air and then quit after reading the type of block below. That happens every time. :?

And if the block below is solid, you must push the character back up. You can do it that way, but you'll have no acceleration at all (because you always add 8), and that looks very bad. The speed of falling objects increases with time, so it would be better that you added a variable instead of a constant number, and every frame that the character is in the air the value of that variable increases. However, if you increase the speed by whole pixels every frame it will grow too fast and you'll barely notice it, so you should probably look into fixed point math, so that you can add fractional numbers to the character's speed to make it more smooth.


Fixed point math. OK... I found this pdf and have read it and understand most of it... i think. I have kind of choose to use Q3.5 nums... on page 13 of that pdf i think I remember. Would something like that work well for this falling faster math? Or they show a Q3.13 also. That's a 2 byte value.

...While reading the pdf it reminded me of Calculus... I was able to retake my calculus class... so I learned it twice... I guess. Those 2 semesters were quite a time ago though... I think. :)

edit: tokumaru,
tokumaru, on page 50, wrote:
EDIT: Damn 8) smiley!
how did you do that? :o


Top
 Profile  
 
PostPosted: Tue Oct 16, 2012 1:40 am 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1154
In this case it's really more of change in perception than learning anything new.

You have two bytes. Together, they represent one number.
You're probably familiar with this way.
Number = hibyte*256+lobyte for a range of 0 through 65535.

But the computer really doesn't care about what the bytes represent to you.

Number could also represent onebyte + (otherbyte/256) to you for a range of 0 through 255+(255/256). In this case "otherbyte" represents the fractional part of a number.

In both cases additions/subtractions to the bytes are done in exactly the same way, they just represent something different for you, the programmer.

A speed like this:
onebyte = #$01
otherbyte = #$00
added to the characters position means the character moves one pixel every frame.
A speed like this:
onebyte = #$00
otherbyte = #$40
added means the character moves one pixel every 4 frames. (Because that's how many adds of that amount it would take to carry 1 pixel over)

(This also means your position will need another byte to represent the fractional part of the position, which if you scroll means you'll need at least 3 bytes for the position alone, two for the speed)

At least, that's one way to set it up. Make sense?

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Tue Oct 16, 2012 7:13 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20270
Location: NE Indiana, USA (NTSC)
The code 8) used to make the emoticon with sunglasses. As of two minutes ago, I have turned it off in favor of 8-), which produces 8-).


Top
 Profile  
 
PostPosted: Tue Oct 16, 2012 7:20 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10609
Location: Rio de Janeiro - Brazil
unregistered wrote:
I have kind of choose to use Q3.5 nums... on page 13 of that pdf i think I remember. Would something like that work well for this falling faster math? Or they show a Q3.13 also.

Those will make it hard to use the integer part of the values... Kasumi's suggestion of using 1 byte for the integer part and another for the fractional part (i.e. 8.8) makes much more sense. That way you easily use the high byte as the integer part as is, without having to shift bits around.

Quote:
how did you do that? :o

How did I do what? Show 8 and ) instead of the smiley? There's a checkbox in below the text area in the posting/editing page that disables smileys in the current post.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1451 posts ]  Go to page Previous  1 ... 48, 49, 50, 51, 52, 53, 54 ... 97  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group