.TEST
[002442DBE7BD2400->Pic1
[0000183C3C240000->Pic2
DiagnosticOff
ClrDraw
DrawInv
44->X
54->Y
0->B->E->T
Repeat getKey(15)
sub(D
DispGraph
sub(D
If getKey(2) and (X!=1
X-1->X
End
If getKey(3) and (X!=87
X+1->X
End
If getKey(4) and (Y!=1
Y-1->Y
End
If getKey(1) and (Y!=55
Y+1->Y
End
If getKey(54) and (T=0
B+1->B*3+L1->I
0->{I-2}
X->{I-1}
Y->{I}
15->T
End
T=0+T-1->T
For(I,0,B
I*3+L1->J
{J-2}-1+{J}->{J}
If {J}=57 or ({J}=0
B*3+L1->K
Copy(J,K,3)^^r
B-1->B
End
End
End
ClrDraw
ClrHome
Return
Lbl D
Pt-Change(X,Y,Pic1
For(I,0,B
Pt-Change({I*3+L1-1},{I*3+L1},Pic2
End
For(I,1,B
I*3+L1->J
{J-2}-1+{J}->{J}
If {J}=57 or ({J}=0
B*3+L1->K
Copy(K,J,3)^^r
B-1->B
I-1->I
End
End
Also note that Axe is not Basic. The main difference being that Axe is compiled while Basic is not. This means that "forgetting" parentheses in Basic saves space in the executable and in the source (since they are the same), but in Axe, that doesn't save anything for the executable. And saving space in the source only is not useful except if you have a 83+ non-SE. Otherwise, I'd advise you to close your parentheses to avoid mistakes such as writing A+(C=1→A which you understand as A+(C=1)→A but which the parser understands as A+(C=1→A).Ah yes. I've been coding with ti-basic for a while and its sorta confusing because my brain is still thinking on how I'd do a program in ti-basic when here things like speed dont matter as much.
Even when you code in axe, it's bets to try limit the size of the executable as much as possible and making it as fast and optimized as possible. Axe is a great and powerfull language, but the calc's hardware is very limited. When you have to handle a lot of objects at once, that work really pays off.Also note that Axe is not Basic. The main difference being that Axe is compiled while Basic is not. This means that "forgetting" parentheses in Basic saves space in the executable and in the source (since they are the same), but in Axe, that doesn't save anything for the executable. And saving space in the source only is not useful except if you have a 83+ non-SE. Otherwise, I'd advise you to close your parentheses to avoid mistakes such as writing A+(C=1→A which you understand as A+(C=1)→A but which the parser understands as A+(C=1→A).Ah yes. I've been coding with ti-basic for a while and its sorta confusing because my brain is still thinking on how I'd do a program in ti-basic when here things like speed dont matter as much.
Yea I came across another thing I wanted to ask about here, With some code like:Nope, it's impossible because foo->{bar} will return bar. The select command may help you though :
0->{I-2}->{I-3} The {I-3} dosent work for some reason when something like 0->A->B would. Is there any way to do that with the value of a pointer thing?
Select(foo,->{bar1})
Select(,->{bar2})
Select(,->{bar3})
This is another example of HL abuse using the stack (am I right Runer ?) to help keep the correct value. It's definitely smaller thanfoo->{bar1}
foo->{bar2}
foo->{bar3}
But it's slower.
Yeah, it is a good thing to optimize the executable for speed and size, but there is no point optimizing the source (except if you have a 83+ non-SE and have very little space).Even when you code in axe, it's bets to try limit the size of the executable as much as possible and making it as fast and optimized as possible. Axe is a great and powerfull language, but the calc's hardware is very limited. When you have to handle a lot of objects at once, that work really pays off.Also note that Axe is not Basic. The main difference being that Axe is compiled while Basic is not. This means that "forgetting" parentheses in Basic saves space in the executable and in the source (since they are the same), but in Axe, that doesn't save anything for the executable. And saving space in the source only is not useful except if you have a 83+ non-SE. Otherwise, I'd advise you to close your parentheses to avoid mistakes such as writing A+(C=1→A which you understand as A+(C=1)→A but which the parser understands as A+(C=1→A).Ah yes. I've been coding with ti-basic for a while and its sorta confusing because my brain is still thinking on how I'd do a program in ti-basic when here things like speed dont matter as much.
Sorry for asking a lot of questions here but I think its better than making new threads. So I was wondering about a few things:
1. Are axe programs in the Full 15mhz mode by default
2. Is using things like rotC, flipH and flipV instead of making sprites for different angles better (speed/space wise)
3. I heard that separating if statements (If A:If B) is faster than combining them (If A and B), is this true? Which one uses less space also
and finally
4. Whats the risk of using L3 for data, or is it safer to just use a pseudo list (L2+250 being the start of it) if you know the data in L2 wont extend that far
edit:
Oh yea does sound with the freq command play synchronously (meaning if its told to play for 1 second will it wait 1 second to go to the next command or does it play as stuff is happening)
(also this is what I have so far for my game thing, ignore the completely terrible explosion sprites and stuff)
(http://i.imgur.com/WtFi5RD.gif)
On line 92, should If J>6 be If {J-2}>6 instead?Wow I'm pretty stupid not to have seen that lol. Oh well that happens when you code for a long time without a break lol.
(By the way, if you post code then somebody steals it, releasing it on ticalc.org or re-using it without your permission there, I'M fairly certain that his file will not last for long, because many people here knows Axe very well and even if the guy releases a closed-source game using stolen code, he'll get caught very fast. Basically you would just have to complain here then someone will immediately try old pieces of your code then notice immediately. In other words, you shouldn't worry about keeping source code here, although it's your choice to remove it after getting help)
-code removed because copyprotection-
What you want is fixed point math, which is pretty fast. Also take a look at Bresenham's algorithm. It's a very simple line drawing algorithm and I'm sure it can be used to move a bullet around. ;)Yea thats what I am looking for, but I have no idea how I would implement that. Also that looks like it can only determine if a point is supposed to be where it is, the main problem I am having is how to calculate a points position in the first place given its Y value.
a simpler, faster method to manage this would be to just make your playing area be larger than the actual screen resolution by some factor of two. then you can accomplish this with only a single slope calculation when the bullet is initially fired and without using anything but simple integers. what this looks like in realisation would be having a one byte each for x and y positions (or two for x, if you choose a factor greater than two and thus end up with more than 192 horizontal logical pixels mapped to your 96 physical pixels), and one byte each for the x and y velocities (or a nibble, if you want to conserve space). then just add the velocities to the positions each frame and then map the resulting logical positions to their physical positions with a quick division by your chosen factor of two (sure, other factors could be used, but they would be MUCH slower). thus, if you chose a factor of four and only set the x velocity to 1, your bullet would only "drift" over one physical pixel every 4 frames.Yea this is what I was thinking about doing. Thanks for the help.
;Given : (x1,y1) and (x2,y2)
x2-x1 → width
y2-y1 → height
1 → xinc
1 → yinc
If width>0
1 → xinc
Else
-1 → xinc
-width → width
If height>0
1 → yinc
Else
-1 → yinc
-height → height
If width=0
y1 → count
while count <= y1+height
plotpixel(y1,x1)
x1+1 → x1
else
width → accumulator
width*2 → width
height*2 → height
0 → count
while count < width
plotpixel(y1,x1)
y1+yinc → y1
accumulator - height → accumulator
while accumulator < 0
x1 + xinc → x1
plotpixel(y1,x1)
accumulator + width → accumulator
plotpixel(y1,x1)
While that may look complicated, it actually simplifies quite a bit when put in use. To describe the algorithm, there is an accumulator that starts at 1/2 the width (because we are using integers, I store the width to the accumulator and then double width and height, so the accumulator is half the width). Then at every cycle, a much more general algorithm might increment y and add height/width to to x. However, we cannot use non-integers, so we need to be more clever. This is why I have an accumulator. What we could do is add height to the accumulator and if the acc>width, then we need to increment the x coordinate. To determine how many times we need to increment, just subtract accumulator-width until accumulator<width, each time incrementing x and plotting a pixel. In the algorithm above, it is more optimised for assembly and instead of doing accumulator+height, I do accumulator-height until accumulator<0 (which the processor automatically recognises without needing to do a compare).Lbl BNEXT
.IN: Ptr
.accumulator,dir,x,xinc,w, y,yinc,h,counter
{r1}→r3
!If {r1+1}
r1+4→r1
{r1++)→r2+{r1++)→r2
r3-{r1++}→r3→{r1-8}
r3<<0→{r1-7}
Else
r1+1→r1
{r1++)→r2+{r1++)→r2
r3+{r1++}→r3→{r1-5}
r3<<0→{r1-4}
r1+3→r1
End
{r1-5}→X
{r1-2}→Y
If {r1++}--
Return
End
r1-8→r1
Lbl DELB
.REMOVE THE BULLET
Return!If {GDB1)
Exch(GDB1Z,r1,9)
{GDB1}--
Return
Lbl ADDB
.IN: (x1,y1,x2,y2)
ReturnIf {GDB1}=10
{GDB1}++→r6*2*2*2+r6+GDB1-9→r6
r3-r1→{r6++}→r5=0→{r6++}
r1→{r6++}
0→{r6++}
If r6>0
1→{r6}
ElseIf r6>32767
-1→{r6}
-r5→r5
End
r5→{r6++}
r5→{r6+4}
r4-r5→{r6++}→r5=0→{r6++}
r2→{r6++}
0→{r6++}
If r6>0
1→{r6}
ElseIf r6>32767
-1→{r6}
-r5→r5
End
r5→{r6++}
Return
-lots of helpful stuff-Ok so I spent the night writing my own axe test code based on the way I store data and calculate bullets and came up with this based off the way you explained your math calculations:
.ANGLEA
[00003C3C3C3C0000]->Pic1
[0000001818000000]->Pic2
DiagnosticOff
ClrDraw
DrawInv
StorePic
.FIRING POS: 44,25
30->X
54->Y
0->B
Repeat getKey(15)
RecallPic
sub(D
DispGraph
If getKey(2) and (X!=1
X-1->X
End
If getKey(3) and (X!=87
X+1->X
End
If getKey(4) and (Y!=1
Y-1->Y
End
If getKey(1) and (Y!=55
Y+1->Y
End
.BULLET STRUCUTRE: {PTR-7}-None {PTR-6}-Accumulator {PTR-5}-Width {PTR-4}-Height
.{PTR-3}-XSpeed {PTR-2}-YSPEED {PTR-1}-X {PTR}-Y
!If rand^(8)
.MAKE NEW BULLET
B+1->B*8+L1->I
25->{I}
44->{I-1}
.SET X AND Y SPEED (2 being 1, 0 being -1)
If 25>Y
0->{I-2}
25-X->{I-4}
Else
2->{I-2}
X-25->{I-4}
End
If 44>X
0->{I-3}
44-X->{I-5}
Else
2->{I-3}
X-44->{I-5}
End
.SET ACCUMULATOR, W, H (I-7 is nothing)
{I-5}->{I-6}
{I-5}*2->{I-5}
{I-4}*2->{I-4}
0->{I-7}
End
For(I,1,B
8*I+L1->J
.CALCULATE BULLETS POSITION
If {J-6}>{J-5}
{J-1}+{J-3}-1->{J-1}
{J-6}-{J-5}->{J-6}
Else
{J}+{J-2}-1->{J}
{J-6}+{J-4}->{J-6}
End
.DELETE OFFSCREEN BULLETS
If ({J}=57) or ({J}=0) or ({J-1}=94) or ({J-1}=0)
8*B+L1->K
Copy(K,J,8)^^r
B-1->B
I-1->I
End
End
End
Lbl D
.DISPLAY BULLETS/SHIPS
For(I,1,B
8*I+L1->J
Pt-Change({J-1},{J},Pic2)
End
Pt-Change(44,25,Pic1)
Pt-Change(X,Y,Pic1)
8*I+L1->J
So that definition defines J, which then calculates the bullets' positions. Could this be it? Also how is the code for taking the player's position on the screen taken into account?
That's weird, sometimes there's some sort of delay of the bullets changing direction as the player moves around the screen, sometimes it happens much more quicklyIf you look at the code where the bullets are created, you can see that X and Y are subtracted in a way that gives a width and height value. Because there can be no signed numbers, I check to see if they are less or greater than the fixed position of the enemy (44,25) and then set the "x and y speed" accordingly so when the operations are preformed later it simply adds that value minus one to the x or y position of the bullet when needed.Code: [Select]8*I+L1->J
So that definition defines J, which then calculates the bullets' positions. Could this be it? Also how is the code for taking the player's position on the screen taken into account?
I've been looking at the behaviour and I may have another idea why it's not completely working, though it's hard to explain and I'm not sure it happens all the time. When you move vertically up, your x value doesn't change, perhaps your program isn't always calculating the change in y value, and because the x value is not changing, the program isn't calculating a new angle for the bullets to shoot to.I really dont think thats the problem, or atleast I dont think that would happen in axe, but I'll check it out.
Just a suggestion.
Hmm, I recognise the problem, but I did not see the issue in your source code immediately. Hopefully I will take a look at it tomorrow and possibly figure out the issue.Well if you can show me the basic code that would be nice because I know that really well, also I would be using singed numbers except a 8bit one is limited to -127 to 126 or whatever, and there is a possibility of the accumulator exceeding that (its maximum possible value is 250)
I would also like to point out that you can do signed comparisons. For example, {J-6}<<0 to see if it went below zero. I think Axe probably does an auto-optimisation for that.
I tried my attempt above and found that it doesn't work (I forgot some of the nuances of Axe x.x). I did get it to work in BASIC, though.
;draw from B,C to D,E (b=x1)
D-B→D
E-C→E
1→F:1→G ;these are the xinc and yinc
If D<0
-1→F
If E<0
-1→F
abs(E→E
abs(D→D
If not(Ans
Then ;draw a vertical line
For(A,C,C+E,G
Pxl-On(A,B
End
Return
End
D→A
2D→D
2E→E
For(H,1,.5D
Pxl-On(C,B
B+F→B
A-E→A
While A<0
C+G→C
Pxl-On(C,B ;ideally, this should come first and be skipped on the first iteration of the loop, but this isn't that easy in BASIC
A+D→A
End
End
Pxl-On(C,B
While A<0
C+G→C
Pxl-On(C,B ;ideally, this should come first and be skipped on the first iteration of the loop, but this isn't that easy in BASIC
A+D→A
End
To work better, it should be more like this in Axe:If 0
Lbl 01
Pxl-On(B,C
End
C+G→C
A+D→A
If <0 ;well, change this to the proper Axe syntax
Goto 01
End
That skips the first pixel plotting which is only a problem if you are inverting the pixels. Hopefully you can derive a working algorithm from this!
-snipped-Ok so I completely fixed my code:
That looks great! I was in town earlier today with no obligations, so I programmed for a bit and converted my BASIC code to Axe and then modified it a little. It currently only does one bullet at a time, but I am going to add in code to have a bullet buffer. I managed to figure out a way to make sure bullet movement was not bugged except for one case with an acceptable bug (I think). Shooting vertically will cause it to shift 1 pixel off course, but I don't think that should be a problem. Anyways, see the screenshot :)Nice, I'll definitely have to check that code out, might use something from it. My next thing to be dealing with however is the enemy movement. I see you have some sort of AI in that second image so I'll see how you did that too and maybe get some ideas.
EDIT: Updated the code, now it uses a bullet buffer. It currently handles 64 bullets on screen at a time and it is still at 6MHz. Feel free to use any of the code or look at it or whatever!