Need help working with bullets [Resolved]

Just started using Construct 2? Post your questions here

Post » Mon Feb 22, 2016 5:39 pm

Here's the basics of how to do it. It can be further refined to be more precise and you can use a family instead of wall to hit more object types.

Add a Sprite to your project and call it Ray. In the image editor put it's origin on the left-center and add another image point to the right center. Once on the layout, make it's height 1.

Every tick
--- ray: set position to player
--- ray: set angle towards (mouse.x, mouse.y)

Repeat 100 times
--- ray: set width to 100*(loopindex+1)
[sub event] ray: overlaps wall
--- stop loop
--- ray: spawn explosion at imagepoint 1
--- wall: destroy
B
92
S
32
G
107
Posts: 5,274
Reputation: 69,959

Post » Mon Feb 22, 2016 7:25 pm

Nifty! So looking at this the ray keeps growing until it hits something, but the explosions would always spawn at 100 pixel intervals, at the end of the ray. You can increase the resolution by decreasing the width increase but at the cost of more repeats in your loop which *might* lag.

How about spawning the explosion/hit from the target that got hit instead? After you confirm a hit, spawn the explosion from the sprite that got hit - at an angle back towards the player a certain distance based on the size of the target.

You'll be able to get the distance from the player to the target as well, which can be useful for graphical elements like so the tracer doesn't go through the target (unless you want it to).

Another problem I anticipate: what if there are two targets in close proximity, that both get overlapped when the ray grows? Maybe use another sub event to pick the closest out of the targets that were picked by the ray?
Mistakes were made.
B
51
S
25
G
107
Posts: 1,581
Reputation: 60,458

Post » Mon Feb 22, 2016 11:29 pm

@oosyrag
I meant it to be 10 pixel intervals:
ray: set width to 10*(loopindex+1)

So the furthest a ray would be able to go is 100*10 or 1000 pixels which is fine for stuff on screen with a res of 640x480. Best case it would check for collisions once, and worst case it would check for collisions 100 times. It's the difference of hitting something close or nothing at all.

If you're curious here's a more advanced example that also can be tweaked:
https://dl.dropboxusercontent.com/u/542 ... laser.capx
The laser in it has a range of 1000 pixels and only checks for collisions 10 times if nothing is hit. It's progressive so it finds the hit point with a 1/1000 pixel accuracy. The worst case is around 50 collision checks if it hits an object near the 1000 pixel range, but typically it's much lower.
B
92
S
32
G
107
Posts: 5,274
Reputation: 69,959

Post » Tue Feb 23, 2016 12:19 am

I see, a progressive increase in accuracy is much more efficient, and no need to worry about overlapping multiple objects.. Also yay for custom particles, I was just running into some limitations of the particle object in my own project, like not being able to have random angles. This will do nicely :)
Mistakes were made.
B
51
S
25
G
107
Posts: 1,581
Reputation: 60,458

Post » Tue Feb 23, 2016 2:47 am

With the help of the information I've gleaned from this thread, and the raycasting tutorial I discovered, I put together the following function:

Image

This function performs very well, since it is only called once per "pull of the trigger," so to speak. There's no need to constantly call it since I only need to check once whether or not each bullet hits.

However, there is still one small problem I'm experiencing when dealing with multiple targets. If multiple targets are lined up, both horizontally and vertically, then when shots are fired into the group, shots coming from the left and from the top (firing toward 0° and 270° respectively) hit only the first target in range, as it's supposed to, leaving the ones "behind" them in line untouched. However, if firing into the group from the bottom or from the right (90° and 180° respectively), then the shots hit all targets in the line instead of just the first one.

I find it odd that it works perfectly from two sides, and not from the other. The sprite itself (the visual component) is properly sized for all shots, those that work right and those that don't. i.e., even when shots are hitting multiple targets, the width of the "ray" sprite displays correctly (stops upon hitting the first target in line). This leads me to believe I'm selecting instances from the data structure incorrectly.

Any thoughts?
B
7
Posts: 15
Reputation: 305

Post » Tue Feb 23, 2016 5:19 am

I would try simplifying by cutting out the for each and avoiding UID, two common sources of problems. You probably don't need the array either.

Try using "pick nearest hrrrn to player.x player.y" in place of the "for each hrrnn" underneath the overlap condition. From then on in this event, only that hrrnn will be affected by actions.
Mistakes were made.
B
51
S
25
G
107
Posts: 1,581
Reputation: 60,458

Post » Tue Feb 23, 2016 7:01 am

No thoughts other than that looks complex. It probably doesn't need to be.

The idea I presented basically points a sprite in a direction and increases it's width until an object is hit. That gives the hit object and a point of collision.

Yours seems to set the sprite to be full length first and then add all the overlapping objects to an array, then loops over the array in some way while shortening the line by halves. So I'm guessing some kind of binary search? I guess I'd have to look at the tutorial you reference. My guess is the issue may be the order of the sprites, but really there is no way of knowing without something to test.
B
92
S
32
G
107
Posts: 5,274
Reputation: 69,959

