Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: LemonDrop on August 01, 2013, 01:51:47 pm

Title: Problem with shooter code
Post by: LemonDrop on August 01, 2013, 01:51:47 pm
So pretty much I was looking at the axe example of a space invaders clone thing and was trying to just get movement and bullets working by using the system they had, just to try to learn the language better. Oddly though even though the code is very close to the example mine crashes after like 3 seconds. Before then it works fine but then a bullet sprite appears in the bottom left corner for some reason. Heres the code that isnt working:

Code: [Select]
.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

And what happens when I try to do stuff:
(http://i.imgur.com/Od5e1Cv.gif)

Dunno if this is the right place to ask this but any help would be nice
Title: Re: Problem with shooter code
Post by: Runer112 on August 01, 2013, 02:51:52 pm
Yes, this is the right place to ask. :) I didn't actively debug the code, but I suspect the problem has to do with the bullet logic. My suspicion is that, as the result of a few code issues, the number of bullets is getting decreased when it's already zero, wrapping around from 0 to 65535 and then causing a great big mess. Here are the three culprits that appear to me:


Here's your bullet processing code with the above fixes applied:
Code: [Select]
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

I quickly tested plugging that into your code, and it seemed to work great. I've also attached the working source program; not that it's really needed, because the changes made were quite minimal and should be easy to apply directly to your copy of the source.

Good luck expanding this code out, I'd love to see a full-fledged game result from it! If you have any other questions with your project in the future, you can always post them back in this thread and they should hopefully be answered swiftly as well. :)
Title: Re: Problem with shooter code
Post by: Hayleia on August 01, 2013, 03:27:35 pm
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).
Title: Re: Problem with shooter code
Post by: LemonDrop on August 01, 2013, 04:23:19 pm
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.
Title: Re: Problem with shooter code
Post by: ben_g on August 01, 2013, 05:49:39 pm
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.
Title: Re: Problem with shooter code
Post by: LemonDrop on August 02, 2013, 01:11:24 am
Yea I came across another thing I wanted to ask about here, With some code like:

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?
Title: Re: Problem with shooter code
Post by: Streetwalrus on August 02, 2013, 02:23:53 am
Yea I came across another thing I wanted to ask about here, With some code like:

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?
Nope, it's impossible because foo->{bar} will return bar. The select command may help you though :
Code: [Select]
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 than
Code: [Select]
foo->{bar1}
foo->{bar2}
foo->{bar3}
But it's slower.
Title: Re: Problem with shooter code
Post by: Hayleia on August 02, 2013, 02:43:20 am
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.
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).
Title: Re: Problem with shooter code
Post by: LemonDrop on August 03, 2013, 05:20:58 pm
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)
Title: Re: Problem with shooter code
Post by: Runer112 on August 03, 2013, 06:58:36 pm
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)

1. Nope, all assembly programs should start at 6MHz.

2. Using the sprite rotate/flip commands will always be slower than not using them. flipV() takes 339 cycles, flipH() takes 1908 cycles, and rotC() and rotCC() take 2661 cycles. All four rotate/flip subroutines take up 73 bytes of space in total, so if you only have a few sprites that have rotated versions and the extra data isn't much larger than that, it would probably be smaller (and faster) to just include the rotated sprites as data. With more sprites, it begins to become more of a trade-off between size and speed. But if you want the speed of not using flip/rotate commands when sprites are drawn without the size of including extra copies of lots of sprites, you can still get the best of both worlds. Just include one copy of each sprite and then producing the flipped/rotated copies at startup time and save them in a static RAM area like L?-L? or a temporary OS variable.

