It is currently Sat Jul 21, 2018 10:56 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 1451 posts ]  Go to page Previous  1 ... 50, 51, 52, 53, 54, 55, 56 ... 97  Next
Author Message
PostPosted: Tue Oct 23, 2012 9:08 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
qbradq wrote:
So I'm not going to read 52 pages back :D I assume from the few pages I've caught up on this is not cell-based (like Zelda II's overworld), but subpixel-based (like Mario).
Yes, I guess it's subpixel-based like Mario. :)

qbradq wrote:
Typically I use a velocity variable for every object. So in the above code snippet I would set the player's X velocity value to some value. Then during the object update routine I apply the velocity to the position, then check for collisions, and if there is a collision react to it. If you do go this route, do Y movement and collision detection first, then X. Trust me on that one :D
Ok, thank you qbradq! :D

qbradq wrote:
Also, sounds like you've got good parents and a pretty awesome sister :D
YES! Thank you so very much qbradq! :D

tokumaru wrote:
Controller input shouldn't directly affect the horizontal position of the player. Instead, it should affect the horizontal velocity (just like gravity affects its vertical velocity), and the velocity, whatever it is, should be added to the player's position every frame (again, like happens with vertical movement).

If a direction is pressed, increase velocity in that direction, if no direction is pressed, gradually decrease the velocity until it reaches 0 (this creates a nice inertia effect). After adding the velocity variable to the current position, check whether the block(s) at the edge of the player in the direction of the movement are solid, in which case you need to push the character back, like we discussed before.

Ejecting from the right should be exactly same as repelling from the ground, while the formula for ejecting from the left or from the ceiling is a bit different, but I'm sure you'll figure it out.
Thank you very much tokumaru! :D

qbradq wrote:
Yea, platformer physics can be painful at times.

So OP, here's a list of games off the top of my head you can look at that do it right:

Zelda II: Adventure of Link, The
Super Mario Bro.s
Super Mario Bro.s 3
Metroid
I have metroid but have not played it much. Though, I do remember the great platforming it has; it has jumps as in Mario. :)

qbradq wrote:
And here's a few that do it very poorly:

EVERY Castlevania game, but especially CV1
Most Mega Man games, especially MM1
Any Donkey Kong game
Ghosts 'n Goblins
I have CV1 and MM3 and Ghosts 'n Goblins. Castlevania is interesting... but I don't see how it does very poorly. I'm hoping you will explain what you mean by that. I'm eager to learn! :D

---
I spent some time last night looking up velocity in my Physics textbook. Velocity is speed/time, right? I'm going to look up inertia tomorrow. :)


Top
 Profile  
 
PostPosted: Wed Oct 24, 2012 4:57 am 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 939
For inertia in games you can do this:

1. When striking a solid object, zero out velocity
2. When trying to stop (I.E. letting off the DPad), you can reduce the velocity toward zero by a fixed amount.

In CV1, here's what they got wrong (or at least wrong in my opinion)

1. Jumps are not controllable at all
2. Difficult to jump horizontally from a standing start
3. No acceleration / deceleration while walking
4. Collision detection is VERY off. You don't collide with anything from the top, and there's all sorts of bugs with the collision detection they did implement

The main thing I don't like about CV1 is the inability to control your jump. That's very bad for a platformer.


Top
 Profile  
 
 Post subject: Re:
PostPosted: Fri Nov 02, 2012 10:30 am 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
tokumaru, on page 35, wrote:
Dwedit wrote:
When using jump tables, be very careful about safety. Don't allow out-of-range values to be used. Use bounds checking, or bit masking and dummy entries.

I was gonna say something like that... Jump tables are great when your cases are all consecutive numbers (and you should always try to make it so, since it's easier that way), but when the cases are scattered values or ranges of different sizes, jump tables are not so good.


Ok... I need your help. I currently have cases numbered 21 through 28. So they are all consecutive right now! :) But I thought of trying something... would this improve my jump table? My code will follow Kasumi's example...

Kasumi, also on page 35, wrote:
Code:
;y contains the case number
lda jumptablelow,y
sta tempaddress
lda jumptablehigh,y
sta tempaddress+1

jmp [tempaddress]

jumptablehigh:
.db high(case0)
.db high(case1)
.db high(case2)
jumptablelow:
.db low(case0)
.db low(case1)
.db low(case2)
case0:

case1:

case2:


Underneath each case label would be the code corresponding to the case. Then, we store the addresses of all the cases in two tables. We load the low and high byte of the address we want, and store them in two contiguous bytes in low/high order. Then we jmp indirect to byte where the low part of the address was stored which will take us to the case label.

