jbs30000 Posted March 30, 2007 Share Posted March 30, 2007 (edited) First off, forgive me for how long this is going to be. It's increadibly rare for me to write a post this long. OK, so I'm working on the Light Cycle game for the Tron game I'm making. I have the perfect code for moving around the player, but for the past 3 or 4 days I've not been able to make a decent collision check for the enemy lightcycle(s). So a few minutes ago, I pulled out some code and placed it in a new file. All it's supposed to do is draw a light cycle and then two playfield blocks side by side underneath it. Since the standard playfield block is 4x8 pixels then the light traces are 2 pf pixels togeather so that the light walls will be 8x8. In order to move the player and the enemies I have a data lookup table of X and Y locations to place the light cycles (PX and PY) and the light traces (LX and LY) All right, so, here's the code from the test program. When I run it, the playfield: command should cause a wall on the left side, but instead I get some pixels seperated by a space of 2 or 3 pixels, instead of a continuous line. Then, if I take out the + 1 from NextY = LY[Enemy1y] + 1 then the playfield pixels line up under the light cycle just fine, but add the + 1, and there's only partial playfield pixels underneath. Of course, if you run this program, and everything looks like it should, then maybe I have a/some corrupt DASM or bB files and need to redownload them. Anyway, here's the code: set kernel_options pfcolors no_blank_lines set smartbranching on dim CurX=a dim CurY=b dim NextX=c dim NextY=d dim Enemy1x=e dim Enemy1y=f data PX 21,29,37,45,53,61,69,77,85,93,101,109,117,125,133 end data PY 15,23,31,39,47,55,63,71,79 end data LX 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29 end data LY 1,2,3,4,5,6,7,8,9 end data HC 10,8,6 end playfield: X............................... X............................... X............................... X............................... X............................... X............................... X............................... X............................... X............................... X............................... X............................... end COLUPF = 254 player0: %00000000 %01111110 %01100110 %00100100 %00100100 %01100110 %00111100 %00000000 end rem Enemy1x = 5: Enemy1y = 5 rem player0x = PX[Enemy1x]: player0y = PY[Enemy1y] rem NextX = LX[Enemy1x]: NextY = LY[Enemy1y] + 1 rem pfpixel NextX NextY on: NextX = NextX + 1: pfpixel NextX NextY on Main COLUP0 = 64: scorecolor = 14: COLUPF = 254: drawscreen goto Main Also, if I could have some advice on colliison detection, I've tried a few different things but with no luck. Since I only want to draw the screen when moving the cycles, as oppsed to when I'm checking for collisons, I try to check for playfield pixels. For example, if the cycle is moving up, then I check for pixels above it. If there are pixels then I check to the left, and if there are some there, then to the right. If the enemy will collide no matter what, then I keep it going in the direction it's already going and let it crash. However, I can't do it right. This wil make this long post even longer, but I'll show the variables I use and what they mean. This is all probably needlessly complicated, but here's code for checking the first light cycle First, the code MoveLC1 if Enemy1y = 0 then goto MoveLC2 Arg1=(Direction&Enemy1)/4: CurX = Enemy1x: CurY = Enemy1y: gosub ELCCT Direction=(Direction&Enemies23)|(Arg2*4) Enemy1x = Enemy1x + NextX: Enemy1y = Enemy1y + NextY ELCCT on Arg1 goto CTU CTD CTL CTR CTU gosub DLTU: if Arg2 = 0 then NextX = 0: NextY = 255: return thisbank gosub DLTL: if Arg2 = 2 then NextX = 255: NextY = 0: return thisbank gosub DLTR: if Arg2 = 3 then NextX = 3: NextY = 0: return thisbank Arg2 = 0: NextX = 0: NextY = 255: return thisbank CTD gosub DLTD: if Arg2 = 1 then NextX = 0: NextY = 1: return thisbank gosub DLTL: if Arg2 = 2 then NextX = 255: NextY = 0: return thisbank gosub DLTR: if Arg2 = 3 then NextX = 3: NextY = 0: return thisbank Arg2 = 1: NextX = 0: NextY = 255: return thisbank CTL gosub DLTL: if Arg2 = 2 then NextX = 255: NextY = 0: return thisbank gosub DLTU: if Arg2 = 0 then NextX = 0: NextY = 255: return thisbank gosub DLTD: if Arg2 = 1 then NextX = 0: NextY = 1: return thisbank Arg2 = 2: NextX = 255: NextY = 0 CTR gosub DLTR: if Arg2 = 3 then NextX = 1: NextY = 0: return thisbank gosub DLTU: if Arg2 = 0 then NextX = 0: NextY = 255: return thisbank gosub DLTD: if Arg2 = 1 then NextX = 0: NextY = 1: return thisbank Arg2 = 3: NextX = 1: NextY = 0 DLTU DLTD DLTL DLTR Direction holds which way all the cycles are moving. {0}{1}Player {2}{3}Enemy1 {4}{5}Enemy2 {6}{7}Enemy 3 The bits work like this 00 = Up, 01 = Down, 10 = Left, 11 = Right. For each cycle, the directions are divided by 4, 16, or 64 so that Arg1 holds 0, 1, 2, or 3 (Up, Down, Left, Right). Then, in ELCCT (Enemy Light Cycle Collision Test) check 3 directions depending on which way the cycle is going. In CTU (Collision Test Up) check up, if there's a light trace there, then check left, if a light trace is there, then check right. If a light trace is there, keep going up. For CTL check left, if a light trace is there, then check up and down. Etc... Returning from this sub, Direction is updated and Enemy1/2/3X or Enemy1/2/3Y is increased or decreased accordingly. The problem is with writting a good routine for DLTU/D/L/R (Detect Light Trace Up/Down/Left/Right). What I've tried to do is place the locations to check out in NextX and NextY and either return Arg2 with the direction to go if the way is clear, or 255 if there will be a crash. Basically, say to check for light traces above the the cycle, I'd go something like: NextX = LX[CurX]: NextY = CurY - 1: NextY = LY[NextY] then use pfread(NextX, NextY) to see if a playfield pixel is there. And, to be safe, maybe increase NextX by 1 and check again since the light walls are made up of 2 pixels across. Anyway, if you read all this, and I explained everything clearly any and all help would be appreciated. Thanks. Edited March 30, 2007 by jbs30000 Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted March 30, 2007 Share Posted March 30, 2007 the playfield: command should cause a wall on the left side, but instead I get some pixels seperated by a space of 2 or 3 pixels, instead of a continuous line. It's because you specified the "pfcolors" kernel option, but you didn't include a "pfcolors:" statement in the sample code. The playfield pixels are being drawn correctly, but since you didn't specify what the colors should be for each row, some rows are black (so they're essentially "invisible" against the black background), and some rows are blue. You can see this by setting the background color to something other than black, such as "COLUBK = 4" (gray). To fix it, you should either remove the "pfcolors" kernel option from the sample code, or else put in a "pfcolors:" statement to set the color for each row of the playfield. Also, if I could have some advice on colliison detection, I've tried a few different things but with no luck. This one will take a little longer to figure out! I'll read through your explanation and check the code to see what kind of suggestions I can offer. Michael Quote Link to comment Share on other sites More sharing options...
jbs30000 Posted March 30, 2007 Author Share Posted March 30, 2007 (edited) Yeah, it is pretty complicated. I shouldn't have posted it probably. Hey, I know, just ignore everything in the second code box. Just use what's in the first. Basically, for the cycle, there are two variables to hold the X and Y positions. X is any value 0 to 14 and Y is 0 to 8. To place the cycle on the screen player0x is PX[X variable] and player0y is PY[Y variable]. For the light traces the same X and Y variables are used, but with the LX and LY data statements: pfpixel LX[X variable] LY[Y variable] on. Also, since a light trace is two pixels side by side, then there's an additional pfpixel LX[X variable + 1] LY[Y variable] on. So, logically, if you're checking for light traces, all that should be required is a variable to be one more or one less......for example, to check for a light trace above the cycle it should just simply be a case of pfread(LX[X variable], LY[Y variable - 1]), but that kind of checking doesn't seem to work. There, that was a lot shorter and less complicated than in the first post. Edited March 30, 2007 by jbs30000 Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted March 30, 2007 Share Posted March 30, 2007 I'm experimenting with using the Superchip so the playfield pixels can be smaller, and using smaller light cycles (4x4 instead of 8x8-- or really 6x6, since you've got blank rows and columns on all sides of the players). But I have to go to bed now, so I won't be able to post any suggestions until Friday night. Michael Quote Link to comment Share on other sites More sharing options...
jbs30000 Posted March 30, 2007 Author Share Posted March 30, 2007 I'm experimenting with using the Superchip so the playfield pixels can be smaller, and using smaller light cycles (4x4 instead of 8x8-- or really 6x6, since you've got blank rows and columns on all sides of the players). But I have to go to bed now, so I won't be able to post any suggestions until Friday night. Michael After I finish (if I can finish) my game using the standard kernel, I'm going to make another using the superchip. I already remade the playfields using 32x32 screen, so the main screen looks better (although I couldn't make it look like the origional) and the tank screen will look just like what's in the arcade game. Quote Link to comment Share on other sites More sharing options...
jbs30000 Posted March 31, 2007 Author Share Posted March 31, 2007 OK, I've been going about this all wrong. I pulled out the code for the light cycle game and placed it in its own program. Everything runs real slow, but it runs. You can control the blue (player) light cycle and there are 3 yellow enemy cycles. There's a timer that every 5 seconds (and also every 3 if you're holding down the trigger) will call the routine to move the blue cycle, then the enemy cycles. The way I have it now, the enemy cycles are move twice. The first is just to check for collisions, and the other is the actual moving of the cycle. However, this doesn't quiet work, and one cycle crashes almost instantly, and one of the others, or both, sometimes drive outside the square border surrounding the playfield. Anyway, all the code's here, so if it's still to hard or complicated, I'll just scrap it and start from scratch. Test.basTest.bas.bin Quote Link to comment 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.