Calculator Community => Major Community Projects => The Axe Parser Project => Topic started by: p2 on August 24, 2016, 08:24:38 am

Title: Some super crappy Axe code...
Post by: p2 on August 24, 2016, 08:24:38 am
Hey guys,
As some of you might already know, I haven't used axe for a couple of years and forgot almost everything about it  :'(
So now I'm trying to relearn axe and wanted ot ask you how I could improve the following code I wrote...
It's ment to be a player (just a square) kickign arount a Ball (a nice circle) with workign colission and gravty stuff...
I'm really sorry but I got no GIF to upload yet, hope you still understand what the code should do...  :(

Spoiler For Main Program:
.L1{0,2, 4, 6
.Pos Player *100 = V,W
.N=NotCollide to prevent double collision
Repeat getKey(15)

Spoiler For Program for players Movement:
If getKey(1) and (W<5600):W+100->W:End
If getKey(2) and (V>0):V-100->V:End
If getKey(3) and (V<8600):V+100->V:End
If getKey(4) and (W>0):W-100->W:End

Spoiler For Program for colission and stuff:
N-1->N:If N=(0-1):0->N:End
.Top Left
If (N=0) and (({L1+0}^r/100)>=((V/100)-7)) and (({L1+0}^r/100)<=((V/100)-6)) and (({L1+2}^r/100)>=((V/100)-7)) and (({L1+2}^r/100)<=((V/100)-6)):{L1+4}^r+80->{L1+4}^r:{L1+6}^r+80->{L1+6}^r:(0-1)->T->U:5->N:0->G:End
.Top Right
If (N=0) and (({L1+0}^r/100)>=((V/100)+7)) and (({L1+0}^r/100)<=((V/100)+7)) and (({L1+2}^r/100)>=((V/100)-7)) and (({L1+2}^r/100)<=((V/100)-6)):{L1+4}^r+80->{L1+4}^r:{L1+6}^r+80->{L1+6}^r:1->T:(0-1)->U:5->N:0->G:End
.Bottom Left
If (N=0) and (({L1+0}^r/100)>=((V/100)-7)) and (({L1+0}^r/100)<=((V/100)-6)) and (({L1+2}^r/100)>=((V/100)+6)) and (({L1+2}^r/100)<=((V/100)+7)):{L1+4}^r+100->{L1+4}^r:{L1+6}^r+100->{L1+6}^r:(0-1)->T:1->U:5->N:End
.Bottom Right
If (N=0) and (({L1+0}^r/100)>=((V/100)+6)) and (({L1+0}^r/100)<=((V/100)+7)) and (({L1+2}^r/100)>=((V/100)+6)) and (({L1+2}^r/100)<=((V/100)+7)):{L1+4}^r+100->{L1+4}^r:{L1+6}^r+100->{L1+6}^r:1->T->U:5->N:End
If (N=0) and (({L1+0}^r/100)>=((V/100)-5)) and (({L1+0}^r/100)<=((V/100)+5)) and (({L1+2}^r/100)>=((V/100)-8)) and (({L1+2}^r/100)<=((V/100)-6)):{L1+6}^r+100->{L1+6}^r:(0-1)->U:5->N:0->G:End
If (N=0) and (({L1+0}^r/100)>=((V/100)-8)) and (({L1+0}^r/100)<=((V/100)-7)) and (({L1+2}^r/100)>=((V/100)-5)) and (({L1+2}^r/100)<=((V/100)+5)):{L1+4}^r+80->{L1+4}^r:5->N:If ({L1+2}^r>5500):(0-1)->U:{L1+6}^r+80->{L1+6}^r:{L1+4}^r+20->{L1+4}^r:End:End
If (N=0) and (({L1+0}^r/100)>=((V/100)+7)) and (({L1+0}^r/100)<=((V/100)+8)) and (({L1+2}^r/100)>=((V/100)-5)) and (({L1+2}^r/100)<=((V/100)+5)):{L1+4}^r+80->{L1+4}^r:5->N:If ({L1+2}^r>5500):(0-1)->U:{L1+6}^r+80->{L1+6}^r:{L1+4}^r+20->{L1+4}^r:End:End
If (N=0) and (({L1+0}^r/100)>=((V/100)-5)) and (({L1+0}^r/100)<=((V/100)+5)) and (({L1+2}^r/100)>=((V/100)+7)) and (({L1+2}^r/100)<=((V/100)+8)):1->U:G/5+{L1+6}^r/2+50->{L1+6}^r:0->G:End
If ({L1+0}^r<100) or ({L1+0}^r>(0-1000)):100->{L1+0}^r:1->T:End
If ({L1+0}^r>8600):8600->{L1+0}^r:(0-1)->T:End
If ({L1+2}^r)<100):100->{L1+2}^r:1->U:({L1+6}^r/2)->{L1+6}^r:End
If ({L1+2}^r)>5600):5600->{L1+2}^r:(0-1)->U:((G/10)+{L1+6}^r)->{L1+6}^r:0->G:End

