R0J0hound's Recent Forum Activity

  • Setting the camera location in the "look at" action would make the camera angle to the standard 22.5 degree view. For 45 you'd remove the /2. That 1.125 was a correction to make the tile diamond exactly 2:1.

    player.x+1000
    player.y+1000
    player.z+1000*sqrt(2)/2*1.125

    Anyways, that will still have perspective, so to remove that you need to change the layout property "projection" to "orthogonal". However, with orthogonal you lose the ability to zoom in and out.

    To keep the ability to zoom in and out you could keep the projection as perspective and make the "field of view" to be very small to make it nearly orthogonal. The smaller FOV will zoom in more so you'll need to move the camera further back so you may end up needing to increase the advanced project property "far distance" if things disappear. Increasing that will also increase z-fighting artifacts, so you may be able to increase the "near distance" as well to reduce that just as long as things don't disappear.

    You may also be able to counter that near/far fiddling by scaling things in other ways, but I haven't tested that.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • The instance variable idea sounds like it would work.

    If all the cards were just one object type and had different animation frames and variable values and all the cards were created. then just picking 8 from that and in turn four from that would be fairly easy with events.

    Some like having different cards be separate object types. In which case putting all those types in a family would be an option. But again to make it easy to pick you’d want all the instances created beforehand.

    Some like the idea of not having to have a card instance for every card in the deck, so instead you could instead create/destroy the cards on the fly. Simple to do but it will throw a slight inconvenience with picking events. Namely there has to be a so called delay after creating instances so they can be picked normally.

    The closest point is at the next “top level event” but I’m not sure anyone else has utilized that.

    The next closest would be at the end of the frame. Using a wait 0 action defers to the end of the frame.

    Others have tried the next frame or waiting some longer period of time.

    Anyways, I’ve found it cleaner to avoid that altogether and just create the instances beforehand or at the start of the layout. With the cards being a single object type you can just change one card into another by changing its properties instead of creating/destroying.

    Personally I’d be inclined to do the first idea. One object type for all cards. Create each card on the layout and customize each of their animation frames and variables. Some of the variables could be deck=0 and hand=0. You’d just set any to 1 that you’d want to hold. It’s easy to pick them by variable in events. You could just move the other instances off screen.

    The second iteration could be to do the same thing but instead of creating all the cards I’d just create all the ones in your deck. Then I’d have an array or json with all the specs or each possible card and then change the created instances from that.

  • Looks like your requirements were simpler than I thought after looking at your c3p.

    Updated and tested this as working in events. Adapting it to js will require you to convert the fov of 45 to radians.

    It takes the height of the viewport, 45 which is the fov, and the center of the screen which can be the scroll center or just half the viewport size if there is no scrolling.

    zplane = -100
    scale = 1-zplane*tan(45/2)/(Height/2)
    
    x = (mouse.x - center.x)*scale + center.x
    y = (mouse.y - center.y)*scale + center.x
    z = zplane
  • So it’s mostly just a matter of calculating the intersection of the mouse ray (camera to mouse) and the plane at z=-100.

    So the long way of calculating the mouse ray would be to consider the mouse position on a 2d layer and make a vector from the center of the screen and camera eye distance ( can be calculated from screen size and fov) to the mouse position. Then you’d need to rotate that by the camera’s orientation matrix and adding the camera position.

    The simpler way to get the mouse ray could be to leverage existing c3 features. If you get the mouse position on a 3d layer it will give you the xy of the mouse projected on the z=0 plane. So the ray would be from the camera to that.

    So, anyways the generic formulas for a line and plane are:

    P=p1+u*(p2-p1)

    N dot (P-p3)=0

    And the intersection can be found by combining the two formulas and solving for u:

    U= (N dot (p3-p1))/(N dot (p2-p1))

    And finally plugging that back into the line equation to get the actual point.

    However in your case it all can be simplified at lot.

    P1 = camera.pos

    P2 = vec(mouse.x, mouse.y, 0)

    P3 = vec(0,0,-100)

    N = vec(0,0,1)

    So barring any errors the final equations should be:

    PlaneZ =-100

    X = lerp(camera.x, mouse.x, -planeZ/camera.z+1)

    y = lerp(camera.y, mouse.y, -planeZ/camera.z+1)

    Z = planeZ

    Just make sure the mouse coordinates are from a 3d layer. You can specify the layer you get the mouse coordinates from with mouse.X(layer)

  • Looks cool as always.

    Is there a particular project that you're making to utilize this? Or is there any end goal feature set you want to have?

  • One way could be to have a dummy 3d object that you rotate (since you said you have been able to do that).

    Then just set the 3dcamera’s orientation from that object’s orientation.

    The main issue is there are three ways to specify 3d orientation: Euler, quaternion, and 3x3matrix. Most objects let you use Euler and quaternion, but with the camera you can only set the orientation in a general way with the look at action which basically takes a 3x3matrix.

    You can convert between the different orientation representations with some math that you can find online. For example:

    euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm

    So say you have an object’s orientation as a quaternion (qx,qy,qz,qw) which there are expressions for. Then you can convert it to a 3x3 matrix. In the matrix the second row would be the up vector, and the third row would be the forward or basically the look at vector if you add the camera position.

    So the parameters for the look at action should be:

    Camera x = self.x
    Camera y = self.y
    Camera z = self.z
    Look x = 2*qx*qz - 2*qy*qw +self.x
    Look y = 2*qy*qz + 2*qx*qw +self.y
    Look z = 1 - 2*qx^2 - 2*qy^2 +self.z
    Up x = 2*qx*qy + 2*qz*qw
    Up y = 1 - 2*qx^2 - 2*qz^2
    Up z = 2*qy*qz - 2*qx*qw

    The qx means 3dobject.QuaternionX In those expressions if that’s not clear. Same for qy, qz and qw.

    Anyways, barring any typos on my part or some oddity in c3 then that should work.

    You could also convert between Euler and matrix instead. But you’d have to try different rotation orders if c3 rotates xyz in different orders than the formulas.

    Maybe c3 will hide the complexity at a later date and just let you set the camera’s orientation from another object, or just give everything the same rotation tools. But short term things seem to look more and more cluttered to me.

  • You need to edit the function and specify the return value type there.

    Just using the return action isn’t enough.

  • I think most missing things are usually an oversight that a quick feature request could probably remedy.

    So apart from agreeing that such a feature sounds like it could be useful, I don’t have much to add.

  • Maybe you could set an instance variable in the timeline that’s normally a different value. Or if you specify the instance at runtime with the “set instance” action you could try to keep track of it then too.

    If you don’t mind a multiple build step approach you could make a tool to parses the timeline information out of the c3p file and sets a json file in the project you can access. Or maybe you could access the exported data file directly and parse out the timeline info from that.

    Scripting wise it may be easier to just request a method to be able to access it from the api.

  • Short of access to the actual project and someone taking time to look through it it won’t be possible to debug.

    That said areas you could focus your attention on is the “or” blocks and “trigger once” conditions. Or blocks tend to bite me often so I carefully ensure they are doing what I intend when I use them.

    Maybe putting a for each in the custom actions may help too. In general many find it simpler to use “for each” in any place that there may be multiple picked instances to make the logic more clear to them.

  • Let us know if you want to be confined to any other shape.

    A rotated rectangle can be done by first rotating position offset by the -angle, then clamping by the size, and rotating the angle back again.

    A circle shape can be done by measuring the angle and distance, clamping the distance, the calculating a new position from that.

    If you want to limit it to an object’s collision polygon, and the polygon is a convex polygon, you can take the position offset and clip it by each edge with a bit of math. Namely with (x-x0)*cos(a)+(y-y0)*sin(a) you can measure a distance along a certain direction. If you use that with an angle 90 degrees from an edge you can find if a point is on either side of an edge and clip it if on one side.

    Finally if you want to limit the motion to a concave shape you probably could do that by storing the players previous position and calculating the line intersections between the edges and the segment connecting the new and old position, and finally just stop at the first intersection. I don’t think that would provide any wall sliding but one idea for that involves decomposing the concave shape into convex ones, but it may be a bit more involved. Basically you’d check for overlaps with edges, the limit to the convex sub polygon that edge is part of.

    Also depending on the shape you could possibly utilize sdfs to implement the limit. That would let you have shapes with rounded corners.

    Taking the sdf idea further, you could make an approximate sdf on a 2d grid of any shape and raymarch through that. The main complexity there would be generating it.

    There are some low tech approaches too. You could store the old and new positions and use a loop with an overlap test to move but stop short of leaving the other object.

    Dop’s suggestion to place invisible solid objects around the shape is probably the easiest no code option. Another is to make the collision polygon a crescent shape that you wrap around the object image so there’s a thick wall around it.

    With collision based approaches beware of tunneling. Aka with high speeds and thin walls the collisions can be missed and objects will move right through.

    There are probably other approaches with varying pros and cons.

  • That’s a tricky one to give an exact answer since most don’t have such specific requirements.

    That said, it looks like there are expressions to get the current playback time and the time of nodes on the timeline. That combined with the duration of a landing animation you could have an event to check the time to decide when to change the animation.

    Having the requirement of only changing animations on a particular frame can be handled with events too. However combined with that other constraint you may need to adjust the speeds of things.

    For example, say you have a looping running animation you want to jump at a node on the timeline, but you only want it to change on a particular frame you’d want to either pause the timeline at that node and wait till it’s at the right frame or look at the time anticipating the node and speed up/ or slow down the animation speed so that the frame is where you want it to be at that node.

    There’s probably a system you could make to do that in a general way. Like you’d have the list of animations you know you need to move through and a list of the nodes on the timeline where you what the transitions to be. Then it would adjust either the speed on the path or the speed of the animations so that the transitions are at the exact time and frame you want.