Learning Action Game Basics
Moderator: Moderators
Re: Learning Action Game Basics
Ah that was the problem. My math was wrong.
Ah good idea Fox. I actually solved it the other way around and combined them:
I changed all the "#(256-MOB_MSPD_L)" and "#(256-MOB_MSPD_H)" to "#<(-(MOB_MSPD_L+(MOB_MSPD_H*256)))" and "#>(-(MOB_MSPD_L+(MOB_MSPD_H*256)))" respectively and now the character moves in the same speed in both directions. But your way makes much more readable code.
Thanks a lot both of you!
I also just solved the jumping problem I think, so that's probably good now.
So I'm done with basic movement for now, next comes collision. I guess I'd need to load a collision map in RAM that matches the level map on screen.
Ah good idea Fox. I actually solved it the other way around and combined them:
I changed all the "#(256-MOB_MSPD_L)" and "#(256-MOB_MSPD_H)" to "#<(-(MOB_MSPD_L+(MOB_MSPD_H*256)))" and "#>(-(MOB_MSPD_L+(MOB_MSPD_H*256)))" respectively and now the character moves in the same speed in both directions. But your way makes much more readable code.
Thanks a lot both of you!
I also just solved the jumping problem I think, so that's probably good now.
So I'm done with basic movement for now, next comes collision. I guess I'd need to load a collision map in RAM that matches the level map on screen.
-
- Posts: 1318
- Joined: Thu Apr 23, 2009 11:21 pm
- Location: cypress, texas
Re: Learning Action Game Basics
I used to miss an OAM viewer too; but, after understanding that page 2 is jammed into OAM each frame using the OAM_DMA register, $4014, taking 513 cycles, I just check page 2 in the hex editor to look at OAM.Pokun wrote:One thing FCEUX is missing though is an OAM viewer.
Code: Select all
sprite = $200
Code: Select all
.MACRO update_sprite
lda #>sprite
sta $4014
.ENDM
edit: I don't understand most of this thread, but I'm happy your problem is solved!
-
- Posts: 1318
- Joined: Thu Apr 23, 2009 11:21 pm
- Location: cypress, texas
Re: Learning Action Game Basics
No, you can access the collision values from ROM using lda (ptr), y Much easier accessing collision values from ROM than loading RAM with an entire screen worth of values. Think tokumaru told me something like that in my thread on page 50.Pokun wrote:So I'm done with basic movement for now, next comes collision. I guess I'd need to load a collision map in RAM that matches the level map on screen.
Re: Learning Action Game Basics
Many games use the same map for display and for collisions. It's very reasonable to assume that blocks that look the same will behave the same, so you actually save a lot of space by defining the collision information only once for each type of block, instead of multiple times, once for each instance of each type of block.
Depending on how your levels are compressed, you can read the collision information directly from ROM without problems. If you use something that doesn't allow random access though, such as RLE or LZ, then it does make sense to buffer a small section of the level in RAM, and update that as the player walks around.
Depending on how your levels are compressed, you can read the collision information directly from ROM without problems. If you use something that doesn't allow random access though, such as RLE or LZ, then it does make sense to buffer a small section of the level in RAM, and update that as the player walks around.
Re: Learning Action Game Basics
I guess collision map was the wrong term. I didn't mean a separate collision mask, but actual level data: $00 = empty space, $01 = wall, $02 = one-way platform, $03 = water, $04 = spikes, $05 = ladder etc (as an example, currently I only have wall and empty space). Both collisions and the level drawing routine are going to use the same data.
I see, currently I have no compression at all though, I want to figure out how to get things to work first. One advantage I see with RAM, besides compression, is destructible tiles. ROM or RAM is something I can decide on later though, and if I run out of either I'll just use a mapper.
I'm not sure how I can calculate collision positions with level tiles though. With objects I can just compare their coordinates, but with level tiles I have to somehow translate the object coordinates to a position in my level map which is using 16x16 metatiles, one byte per metatile.
I see, currently I have no compression at all though, I want to figure out how to get things to work first. One advantage I see with RAM, besides compression, is destructible tiles. ROM or RAM is something I can decide on later though, and if I run out of either I'll just use a mapper.
I'm not sure how I can calculate collision positions with level tiles though. With objects I can just compare their coordinates, but with level tiles I have to somehow translate the object coordinates to a position in my level map which is using 16x16 metatiles, one byte per metatile.
Yeah well actually FCEUX is able to show the internal OAM in the hex editor (click on "View"), not only the "shadow OAM" in RAM. But I meant a more visual sprite viewer like in Nintendulator and Mesen. I guess you can't have everything.unregistered wrote:I used to miss an OAM viewer too; but, after understanding that page 2 is jammed into OAM each frame using the OAM_DMA register, $4014, taking 513 cycles, I just check page 2 in the hex editor to look at OAM.Pokun wrote:One thing FCEUX is missing though is an OAM viewer.
Haha thank you. I tried to explain what I'm doing so people don't have to study my code too much, but it's hard to type short and concise text.unregistered wrote:I don't understand most of this thread, but I'm happy your problem is solved!
Re: Learning Action Game Basics
Even if you're not going to implement the final formats/algorithms for everything now, it helps to have an idea of what you'll want to do in the future to avoid having to throw out everything you're doing now.Pokun wrote:I see, currently I have no compression at all though, I want to figure out how to get things to work first. One advantage I see with RAM, besides compression, is destructible tiles. ROM or RAM is something I can decide on later though, and if I run out of either I'll just use a mapper.
If you think you can spare the RAM, it may be a good idea to have your engine working mostly with data from there, because later on when you do implement compression and such, you'll only have to change the code that populates those RAM buffers, while the bulk of the engine will remain the same.
Converting coordinates between different spaces is something that many games have to do quite often, specially if scrolling is involved. It's true, you will have to convert pixel coordinates into metatile coordinates to find out which blocks the sprites are touching. There's a very simple formula for this conversion:I'm not sure how I can calculate collision positions with level tiles though. With objects I can just compare their coordinates, but with level tiles I have to somehow translate the object coordinates to a position in my level map which is using 16x16 metatiles, one byte per metatile.
Offset = (PixelY / 16) * MapWidth + (PixelX / 16)
If you don't have any scrolling (i.e the map width is 16 metatiles and coordinates are 8-bit), the conversion is dead simple:
Code: Select all
lda PixelY
and #%11110000
sta Offset
lda PixelX
lsr
lsr
lsr
lsr
ora Offset
sta Offset
Code: Select all
ldx Offset
lda LevelMap, x
- rainwarrior
- Posts: 8734
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Learning Action Game Basics
tokumaru wrote a really nice lua script that does a pretty good job of it:Pokun wrote:Yeah well actually FCEUX is able to show the internal OAM in the hex editor (click on "View"), not only the "shadow OAM" in RAM. But I meant a more visual sprite viewer like in Nintendulator and Mesen. I guess you can't have everything.
https://forums.nesdev.com/viewtopic.php ... 08#p181008
-
- Posts: 1318
- Joined: Thu Apr 23, 2009 11:21 pm
- Location: cypress, texas
Re: Learning Action Game Basics
Wow, thanks for the link rainwarrior!rainwarrior wrote:tokumaru wrote a really nice lua script that does a pretty good job of it:Pokun wrote:Yeah well actually FCEUX is able to show the internal OAM in the hex editor (click on "View"), not only the "shadow OAM" in RAM. But I meant a more visual sprite viewer like in Nintendulator and Mesen. I guess you can't have everything.
https://forums.nesdev.com/viewtopic.php ... 08#p181008
ps. How did you find the post number? There used to be a permalink button, but I haven't found it in a long while.
-
- Posts: 1318
- Joined: Thu Apr 23, 2009 11:21 pm
- Location: cypress, texas
Re: Learning Action Game Basics
I don't understand most of this thread because it takes me a lot of concentration to try and understand programming concepts... I just didn't apply myself; wasn't criticizing your efforts.Pokun wrote:Haha thank you. I tried to explain what I'm doing so people don't have to study my code too much, but it's hard to type short and concise text.unregistered wrote:I don't understand most of this thread, but I'm happy your problem is solved!
- rainwarrior
- Posts: 8734
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Learning Action Game Basics
At the top of any post, there's a line with the subject on the left, and on the right there's a "posted" with a date and a little paper icon next to it. The link is the paper icon.unregistered wrote:ps. How did you find the post number? There used to be a permalink button, but I haven't found it in a long while.
-
- Posts: 1318
- Joined: Thu Apr 23, 2009 11:21 pm
- Location: cypress, texas
Re: Learning Action Game Basics
^Thank you rainwarrior so much!!
Pokun, I'll try to write future posts more clearly. Thanks for this learning experience.
Pokun, I'll try to write future posts more clearly. Thanks for this learning experience.
Re: Learning Action Game Basics
I know what you mean, I only learned this stuff in this thread myself just before coding it. If you want to understand it, you may need to study signed 16-bit comparisons in the links in the first post.unregistered wrote:I don't understand most of this thread because it takes me a lot of concentration to try and understand programming concepts... I just didn't apply myself; wasn't criticizing your efforts.Pokun wrote:Haha thank you. I tried to explain what I'm doing so people don't have to study my code too much, but it's hard to type short and concise text.unregistered wrote:I don't understand most of this thread, but I'm happy your problem is solved!
Thanks everyone. The formula Tokumaru posted worked like a charm and now floor collision works like it should. Although jumping down with high speed makes the player's feet dig into the ground and jumping into the roof makes his head stuck in there so I have to eject him from the tile he collided with. I found a formula for how many pixels to eject in this post. The formula for positive velocity (eject_value = (pixel_coordinate AND $0F) + 1) works for the floor, but doing the the formula for negative velocity (eject_value = (pixel_coordinate EOR $0F) + 1) does not work for the ceiling. The player teleports far above the ceiling whenever he bumps his head into it.
Positive Y-velocity (for floors) Ejection:
Code: Select all
;This code works fine:
lda #$00
sta p1_vy+0
sta p1_vy+1 ;stop velocity when landing on floor
sta p1_y+0
lda p1_y+1
and #$0F
sta temp+1
lda p1_y+1
clc
adc #$08 ;+height
sec
sbc temp+1
sta p1_y+1 ;eject from tile, Y = Y - (Y AND $0F)
lda #$01
sta p1_ground ;set state to grounded
Code: Select all
;This code does not work correctly:
lda #$00
sta p1_vy+0
sta p1_vy+1 ;stop velocity when banging head in ceiling
sta p1_y+0
lda p1_y+1
eor #$0F
sta temp+1
lda p1_y+1
clc
adc temp+1
sta p1_y+1 ;eject from tile, Y = Y + (Y XOR $0F)
Did I misunderstand the formula or is the problem somewhere else?
Re: Learning Action Game Basics
Don't forget to account for the heights of the player and metatiles.Pokun wrote:The player teleports far above the ceiling whenever he bumps his head into it.
-
- Posts: 1318
- Joined: Thu Apr 23, 2009 11:21 pm
- Location: cypress, texas
Re: Learning Action Game Basics
small note: when adding and you want to add one more, it's easy to do, just change your clc to sec. Learned that from Kasumi.
Re: Learning Action Game Basics
I believe I use a similar trick when calculating sprite coordinates, to compensate for the fact that sprites are positioned one scanline lower than the Y coordinate specified in their OAM entries. Instead of doing SpriteY = ObjectY - CameraY, I do SpriteY = ObjectY - CameraY - 1 by putting a CLC before the subtraction, instead of the usual SEC.