There's actually a small bug with the 6502 jmp indirection instruction. From here:

An original 6502 has does not correctly fetch the target address if the indirect vector falls on a page boundary (e.g. $xxFF where xx is and value from $00 to $FF). In this case fetches the LSB from $xxFF as expected but takes the MSB from $xx00. This is fixed in some later chips like the 65SC02 so for compatibility always ensure the indirect vector is not at the end of the page.


This is susposed to run animation as character moves across the screen... my sister is an animator. :D
Code:
;if left is pressed,
    lda Next-1
    jmp +
;if right is pressed,
    lda Next+1
+   sta NewNext

;y contains the case number
lda jumptablelow,y
sta tempaddress
lda jumptablehigh,y
sta tempaddress+1

jmp [tempaddress] ;<??????????? what do [] mean? :?

jumptablehigh:
.db >case0, >case0, >case1, >case2, >case2, >case2, >case1, >case0
jumptablelow:
.db <case0, <case0, <case1, <case2, <case2, <case2, <case1, <case0

case0:
  jsr record ;<--this is just an idea right now
  bne case2

case1:
  lda Next
  sta NewNext
  jmp endCaseJump

case2:
  ;this is just an idea also
 
endCaseJump:



...So if I modified Kasumi's jump table like this would this be bad or good? It would still work the same way... I think... let's say y is equal to 22 - 20...2 ... it would run case 1 right? Well, that's what I want it to do.... :oops:


Top
 Profile  
 
PostPosted: Fri Nov 02, 2012 1:35 pm 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 939
If Y is in the range 20-28 inclusive, then you'll need to modify one section of code:

Code:
;y contains the case number (20-28 inclusive)
lda jumptablelow-20,y
sta tempaddress
lda jumptablehigh-20,y
sta tempaddress+1

jmp [tempaddress] ;<??????????? what do [] mean?

; It means Jump Indirect. Here's how it works:
; Load the value at tempaddress into the program counter
; Continue to next instruction, which is now the instruction at the address stored in tempaddress


Note that you're applying some static math to the pointer table address to account for the minimum value of Y. This is more efficient that doing math at run-time, but also a little less clear (to some folks).

Without doing this then when Y is 20 you'll be accessing the 20'th element of the array, which is well outside it's bounds, and you'll get junk data.


Top
 Profile  
 
 Post subject: Re: Re:
PostPosted: Fri Nov 02, 2012 2:06 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
unregistered wrote:
It would still work the same way... I think... let's say y is equal to 22 - 20...2 ... it would run case 1 right? Well, that's what I want it to do.... :oops:


edit: ... sorry. :( Thanks qbradq. :) Next time I hope to provide better coding that describes my purpose and logic better. :)

qbradq wrote:
Code:
jmp [tempaddress] ;<??????????? what do [] mean?

; It means Jump Indirect. Here's how it works:
; Load the value at tempaddress into the program counter
; Continue to next instruction, which is now the instruction at the address stored in tempaddress


I think I remember tokumaru telling me that [] aren't used in asm6, that's the assembler i'm using. Though, that's a great description... I'll have to memorize that! :D


Top
 Profile  
 
PostPosted: Fri Nov 02, 2012 4:29 pm 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 939
The normal syntax would be:

Code:
jmp (tempaddress)


Top
 Profile  
 
PostPosted: Fri Nov 02, 2012 4:38 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
qbradq wrote:
The normal syntax would be:

Code:
jmp (tempaddress)


...well my assembler is complaining Unknown Label... so I'm guessing Kasumi ment
Code:
jmp (tempaddress), y


Top
 Profile  
 
PostPosted: Fri Nov 02, 2012 4:47 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20280
Location: NE Indiana, USA (NTSC)
The (d),y addressing mode does not work with JMP. "Unknown label" means there isn't a symbol called tempaddress.


Top
 Profile  
 