Spoiler For Program for gravity:
If {L1+4}^r>50:{L1+4}^r+99/100->{L1+4}^r:Else:If {L1+4}^r<20:If (C/4+4)=C:{L1+4}^r*99/100->{L1+4}^r:End:Else:If (C/2+2)=C:{L1+4}^r*99/100->{L1+4}^r:End:End:End
.Slow down and speed up
If U=1:{L1+6}^r+102->{L1+6}^r:Else:{L1+6}^r+97->{L1+6}^r:End:{L1+6}^r/100->{L1+6}^r
.Add Gravity

Aaand explanations:
You're a square kicking arount a circle....
{L1+0}^r = X-pos ball
{L1+2}^r = Y-pos ball
{L1+4}^r = X-speed ball
{L1+6}^r = Y-Speed ball
T = Direction X-Movement ball (1 or -1)
U = Direction Y-Movement ball (1 or -1)
V = X-Pos player
W = Y-Pos player
C = Counter (add 1 each loop in main program so I can use it for executing stuff every 2 or every 4 rounds)
N = No-collide (counter for how many "rounds" it's gonna ignore colission stuff. To prevent trigering the colusion twice at once)
G = Gravitation (always rising and reset/changed by colissions)

Important: All graphic-related stuff is multiplied with 100... So I't wirking with a 9600x6400 screen and a Speed of 100 means 1px movement per round.
That's where all the /100 is coming from :)
Spoiler For Where the strange numbers in Colission come from:
( numbers seem a bit strange because it's actually the positions for the coliding object:
It's the top-left coordinates of an 8x8 image (the ball in this case) that collides with these zones (marked orange and green).
The darked boxes are the border of the player itself (just a square)

I used this for colission in order to bet the edges working well, too and also to prevent a colision from not being detected
(for example if the ball is faster than 1px/round and "jumps" inside the player)

I really hope you understand what I mean... :/

I plan on moving all teh vars inside L1, add a second player, add Goals and add the gravity for players, too (so you got a realistic jump isntead of just floating around).
Still It'll be a crappy game, but it's just for learning purposes not for being published or something ^^

Pls dont hate me for writing such crappy code - this is my first attempt after more than 4 years... :(
Title: Re: Some super crappy Axe code...
Post by: Sorunome on August 24, 2016, 09:21:24 am
Let's see....

Instead of
Code: [Select]
Repeat getKey(15)
. code here
This does (almost) the same (almost becasue the loop will get run at least once, which is irrelivant in your case) but is smaller&faster:
Code: [Select]
While 1
. code here
EndIf getKey(15)
The reason for that is that while 1-loops are way simpler to implement in asm.

If I understand it correctly you are using *100 so that you have greater precission on your numbers? If so, it might be a good idea to switch to Axe's 8.8 fixed point variables for greater performance: See The commands.html at advancedMath ( for more information (and ask if you have any questions!)

As for code-flow, i'd recommend against using the ":" token and instead use a new line, IMO at least it results in code being more easily readable, that's up to you, though.
Title: Re: Some super crappy Axe code...
Post by: p2 on August 24, 2016, 09:28:52 am
massive use of : is because I hate scrolling on calcs (so slooow) and putting stuff in one lone makes it faster to jump to end of the block ;)

But thanks for the hin wit hthe While :)
Will definitely use that in my next version ^.^
*As you can see in the names this is teh 7th "version" of the program since I started learning axe again ^^
Adding gravity or edge collision or L1 usage always ended up in a new version ^^
Title: Re: Some super crappy Axe code...
Post by: Sorunome on August 24, 2016, 09:52:00 am
Here's some stuff on 8.8 fixed point.

The basic idea is that you have a two-byte variable where one byte is the integer part and the other byte is the fraction part of your number.

here ( you can see available stuff.

So, I made a little demonstration program for you to show off what it can do!

Code: [Select]
2.1 -> A
A^2^r -> A
Disp {°A}>Dec
Disp {°A+1}>Dec
So, what this should do is multiply 2.1 with itself and display the let's see them! (2.1 * 2.1 = 4.41)

It displays "102" and "4". As already mentioned, with 8.8 numbers one byte represents the integer part and the other one the fraction part. so our {L1+1} clearly gets the intiger part.
What about that 102 though? Well, that is correctly the fraction part! 102 / 256 = 0.398... so ignoring the fact that the calculator works in binary and we think in decimals, thus some weird rounding errors can appear, it is spot-on!

So, what's the good thing? You can go ahead, store fixed-point numbers, do normal math on them, compare them with your known operations as long as everything is fixed point. Keep in mind that means you'll need to do e.g. something like A > 5.0 instead of A > 5.

Now, when displaying the sprite you only want the integer part. So only the upper 8 bit of the number. So we need the pointer of the variable °A and need to fetch the byte at °A+1, thus {°A+1}

Am I being clear? :3

EDIT: So axe has a way to fetch the pointer of a variable that i didn't know of, e.g. °A
I adjusted the examples accordingly

EDIT2: If you use it a lot you can define a custom variable to get the integer part quicker:
Code: [Select]
°A+1 -> °AH
<do 8.8 stuff with A>
AH^r returns now the integer part of A
Which is equivalent to
Code: [Select]
<do 8.8 stuff with A>
{°A+1} returns the integer part of A
Title: Re: Some super crappy Axe code...
Post by: p2 on August 25, 2016, 04:54:07 pm
I modified the entire code as far as I understand it by now :)
I'm sure it's still far from being perfect, so please tell me if you notice anything that still can be modified :) Thank you!  :thumbsup:
Code: [Select]

