top of page

בניית פרמוורק - ציור פשוט בcanvas

מתחילים תמיד מבנייה של פרמוורק, כדי ליצור שימוש חוזר וקליל של מתודות בסיס שמאפשר בנייה של מנוע משחק. פרמוורק יכול להכיל שימוש בפיזיקה, אנימציות, גרפיקה וממשק משתמש.

תחילה בניתי את מנוע הרינדור (Rendering engine)ההתחלתי. רינדור - זה בעצם תהליך לציור של אלמנטים על המסך צורות עם צבעים או תמונות. וכמובן הכי טוב לבנות את מנוע הרינדור בצורה של קואורדינטות (שימוש במתמטיקה לינארית). תמיד לוקחים קואורדינטה סופית פחות התחלתית וחוזרים על זה עם עוד קואורדינטות((x2-x1 y2-y1)). הסבר בצורה פשוטה כך אפשר לחשב בצורה מדויקת רוחב ועורך של צורות. היופי בפרמוורק שפשוט בסופו של דבר צריך רק לקרוא לפונקציות שכל המורכבות היא בתוכן ולא בשימוש בהם כלומר צריך בפשטות לקרוא רק לפונקציות וכל הקסם נעשה אוטומטית.

זה קטע קוד הראשון צריך תמיד לשמור על פשטות:

קובץ RenderShapes.js:

 class RenderShapes {
    //think like architect nott coder
    //Thinking in mathematic terms
    //_ It indicate private variables
    _vertex = [{}]; //Array of vertex objects {x: number, y: number}
    _shapeType = ""; //String representing the shape type e.g. "circle", "rectangle", "polygon"
    _color = ""; //String representing the color e.g. "#FF0000"
    _context = null; //Rendering context (e.g., CanvasRenderingContext2D)
    constructor(_vertex, _shapeType, _color, _context) {
        //Initialize the private variables with the provided parameters
        this._vertex = _vertex;
        this._shapeType = _shapeType;
        this._color = _color;
        this._context = _context;
    }

    //I like  to set getter and setter methods for encapsulation
    setVertex(_vertex) {
        this._vertex = _vertex;
    }
    getVertex() {
        return this._vertex;
    }

    setShapeType(_shapeType) {
        this._shapeType = _shapeType;
    }
    getShapeType() {
        return this._shapeType;
    }
    setColor(_color) {
        this._color = _color;
    }
    getColor() {
        return this._color;
    }
    setContext(_context) {
        this._context = _context;
    }
    getContext() {  
        return this._context;
    }
 renderRect() {
    try{
        //Render a rectangle using the vertex data
        this.getContext().fillStyle = this.getColor();
        const vertex = this.getVertex();
        const width = vertex[1].x - vertex[0].x;
        const height = vertex[1].y - vertex[0].y;
        this.getContext().fillRect(vertex[0].x, vertex[0].y, width, height);
    }catch(e){
        console.error("Error rendering rectangle: " + e.message);
    }
 }

    renderCircle(){
        try{
        //Render a circle using the vertex data
        this.getContext().fillStyle = this.getColor();
        const vertex = this.getVertex();
        const centerX = vertex[0].x;
        const centerY = vertex[0].y;
        const radius = vertex[1].x;
        this.getContext().beginPath();
        this.getContext().arc(centerX, centerY, radius, 0, 2 * Math.PI);
        this.getContext().fill();
        }
        catch(e){
            console.error("Error rendering circle: " + e.message);
        }
    }

    renderPolygon(){
        try{
        //Render a polygon using the vertex data
        this.getContext().fillStyle = this.getColor();
        const vertex = this.getVertex();
        this.getContext().beginPath();
        this.getContext().moveTo(vertex[0].x, vertex[0].y);
        for (let i = 1; i < vertex.length; i++) {
            this.getContext().lineTo(vertex[i].x, vertex[i].y);
        }
        this.getContext().closePath();
        this.getContext().fill();
        }
        catch(e){
            console.error("Error rendering polygon: " + e.message);
        }
    }
    render(){

            try{
            //Render the shape based on its type
            switch (this.getShapeType()) {
                case "rectangle":
                    this.renderRect();
                    break;
                case "circle":
                    this.renderCircle();
                    break;
                case "polygon":
                    this.renderPolygon();
                    break;
                default:
                    console.error("Unsupported shape type: " + this.getShapeType());
            }

        }
        catch(e){
            console.error("Error in render method: " + e.message);
        }
    }
}

לאחר מכן אפשר להשתמש במחלקה בצורה חוזרת ועם קוד נקי ומסודר פה השתמשתי במחלקת ציור הצורות בכדי ליצור את הגרפיקה:

let canvasContext = document.getElementById('myCanvas').getContext('2d');
//using classes of framework
let rect = new RenderShapes(
    [ {x: 50, y: 50}, {x: 150, y: 100} ], //vertex for rectangle
    "rectangle", //shape type
    "#FF5733", //color
    canvasContext //assuming canvasContext is defined elsewhere
);

let circle = new RenderShapes(
    [ {x: 300, y: 75}, {x: 50, y: 0} ], //vertex for circle (center and radius)
    "circle", //shape type
    "#33FF57", //color
    canvasContext
);

let polygon = new RenderShapes(
    [ {x: 400, y: 50}, {x: 450, y: 100}, {x: 350, y: 100} ], //vertex for polygon
    "polygon", //shape type
    "#3357FF", //color
    canvasContext
);

rect.render(); //Render the rectangle
circle.render(); //Render the circle
polygon.render(); //Render the polygon

כפי שניתן לראות יש מספר Instances (מופעים) של המחלקה ליצירת צורה שונה.

בכל צורה יש מספר קואורדינטות שונה יצרתי מלבן, עיגול ומשולש בצבעים שונים.

לאחר מכן יוצרים קוד HTML הכי פשוט: index.html:

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <canvas id="myCanvas" width="800" height="600"></canvas>
    <!-- include framework files simplest way -->
    <script src="./2DFramework/Rendering/RenderShapes.js"></script>
    <script src="./2DFramework/frameworkUsage.js"></script>
</body>
</html>

זאת התוצאה של הקוד:

סיכום:

זאת התחלתה של יצירה. חלק קטן מאוד ממערכת גדולה עם רבדים מורכבים ומעניינים מאוד. בחלק הבא של תהליך בניית הפרמוורק, אני אלמד כיצד ליצור לולאת משחק ואנימציות עדיין צורות פשוטות זה החלק החשוב ביותר בכל התחלה של פיתוח מנוע המשחק.

פוסטים אחרונים

הצג הכול

תגובות


bottom of page