Я сделал эту игру с Python + Pygame, но она была медленной, поэтому я попробовал ее с C # и его формами. Это еще медленнее! Я получаю только 20 кадров в секунду на i5 radeon 6770m NTB в миллионы раз быстрее, чем оборудование. Я хочу, чтобы эта игра запускалась, но я еще даже не закончил игру, это всего лишь рендеринг карты. Это римейк игры, работающей на медленных процессорах с частотой несколько МГц. Карта содержит плитки 400x200, а камера показывает только 79 * 79. Я также установил unity 4.5; Стоит ли это изучать, принесет ли это мне значительное повышение производительности - если кто-то знает, как бы я сделал карту, состоящую из 600 * 400 плиток случайным образом, либо темных, либо ярких; он должен быть "конфликтующим"? Или я что-то не так делаю в формах?

public void render()
    {

        Bitmap frame = new Bitmap(Game.CANVAS_WIDTH, Game.CANVAS_HEIGHT);
        Graphics frameGraphics = Graphics.FromImage(frame);

        TextureID[,] textures = Background.Blocks;

        while (true)
        {

            //frameGraphics.FillRectangle(new SolidBrush(Color.Aqua), 0, 0, Game.CANVAS_WIDTH, Game.CANVAS_HEIGHT);
            for (int x = 0; x < Game.AR_WIDTH; x++)
            {
                int xx = x * Game.TILE_SIDE - game.green_tank_pos[0] + Game.DIFF;
                if (xx < 0) continue;
                if (xx > Game.CANVAS_WIDTH) break;

                for (int y = 0; y < Game.AR_HEIGHT; y++)
                {
                    int yy = y * Game.TILE_SIDE - game.green_tank_pos[1] + Game.DIFF;
                    if (yy < 0) continue;
                    if (yy > Game.CANVAS_HEIGHT) continue;
                    switch(textures[x,y])
                    {
                        case TextureID.dark:
                            frameGraphics.DrawImage(tex_dark_gnd, xx, yy);
                            break;
                        case TextureID.bright:
                            frameGraphics.DrawImage(tex_bright_gnd, x * Game.TILE_SIDE - game.green_tank_pos[0] + Game.DIFF, y * Game.TILE_SIDE - game.green_tank_pos[1] + Game.DIFF);
                            break;
                    }
                }
            }

            frameGraphics.DrawImage(tex_green_tank, Game.DIFF, Game.DIFF);



            drawHandle.DrawImage(frame, 0, 0);
1
Adam 31 Июл 2014 в 20:34

2 ответа

Лучший ответ

WinForms - это ужасная платформа для игры, даже 2D. Он был предназначен для бизнес-приложений и практически не включает аппаратного ускорения.

Плюс к этому с помощью этой технологии просто сложно написать игру, не говоря уже об эффективной. Вы можете обойтись без использования WPF для очень простой игры, но вы действительно захотите изучить XNA, MonoGame, Unity или какую-либо другую реальную игровую платформу, которая может использовать преимущества DirectX (WPF также делает это. , Кстати).

5
BradleyDotNET 31 Июл 2014 в 16:39

Есть способы повысить производительность рисования в winforms, но для игры лучше всего использовать инструменты, которые лучше подходят для работы. (не забивайте гвоздь отверткой).

В более новых версиях Unity3D есть встроенные 2D-инструменты. Я лично создаю в нем 2D-игру и очень рекомендую.

РЕДАКТИРОВАТЬ : удалено упоминание XNA - я не знал, что он «мертв».

Создавать плитки в Unity3D можно несколькими способами.

  • Поместите спрайты в сцену вручную. Их расположение и настройки будут сохранены вместе со сценой.
  • Поместите спрайты в сцену вручную и создайте из нее префаб. Таким образом, этот набор плиток можно использовать повторно.
  • Создайте префаб из одной плитки и создайте экземпляры, кратные этому префабу, в поведении, которое прикреплено где-нибудь в сцене.

Что касается рендеринга, Unity3D позаботится об этом за вас.

EDIT2 : я создал короткое поведение Unity3D, которое вы можете прикрепить где-нибудь внутри вашей сцены. Здесь используется третий подход, который я описал выше, и он будет случайным образом выбирать из набора примененных префабов. Этот скрипт предполагает случайный выбор из плиток, и что ширина плиток составляет 1 игровую единицу шириной / высотой.

  1. Прикрепите поведение к чему-то в сцене (например, к основной камере)
  2. Создавайте плитки как сборные
  3. Перетащите префабы в редакторе в массив «Tile Prefabs» для поведения, которое вы прикрепили.
  4. Установите "Tiles High" на 400 и "Tiles Wide" на 600.
  5. Установите TileMapTopLeft в верхнее левое положение, при котором он должен запускаться.
  6. Запустите свою сцену.

Вот такое поведение:

using UnityEngine;

class TileCreator : MonoBehaviour
{
    private static System.Random rng = new System.Random();

    public GameObject[] TilePrefabs;

    public int TilesWide;

    public int TilesHigh;

    public Vector3 TileMapTopLeft;

    void Start()
    {
        for (int x = 0; x < TilesWide; x++)
        {
            for (int y = 0; y < TilesHigh; y++)
            {
                Instantiate(TilePrefabs[rng.Next(TilePrefabs.Length)], new Vector3(x + TileMapTopLeft.x, y + TileMapTopLeft.y, TileMapTopLeft.z), Quaternion.identity);
            }
        }
    }
}

Вам, вероятно, потребуется найти руководство о том, как импортировать ресурсы и создавать префабы, но этот сценарий должен направить вас в правильном направлении.

2
McAden 31 Июл 2014 в 18:36