KTB Tutorial 1: 2d randomly generated terrain for Worms style game

本文介绍了一种用于生成2D地形的方法,类似于Worms风格的游戏。教程详细解释了如何生成黑白地形,并对其进行纹理处理以获得逼真的效果。此外,还提供了一个开源Java游戏KillerTeddyBear作为实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

KTB Tutorial 1: 2d randomly generated terrain for Worms style game

March 22nd, 2007

Important note: this tutorial is the part 1 related to Killer Teddy Bear Game (open source game in java). You can read the rest of the tutorials here.

You can also download the full game for playing online against other player. It is completely free and you can use it like a base for your own game. Don’t expect anything incredible, it’s more an experiment than a finished game:

* Download Killer Teddy Bear game (.jar file, you need the JVM)
* Download Killer Teddy Bear source code (Eclipse project)

0. Introduction

In this first tutorial I will explain how to generate 2d terrains like the one we are used to see in Worms games. The explanation will not be in any programming language but in a general way of tackling the problem. But you have here the source code of KTB game that uses these ideas. The classes that implements the terrain generator are TerrainGenerator.java and MapGenerator.java.

KTB Tutorial 1

1. Generating a random terrain in black and white (TerrainGenerator.java)

If you have played any Worms games you would probably have designed some worlds with the terrain editor. Basically, what this editor allow you is to draw a black and white 2d map. Later, in the game, the black areas will be considered as terrain and will be properly textured. Of course, these worlds can be textured with different layouts: forest, desert, snow, etc.

Furthermore, in order to share these worlds between players in a net, you only have to send the seed that generated the terrain. So, if the seed it’s an integer one map will be encoded in 4 bytes!

So the first step is to generate this black and white terrain (you can use alpha = 0 instead of white in order to be able to put a sky layout in the background), but of course, it has to be generated randomly. There are thousands of algorithms for doing this, for sure lot of theme will be faster than the one I will propose here, you are free for trying the one that would fulfill your needs.

The first thing I wanted was to generate some mountains, so I called my friend Google and we found together this approach to a terrain generator solution in robot frog.

Terrain Generator

The algorithm was, clear, well explained and “render independent”, so I quickly decided to use it. Basically it generates a matrix of vertex as big as you need. It is up to you what will you do with these vertex’s than “describes” the mountains. So, the generator is not linked to any render.

The first fix I needed to implement, after easily moving the code from c++ to java, was to change it from 3d to a 2d space. That was an easy task because in fact I didn’t touch the code. I just generated a 640* 640 matrix terrain (640 = width in pixels of my black mountains) and I basically got a “mountain line vertex’s” from (0, 320) to (640, 320). 1D noise function should be faster than this, I mean, to calculate only one line of mountains, you can experiment with the code as you wish trying other procedures for generating these mountains.

Terrain Generator

Later I drew vertical columns of one pixel width using these vertex heights. Et voila!

Terrain Generator

Of course, having only mountains it’s a bit sad, so I implemented a function that draws groups of ovals of random radius in different positions of the screen. This, together with the base mountains, generated a nice result.

Terrain Generator

2. Texturing the black and white generated terrain (MapGenerator.java)

This was my favourite part of the implementation. I remember that it take me only 3 hours to have a rough approximation and it was a great pleasure to see that the result was really near to the one used in Worms game.

The first thing you need are three textures for texturing. The first one will be the base texture, the second will texture the upper areas and the last one the lower areas. Changing these textures the whole map will look different. I used grass, sand and stone.



Applying base texture

This was the easier part. You just have to check all the black pixels in the map image and to put on each of them the appropriate pixel from the base texture. Take care of starting again from the beginning of the base texture if you arrive to the end.

Applying upper and lower textures

And this was a bit tricky… but funny!

The algorithm for upper and lower texturing is the same. Basically, once you find an upper edge, you will draw a column of grass pixels in down direction, and you will do the same for the sand but in opposite direction. But there is an important thing can not forget: the height of that column will be in most of the cases the height of the grass texture… but not always! If you take a close look at the textured images, in the floating islands the grass is very shallow along the edges, producing a curve as it progresses towards the center. This is because the height of the grass column is getting lower and lower in these areas.

These are the steps you have to follow (in this case for the upper texture, but the procedure for the lower texture is the same):

* In a nested loop
* For each pixel in the map check if the above pixel is white (so it’s an upper edge pixel)
* Go down from this position increasing a counter until you reach a white pixel (lower edge)
* If this valour is bigger than the height of a column in the grass texture, we can directly draw it. If not, we can get the height of the grass column we have to draw dividing this valour by 1.4 (I tried 2, but this valour gave me better results).

Please check the source code, there are additional comments that should be useful.

And this is the final result, with a background and some funny killer teddy bears.

And now… what about having destructible terrain?

Well, depending of what you want to do, this can be really easy. For example, you can just draw an oval with alpha = 0 and erase this area of the terrain directly from the textured map. The trick for having better results is to have a second background terrain (with a different texture, for simulating some distance) and erase it with an oval of less radius.

In Killer Teddy Bear game, what I do it’s just to erase the terrain with that oval of alpha = 0. But you can implement new weapons that chomp the terrain in other way! Just user your imagination!

And soon… the second tutorial of the game: how to make an online game using java sockets! Tell me if you are interested in this tutorial writing some comments, please!

7 Comments »

  1. That’s really quite impressive. I’d read that robot-frog tutorial before and used it for actual 3D terrain generation but I never thought of applying it to 2D.

    Good tutorial too, well-explained.

    Comment by Steve � March 22, 2007 @ 11:17 am

  2. Nice tutorial indeed, thanks for sharing.

    Comment by Raine � March 22, 2007 @ 11:48 am

  3. Thank you for reading it!

    Comment by Indie Rover � March 27, 2007 @ 4:42 am

  4. Thanks, very nice and easy to understand tutorial. Gave me some ideas.

    But what if the map is larger than the screen .. let’s say 1200×600 or even larger .. then it would get really slow and take up a lot of texture memory to render. How would you go about optimizing it? Because Worms has quite large terrains..

    Even if you render the map onto a texture once and then place the texture on screen according to ‘camera’ position, it would get really slow and even more slow as you used higher screen resolution.

    Comment by Eigen � March 29, 2007 @ 8:16 am

  5. As you have read, the code is thought for generating the terrain in a bitmap. It’s up to you how will you render it later in the screen.

    In my java game I put it directly in a BufferImage, that can be rendered directly into the screen. Once the terrain is generated, you dont have to touch it until there is an explosion. In the areas that suffer an explosion, I only draw an alpha = 0 circle in this position. This is giving me good performance at (640×480) with 100fps.

    But for example, for one of the demos of my graphic 2d library LooverLib I first generated the terrain (only one time), and then I cut it in blocks and made textures for rendering quads.

    So, the tricky part, if you use textures, will be to regenerate the terrain in these areas that had and explosion. You should access to this texture texels (only the quad or quads that suffered the explosion) and make the holes. But will be fast, because you will be all the time rendering the quads and only making the holes when there is an explosion.

    Comment by Indie Rover � March 29, 2007 @ 9:15 am

  6. Where did you get the texture image from? Its nice

    Comment by Ryan � April 7, 2007 @ 5:04 pm

  7. It’s from Worms game, and of course It is only used for didactic purpose :)

    Comment by Indie Rover � April 8, 2007 @ 8:30 am

Comments RSS

Leave a comment





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值