Jump to content
Sign in to follow this  
jbs30000

Problem with my program

Recommended Posts

This post will be kind of long, but I need to give plenty of information in order to ask for help.

 

In my Super Mario game adaptation I recently created a routine to determine if a collision occurs. There's three outcomes. 1, no collision occurs - 2, Mario lands on top of an enemy killing it - 3, an enemy collides with Mario killing him. I have a couple of problems. Sometimes I'd land on both enemies, kill them, walk a few steps to the right, and die for no apparent reason. So I REMed out the code to check for a crash into enemy 1. If I land on and kill enemy 2, enemy 1 dies as well. This shouldn't happen.

 

There are two enemies, one is player 0 and the other is player 1. Since players 0 and 1 make up Mario I have variables to hold the various positions:

Mario

dim X_Pos=k.l
dim Y_Pos=m

 

Enemy 1

dim Enemy1X=q
dim Enemy1Y=r

 

Enemy 2

dim Enemy2X=s
dim Enemy2Y=t

 

I also have two variables to determine if enemies 1 and 2 exist or not:

rem See if Enemy number 1 is on screen or not - (E)nemy (S)creen
def ES1=p{1}
rem See if Enemy number 2 is on screen or not - (E)nemy (S)creen
def ES2=p{2}

If the bit is set, the enemy is on the screen. If it is not set, no enemy.

 

Finally, some DEFs in my program:

dim Crash_Value=y
def No_Crash=0
def Land_on_Enemy=1
def Killed_By_Enemy=2

 

With that, here is the code to determine a crash:

function Crash_Detection
rem temp1 - 1=Enemy1, 2=Enemy2
if temp1=2 then goto Crash_Detect_Enemy2

Crash_Detect_Enemy1
if !ES1 then return No_Crash
rem If Mario is in front of or behind an enemy then no contact has been made.
temp1=Enemy1X-8: temp2=Enemy1X+8
if k<=temp1 || k>temp2 then return No_Crash
rem If Mario is 1 or more pixels above an enemy then no contact has been made
temp1=Enemy1Y-9
if Y_Pos<temp1 then return No_Crash
rem All remaining options are that a collision took place.  The following code will determine what type.
rem If Mario is jumping or he's not jumping or falling then it's an instant kill.
if Jumping then return Killed_By_Enemy
if !Falling then return Killed_By_Enemy
rem If Mario is falling, then if he's right on top of an enemy, or 4 pixels into an enemy, then he's landing on them and kills them.
temp1=Enemy1Y-4
if Y_Pos<=temp1 then return Land_on_Enemy
return Killed_By_Enemy

Crash_Detect_Enemy2
if !ES2 then return No_Crash
rem If Mario is in front of or behind an enemy then no contact has been made.
temp1=Enemy2X-8: temp2=Enemy2X+8
if k<temp1 || k>temp2 then return No_Crash
rem If Mario is 1 or more pixels above an enemy then no contact has been made
temp1=Enemy2Y-9
if Y_Pos<=temp1 then return No_Crash
rem All remaining options are that a collision took place.  The following code will determine what type.
rem If Mario is jumping or he's not jumping or falling then it's an instant kill.
if Jumping then return Killed_By_Enemy
if !Falling then return Killed_By_Enemy
rem If Mario is falling, then if he's right on top of an enemy, or 4 pixels into an enemy, then he's landing on them and kills them.
temp1=Enemy2Y-4
if Y_Pos<=temp1 then return Land_on_Enemy
return Killed_By_Enemy

end

Here is the code to see if a crash has happened.

rem Check to see if Mario has collided with an Enemy
if !ES1 then goto CV2
Crash_Value=Crash_Detection(1)
if Crash_Value=Killed_By_Enemy then goto End_Game
if Crash_Value=Land_on_Enemy then ES1=0: Enemy1X=0: Enemy1Y=0
CV2
if !ES2 then return otherbank
Crash_Value=Crash_Detection(2)
if Crash_Value=Killed_By_Enemy then goto End_Game
if Crash_Value=Land_on_Enemy then ES2=0: Enemy2X=0: Enemy2Y=0
return otherbank

Does anybody see any obvious errors that I am overlooking?

