+atari2600land Posted December 31, 2006 Share Posted December 31, 2006 From now on, when I have a problem with some code, I'll post it on this topic. And, knowing me, I'll probably have a lot of problems from now on. Problem the first: I got a "kamikaze" sub up and going (see Homebrew thread on GoSub). The problem is I set the x and y variables for it (i & j) to random. Usually it just ends up on the left side border, but when it doesn't, it just goes into a wall and stops. Why does it usually end up stuck on the left side border, and why does it stop once it reaches a wall? gosub123106a.bas Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/ Share on other sites More sharing options...
SeaGtGruff Posted December 31, 2006 Share Posted December 31, 2006 I got a "kamikaze" sub up and going (see Homebrew thread on GoSub). The problem is I set the x and y variables for it (i & j) to random. Usually it just ends up on the left side border, but when it doesn't, it just goes into a wall and stops. Why does it usually end up stuck on the left side border, and why does it stop once it reaches a wall? I haven't figured everything out yet, but you aren't going to the line where you set player1x and player1y (line 505). Instead, after you perform the routines in bank2, you're jumping to line 542. Unfortunately, if I change line 505 to line 542, or change all the goto statements so they jump to line 505, the program either doesn't display the second sub at all, or it just draws a blank screen! I'll keep looking and see if I can figure it out. Michael Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/#findComment-1207020 Share on other sites More sharing options...
+atari2600land Posted December 31, 2006 Author Share Posted December 31, 2006 In lines 493 & 494, I initially set player1x & player1y to be random. And if I move line 505 to be with the others in line 606, the player1 sub doesn't show up at all. So that's why I moved it to be 505. There is a place where I tell the program to draw a blank screen (line 1700 in bank 2.), but that's for the title screen. Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/#findComment-1207236 Share on other sites More sharing options...
SeaGtGruff Posted December 31, 2006 Share Posted December 31, 2006 (edited) In lines 493 & 494, I initially set player1x & player1y to be random. And if I move line 505 to be with the others in line 606, the player1 sub doesn't show up at all. So that's why I moved it to be 505. There is a place where I tell the program to draw a blank screen (line 1700 in bank 2.), but that's for the title screen. Your current problems are being caused by the way some of the lines are arranged (i.e., the order they're performed in), and also some comparison signs (i.e., < and >) that are backwards, but I'm not entirely sure yet what all needs to be done, so I'll do this step-by-step and see what happens: (1) In the comparisons between line 618 and line 620, the comparison signs are backwards, so you need to change them to point in the opposite directions: Current buggy code: 618 s=rand if s>=32 then s=1 if s<32 && s>=64 then s=2 if s<64 && s>=96 then s=3 if s<96 && s>=128 then s=4 if s<128 && s>=160 then s=5 if s<160 && s>=192 then s=6 if s<192 && s>=224 then s=7 if s<224 && s>=255 then s=8 620 if s=1 then i=255 Corrected code: 618 s=rand if s<=32 then s=1 if s>32 && s<=64 then s=2 if s>64 && s<=96 then s=3 if s>96 && s<=128 then s=4 if s>128 && s<=160 then s=5 if s>160 && s<=192 then s=6 if s>192 && s<=224 then s=7 if s>224 && s<=255 then s=8 620 if s=1 then i=255 This is where you're making the second sub move around randomly, so that's part of the reason why there's a problem with the second sub's movement. Basically, the way it's currently coded, the first if statement will set s so it's less than 32 (i.e., if it's greater than or equal to 32, it will be set to 1; but if it's already less than 32, it will be left alone), and the other if statements never do anything (e.g., a number can't be less than 32 and greater than or equal to 64 at the same time, etc.). So it's possible for s to be between 9 and 31 when the program reaches line 620, in which case the program will fall through all of the if statements in lines 620 through line 627, and will do line 666 without first setting the values of i and j as desired. After you fix the directions that the comparison signs are pointing in (as shown above), s will always be set to 1 through 8 by the time it reaches line 620. I haven't checked all the other comparisons in the program, but if you're like some people, and tend to have trouble remembering which way the arrow is supposed to be pointing for a less than and for a greater than (and I've met a lot of people who have that trouble, so I know it's pretty common-- and even if you don't usually have that trouble, I can personally attest to how easy it is to make a typo or other kinds of coding mistakes), then you might want to scan through the rest of the program and see if there are any other places where the comparison signs need to be pointed in the opposite directions. Remember: The "arrow" or pointy end of the comparison sign should point to the side with the smaller number-- e.g., 4<6, or 10>2. (2) There are at least two places where you're trying to check for a collision right after updating the position of an object, but before you've actually redrawn the screen with the object's new position. You must always redraw the screen with the updated graphic shapes and positions before you can check for a collision, otherwise you'll end up looking at however the collision flags were set *before* the graphics were updated. In lines 505 and 506, you set player1's position to the random i and j values, then check to see if player1 has collided with the playfield; but you haven't drawn the screen yet, so you need to draw the screen after setting player1's position: Current buggy code: 505 player1x=i : player1y=j 506 if collision(player1,playfield) then goto 493 Corrected code: 505 player1x=i : player1y=j : drawscreen 506 if collision(player1,playfield) then goto 493 (3) Likewise, in lines 666 and 668, you update player1's position by adding the incremental values of i and j, then check to see if player1 has collided with the playfield; but you haven't drawn the screen yet with the new position. However, you can't just add a drawscreen command as in the previous case, because what you're trying to do in line 668 is bump the second sub back if it's just hit a wall, and you can't do that by subtracting i and j if you've already changed i and j to new values (i.e., if you want to bump the second sub back in the direction it just came from, you have to subtract the old values of i and j). Thus, line 668 needs to be moved up so it comes before lines 620 through 627 (i.e., before i and j get set to new values). Also, in lines 620 through 627, there are some cases where you aren't setting i or aren't setting j, because you want them to be 0. You *are* resetting them both to 0 in line 670, so after the first time through, they should be 0 by the time you loop back and get to line 620 again. However, it would be better to move line 670 up so it comes before line 620, but after line 668 (meaning the new position of line 668, once you've moved it up in front of line 620), because otherwise i or j could be left at some other random value the *first* time the program reaches line 620 (i.e., because they'll still be set to whatever random value they got set to in lines 493 and 494). Thus, the code should look something like the following: Current buggy code (with the first line corrected as shown in number 1 above): if s>224 && s<=255 then s=8 620 if s=1 then i=255 621 if s=2 then i=1 622 if s=3 then j=255 623 if s=4 then j=1 624 if s=5 then i=255 : j=1 625 if s=6 then i=255 : j=255 626 if s=7 then i=1 : j=255 627 if s=8 then i=i : j=1 666 player1x=player1x+i : player1y=player1y+j 668 if collision(player1,playfield) then player1x=player1x-i : player1y=player1y-j 670 i=0 : j=0 Corrected code: if s>224 && s<=255 then s=8 668 if collision(player1,playfield) then player1x=player1x-i : player1y=player1y-j 670 i=0 : j=0 620 if s=1 then i=255 621 if s=2 then i=1 622 if s=3 then j=255 623 if s=4 then j=1 624 if s=5 then i=255 : j=1 625 if s=6 then i=255 : j=255 626 if s=7 then i=1 : j=255 627 if s=8 then i=i : j=1 666 player1x=player1x+i : player1y=player1y+j You might want to scan through the program for other places where you're checking for collisions before actually redrawing the screen with any updated graphics. (4) As I mentioned last night (although I might not have been very clear, since it was late and I was half asleep), you aren't actually performing lines 505 and 506 after you define the playfield for the current level, because after you goto the routines in bank2 that set up the playfield for each level, you're doing goto 542, so lines 505 and 506 are getting skipped. You can fix that by changing all of those goto statements so they goto 505 instead of 542. But be careful when making that change, because there's also a goto 542 in line 869, and *that* goto needs to be left as is. So the lines you need to change are 1128, 1134, 1138, 1143, 1148, 1153, 1158, 1163, 1168, 1173, 1178, 1187, 1193, 1198, 1203, 1208, 1213, 1218, 1223, and 1776, as follows (I'm showing just line 1128): Current buggy code: 1128 goto 542 bank1 Corrected code: 1128 goto 505 bank1 If you make the various changes described above, the problems you're currently having with the second sub should be corrected. However, the second sub is now moving around in a jittery manner, because of how its movement is being randomized. Aside from looking very unnatural for a sub, it makes it extremely difficult for the player's sub to squeeze past the second sub. I suggest that you change the way you're moving the second sub around. For example, one idea is to keep the same values of i and j until the second sub hits a wall, and when it does finally hit a wall, bump it back and *then* (and only then) set i and j to new random values. This should make the second sub bounce around a bit like Pong, but will bounce it in an unpredictable direction whenever it hits a wall. Another idea is to have the second sub move in the same random direction for a second or two, then stop for a second or two, and then move in a different random direction for a second or two, etc. To do that, you could add another counter that goes from 0 to 60, or from 0 to 120, etc. You could increment the counter each frame, and reset it to 0 whenever it hits 60 or 120 or whatever-- but each time you reset the counter, either set i and j to new random values, or set them both to 0. You could even combine these two ideas, so the second sub moves in a particular random direction for a second, but bounces off the walls in another random direction if it hits a wall, then stops for a second, then moves again for a second, then stops, etc. Anyway, I'm posting the code with the changes described above, but I'm not doing anything with the second sub's random movement, since I don't know how you want it to behave. However, if you'd like to try either or both of my suggestions, I'll be happy to help you add or change the code for it. Michael (PS -- The code is named gosub123106c.bas, because last night I was messing around with it using the name gosub123106b.bas, and I kind of murderated it. I used c for the new version, so I could compare versions a and b to see what I'd been trying to do in version b.) gosub123106c.bas Edited December 31, 2006 by SeaGtGruff Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/#findComment-1207444 Share on other sites More sharing options...
+atari2600land Posted January 1, 2007 Author Share Posted January 1, 2007 (edited) However, the second sub is now moving around in a jittery manner, because of how its movement is being randomized. Aside from looking very unnatural for a sub, it makes it extremely difficult for the player's sub to squeeze past the second sub. Another idea is to have the second sub move in the same random direction for a second or two, then stop for a second or two, and then move in a different random direction for a second or two, etc. To do that, you could add another counter that goes from 0 to 60, or from 0 to 120, etc. You could increment the counter each frame, and reset it to 0 whenever it hits 60 or 120 or whatever-- but each time you reset the counter, either set i and j to new random values, or set them both to 0. You could even combine these two ideas, so the second sub moves in a particular random direction for a second, but bounces off the walls in another random direction if it hits a wall, then stops for a second, then moves again for a second, then stops, etc. Phew! That's a lot of work you did for me! Thank you very much! I'm currently trying to figure out the idea posted above. I've got it to a point where it appears in every level. Also, the timer I'm using for this is the variable k. Now all I have to do is figure out how to make it move more slowly. It seems like line 710 isn't working the way it should. EDIT: Also, I'm having a little trouble with the selectswitch on the title screen that hopefully someone will be able to help me with. In gosub010107.bas, game 1 is no enemy ship and game 2 has enemy ship. I can't seem to make the selectswitch work. gosub123106d.bas gosub010107.bas Edited January 1, 2007 by atari2600land Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/#findComment-1207519 Share on other sites More sharing options...
SeaGtGruff Posted January 1, 2007 Share Posted January 1, 2007 (edited) However, the second sub is now moving around in a jittery manner, because of how its movement is being randomized. Aside from looking very unnatural for a sub, it makes it extremely difficult for the player's sub to squeeze past the second sub. Another idea is to have the second sub move in the same random direction for a second or two, then stop for a second or two, and then move in a different random direction for a second or two, etc. To do that, you could add another counter that goes from 0 to 60, or from 0 to 120, etc. You could increment the counter each frame, and reset it to 0 whenever it hits 60 or 120 or whatever-- but each time you reset the counter, either set i and j to new random values, or set them both to 0. You could even combine these two ideas, so the second sub moves in a particular random direction for a second, but bounces off the walls in another random direction if it hits a wall, then stops for a second, then moves again for a second, then stops, etc. Phew! That's a lot of work you did for me! Thank you very much! I'm currently trying to figure out the idea posted above. I've got it to a point where it appears in every level. Also, the timer I'm using for this is the variable k. Now all I have to do is figure out how to make it move more slowly. It seems like line 710 isn't working the way it should. No, line 710 is working fine. What you need to do is update player1's position every other frame to make it move half as fast, or every third frame to make it move a third as fast, or every fourth frame to make it move a fourth as fast, etc. I tried every fourth frame and it didn't look too good-- it was too slow; the sub moved in little jerks or steps instead of moving smoothely. Every other frame looks better. The easiest way to do this is to add an if to line 766, where player1's position is being updated, such as follows: 766 if k{0} then player1x=player1x+i : player1y=player1y+j Since k is the variable you added for counting the frames, you can check k{0} to see if it's an odd frame or an even frame. For example, if k=0, or k=2, or k=4, or k=6, etc., then the above if will make the program skip over the updating of player1's position, since k{0} will be 0 (or "false"). But if k=1, or k=3, or k=5, etc., then k{0} will be 1 (or "true"), so player1's position will be updated. EDIT: Also, I'm having a little trouble with the selectswitch on the title screen that hopefully someone will be able to help me with. In gosub010107.bas, game 1 is no enemy ship and game 2 has enemy ship. I can't seem to make the selectswitch work. It's the way you're doing the if statements when the select switch is pressed: 166 if c{3} then c{3}=0 if !c{3} then c{3}=1 If c{3} is true (equal to 1), then the two if statements at line 166 will turn c{3} off and on again, like saying "if the light is on, turn it off; if the light is off, turn it on." If the light is on and you turn it off, then you're just going to turn around and turn it back on again because now it's off, if you see what I mean. You could fix it by sticking a goto 167 on the end of the first if, but the simplest way to fix it is to turn the second if into an else, as follows: 166 if c{3} then c{3}=0 else c{3}=1 I'm posting the code with that fix in it, plus I moved line 768 above line 766 (because the collision check in line 768 is going to apply to wherever player1 was *before* you updated its position in line 766-- since you haven't redrawn the screen yet after updating player1's position-- so it makes more sense to put line 768 before line 766), and I also added if k{0} to line 766 to slow the second sub down a bit: 768 if collision(player1,player0) then goto 880 766 if k{0} then player1x=player1x+i : player1y=player1y+j Michael gosub010107a.bas Edited January 1, 2007 by SeaGtGruff Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/#findComment-1207719 Share on other sites More sharing options...
SeaGtGruff Posted January 1, 2007 Share Posted January 1, 2007 By the way, there's a few more little changes you ought to make. I had made these changes in the version b that I was messing with last night, but at that time I hadn't spotted the problem with the < and > signs, so I never got version b working right. And when I posted version c, I forgot to make these changes again. So that's why, when you press RESET to begin the game, you see the GOSUB title flicker around the maze for a half second or so! Line 542 defines player1's shape for the second sub, but (1) you don't need to keep looping back to line 542-- since once you define player1's shape, it should stay that shape until you define it to be some other shape-- and (2) you need to put that player1: statement up above the point where you first draw the screen after RESET has been pressed. So you *could* change 505 player1x=i : player1y=j : drawscreen 506 if collision(player1,playfield) then goto 493 : rem changed line (if v=1 &&) 541 s=0 542 player1: %01111110 %11111111 %11111111 %11111111 %01111110 %00001000 %00001000 %00111000 end 603 if !c{0} then u=4 : e=8 : g=14 : COLUP0=0 to be as follows: 542 player1: %01111110 %11111111 %11111111 %11111111 %01111110 %00001000 %00001000 %00111000 end 505 player1x=i : player1y=j : drawscreen 506 if collision(player1,playfield) then goto 493 : rem changed line (if v=1 &&) 541 s=0 603 if !c{0} then u=4 : e=8 : g=14 : COLUP0=0 Unfortunately, that means you'd have to change all those goto statements from goto 505 back to goto 542, and then change the goto in line 869 to goto 603. So at this point it would be much simpler (less stuff to change) to move line 542 up to where you set i and j to random values: 492 byte2=$3B : q=3 : timer=0 : timer2=0 : timer3=m : c{4}=0 542 player1: %01111110 %11111111 %11111111 %11111111 %01111110 %00001000 %00001000 %00111000 end 493 i=rand if i<40 then goto 493 if i>150 then goto 493 494 j=rand if j<28 then goto 494 if j>80 then goto 494 541 s=0 603 if !c{0} then u=4 : e=8 : g=14 : COLUP0=0 You *will* need to change the goto in line 869, since you don't want it to loop all the way back to the new location of line 542: 869 goto 603 By making these changes, the transition from the title screen to the level 1 screen won't have that momentary flashing with the title jumping around on top of the level 1 maze. Michael gosub010107b.bas Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/#findComment-1207732 Share on other sites More sharing options...
+atari2600land Posted January 1, 2007 Author Share Posted January 1, 2007 You are definitely going to be credited with programming with me in the credits listed in the manual, Mike (that is, if it makes it to the store.) Anyway, I made the enemy sub smaller so it's easier to avoid, but I think I may have to scrap it altogether if it's unpopular enough. gosub010107c.bas.bin gosub010107c.bas Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/#findComment-1207940 Share on other sites More sharing options...
+atari2600land Posted January 3, 2007 Author Share Posted January 3, 2007 How do I make the sub go through walls and yet still not go through the edges? I've tried to do this but I can't. gosub010207b.bas Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/#findComment-1209031 Share on other sites More sharing options...
+atari2600land Posted January 3, 2007 Author Share Posted January 3, 2007 Never mind. I figured it out. gosub010207e.bas Quote Link to comment https://forums.atariage.com/topic/99598-gosub-problem-thread/#findComment-1209099 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.