sfc-sdp / GameCanvas-Unity

慶應義塾大学『スマートデバイスプログラミング』教材 GameCanvas for Unity
http://web.sfc.keio.ac.jp/~wadari/sdp/
MIT License
46 stars 19 forks source link

同一フレーム2回目以降の gc.DrawRect 呼び出しが正しく描画されない #101

Closed Chiji1108 closed 5 years ago

Chiji1108 commented 5 years ago

概要

塗り潰し長方形描画のgc.FillRectと、中抜き長方形描画のgc.DrawRectの挙動の違いについて

ドラッグした所に長方形が描画されるプログラムを作ったところ、1つ目の長方形はどちらとも正常に描画されるが、2つ目の長方形からgc.DrawRectの挙動がおかしくなる

再現手順

下記コードを次の実行環境で実行した時発生する

using Sequence = System.Collections.IEnumerator;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// ゲームクラス。
/// 学生が編集すべきソースコードです。
/// </summary>
public sealed class Game : GameBase
{
    class Rect {
        public int startX {get;set;} // タッチ始めの位置
        public int startY {get;set;} // タッチ始めの位置
        public int endX {get;set;} // タッチ終わりの位置
        public int endY {get;set;} // タッチ終わりの位置
        public int DrawStatus {get;set;} = 0; 
        /*  
        0: 描かれてない
        1: 描き途中
        2: 書き終わった
         */
        public int index {get;set;} = -1; // 番号
        public string type {get;set;} = "N/A"; // 向き
        // FillRectに代入する値
        public int x {get;set;} = 0;
        public int y {get;set;} = 0;
        public int width {get;set;} = 0;
        public int height {get;set;} = 0;
        // 代入用変換メソッド
        public void Put() {
            if (startX == endX || startY == endY) { // 描画しない
                type = "N/A";
                x = startX;
                y = startY;
                width = 0;
                height = 0;
            } else if (startX < endX && startY < endY) { // 右下
                type = "RD";
                x = startX;
                y = startY;
                width = endX - startX;
                height = endY - startY;
            } else if (startX < endX && startY > endY) { // 右上
                type = "RU";
                x = startX;
                y = endY;
                width = endX - startX;
                height = startY - endY;
            } else if (startX > endX && startY > endY) { // 左上
                type = "LU";
                x = endX;
                y = endY;
                width = startX - endX;
                height = startY - endY;
            } else if (startX > endX && startY < endY) { // 左下
                type = "LD";
                x = endX;
                y = startY;
                width = startX - endX;
                height = endY - startY;
            }
        }
    }
    int rect_number = -1;
    List<Rect> rects = new List<Rect>();
    /// <summary>
    /// 初期化処理
    /// </summary>
    public override void InitGame()
    {
        gc.SetResolution(1920, 1080);
    }

    /// <summary>
    /// 動きなどの更新処理
    /// </summary>
    public override void UpdateGame()
    {
        if(gc.GetPointerFrameCount(0) > 0) {
            if (gc.GetIsPointerBegan(0)) { //描き始め
                var newRect = new Rect();
                rect_number++;
                newRect.index = rect_number;
                newRect.DrawStatus = 1;
                newRect.startX = gc.GetPointerX(0);
                newRect.startY = gc.GetPointerY(0);
                newRect.endX = gc.GetPointerX(0);
                newRect.endY = gc.GetPointerY(0); 
                newRect.Put();
                rects.Add(newRect);
            } else if (!gc.GetIsPointerEnded(0)) { //描き途中
                var tempRect = rects.FindLast(i => i.DrawStatus == 1);
                rects.Remove(rects.FindLast(i => i.DrawStatus == 1));
                tempRect.endX = gc.GetPointerX(0);
                tempRect.endY = gc.GetPointerY(0);
                tempRect.Put();
                rects.Add(tempRect);
            } else if (gc.GetIsPointerEnded(0)) { //描き終わり
                var endRect = rects.FindLast(i => i.DrawStatus == 1);
                rects.Remove(rects.FindLast(i => i.DrawStatus == 1));
                endRect.DrawStatus = 2;
                rects.Add(endRect);
            }
        }
    }

    /// <summary>
    /// 描画の処理
    /// </summary>
    public override void DrawGame()
    {
        gc.ClearScreen();
        foreach (Rect r in rects) {
            if (r.type != "N/A") {
                gc.SetColor(128,128,128,128);
                gc.FillRect(r.x, r.y, r.width, r.height);
                gc.SetColor(0,0,0);
                gc.DrawRect(r.x, r.y, r.width, r.height); // 問題はここ
            }
            // デバッグ(?)
            gc.SetColor(0,0,0);
            gc.DrawString($"{r.index}\nstart: ({r.startX}, {r.startY})\nend: ({r.endX}, {r.endY})\nxy: ({r.x}, {r.y})\nwh: ({r.width}, {r.height})\nstatus: {r.DrawStatus}", r.x, r.y);
        }
    }
}

実行環境

環境 バージョン
macOS 10.14.1
Unity 2018.2.10f1
GameCanvas 3.1.0
seibe commented 5 years ago

@Chiji1108 お返事が遅くなりすみません。

同一フレーム2回目以降の gc.DrawRect 呼び出しが正しく描画されない件ですが、こちらご指摘の通りバグです。 急ぎ修正しますので、少々お待ちください。

seibe commented 5 years ago

修正後の実行時スクリーンショット

seibe commented 5 years ago

Release v3.1.2