• Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

135 Neutral

About PiCroft

  • Rank
  1. [quote name='Olof Hedman' timestamp='1328714857' post='4910917'] how do you want it to move? My first thought is to separate y and x-movement. x-movement could be constant or slightly accelerating (endless runner style) when you press, you start to accelerate the y-speed, making it "go down" faster and faster while holding the button. Maybe you want a "lower limit" where it will start decellerating instead so it can't go below a fixed height too. Releasing the button to reverse it. (start accelerating upward until its "close enough" to the top, then decellerate so it levels out at the max height) This would give it a bit "sinus"-like movement. [/quote] This is actually what i had in mind, my worry was that the x-movement would remain constant and it would simply replicate my current problem, only limiting it to x-axis movement. I suppose I could try accelerating x-movement by using y-speed as some kind of input but I'm not entirely sure how this would work.
  2. [quote name='before-it-was-popular' timestamp='1328711343' post='4910901'] So I take it no gravity means top-down? One clarification: how is the angle you need to turn to calculated? Does the player press left or right to rotate continuously, or does he press a direction to instantly face that direction - or is it something different? [/quote] Sorry, I'll try and clarify: Its actually side-on, the character by default hovers at a certain height and when a button is pressed, they dive down. When the button is released, the character returns to their original height. The angle is calculated using this code: [code]//We need to calculate absolute angles between character current heading and upper limit/ground //get vector to upper y zVec2f vecToUpper, vecToLower; vecToUpper.x = getPosition().x + 5.0f; vecToUpper.y = baseline_y_upper; vecToUpper = vecToUpper - getPosition(); vecToUpper.normalise(); //angle from straight-up to vector pointing towards upper limit float UpperVecAng = vecToUpper.getAngle(); //get vector to lower y vecToLower.x = getPosition().x + 5.0f; vecToLower.y = baseline_y_lower; vecToLower = vecToLower - getPosition(); vecToLower.normalise(); //angle from straight-up to vector pointing towards ground float LowerVecAng = vecToLower.getAngle(); zVec2f heading = moveDir; heading.normalise(); float headingAng = heading.getAngle(); //calculate difference in current heading and upper/lower trajectories float UpperAngDiff = UpperVecAng - headingAng; float LowerAngDiff = LowerVecAng - headingAng; [/code] Once I have the difference between the character heading and the upper/lower limit, I reset the character heading back to default, calculate a turn based on a turning speed value and set the new angle to that. The only input the player makes is pressing a button to make the character start diving, if they press nothing, the character just flies forwards and bobs at the maximum height (or turns upwards and flies towards the max height if they are below it).
  3. Hi, I've got a small prototype involving a character that flies across a 2d landscape. The character in question isn't a plane and I'm not requiring any advanced physics such as lift, gravity etc. The character in question currently moves by having a set speed and between frames, I calculate the angle I need to turn from the default and set the character's heading appropriately by rotating the movement vector. While this works, the character has a very uniform movement style and speed that isn't very interesting. Due to the way I've designed it so far, I'm having trouble creating a system where the character accelerates/decelerates in a fluid way that isn't either horrible to look at or a nightmare to code and I was wondering if anyone might suggest a nice method/way of thinking about the problem that might work? Please let me know if I need to clarify anything.
  4. Hi there. I have a simple game where I want to be able to drag tiles around on a board. The game is entirely 2D. I have it set up so that it takes in a touch (or mouse click), sees if the click is with the boundary of a tile and then moves it accordingly. However, the engine I use doesn't provide localised touch coordinates, only in screen coords. This means that if I click in the centre of the screen, instead of getting 0,0, I will get half the window size in length/height in pixels. Now, I expect this for screen coordinates, but what I don't know is how to convert this to local coordinates. I have made a start by normalising the coords and shifting them so they are relative to the centre of the screen: [code] float width = zGetScreenWidth(); float height = zGetScreenHeight(); float halfwidth = width/2; float halfheight = height/2; float aspect = 1.3333f; float x = touch_coords.x; float y = touch_coords.y; float dx = (x/halfwidth-1.0f)/aspect; float dy = 1.0f-y/halfheight; return newpos;[/code] This works, when I click dead-centre in the middle of the screen I do indeed get 0,0 but because it is normalized, all my coords are clamped between 1 > -1. I'm not sure how to "up-scale" the coordinates so they match the local coordinates of my game board. Can anyone assist?
  5. I was right, the rotations were being added every frame, resetting the rotation each time works Sorry for being mysterious , to clear things up: there's no gravity required, the object in question is an insect that bobs up and down at a certain height and when a button is pressed, it swoops down to a lower height and bobs up and down at that height. I am in fact looking to make the insect speed up during dives/rises, but at the moment I'm just kind of experimenting with ways of doing things and seeing what feels right, so for the time being there is no real "right" way to do it
  6. Thanks guys, this is a lot of help! I think I know why my object isn't behaving as I thought - the rotate() function is relative to the current position, so when it gets and angle of, say, 4.1 radians, its rotating that amount every frame which may be why its flying about all over the place. I'm going to try resetting the rotation back to a specific default value every frame and rotating from there and see if it fixes the problem.
  7. [quote name='Tom KQT' timestamp='1320671819' post='4881384'] [quote name='PiCroft' timestamp='1319728613' post='4877578'] Hello, I'm trying to create a simple 2D game where an object is flying at a particular height at constant velocity. When I press a button, the object starts to dive, the dive getting steeper the longer you hold the button. When you release the button, the object levels out, then starts to climb back up to its original height. Could someone give me some math pointers for making this mechanic? [/quote] I wouldn't go with splitting the velocity into horizontal and vertical. In fact, if you keep horizontal as it is and increse the vertical part, the total velocity will have higher magnitude, which probably won't be what you want. I would solve your problem by having a velocity vector [b]v[/b] (which will be horizontal during the initial flying at a constant height). When you hold a dive button, I would simply rotate the vector down. The longer you hold the button, the bigger the overall rotation, but with a limit at some defined angle (for example 70 degrees to not let it dive too steep) When you don't hold the button, I would gradually rotate the vector back to the initial horizontal orientation, then compare the current height with the target height and if it is smaller, rotate the vector further upwards to make the object ascend to the required target height. Your actual position is then simply updated every frame as [b]p[/b] = [b]p[/b] + [b]v[/b] * dt; where dt is the timestep between frames, [b]p[/b] is a position vector (2D) and [b]v[/b] is the velocity vector (2D). If you always change the rotation gradually (so not for example from 0 to 40 degrees in one step), the resulting movement will be nicely smooth (the object's central point would draw a smooth curve). Please let me know if this verbal explanation isn't clear and/or if you would prefer some equations. Btw, it of course all depends on what kind of movement are you trying to get, what kind of object it is etc. Maybe you really want it to dive at higher overall velocity than when it flies horizontal?The solution with rotating velocity vector would suit something like an airplane, where the rotation even can be nicely visualised (the whole airplane rotates). [/quote] Thatnks, this is closer to what I want. The idea is that the object will have 2 heights: at default, the object will move towards the upper height (default behaviour) and when diving, it will move towards the lower height. I have the velocity and I'm adding it to the position as you suggested, and I am getting movement forward (because the default velocity is forwards, but I'm having difficulty correctly calculating the rotation. [code] //if diving, set target y to lower limit zVec2f target; target.x = getPosition().x; target.x += 5.0f; if(diving) target.y = baseline_y_lower; else target.y = baseline_y_upper; zVec2f delta = (getPosition()-target); float TurnDir = delta.getAngle(); float rotDif = zRadRelative(TurnDir-physOrientatiation.xa.getAngle()); physOrientatiation.xa.rotate(rotDif); //set final velocity zVec2f velocity = physOrientatiation.xa; velocity.normalise(); setPosition(getPosition() + velocity * ev.getTime().dt); //rotate sprite mainr->setRotation(physOrientatiation.xa.getAngle());[/code] The above code makes my object fly in weird directions. I'm not entirely sure why though :/ Edit: [b]physOrientatiation.xa.rotate(rotDif); [/b]rotates to an absolute value in radians I believe, so when it calculates the difference in angle between the current heading and the target point, the value returned is the total angle needed to turn, not the angle needed to turn this frame. That being said, I'm wondering why this is causing such odd behaviour since, if the object turns directly towards the target in 1 frame, the next frame the difference should be tiny or non-existant, meaning that it should snap to facing the right direction immediately and then continue correctly, but instead it floats off in odd directions.
  8. Thanks, that's useful! I need to make the object rotate correctly too, I'm using a second object hovering slightly in front of the main object thats invisible, so the object always rotates to face it. It doesn't look right atm, but Its a good stop-gap until I can make a movement algorithm that correctly applies physics to it.
  9. Hello, I'm trying to create a simple 2D game where an object is flying at a particular height at constant velocity. When I press a button, the object starts to dive, the dive getting steeper the longer you hold the button. When you release the button, the object levels out, then starts to climb back up to its original height. Could someone give me some math pointers for making this mechanic?
  10. Apologies, I fixed it, here was the problem: [code]std::list<cHBGameObject*>::iterator i; //remove any object that has passed the cutoff if(!lObjects.empty()) { i = lObjects.begin(); while (i != lObjects.end()) { if((*i)->checkIfOverDeletionThreshold(xDeletionPoint)) lObjects.erase(i); else ++i; } }[/code] the bolded bit needed to be changed to: [code] i = lObjects.erase(i);[/code] So that i recieved a valid pointer after the erasure. Sorry for the wast of time, though if someone else stumbles on this problem, I hope this helps Edit: Thanks Erik, I just spotted that myself
  11. I've got code which loops through a list using an iterator. It performs a check on that object and if the condition fails, the item is deleted using the list::erase() method. [code] std::list<cHBGameObject*>::iterator i; //remove any object that has passed the cutoff if(!lObjects.empty()) { i = lObjects.begin(); while (i != lObjects.end()) { if((*i)->checkIfOverDeletionThreshold(xDeletionPoint)) lObjects.erase(i); else ++i; } } [/code] In this case, the crash occurs if there is only 1 remaining object and the object is deleted, then when it returns to the "while" statement, the error is thrown. I can sort of see where I'm going wrong, I think when it hits "while", because the list is empty, it may be that the iterator no longer points to anything valid. I have looked up examples to make sure I'm not doing it wrong but every analogous example I have seen have suggested this approach to looping through a list where you may delete objects. Besides, being able to delete objects in this manner is one of lists' advantages over vectors, no? Could someone kindly point out where I am going wrong?
  12. Converting map coords to screen coords

    Nevermind, I removed the screen drift so the character is always dead-centre. E: The character wasn't a constant distance, if the player started in the centre, then moved forward, the screen would drift forward in front of the player slightly so the player could see more space in front fo them. This also applied if the player turned, so it would drift to the left if the player was moving left, and so on. Basically, the player and camera were positioned relative to the game map, the mouse coordinates were only in screen coords. Its a massive pain to draw this in MS paint and I can't install a decent drawing program on this machine.
  13. Converting map coords to screen coords

    Well here is a quick and dirty diagram. In this case, the map origin is in the centre of the game world, at 0,0. In map coords, the player is at, say, -10,-10 and the camera -7,-7. Now the mouse cursor is what the player is always looking at, and it is it something like 400,565 since the screen resolution is 960x640 (I know it isn't exact, its just for example) Currently, I am converting the camera to screen space simply by taking half-screen-width and half-screen-height to get the centre point of the screen and using this with the screen-space mouse cursor coordinates. As I said, since the character is not in the exact centre of the screen, this means the character facing is inaccurate. What I need is a way to convert the map-coord character position (-10,-10 relative to the map origin) to the screen-space equivalent (for arguments sake, 320, 670).
  14. I've got a problem where I'm trying to get a character on screen in a top-down 2d game who always faces the mouse cursor. The engine I'm using uses a map, and all objects on the map provide their position relative to the map origin. I can use calls to get the mouse position in screen coordinates and I have a camera thats always centred in the middle of the screen. I've currently got it working by getting the mouse coords (in screen space), getting the camera (which is provided in map coords for some reason, but since its always centered, I can just set it to half screen height/half screen width) and calculating the delta as (mouse pos - cam pos) and getting the angle from there. The problem is, the game is designed with a drifting camera that floats slightly ahead of the player as they move forwards to allow them to see further ahead, and since the character turning angle is calculated from the centre of the screen, the character aim is off when the camera drifts ahead, since the character is no longer at the centre of the screen. What I'm looking for is a way to convert the character in map coords into screen coords, so I can perform the calculation from there. Any help would be appreciated! Also, any questions, feel free to ask if I haven't explained something well.
  15. [quote name='Hodgman' timestamp='1309442061' post='4829575'] Only multiply the 'specular' variable with your alpha-channel, not the final lighting result. [/quote] My original fragment shader didn't have a specular variable unfortunately. I've since modified it with what I believe should correctly calculate the specular component (or rather all of them, but I only need the specular component of the result). For reference, here is the vertex shader: [code]void main( in float4 position : POSITION, // The position of the current vertex. This parameter is required by CG in a vertex shader! in float2 texCoords : TEXCOORD0, in float3 vTangent : TEXCOORD1, in float3 vBinormal : TEXCOORD2, in float3 vNormal : NORMAL, out float4 positionOUT : POSITION, // Send the transformed vertex position on to the fragment shader out float2 texCoordsOUT : TEXCOORD0, // Send the texture map's texcoords to the fragment shader out float2 normalCoordsOUT : TEXCOORD1, // Send the normal map's texcoords to the fragment shader out float3 vLightVector : TEXCOORD2, // Send the transformed light vector to the fragment shader out float3 positionPassed : TEXCOORD3, out float3 normal : TEXCOORD4, const uniform float4x4 ModelViewProj, // The concatenated modelview and projection matrix const uniform float4 lightPositionOS) // The light sphere's position in object space { // Calculate the light vector vLightVector = lightPositionOS - position.xyz; // Transform the light vector from object space into tangent space float3 binormal = cross(vTangent,vNormal); float3x3 T = float3x3(vTangent, binormal, vNormal); vLightVector.xyz = mul(T, (lightPositionOS.xyz - position.xyz * lightPositionOS.w)); // Transform the current vertex from object space to clip space, since OpenGL isn't doing it for us // as long we're using a vertex shader positionOUT = mul(ModelViewProj, position); // Send the texture map coords and normal map coords to the fragment shader texCoordsOUT = texCoords; normalCoordsOUT = texCoords; positionPassed = positionOUT; }[/code] and here's the (modified) fragment: [code]void main( in float4 colorIN : COLOR0, in float2 texCoords : TEXCOORD0, // The texture map's texcoords in float2 normalCoords : TEXCOORD1, // The normal map's texcoords in float3 vLightVector : TEXCOORD2, // The transformed light vector (in tangent space) in float3 position : TEXCOORD3, in float3 normal : TEXCOORD4, out float4 colorOUT : COLOR0, // The final color of the current pixel uniform sampler2D baseTexture : TEXUNIT0, // The whole rock texture map uniform sampler2D normalTexture : TEXUNIT1, // The whole normal map uniform float3 lightcolor, uniform float3 eyePositionOS, uniform float3 lightPositionOS) // The diffuse color of the light source { // We must remember to normalize the light vector as it's linearly interpolated across the surface, // which in turn means the length of the vector will change as we interpolate vLightVector = normalize(vLightVector); // Since the normals in the normal map are in the (color) range [0, 1] we need to uncompress them // to "real" normal (vector) directions. // Decompress vector ([0, 1] -> [-1, 1]) float3 vNormal = 2.0f * (tex2D(normalTexture, normalCoords).rgb - 0.5f); float4 normMap = tex2D(normalTexture, normalCoords); float shininess = 16.0; half3 L = normalize(lightPositionOS - position); // Vertex to light half3 V = normalize(eyePositionOS - position); // Vertex to eye half3 N = normalize(normal); // Normal half3 H = normalize(L + V); // Half angle vector float NdotL = dot(N, L); float NdotH = dot(N, H); half4 lighting = lit(NdotL, NdotH, shininess); lighting.z = lighting.z * normMap.w; // Calculate the diffuse component and store it as the final color in 'colorOUT' // The diffuse component is defined as: I = Dl * Dm * clamp(L?, 0, 1) // saturate() works just like clamp() except that it implies a clamping between [0;1] colorOUT.rgb =lightcolor * tex2D(baseTexture, texCoords).rgb * saturate(dot(vLightVector, vNormal)); }[/code] I'm still learning my way through the basics right now so forgive me for missing stuff. I think I have calculated the specular component in the fragment shader, and I've multiplied this by the alpah component sampled from the normal map, but I'm not entirely sure how this ties into the final colour calculation.
  • Advertisement