3. In that direct comparison, separating the if statements does not save space. In fact, it costs 2 bytes. However, it does have two advantages. The first is that by breaking multiple conditions up into multiple if statements, if any condition is not true, none of the following conditions are even reached, thus saving time. The second advantage, and probably the more common reason why this is done, is that it works when one or more of the conditions doesn't actually depend on a boolean being zero or one, but on an integer being zero or nonzero. The and operator is an 8-bit bitwise AND, which works just like a logical AND for boolean values. But it doesn't work like a logical AND for integer values. (In case bitwise AND needs a bit of explanation, here's (http://en.wikipedia.org/wiki/Bitwise_AND#AND) the wikipedia entry for it)

4. The Commands.html file included in Axe releases explains fairly well how large and how "safe" the L?-L? areas are. If you don't use any grayscale drawing commands or StorePic/RecallPic, L? should be safe to use.

5. The Freq() command in Axe is fairly primitive, so program execution doesn't continue while the tone plays. Having notes that play in the background requires fairly complicated interrupts and timing logic, so it hasn't been enough of a priority to find its way into Axe. However, I'm keeping an eye on Iambian's interrupt-based audio (http://ourl.ca/19219) solution, which seems quite good. It might eventually be available as an Axiom (an external library for Axe programs).
Title: Re: Problem with shooter code
Post by: LemonDrop on August 04, 2013, 12:17:18 am
Soo apparently I have another problem I cant fix (stared at this code for a good 15 minutes and couldn't figure it out lol). Pretty much everything in this works fine except the explosions from the dead test enemy dont display. This was after I decided to handle them in a array structure like I have been doing with the bullets and enemies. I cant tell if its a drawing issue with the sprites or a logic issue where the explosions are processed but maybe one of you can help. Helpful infos: C (number of explosions) gets 1 added to it when a enemies health hits 0 (!If {J-4}), and a new explosion entry is added at the current enemy position {J-1},{J}. The third value for explosions is the sprite offset which gets multiplied by 8 later.
-code removed because copyprotection-
Title: Re: Problem with shooter code
Post by: Runer112 on August 04, 2013, 12:34:23 am
On line 92, should If J>6 be If {J-2}>6 instead?
Title: Re: Problem with shooter code
Post by: LemonDrop on August 04, 2013, 12:40:27 am
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.
Title: Re: Problem with shooter code
Post by: Runer112 on August 04, 2013, 12:47:41 am
Getting a second set of eyes can greatly increase debugging ability. Sometimes you're just completely blind to a certain error for no apparent reason. :P
Title: Re: Problem with shooter code
Post by: DJ Omnimaga on August 04, 2013, 01:19:36 am

-code removed because copyprotection-
(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)
Title: Re: Problem with shooter code
Post by: LemonDrop on August 04, 2013, 04:13:11 am
So heres another interesting problem (math oh noes):
Right now bullets can only move up/down depending on a value controlling that. Pretty much thats kinda boring and I wanted bullets to sorta drift to the side a bit towards a player (if you guys have played galaga) when fired by enemies to make it a bit more difficult. Lets say the enemy ship was at 3,30 and you were at 1,10. Normally I'd just make another value for the Y direction per cycle and base it off the slope between those points (-.1). Adding this to the current Y every cycle would just be ignored until it hit a X position like 20, when it would finally be at 2 (technically at least, with calculator math I think it rounds down so it would be 2 right off the start but thats close enough). Problem is that uses floating points and signed numbers which seems really difficult to do, so I was thinking why not just add 4 extra bytes to each bullet, 2 being the x and y it was fired from and 2 more for the x and y destination. Because the bullet will move 1 pixel per cycle down, the slope could be calculated every cycle and only add/subtract the position if it actually equals something (e.g. (1/10)*2, nothing (1/10)*10 returns 1), but this still calls for signed numbers and some pretty complex math to be done over and over. So knowing that people here have done really amazing looking shooters before, I thought someone might have some magical solution to this problem or something. If not I can just have the enemies shoot straight down but yea.
Title: Re: Problem with shooter code
Post by: Streetwalrus on August 04, 2013, 04:50:50 am
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. ;)
Title: Re: Problem with shooter code
Post by: LemonDrop on August 04, 2013, 05:37:35 am
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.
Title: Re: Problem with shooter code
Post by: Streetwalrus on August 04, 2013, 06:11:32 am
Basically for fixed point math, you use the most significant byte (MSB) for the integer part and the least significant byte (LSB) for the decimal part.
Then addition/substraction is the same (just make sure to multiply your integers by 256). Multiplying/dividing by an integer is also the same and Axe has some routines if you want to multiply/divide two fixed point numbers together. ;)
Title: Re: Problem with shooter code
Post by: shmibs on August 04, 2013, 05:09:13 pm
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.
Title: Re: Problem with shooter code
Post by: LemonDrop on August 04, 2013, 05:19:53 pm
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.
Title: Re: Problem with shooter code
Post by: LemonDrop on August 04, 2013, 10:19:44 pm
So I decided that a 2x logical grid would allow for enough precision and I want to make it 10x the size of the screen, but I am not sure about how to do some stuff. Firstly I decided to make the x and y speeds into signed numbers just for convenience, but I do not know how to make a number signed and dont know if it works with normal math like Adding a signed number to a non signed one (e.g. 2+(-1) equaling 1 like it should). Also to make the logical grid that big, I would have to use 16 bit numbers which I know take up 2 bytes but I dont know how to create them and again dont know if they work with non 16 bit numbers (final product being the signed x and y speeds are added to 16 bit x and y positions, which are then divided by 10 and displayed to the screen). Sorry for asking so many questions but theres not much stuff about axe I could find on the internet.
Title: Re: Problem with shooter code
Post by: shmibs on August 04, 2013, 11:11:56 pm
there are no "signed" and "unsigned" integers in axe. all integers are the same. the following from the somewhat-outdated but still useful Documentation.pdf explains how this works out:

Spoiler For "quote from Documentation.pdf:
Alright, now to the fun stuff! Okay, this is one of the most important differences between
Axe and BASIC. Numbers in Axe are all 16-bit integers meaning that there's no such
thing as fractions and decimals. What the 16-bit part of it means is that a number can
only hold a value between 0 and 65,535. This is called the unsigned number system
meaning that there is no sign: all the numbers are positive.
Now wait a minute you say, what if I want to use negative numbers? Well in that case,
you want to use signed representation. The way that works is that we cut our range in
half and say that all the numbers on one side are positive and numbers on the other
side are negative. So numbers from 0 to 32767 we still say are positive but now the
numbers from 32768 to 65535 we say are actually -32768 to -1. So our new range is
-32,768 to 32,767
Remember, both representations are really the exact same number. It's just a different
way of representing it. So -1 really is the same number as 65535. And I'm not just
making this up, the mathematics works this way. If you add 65535 to a number you get
exactly the same result as if you subtracted 1! How the heck does that happen? That
brings me to my next point which is modular arithmetic.

Remember, we can only hold values between 0 and 65535 right? Well what happens if
we keep adding and overflow the maximum value? Let's count by constantly adding 1:
0,1,2,3,...,65533,65534,65535,0,1,2,3...
Do you see what happened? Once you pass the maximum, you loop around back to 0
again. Signed representation does the same thing, best illustrated by this xkcd comic:
[image with a fellow counting sheep here. when he gets to 32,767, he loops back
around to -32,768 and starts counting up]

basically, what this means is that you can just use plain integers and not worry about it (unless you're using division, in which case a single division symbol will yield an unsigned division while two symbols will yield a signed division).

as for single and multi-byte numbers, all of axe's variables are two-byte numbers by default and all referenced positions are single-byte numbers by default. if you want to access a single byte of a variable, you have to use the variable's location to reference it, and, if you want to read some given location as a two-byte number, you add a ^r (that's Angle+3) after the curly braces (so something like {Pic1+8}^r, for example).


EDIT: also, please don't double post (post twice consecutively in the same topic under 24 hours). if you use the "Modify" button to edit your post (like i did just now with this post), the topic will be marked as unread again for everyone.
Title: Re: Problem with shooter code
Post by: Xeda112358 on August 04, 2013, 11:59:46 pm
Hey LemonDrop, I am not sure if this is the Bresenham method, but this is a line drawing algorithm I came up with a few years ago that is fast and easy to implement in Axe, Assembly, BASIC, Grammer -- you name it. Modified, instead of drawing a line, you can make a bullet follow a trajectory. This will also work smoothly using the the inflated coordinates that shmibs was referring to (this is an excellent technique, especially when you start doing physicsy things) or just the regular 96x64 pixel area. Anyways, the basic pseudo-code looks like this:
Code: [Select]
;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).


Anyways, now for some actual Axe code! (Note: I am not a very knowledgeable Axe coder, so there may be many optimisations to be had!) The first thing we are going to need to take note of is that we aren't drawing a whole line at once (unless you are making a laser effect) so it will be more useful to make a subroutine that returns the coordinates of the next pixel. As well, in the event that we have multiple bullets on screen, we might want to make the routine even more flexible to work with a buffer of bullet data so that we don't tie up variables.
Here we go:
Code: [Select]
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

I have not tested that code, so I doubt it will work, but just in case it does, GDB1 should point to a buffer large enough to hold the bullet data (in the code above, it limits to 10 bullets, so 9*10+1 = 91 bytes). This buffer should be zeroed, and GDB1+9*9+1→GDB1Z should be defined (GDB1Z points to the last bullet).
The 3 routines, if they work, are:

BNEXT(ptr) : ptr points to 9 bytes of bullet data. Returns X,Y as the coordinates of the bullet.
DELB(ptr)  : ptr points to the 9 bytes of the bullet data to remove from the bullet buffer.
ADDB(x1,y1,x2,y2) : If there is room on the bullet buffer, the bullet trajectory is added.

As a note, BNEXT automatically removes the bullet if it reaches its destination coordinate. If you want it to continue past the destination until it goes offscreen, the code can be modified.


I hope it works, but I am too tired to test it tonight. I need sleep :P
Title: Re: Problem with shooter code
Post by: LemonDrop on August 05, 2013, 06:34:10 pm
-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:
(http://i.imgur.com/gaC9NPs.gif)
But as you can see it really doesn't work too well. Heres the source of the test:

Code: [Select]
.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)

Is there something wrong with it which would make the bullets not really target the player (ignoring the check for if width=0, I skipped that because its easy to do)? Or is this just how its supposed to work.
Title: Re: Problem with shooter code
Post by: Jonius7 on August 05, 2013, 10:25:01 pm
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 quickly
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?
Title: Re: Problem with shooter code
Post by: LemonDrop on August 05, 2013, 10:30:09 pm
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 quickly
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?
If 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.

Its pretty hard to explain and its based off the algorithm the person above that post came up with so any more information lies in there.
Title: Re: Problem with shooter code
Post by: Jonius7 on August 05, 2013, 10:33:13 pm
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.

Just a suggestion.
Title: Re: Problem with shooter code
Post by: LemonDrop on August 05, 2013, 11:02:32 pm
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.

Just a suggestion.
I really dont think thats the problem, or atleast I dont think that would happen in axe, but I'll check it out.
Title: Re: Problem with shooter code
Post by: Xeda112358 on August 05, 2013, 11:19:00 pm
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.

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.
Title: Re: Problem with shooter code
Post by: LemonDrop on August 05, 2013, 11:30:56 pm
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.

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.
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)
Title: Re: Problem with shooter code
Post by: Xeda112358 on August 05, 2013, 11:53:11 pm
This is the BASIC line drawing routine (I don't have easy access to my calculator at the moment, so this is just what I wrote in my notebook):
Code: [Select]
;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


In this part of the code above:
Code: [Select]
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:
Code: [Select]
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!
Title: Re: Problem with shooter code
Post by: LemonDrop on August 06, 2013, 01:04:11 am
-snipped-
Ok so I completely fixed my code:
On line 41 and 44 X should've been Y, thats just a stupid mistake, but there was also a problem with the pseudo code of your algorithm I was basing my calculations off of. You mixed up the width and height calculations for the accumulator, causing it to not work properly. Just because I was completely out of Ideas I just switched them in my if statement and it worked perfectly (well sometimes the bullets take really sharp turns but its only in certain positions). Heres an image:
(http://i.imgur.com/Ycn3io2.gif)
So thank you so much and sorry it took so long to get something working, but couldn't have done it without your algorithm.
Title: Re: Problem with shooter code
Post by: TIfanx1999 on August 06, 2013, 02:00:28 am
Looks good, I'd also say credit goes to you persistence. :)
Title: Re: Problem with shooter code
Post by: Xeda112358 on August 06, 2013, 05:39:19 pm
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 :)

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!
Title: Re: Problem with shooter code
Post by: LemonDrop on August 06, 2013, 08:19:36 pm
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 :)

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!
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.
Title: Re: Problem with shooter code
Post by: Xeda112358 on August 06, 2013, 08:55:05 pm
For the AI, all I did was have it randomly move toward the user. As an example, if playerX>enemyX and rand^2 (which returns 0 or 1) is 1, then do enemyX++
Title: Re: Problem with shooter code
Post by: LemonDrop on September 05, 2013, 06:42:43 pm
Apparently after all this time I still cannot figure out how to make an effective AI system for enemies (firstly what values to even store for each enemies, and also how the ai would work). I could easily just make enemies come down from the top of the screen or do a space-invaders style thing but I wanted them more to actually have more curved movements (some enemies just coming down at angles, others trying to run into players or avoid bullets, etc) but it is complex to try to make a system that allows them to do this type of movement, and also calculates positions for them to go to in the first place. I guess the best way for me to learn is to look at examples of other stuff with the same style (shooter space game thingy) so if anyone knows a game like that that is open source, sharing it would be helpful so I can learn.