1

我想做一个背景和精灵(视图)在屏幕上移动的 2D 游戏。

我想制作一个带有滚动地面的游戏。我的意思是用户必须在屏幕顶部看到一个水平线,填充了屏幕大小的 30%。地面必须滚动并且必须是屏幕大小的 70%。例如,如果我将汽车放在地上,汽车必须驶入滚动的道路,并且必须在屏幕上看到天空(地平线),在道路的顶部,占据屏幕的 30%。

我在谷歌上搜索滚动游戏,但我找不到实现这种带有地平线的滚动地面游戏的方法。

任何想法和方法都会被磨碎,我只是在研究如何做到这一点。

谢谢

4

2 回答 2

1

This kind of effect can be done in various ways, here is one very basic example I can come up with.

First create a background image for your horizon - a blue sky with a sun would be good. Now create some detail images for the background, such as clouds and birds. These can move accross the background image from left to right (and/or vice-versa). In your rendering code you would render the "background" image first, and then the "detail" images. Make sure that your background image covers around 35% of the screen, so that when you render the 70% ground layer there is some overlap - preventing a hole where the two layers meet.

Next create a textured image for the ground. For this I would use a static image that has the correct type of texture for what you are trying to represent (such as dirt). It may also be good to add some basic detail to the top of this image (such as mountains, trees, etc). This should be rendered after the background layer.

Once you have this layout in place, the next step would be to simulate the depth of your world. For this you would need to create objects (2D images) that would be placed in your "world". Some examples would be trees, rocks, houses, etc.

To define your world you would need to store 2 coordinates for each object - a position on the x-axis as well as a depth value on the z-axis (you could also use a y-axis component to include height, but I will omit that for this example).

You will also need to track your player's position on the same x and z axis. These values will change in realtime as the player moves into the screen - z will change based on speed, and x will change based on steering (for example).

Also define a view distance - the number of units away from the player at which objects will be visible.

Now once you have your world set up this way, the rendering is what will give the illusion of moving into the screen. First render your player object at the bottom of the ground layer. Next, for each world object, calculate it's distance to the player - if it's distance is within the view distance you defined then it should be rendered, otherwise it can be ignored.

Once you find an object that should be rendered, you need to scale it based on it's distance from the player. The formula for this scaling would be something like:

distance_from_player_z = object.z - player.z
scale = ( view_distance - distance_from_player_z ) / view_distance

This will result in a float value between 0.0 and 1.0, which can be used to scale your object's size. Using this, the larger the distance from the player, the smaller the object becomes.

Next you need to calculate the position on the x-axis and y-axis to render your object. This can be achieved with the simple 3D projection formulas:

distance_from_player_x = object.x - player.x 
x_render = player.x + ( distance_from_player_x / distance_from_player_z )

y_render = ( distance_from_player_z / view_distance ) * ( height_of_background_img );

This calculates the distance of the object relative to the player on the x-axis only. It then takes this value and "projects" it, based on the distance it is away from the player on the z-axis. The result is that the farther away the object on the z-axis, the closer it is to the player on the x-axis. The y-axis part uses the distance away from the player to place the object "higher" on the background image.

So with all this information, here is a (very basic) example in code (for a single object):

// define the render size of background (resolution specific)
public final static float RENDER_SIZE_Y = 720.0f * 0.7f;  // 70% of 720p

// define your view distance (in world units)
public final static float VIEW_DISTANCE = 10.0f;

// calculate the distance between the object and the player (x + z axis)
float distanceX = object.x - player.x;
float distanceZ = object.z - player.z;

// check if object is visible - i.e. within view distance and in front of player
if ( distanceZ > 0 && distanceZ <= VIEW_DISTANCE )  {

   // object is in view, render it
   float scale = ( VIEW_DISTANCE - distanceZ ) / VIEW_DISTANCE;
   float renderSize = ( object.size * scale );

   // calculate the projected x,y values to render at
   float renderX = player.x + ( distanceX / distanceZ );
   float renderY = ( distanceZ / VIEW_DISTANCE ) * RENDER_SIZE_Y;

   // now render the object scaled to "renderSize" at (renderX, renderY)
}

Note that if distance is smaller than or equal to zero, it means that the object is behind the player, and also not visible. This is important as distanceZ==0 will cause an error, so be sure to exclude it. You may also need to tweak the renderX value, depending on resolution, but I will leave that up to you.

While this is not at all a complete implementation, it should get you going in the right direction.

I hope this makes sense to you, and if not, feel free to ask :)

于 2013-06-04T09:59:44.943 回答
0

好吧,您可以使用 libgdx ( http://libgdx.badlogicgames.com/ )。superjumper 示例将使您以正确的方式 :) ( https://github.com/libgdx/libgdx/tree/master/demos/superjumper )

于 2013-06-04T06:36:37.637 回答