.Pos Player *128 = V,W
.N=NotCollide to prevent double collision
while 1
EndIf getKey(15)

Lbl Movement
V<11008 and getKey(3)-(V>0 and getKey(2))*128+V->V
W<7168 and getKey(1)-(W>0 and getKey(4))*128+W->W

Lbl Collision
.Top Left
If (N=0) and ((BposX/128)>=((V/128)-7)) and ((BposX/128)<=((V/128)-6)) and ((BposY/128)>=((W/128)-7)) and ((BposY/128)<=((W/128)-6))
.Top Right
If (N=0) and ((BposX/128)>=((V/128)+7)) and ((BposX/128)<=((V/128)+7)) and ((BposY/128)>=((W/128)-7)) and ((BposY/128)<=((W/128)-6))
.Bottom Left
If (N=0) and ((BposX/128)>=((V/128)-7)) and ((BposX/128)<=((V/128)-6)) and ((BposY/128)>=((W/128)+6)) and ((BposY/128)<=((W/128)+7))
.Bottom Right
If (N=0) and ((BposX/128)>=((V/128)+6)) and ((BposX/128)<=((V/128)+7)) and ((BposY/128)>=((W/128)+6)) and ((BposY/128)<=((W/128)+7))
If (N=0) and ((BposX/128)>=((V/128)-5)) and ((BposX/128)<=((V/128)+5)) and ((BposY/128)>=((V/128)-8)) and ((BposY/128)<=((V/128)-6))
If (N=0) and ((BposX/128)>=((V/128)-8)) and ((BposX/128)<=((V/128)-7)) and ((BposY/128)>=((V/128)-5)) and ((BposY/128)<=((V/128)+5))
BmovX+102->BmovX:5->N:If (BposY>5500):(0-1)->BdirY:BmovY+102->BmovY:BmovX+20->BmovX:End:End
If (N=0) and ((BposX/128)>=((V/128)+7)) and ((BposX/128)<=((V/128)+8)) and ((BposY/128)>=((V/128)-5)) and ((BposY/128)<=((V/128)+5))
BmovX+102->BmovX:5->N:If (BposY>5500):(0-1)->BdirY:BmovY+102->BmovY:BmovX+20->BmovX:End:End
If (N=0) and ((BposX/128)>=((V/128)-5)) and ((BposX/128)<=((V/128)+5)) and ((BposY/128)>=((V/128)+7)) and ((BposY/128)<=((V/128)+8))

If (BposX<128) or (BposX>(0-1280)):128->BposX:1->BdirX:End
If (BposX>11008):11008->BposX:(0-1)->BdirX:End
If (BposY)<128):128->BposY:1->BdirY:(BmovY/2)->BmovY:End
If (BposY)>7168):7168->BposY:(G/10+BmovY)->BmovY:0->G:-1->BDirY:End

Lbl Gravity
If BmovX>50:BmovX*127/128->BmovX:Else:If BmovX<20:If (C/4+4)=C:BmovX*127/128->BmovX:End:Else:If (C/2+2)=C:BmovX*127/128->BmovX:End:End:End
.Slow down and speed up
If BdirY=1:102:Else:97:End:*BmovY/128->BmovY
.Add Gravity
*I'm didnt add the 88.88 yet since I still didnt have the time to read all the stuff about it, sorry... :( But I definitely will learn it :) :)
Title: Re: Some super crappy Axe code...
Post by: Sorunome on August 25, 2016, 04:57:24 pm
The only thing i can think of right now is, instead of using *128 and /128 the 8.8 fixed point numbers i talked about, it gives you instant access to either the number with the fraction part or only the integar part, no bit-shifting at all is needed (which is what /128 does)
Title: Re: Some super crappy Axe code...
Post by: TIfanx1999 on September 03, 2016, 10:03:36 pm
Hey p2, cool to see you around again. :D Sorry I can't really help with the code as I know next to nothing about actually coding in Axe atm.
Title: Re: Some super crappy Axe code...
Post by: Sorunome on September 04, 2016, 03:24:47 am
So have you implemented 8.8 fixed points yet? How did it go?
Title: Re: Some super crappy Axe code...
Post by: E37 on September 04, 2016, 08:09:01 am
He is mainly discussing his project over at CodeWalrus.
I don't think he has updated it yet. Still optimizing it.
Title: Re: Some super crappy Axe code...
Post by: p2 on September 04, 2016, 10:31:33 am
True teh discussion is more active on CodeWalrus (since people startet discussing general axe code modifications there) but I try to add improvements from both Omni and CodeW to the code ^^
And I still haven't rewritten the code since I was away for a couple of days and people kept posting more and more improvements ^^