Share this post


Link to post
Share on other sites

I barely understand my own code, so I probably can't help. I do know that my program stopped following common sense and I think it probably broke the laws of physics and might have opened up a wormhole. Sometimes code that should work doesn't. At random times, bB will start requiring that only one thing can be on a line or it won't compile, or it will decide to ignore REM and run any code after it, or it will require that then goto be used within the same bank when smartbranching is on. I suspect that too many DEFs causes the problem, but I don't have proof.

 

Programming is hard enough when things are working correctly, but when the fabric of reality starts ripping apart, it's tempting to give up and do something easier, like build a spaceship and fly to Mars.

Edited by Random Terrain

Share this post


Link to post
Share on other sites

Nothing jumps out at me.

 

Can you open up the resulting .asm file and post the assembly code that resulted from line "if Crash_Value=Land_on_Enemy then ES1=0: Enemy1X=0: Enemy1Y=0"?

Share this post


Link to post
Share on other sites

Nothing jumps out at me.

 

Can you open up the resulting .asm file and post the assembly code that resulted from line "if Crash_Value=Land_on_Enemy then ES1=0: Enemy1X=0: Enemy1Y=0"?

.L0553		; if Crash_Value = Land_on_Enemy then ES1 = 0 : Enemy1X = 0 : Enemy1Y = 0
a5 ee		      LDA	Crash_Value
c9 01		      CMP	#1
d0 0c		      BNE	.skipL0553
.condpart142
a5 e5		      LDA	p
29 fd		      AND	#253
85 e5		      STA	p
a9 00		      LDA	#0
85 e6		      STA	Enemy1X
85 e7		      STA	Enemy1Y

And, for comparison's sake

.L0557		; if Crash_Value = Land_on_Enemy then ES2 = 0 : Enemy2X = 0 : Enemy2Y = 0
a5 ee		      LDA	Crash_Value
c9 01		      CMP	#1
d0 0c		      BNE	.skipL0557
.condpart145
a5 e5		      LDA	p
29 fb		      AND	#251
85 e5		      STA	p
a9 00		      LDA	#0
85 e8		      STA	Enemy2X
85 e9		      STA	Enemy2Y

Everything looks OK. Oh well. I'll figure it out eventually.

 

Edit:

Actually, looking at some other code, I have a question:

.L0550		; if !ES1 then goto CV2
a5 e5		      LDA	p
29 02		      AND	#2
d0 03		      BNE	.skipL0550
.condpart140
4c bd 98 	      jmp	.CV2
.skipL0550
.L0551		; Crash_Value = Crash_Detection ( 1 )

and

.L0554		; if !ES2 then return otherbank
a5 e5		      LDA	p
29 04		      AND	#4
d0 03		      BNE	.skipL0554
.condpart143
4c dd ff 	      JMP	BS_return
.skipL0554
.L0555		; Crash_Value = Crash_Detection ( 2 )

So in the first one, if ES1 is 0, skip to the label CV2. But the asm seems to be doing the opposite. OK, ES1 is bit 1 or a value of 2, so this part seems right.

LDA p

AND #2

However, this next part doesn't seem right

BNE .skipL0550

.condpart140

jmp .CV2

.skipL0550

Now it's checking to see if bit 1 is off, or 0. ANDing p with 2 should return 0, the values aren't equal, so shouldn't it be

BNE .CV2

?

Same thing with checking on ES2.

Edited by jbs30000

Share this post


Link to post
Share on other sites

The assembly looks right. p{0} would be the rightmost bit, and p{1} (ES1) is the next one over, so a mask of #2 is appropriate.

 

In a nutshell, the assembly code...

1. loads the byte with the ES1 bit into the A register.

2. keeps only the bit for ES1.

3. If the result is non-zero then a branch is taken to skip over the "jmp .JV2" code.

 

Functionally, that's the same as your basic code.

 

Want to post or PM the code?

Share this post


Link to post
Share on other sites

The whole program? No. There's a lot of code, it's kind of sloppy, and some of the variables are horribly named (like ES1 and ES2).

 

I'm re-writing the program so that the code is a lot neater and over-all it's easier to read. If I'm still having a problem then I'll post it for others to look at.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...