はじめてのYaneSDK.NET番外編4

akiramei2006-04-11

今回はタスクシステムの使い方・・・と言いたいところですが、私自身の勉強の為のサンプルだったり。タスクシステムの場合、弾一つ一つをタスクにするので良いのかしら。あと、移動処理と描画は分けた方がいいと思うけど、上手い分割方法が思いつきませんでした。暫くは試行錯誤かなぁ・・・
上手く弾幕が張れてないです。(^^;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using YD = Yanesdk.Draw;
using YY = Yanesdk.Ytl;

namespace Sample8
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        GameInfo info;
        YD.Win32Window window;
        private void Form1_Load(object sender, EventArgs e)
        {
            ClientSize = new Size(480, 640);
            window = new YD.Win32Window(pictureBox1.Handle);

            info = new GameInfo();
            info.screen = window.Screen;
            info.controller = new YY.TaskController();

            MySceneController sc = new MySceneController();
            sc.TaskFactory = new MySceneFactory();
            info.controller.AddTask(sc, 1);

            info.screen.Select();
            info.bulletR = new YD.GlTexture();
            info.bulletR.SetColorKeyPos(0, 0);
            info.bulletR.Load("bulletR.png");
            info.bulletB = new YD.GlTexture();
            info.bulletB.SetColorKeyPos(0, 0);
            info.bulletB.Load("bulletB.png");
            info.screen.Unselect();

            sc.JumpScene(Tasks.Main);
        }
        
        private void OnTick(object sender, EventArgs e)
        {
            if (!info.controller.End)
            {
                info.screen.Select();
                info.screen.BlendSrcAlpha();
                info.screen.SetClearColor(0, 0, 0);
                info.screen.Clear();
                info.controller.CallTask(info);
                info.screen.Update();
            }
        }
    }

    public enum Tasks
    {
        Main
    }

    public class MySceneFactory : YY.TaskFactoryBase<Tasks>
    {
        public override YY.TaskBase CreateTask(Tasks name)
        {
            switch (name)
            {
                case Tasks.Main:
                    return new MainTask();
            }
            return null;
        }
    }

    public class MySceneController : YY.SceneController<Tasks>
    {
    }

    public class GameInfo
    {
        public YD.Screen screen;
        public YY.TaskController controller;
        public YD.GlTexture bulletR;
        public YD.GlTexture bulletB;
    }

    public class MainTask : YY.TaskBase
    {
        int counter = 0;
        int num = 0;
        int dir = 1;
        public override int Task(object o)
        {
            if (counter++ % 16 == 0)
            {
                // Fire
                GameInfo info = o as GameInfo;
                dir *= -1;
                int speed = dir < 0 ? 2 : 3;
                for (int i = 0; i < 18; ++i)
                    info.controller.AddTask(
                        new BulletTask(dir, 240, 320, 0, speed, 
                        Math.PI * 2 / 18 * i, dir * Math.PI / 360), 100 + num++);
            }
            return 0;
        }
    }

    public class BulletTask : YY.TaskBase
    {
        int dir;
        double x;
        double y;
        double cx;
        double cy;
        double r;
        double vr;
        double t;
        double w;
        public BulletTask(int dir, double cx, double cy, 
            double r, double vr, double t, double w)
        {
            this.dir = dir;
            this.cx = cx;
            this.cy = cy;
            this.r = r;
            this.vr = vr;
            this.t = t;
            this.w = w;
        }

        public override int Task(object o)
        {
            GameInfo info = o as GameInfo;
            t += w;
            r += vr;
            x = cx + r * Math.Cos(t);
            y = cy + r * Math.Sin(t);
            if (x < 0 || x > info.screen.Width || 
                y < 0 || y > info.screen.Height)
                return -1;
            info.screen.Blt(dir < 0 ? info.bulletR : info.bulletB, (int)x, (int)y);
            return 0;
        }
    }
}