2d platformer problem
BlitzPlus Forums/BlitzPlus Beginners Area/2d platformer problem
| ||
Hello all.... newbie coder here looking for some advice... I am trying to write a 2d platform game in the guise of the old fav manic miner, purely for pleasure and I do like a good puzzle, and trying to write code is proving to be quite puzzling ... ive got the guy moving about and jumping ,landing on different platforms, collecting items and dying when falling to far or hitting baddies... all good, But ..... when I come to the edge of any platform and moving my character frame by frame to the right he falls off the edge a good few pixels before he should and I cant for the life of me figure out how this is happening..... 4 frames of animation for left movement.... 4 frames for the right movement. automidhandle true or not doesn't matter.... the screen maps are laid out in an array, x and y pos' of char used to detect what he is stood on, but his position on moving right at the edge of a platform just goes to pot and I cant seem to figure out what im doing wrong.... Its got to be my maths , or there has to be a more efficient way, or to be a more accurate way in determining the position of the char with regards to what he is standing on any ideas would be much appreciated Chris. |
| ||
Without codesample it is a bit hard to tell, as we dont know in which way you are programming. Here is what i would do: To debug this, display the Player x and y coordinates on the screen. Display, aswell, the number of the platform/tile which he is on at that moment. Slowdown the game a bit, so that you can see the exact numbers when he fall down. Then look in your code,if you can see what is happening. |
| ||
Hi.... been trying lots of things like that more info............... animation frames 0 to 3 - right movement animation frames 4 to 8 - left movement xf = pixel movement between frames |
| ||
after checking the movement table : left movement codetable 0+9=9 -1 =8 1+9=10 -1 =9 2+9=11 -1 =10 3+9=12 -1 =11 right movement codetable 8 -9 =-1 +1=0 9 -9 = 0 +1=1 10-9 = 1 +1=2 11-9 = 2 +1=3 this looks ok sofar. Check the code where player is falling down, off the platform. either that, or youll need to define the edges of the screen anew, decreasing the value of where the player stops walking, by the players movement in pixel. instead of : ;-----------------------------stop going off edge of play area------------------- If x > 464 x = 464 xf = 472 use If x > 452 x = 452 xf = 460 Use the same for the opposite direction, but in that case increasing the value. as written earlier, for debugging purpose,display the player x/y coordinates on the screen, and every other info which may appear significant.Like Frame, frame step, tile x, tile y etc. This will allow you to watch the variables in realtime, while playing the game. This is how i do debugging, when there is a need for it. You can uncomment or delete this debugging code later, after you have found and replaced the bugs. It is hard to tell where the error lies, if there is not much of information available. |
| ||
Hiya again..... ive started all over again and trying different things Im definitely not gonna give up my day job... if any one want to have a look at this ... any ideas would be gooood.... any where on the play area there is a 0 ,, as in no floor on frame 0 and frame 7 is when willy will fall through the gap obviously when there is more than one single 16 pixel gap all frames of the animation are susceptible to blk1 returning 0. Graphics 512,384,16,2 SetBuffer BackBuffer() AutoMidHandle = True ;create game timer timer = CreateTimer(15) ;load sprite images Global item=LoadAnimImage("items.png",16,16,0,7) Global ground=LoadAnimImage("16x16floors.png",16,16,0,8) Global lv1=LoadImage("central cavern.png") Global sprite=LoadAnimImage("32x32.png",32,32,0,144) ;load sounds Global collect=LoadSound("pick.wav") Global jump=LoadSound("jump.wav") Global die=LoadSound("die.wav") ;Declare some varibles Global x# = 32 Global y# = 208 Global xf# = 32 ; x cord' 4 pixels at a time Global frame = 0 Global dir = 1 Dim gnd(29,15) ;-------------------------read map data into gnd array------------------------------ For r = 0 To 15 For q = 0 To 29 Read gnd(q,r) Next Next .mapdata Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,1,1,0,1,0,0,1,1,1,1,1,4,4,4,4,1,1,4,4,4,4,1,1,1,1,1,1,1,1 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,1,1,1,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,4,4,4,4,1,1,1,1 Data 1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,0,1,1,0,1,0,1,0,0,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1 ;-------------------------Main Loop-------------------------------------- While Not KeyHit(1) Cls main() willy() ; checkcollisions() Flip ;wait for game timer WaitTimer timer Wend End ;------------------------------------------------------------------------- ;--------------------Draw all the stuff---------------------------------- Function main() DrawImage lv1,0,0 For gndx = 0 To 29 For gndy = 0 To 15 If gnd(gndx,gndy) = 0 Else DrawImage ground,16+gndx*16,gndy*16,gnd(gndx,gndy) EndIf Next Next DrawImage sprite,x,y,frame ;draw willy. ;------------------------------------------------------------------------- ;what block is willy standing on? ;having issues here ;trying all sorts of things ;but as yet tna... blk1 = gnd(x/16,y/16+2) If x = 16 blk1 = gnd(0,y/16+2) EndIf ;------------------------------------------------------------------------- ;some constants that change ;for debug use only. Text 0,280,"x = " + x Text 0,300,"y = " + y Text 0,320,"xf cord = " + xf Text 0,340,"frame = " + frame Text 150,280,"blk1 = " + blk1 Text 150,300,"blk1 x = " + (x/16) Text 150,320,"blk1 y = " + (y/16+2) Text 150,340,"dir = " + dir End Function ;------------------------------------------------------------------------- ;-----------------------------Willy Move Right---------------------------- ;dir var' for direction ,,, ;Not sure how this is gonna help me yet though. Function willy() If KeyDown(205) dir = 1 whatframeright = frame ;get what frame willy was at from opposite direction Select whatframeright ;make willy start off in the correct ;frame when he turns around Case 4 ;without messing with his x cord' frame = -1 ;same with the left turn code below. xf = xf - 4 Case 5 frame = 0 xf = xf - 4 Case 6 frame = 1 xf = xf - 4 Case 7 frame = 2 xf = xf - 4 End Select frame = frame + 1 xf=xf+4 If frame = 4 frame = 0 x=x+16 EndIf EndIf ;-----------------------------Willy Move Left---------------------------- If KeyDown(203) dir = 2 ;var' for direction ,,, not sure how this is gonna help me yet though. whatframeleft = frame ;get what frame willy was at from opposite direction Select whatframeleft Case 0 frame = 5 xf = xf + 4 Case 1 frame = 6 xf = xf + 4 Case 2 frame = 7 xf = xf + 4 Case 3 frame = 8 xf = xf + 4 End Select frame = frame - 1 xf=xf-4 If frame = 3 frame = 7 x = x -16 EndIf EndIf ;---------------------Edge of Screen ?----------------------------------------- If x > 464 x = 464 xf=x frame = 3 EndIf ;just so willy wont walk off the ;edge of the play area If x < 16 x = 16 xf=x frame = 4 EndIf End Function ;------------------------------------------------------------------------------ |
| ||
ok looking at your example, i now see that i have been far off the road: i thought, you were using collision detection, with the map, to determine where willy shall fall off. as i have drawn very simple images, to test your code (very blocky ;( ), i have more questions to this: Shall willy fall down off the single gap ? (the single 0 on the map) ? Shall willy fall down only on the double gap ? Do you want willy to fall down, only when he has specific frame number ? and which frame number shall it be. look on this picture: ![]() this is how it actually shall be: 1.starting from the left side on the first block 2.walking 4 frames 3.the next block starts with the frame 1 4.repeat from 1 now test your code whith this mapdata .mapdata Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,1,1,0,1,0,0,1,1,1,1,1,4,4,4,4,1,1,4,4,4,4,1,1,1,1,1,1,1,1 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,1,1,1,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,4,4,4,4,1,1,1,1 Data 1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2 watch carefully when the willy is at the left side of this map. you will see, that blk1 is jupming from 3 directly to 1, which should not be. that can only mean, that his position is not calculated exactly as it should be. so the right way would be this: blk1 = gnd((x/16)-1,y/16+2) ; If x = 16 ; blk1 = gnd(0,y/16+2) ; EndIf and to fit the whole block range: If x > 476 x = 476 xf=x frame = 3 EndIf |
| ||
Hiya Dan.... Yes I have tried that -1 on the x cord to floor calculation but it has more of a negative effect when walking left.... besides that tho..... as per your diagram... when willy is walking left or right when he gets to the very edge of solid ground frame 0 and frame 7 are the candidates for willy to fall so for instance when I have the jump code added ,( which I have got down pretty much just haven't included it here , trying to keep code to a minimum ish !)..... If willy lands real close to a gap like say frame 1 jumping right or frame 6 jumping left he wont fall but just land on the edge of the floor.... (whilst jumping he goes through the animation frames as for walking in the direction he jumped ) Only frame 0 for moving right and frame 7 for moving left will he fall through a gap of 16 pixels wide. obviously if whilst jumping willy is say at frame 4 or any other frame for that matter , he would still fall through a gap if it is more than 16 pixels wide. It has to be all in the way im trying to work out what part of the floor im standing on and just a division of his x cord to the floor tile position is not gonna cut it... Ive been trying to think of a way to calculate that position with a lot more accuracy .... but now im starting to lose hair through pulling it out lol...... Chris. |
| ||
i have to say that i dont understand exactly what you mean. here im reffering to my above picture If the jumping calculation would be as from frame 4 to frame 1 = 4*4 pixels ,it would make him to jump over one gap. in this way, if he jumps out of the frame 3 he would land on frame 4. if he needs to fall down, when he is on empty block and frame 0, then you can simply do: if blk1=0 and (frame=0 or frame=7) then falldowncode but this would not make him fall down if the next block is empty. so you could make an extra check at the landing time: blk2 would hold the next cell,in the direction which he is facing. and then do a check if blk2=0 ; the next cell is empty if blk1=0 then falldowncode else ;next cell is not empty, only frames 0 or 7 can fall down if blk1=0 and (frame=0 or frame=7) then falldowncode endIf |
| ||
Have you had a go at this version http://retrospec.sgn.net/game-links.php?link=mm blitz version of said game ive been looking at his code but its a bit intense !! |
| ||
iv just checked the code for the willy's movement from that game, interesting way of doing the keycheck. it is a bit complicated to follow the code, at first. The author havent made any comments for the variables and would take a bit until one can uderstand what they do. |
| ||
It does look very interesting.... I have tried to follow it .... but alas tna. My intention is not to copy it though.... just to see if it could spark any ideas. im thinking along the lines at the moment of checking the frame movement and what block is in front of willy before standing on it as it seems the problem lies in the fact that willys x cord' only increments 16 pixels at a time, that's why the xf variable for the frame . Like... If xf not equal to x , moving left or right...what frame is he in.... get the nearest block + or - 16 relevant to x sommin along those confusing lines. |
| ||
here is a link to file dropper with the source and data files for what I have at the moment if you wanna look see and test it out http://www.filedropper.com/willy |
| ||
thanks for the sources and the images, now it is easier to see where willy is walking. the correct way to use the automidhandle is: AutoMidHandle True without = just found this out, by testing what happens, if the sprite has different points on the handle. but this doesnt look good on the game, as it is now ;) |
| ||
ahh I see .... I could kick myself for that !! the automidhandle would include all things printed but with Global sprite sprite=LoadAnimImage("32x32.png",32,32,0,144) MidHandle sprite its just the sprite image that gets the midhandle treatment :) hopefully it will make things a bit easier.... tbc |
| ||
here are few changes, that i have made to the game, maybe youll find it usefull: (replace your code by copy and pasting this over) 1. Graphics 512,384,16,2 Graphics 512,384,16,3 ;makes the window resizeable, allowing it to display in fullscreen 2. Global sprite=LoadAnimImage("32x32.png",32,32,0,144) HandleImage sprite,4,0 3. DrawImage ground,16+gndx*16,gndy*16,gnd(gndx,gndy) Text 16+gndx*16,gndy*16,gnd(gndx,gndy) ;Debugging purpose, display the blocknumbers 4. 5. |
| ||
Well ,,, what can I say :) You have seemed to have got it sorted.... my brain is just getting too old I think lol... thanks for your help in solving that conundrum on to the jumping code now |
| ||
hmmm.... After a closer look its still doing the same thing |
| ||
I got it !!!!!! bit crude for the moment but it does do what I wanted have to think of a way to tidy it up a bit. If dir = 1 And frame < 2 blk1=gnd(x/16-1,y/16+2) EndIf If dir = 1 And frame >= 2 nextblockx = gnd(x/16,y/16+2) blk1 = nextblockx If nextblockx = 0 blk1 = gnd(x/16-1,y/16+2) EndIf EndIf If dir = 2 And frame > 5 blk1 = gnd(x/16,y/16+2) EndIf If dir = 2 And frame <= 5 nextblockx = gnd(x/16-1,y/16+2) blk1 = nextblockx If nextblockx = 0 blk1 = gnd(x/16,y/16+2) EndIf EndIf |
| ||
looking at it again.... prob could do away with the nextblockx var it seemed to help the thought process to split it up like that :) |