PostPosted: Fri Nov 02, 2012 7:27 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
tepples wrote:
The (d),y addressing mode does not work with JMP. "Unknown label" means there isn't a symbol called tempaddress.
Oh :oops: ... well, it was actually my fault, I read the wrong line... after correcting it... it said Illegal Instruction to my JMP (d),y line and so I deleted the ,y part and it compiled correctly and made an nes file! :o I didn't know that JMP (d) was possible and I was wrong to say imply that it wouldn't work. Im sorry qbradq. :(

tepples, thank you for correcting me! :oops:

edited


Top
 Profile  
 
PostPosted: Mon Nov 05, 2012 2:28 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
OK! :D I finally figured out what the problem is... the ground is continuous across the entire screen and so I move our girl character right and then it scrolls a little bit at first. Eventually a new screen scrolls over with a hole of water at the end, but I just figured out that our attribute table doesn't scroll yet and that's why she never decends into the water. And I haven't studied the scrolling knowledge that yall've taught me last... a little more than a year ago; I'll go read right that now. I don't think I got to this question back then; so, how can we get the attribute table to scroll with the screen? Sounds crazy... :?

edit: Ok... I read all of the scrolling knowledge shared... it starts on page 14. This picture is helpful to me on how to scroll the attribute tables... I would enjoy your help if you give it. Maybe I can do this. :)
tepples, on page 15, wrote:
tokumaru wrote:
I just don't recommend it to newbies because sometimes it's hard for them to grasp the concept of the progressive name table updates

Would this GIF make the concept easier for them to grasp?

Image



edit2: Right now my method for building attribute tables builds an entire attribute table... and that would take too long to build an attribute table for each screen that appears, right? :? Do you have any tips for just building the 2 collums of questionmark blocks each time? edit3: I remember that there's a way to go down a collum... it's somehow accomplished by setting a bit somewhere.


Top
 Profile  
 
PostPosted: Mon Nov 05, 2012 5:35 pm 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 939
Going down a column by setting the PPU increment to 32 bytes per increment won't help with the attribute tables. You need an increment of 8 for that.

What I did when I made a scrolling engine (and there's plenty of folks on here with more experience than me) was to keep a copy of both nametable's attribute area in RAM. Then I could make my inserts, then write what I had to the VRAM during NMI.

If you're doing whole attribute bytes at once you don't have to do this though. Just calculate all the bytes, then write them and manually increment the VRAM pointer. You might do this with reads, or more efficiently by setting the address before each byte write.


Top
 Profile  
 
PostPosted: Mon Nov 05, 2012 5:42 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20280
Location: NE Indiana, USA (NTSC)
Tip: If your levels are 12 metatiles tall (as in the GIF example above), you can calculate six bytes of attributes (one for each set of four metatiles in the strip), set the PPU to +32, and write bytes 0 and 4, then 1 and 5, then 2, then 3.


Top
 Profile  
 
PostPosted: Tue Nov 06, 2012 7:11 am 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 939
MIND = BLOWN

Cool! I never even thought of that :D


Top
 Profile  
 
PostPosted: Tue Nov 06, 2012 10:20 am 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 898
Location: cypress, texas
qbradq wrote:
Going down a column by setting the PPU increment to 32 bytes per increment won't help with the attribute tables. You need an increment of 8 for that.
Wow, I'm really glad you understood what I was mumbling about. Thank you! Now I remember that the attribute table is much smaller than the screen! :D

qbradq wrote:
What I did when I made a scrolling engine (and there's plenty of folks on here with more experience than me) was to keep a copy of both nametable's attribute area in RAM. Then I could make my inserts, then write what I had to the VRAM during NMI.
What do you mean by inserts?

qbradq wrote:
If you're doing whole attribute bytes at once you don't have to do this though. Just calculate all the bytes, then write them and manually increment the VRAM pointer. You might do this with reads, or more efficiently by setting the address before each byte write.
AH, :D Setting the address before each byte write will be good... ok! Thank you incredibly much qbradq! :D

tepples wrote:
Tip: If your levels are 12 metatiles tall (as in the GIF example above), you can calculate six bytes of attributes (one for each set of four metatiles in the strip), set the PPU to +32, and write bytes 0 and 4, then 1 and 5, then 2, then 3.
qbradq wrote:
MIND = BLOWN

Cool! I never even thought of that :D
Thank you tepples... I don't quite understand... but I kind of do. It will make sense after I attempt what qbradq said. I do get that you are saying that setting the PPU to +32 could be a possibility for attribute tables. That's amazing to me! :D I hope to have my mind blown out too :lol: ... that seems good to me... thinking. :oops:


Top
 Profile  
 
PostPosted: Tue Nov 06, 2012 10:57 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20280
Location: NE Indiana, USA (NTSC)
Say you have prepared a column of attribute data. You want to write it to offsets 0, 8, 16, 24, 32, 40, 48, and 56 in the attribute table. But the PPU has no +8 increment mode, just +1 and +32. What you can do is this:
  1. Set the PPU to +32.
  2. Seek (set the address) to 0 and write the entries for 0 and 32.
  3. Seek to 8 and write the entries for 8 and 40.
  4. Seek to 16 and write the entries for 16 and 48.
  5. Seek to 24 and write the entries for 24 and 56.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


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