67

Dungeons and Dragons 3.5 (pen-and-paper RPG) has a solution used for both movement and grid-based radius calculations: diagonal movement costs 1.5 what orthogonal costs. Since the diagonal of a unit square is approximately 1.414, 1.5 is pretty close. Because D&D 3.5 only supports integer movement, the way this is actually calculated is that orthogonal ...


66

You need to change the shape of the field of view. So that when you move in any direction, the same number of new squares become visible. Here is one possibility:


38

My first suggestion would be to just stick with A = Counter-clockwise and D = Clockwise movement. It is not very confusing and is pretty much the "standard" (i.e. most common) choice when it comes to orbital movement like this. Another way would be to change the way your game moves. Instead of moving the player when they are on a planet you could rotate the ...


30

Frame based simulations will experience errors when updates fail to compensate for non-linear rates of change. For example consider an object starting with position and velocity values of zero experiencing a constant acceleration of one. If we apply this update logic: velocity += acceleration * elapsedTime position += velocity * elapsedTime We can expect ...


28

You need to take the sum of the directions, normalize that, then multiply by the speed. I tangentially answered this as part of my response to Preventing diagonal movement Specifically: velX = 0; velY = 0; if(keyLeft) velX += -1; if(keyRight) velX += 1; if(keyUp) velY += -1; if(keyDown) velY += 1; // Normalize to prevent high speed diagonals length = ...


26

To have diagonal and orthogonal movement reveal approximately the same area, you need two things (each of which, alone, has already been suggested in another answer or comment): Approximately circular view range: On its own, this won't give exactly the same revealed area for both types of movement. For example, in the image above, orthogonal movement ...


26

There is a simple way to do exactly what you want. In addition to a float velocity you'll need to have a second float variable which will contain and accumulate a difference between real velocity and rounded velocity. This difference is then combined with velocity itself. #include <iostream> #include <cmath> int main() { int pos = 10; ...


18

Game characters are usually animated using a technique called skeletal animation: (Image source: Valve Software) Each 3d model has an invisible bone structure (the red and teal lines in the image above). Each polygon of the model is connected to a bone. When you define a motion sequence, you define it as a sequence of rotations of the bones around their ...


17

There's a number of options: Do as you do. You've already said it doesn't look smooth. There are some flaws with your current method though. For x, you could use the following: tempx += speed * dt while (tempx > 0.5) move sprite to x+1 tempx -= 1 while (tempx < -0.5) move sprite to x-1 tempx += 1 this should be better. I've switched the if ...


16

Use floating values for movement and integer values for collision and rendering. Here's an example: class Character { float position; public: void move(float delta) { this->position += delta; } int getPosition() const { return lround(this->position); } }; When you move you use move() which accumulates the ...


16

When the character gets out of the ship, reorient the view so the character is on top of the planet, and then move the view with the character as they walk around. This way the character is always on top with respect to the view when on a planet, so the left/right controls can stay consistent no matter where you land.


14

One way in which many old-skool games solved (or hid) this problem was to animate the sprite. That is, if your sprite was going to move less than one pixel per frame (or, especially, if the pixels/frame ratio was going to be something odd like 2 pixels in 3 frames), you could hide the jerkiness by making an n frame animation loop that, over those n frames, ...


13

Separate your direction selection code from actual movement code. Choose Direction by checking which keys are pressed. Store it as a unit (normalized) vector. Multiply your Direction with Speed and with DeltaTime. Apply resulting transform to your object/camera.


13

Bresenham In the old times, when people were still writing their own basic video routines for drawing lines and circles, it was not unheard of to use the Bresenham line algorithm for that. Bresenham solves this problem: you want to draw a line on the screen which moves dx pixels in the horizontal direction while at the same time spanning dy pixels in the ...


12

It seems you've already answered your own question. A* is likely the best approach. Yes of course it can be used in the way you describe, including using the height information to avoid mountains. As long as you're able to access information about any grid on the surface of your world, there's no reason you can't use it in the A* heuristic. Finally, you're ...


11