Post » Tue Feb 23, 2016 4:31 pm

oosyrag wrote:I would try simplifying by cutting out the for each and avoiding UID, two common sources of problems. You probably don't need the array either.

Try using "pick nearest hrrrn to player.x player.y" in place of the "for each hrrnn" underneath the overlap condition. From then on in this event, only that hrrnn will be affected by actions.


It is somewhat complex, but I believe that is because the original tutorial that I was working from was designed to detect collisions as accurately as possible when firing a continuous ray through a series of targets with complex motion. I downgraded it somewhat to fit my simpler needs. It's probably true that I could stand to simplify it, but I'd like to try to get it working first, if for no other reason than just for the practice.

I tried using "pick nearest" in a function that I'd written before, but it never worked well. Using it just on those objects that satisfy the overlap condition, however, would probably work as intended. I'll give that a shot later.

R0J0hound wrote:No thoughts other than that looks complex. It probably doesn't need to be.

The idea I presented basically points a sprite in a direction and increases it's width until an object is hit. That gives the hit object and a point of collision.

Yours seems to set the sprite to be full length first and then add all the overlapping objects to an array, then loops over the array in some way while shortening the line by halves. So I'm guessing some kind of binary search? I guess I'd have to look at the tutorial you reference. My guess is the issue may be the order of the sprites, but really there is no way of knowing without something to test.


Yeah, the logic behind it is a simple binary search. That's why I latched on to that tutorial in the first place—it was very familiar to me. In the other game software that I've used in the past, I had written a very similar function for both bullets and beams that determined the exact position of impact by casting a line, checking for collision, halving the distance, and repeating until I got the position of the impact to within two pixels of the object. Then I'd spawn a "collision" object at the end of the ray that actually handled the post-impact processing (incidentally, I'm going to skip that step this time around, as I never did like having to rely on that "third party object" to do the processing). I'm totally unfamiliar with Construct 2, however, and, additionally, its event-based system is something that I haven't yet gotten used to. I was finding it difficult to port the functionality from the old procedural approach to the new event-based one.

I'm gonna give a few more things a try, but if I can't seem to get it to work right, I'll upload the file and ask if folks can take a look at it. If necessary, I'll switch my approach. Really the only reason I haven't uploaded it yet is because I had already added the tons of sounds and music that I already had laying around to the project which, when packaged into the .capx made the file size somewhat ridiculous for what it was. I'll have to yank all that back out so that people won't have to sit there and wait for a zillion megs of sounds to download just so they can test a few lines of game logic. Heh.
B
7
Posts: 15
Reputation: 305

Post » Tue Feb 23, 2016 9:32 pm

I've completed simplifying and testing the function. Below is the pseudo-final version of my game's shooting code.

Image

This function works exactly as I desired. It's called only once per "shot," it selects only the target that is first "impacted" by the ray, and it properly sizes the visual representation of the bullet to stretch from the muzzle to the point of impact. From here, more post-processing could be added easily, and adding in an "accuracy" variance (as I plan to do later) could be done simply by altering the initial angle of the projectile object (Bullet2 in the example).

The function could be (and probably should be) generalized using Families instead of specific objects (as was done in the original tutorial I scavenged from the Internet).

The base complexity of the function should be minimal. The actual logic itself should have base complexity of log(base 2)(n), however, since the repeat command is used, it degrades to (n) complexity—but, that shouldn't have a very big impact on performance. Even if it did, the number of iterations could be reduced without much consequence, as that part of the function is strictly for aesthetics (since the target of the impact has already been decided at that point, functionality wouldn't be impacted at all).

I left in the additional function parameter from the tutorial I used in case I need to identify specific bullets later as the game progresses. In the example shown above, that parameter is not used.

I'm calling the issue resolved. I'd like to thank everyone who took the time to offer their insight during the thread, and also the author of the raycasting tutorial I found on the site, which, again, regrettably, I cannot directly link to because of my lack of forum reputation (Lightning-fast-raycasting by sqiddster).

I've managed to learn a ton about Construct 2 during this process, and I look forward to pestering you all again when the next issue arises. :lol:
B
7
Posts: 15
Reputation: 305

Post » Wed Feb 24, 2016 5:00 pm

I hate bumping a resolved topic, but I wanted to add one thing:

I changed the [Repeat Function.Param(2) times] condition to a [While; Increment > 2] condition, and it seems to have improved the overall complexity of the function as a whole. Rather than executing the sizing loop a flat number of times, it should execute at most ten times (assuming MaxRange is 2,000).

Again, sorry to bump a resolved thread, but I wanted to throw that in there as a theoretical optimization.
B
7
Posts: 15
Reputation: 305

Previous

Return to Beginner's Questions

Who is online

Users browsing this forum: No registered users and 2 guests