Yes, the Update loop is ideal for this. There are no special plug-ins required and you can do this with the free version. Basically you move the objects a tiny bit towards their destination each frame. When all those frames run one right after the other, it gives the appearance of smooth movement. A self contained script would look like the one I've created ...


11

Since you are using a grid and know which direction the user is proceeding there is nothing constraining you from adapting the prior answer and using a different fields of view depending on the direction. For example you could extended the field to include the corners when you travel in cardinal directions and shrink it down two squares on each end in your ...


11

The "normalized direction vector" is how this task is usually approached, and how I often do it, but lately I've simply been clamping the resulting movement vector. It usually achieves the same end result and the code is a lot simpler: var moveSpeed = 6.0f; function Update() { var movement = Vector3.zero; movement.x = Input.GetAxis("Horizontal") * ...


11

The edit is reassuring. :) Okay, here's a straightforward update loop... Assuming when we fire the missile we initialize remainingFlightTime = 5f then... void UpdateMissile(float deltaTime) { remainingFlightTime -= deltaTime; // At the end of the trajectory, snap to target & explode. // The math will put us there anyway, but this saves // ...


10

Both Dijkstra and A* can add different costs to the edges (=connections) from one tile to another. They also allow to connect two nodes (=tiles) with more than one edge, each one with a different cost. The alternative jump-mode would mean that there is an alternative direct edge from each tile to each tile in jump distance. But because a mech can either ...


10

Sleep calls are an extremely bad way of controlling framerate. Use them to reduce CPU usage for sure, but don't use them to control framerate. usleep(1000 * 15), a 15-millisecond pause (~67 FPS, in theory) No, it's not. First of all, see the documentation for usleep: The actual time slept may be longer, due to system latencies and possible ...


10

There are two common patterns for use of Lerp. The one you're using is: current = Lerp(current, target, sharpness) (where sharpness is a constant between 0 and 1) Note that there's a feedback loop here. The value of current is both an input and an output, so the value of current we use as input in the next frame is the output from the last frame. This is ...


10

I suggest you take a look at a similar concept but then in 3d: Super mario galaxy. https://youtu.be/_8eJC4gIAm4?t=19m At short movements the reference frame stays the same, the universe doesn't move, get beyond a certain threshold the universe moves along/shifts along so the reference frame is back in the middle. You might wish to "movement blur" the ...


9

Ok, that's awkward. My last edit revealed the answer to my problem (that I've been struggling with all day): QGraphicsView casts the camera x/y position to integers... This is the solution: void SceneView::centerOn(const QPointF &pos) { if (mScene) { mScene->setX(int(-(pos.x() - width() / 2))); mScene->setY(int(-(pos.y() - ...


8

Allow me to introduce you to Craig Reynolds' famous paper on Steering Behaviors For Autonomous Characters. If you haven't read it, you should, it'll help you think through these sorts of problems, in particular take a look at the section on pathfinding. The idea of Reynolds' paper is that you can use simple forces that combine to produce life-like, ...


8

The typical way of handling this is to create a camera object. The simplest form of a camera is just a position. This simple camera defines the "center" of the current view. So you don't modify all the positions of your tiles/entities, you just subtract the camera coordinates from the positions when drawing. In this situation, the camera does not "move". ...


8

Using a while loop inside your game loop is a basic no-no. Think about how the code is being executed and you'll realize why it just teleported or was frozen and then teleported. (hint: how much of that code do you think is run before the next time your graphics are updated?) You want to have a target position, then on each iteration of your game loop check ...


8

Conceptually, you can do that by animating the rotation of the cube (or as in Bloxorz, a cuboid) 90 degrees around one of its edges. You don't need move() at all! Side-on view of one rotation: Here's a seriously good JMonkeyEngine tutorial showing you how to rotate Boxes around pivot Nodes. It explains everything step-by-step. These are the important lines:...


7

This depends on the combination of frameworks you are using. Sometimes a 2D game framework makes it very difficult to work with coordinates that are not bound to pixels because they were designed specifically for designers to think about their game world in pixel units. However, it's not a requirement. A game I'm currently working on relies on Box2D units ...


Only top voted, non community-wiki answers of a minimum length are eligible