added viewport zoom
This commit is contained in:
		
							parent
							
								
									7a0f9e5c95
								
							
						
					
					
						commit
						d9a87b2727
					
				| 
						 | 
					@ -26,7 +26,10 @@ export default class BoidDemo extends Scene {
 | 
				
			||||||
        this.boids = new Array();
 | 
					        this.boids = new Array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Add the player
 | 
					        // Add the player
 | 
				
			||||||
        this.add.graphic(Player, layer, new Vec2(0, 0));
 | 
					        let player = this.add.graphic(Player, layer, new Vec2(0, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.viewport.follow(player);
 | 
				
			||||||
 | 
					        this.viewport.enableZoom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Create a bunch of boids
 | 
					        // Create a bunch of boids
 | 
				
			||||||
        for(let i = 0; i < 100; i++){
 | 
					        for(let i = 0; i < 100; i++){
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -212,15 +212,15 @@ export default class QuadTree<T extends Region & Unique> implements Collection {
 | 
				
			||||||
     * Renders the quadtree for demo purposes.
 | 
					     * Renders the quadtree for demo purposes.
 | 
				
			||||||
     * @param ctx 
 | 
					     * @param ctx 
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public render_demo(ctx: CanvasRenderingContext2D): void {
 | 
					    public render_demo(ctx: CanvasRenderingContext2D, origin: Vec2, zoom: number): void {
 | 
				
			||||||
        ctx.strokeStyle = "#0000FF";
 | 
					        ctx.strokeStyle = "#0000FF";
 | 
				
			||||||
        ctx.strokeRect(this.boundary.x - this.boundary.hw, this.boundary.y - this.boundary.hh, 2*this.boundary.hw, 2*this.boundary.hh);
 | 
					        ctx.strokeRect((this.boundary.x - this.boundary.hw - origin.x)*zoom, (this.boundary.y - this.boundary.hh - origin.y)*zoom, 2*this.boundary.hw*zoom, 2*this.boundary.hh*zoom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(this.divided){
 | 
					        if(this.divided){
 | 
				
			||||||
            this.nw.render_demo(ctx);
 | 
					            this.nw.render_demo(ctx, origin, zoom);
 | 
				
			||||||
            this.ne.render_demo(ctx);
 | 
					            this.ne.render_demo(ctx, origin, zoom);
 | 
				
			||||||
            this.sw.render_demo(ctx);
 | 
					            this.sw.render_demo(ctx, origin, zoom);
 | 
				
			||||||
            this.se.render_demo(ctx);
 | 
					            this.se.render_demo(ctx, origin, zoom);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,16 @@ export enum GameEventType {
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	CANVAS_BLUR = "canvas_blur",
 | 
						CANVAS_BLUR = "canvas_blur",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Mouse wheel up event. Has data: {}
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						WHEEL_UP = "wheel_up",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Mouse wheel down event. Has data: {}
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						WHEEL_DOWN = "wheel_down",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Start Recording event. Has data: {}
 | 
						 * Start Recording event. Has data: {}
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ export default class InputHandler{
 | 
				
			||||||
        document.onkeyup = this.handleKeyUp;
 | 
					        document.onkeyup = this.handleKeyUp;
 | 
				
			||||||
        document.onblur = this.handleBlur;
 | 
					        document.onblur = this.handleBlur;
 | 
				
			||||||
        document.oncontextmenu = this.handleBlur;
 | 
					        document.oncontextmenu = this.handleBlur;
 | 
				
			||||||
 | 
					        document.onwheel = this.handleWheel;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private handleMouseDown = (event: MouseEvent, canvas: HTMLCanvasElement): void => {
 | 
					    private handleMouseDown = (event: MouseEvent, canvas: HTMLCanvasElement): void => {
 | 
				
			||||||
| 
						 | 
					@ -62,6 +63,19 @@ export default class InputHandler{
 | 
				
			||||||
        event.stopPropagation();
 | 
					        event.stopPropagation();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private handleWheel = (event: WheelEvent): void => {
 | 
				
			||||||
 | 
					        event.preventDefault();
 | 
				
			||||||
 | 
					        event.stopPropagation();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        let gameEvent: GameEvent;
 | 
				
			||||||
 | 
					        if(event.deltaY < 0){
 | 
				
			||||||
 | 
					            gameEvent = new GameEvent(GameEventType.WHEEL_UP, {});
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            gameEvent = new GameEvent(GameEventType.WHEEL_DOWN, {});
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.eventQueue.addEvent(gameEvent);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private getKey(keyEvent: KeyboardEvent){
 | 
					    private getKey(keyEvent: KeyboardEvent){
 | 
				
			||||||
        return keyEvent.key.toLowerCase();
 | 
					        return keyEvent.key.toLowerCase();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,10 +14,16 @@ export default class InputReceiver{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private mousePressed: boolean;
 | 
						private mousePressed: boolean;
 | 
				
			||||||
	private mouseJustPressed: boolean;
 | 
						private mouseJustPressed: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private keyJustPressed: Map<boolean>;
 | 
						private keyJustPressed: Map<boolean>;
 | 
				
			||||||
	private keyPressed: Map<boolean>;
 | 
						private keyPressed: Map<boolean>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private mousePosition: Vec2;
 | 
						private mousePosition: Vec2;
 | 
				
			||||||
	private mousePressPosition: Vec2;
 | 
						private mousePressPosition: Vec2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private scrollDirection: number;
 | 
				
			||||||
 | 
						private justScrolled: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private eventQueue: EventQueue;
 | 
						private eventQueue: EventQueue;
 | 
				
			||||||
	private receiver: Receiver;
 | 
						private receiver: Receiver;
 | 
				
			||||||
	private viewport: Viewport;
 | 
						private viewport: Viewport;
 | 
				
			||||||
| 
						 | 
					@ -30,11 +36,13 @@ export default class InputReceiver{
 | 
				
			||||||
		this.keyPressed = new Map<boolean>();
 | 
							this.keyPressed = new Map<boolean>();
 | 
				
			||||||
		this.mousePosition = new Vec2(0, 0);
 | 
							this.mousePosition = new Vec2(0, 0);
 | 
				
			||||||
		this.mousePressPosition = new Vec2(0, 0);
 | 
							this.mousePressPosition = new Vec2(0, 0);
 | 
				
			||||||
 | 
							this.scrollDirection = 0;
 | 
				
			||||||
 | 
							this.justScrolled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.eventQueue = EventQueue.getInstance();
 | 
							this.eventQueue = EventQueue.getInstance();
 | 
				
			||||||
		// Subscribe to all input events
 | 
							// Subscribe to all input events
 | 
				
			||||||
		this.eventQueue.subscribe(this.receiver, [GameEventType.MOUSE_DOWN, GameEventType.MOUSE_UP, GameEventType.MOUSE_MOVE,
 | 
							this.eventQueue.subscribe(this.receiver, [GameEventType.MOUSE_DOWN, GameEventType.MOUSE_UP, GameEventType.MOUSE_MOVE,
 | 
				
			||||||
			 GameEventType.KEY_DOWN, GameEventType.KEY_UP, GameEventType.CANVAS_BLUR]);
 | 
								 GameEventType.KEY_DOWN, GameEventType.KEY_UP, GameEventType.CANVAS_BLUR, GameEventType.WHEEL_UP, GameEventType.WHEEL_DOWN]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static getInstance(): InputReceiver{
 | 
						static getInstance(): InputReceiver{
 | 
				
			||||||
| 
						 | 
					@ -48,6 +56,8 @@ export default class InputReceiver{
 | 
				
			||||||
		// Reset the justPressed values to false
 | 
							// Reset the justPressed values to false
 | 
				
			||||||
		this.mouseJustPressed = false;
 | 
							this.mouseJustPressed = false;
 | 
				
			||||||
		this.keyJustPressed.forEach((key: string) => this.keyJustPressed.set(key, false));
 | 
							this.keyJustPressed.forEach((key: string) => this.keyJustPressed.set(key, false));
 | 
				
			||||||
 | 
							this.justScrolled = false;
 | 
				
			||||||
 | 
							this.scrollDirection = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while(this.receiver.hasNextEvent()){			
 | 
							while(this.receiver.hasNextEvent()){			
 | 
				
			||||||
			let event = this.receiver.getNextEvent();
 | 
								let event = this.receiver.getNextEvent();
 | 
				
			||||||
| 
						 | 
					@ -91,6 +101,14 @@ export default class InputReceiver{
 | 
				
			||||||
			if(event.type === GameEventType.CANVAS_BLUR){
 | 
								if(event.type === GameEventType.CANVAS_BLUR){
 | 
				
			||||||
				this.clearKeyPresses()
 | 
									this.clearKeyPresses()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if(event.type === GameEventType.WHEEL_UP){
 | 
				
			||||||
 | 
									this.scrollDirection = -1;
 | 
				
			||||||
 | 
									this.justScrolled = true;
 | 
				
			||||||
 | 
								} else if(event.type === GameEventType.WHEEL_DOWN){
 | 
				
			||||||
 | 
									this.scrollDirection = 1;
 | 
				
			||||||
 | 
									this.justScrolled = true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,6 +141,14 @@ export default class InputReceiver{
 | 
				
			||||||
		return this.mousePressed;
 | 
							return this.mousePressed;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						didJustScroll(): boolean {
 | 
				
			||||||
 | 
							return this.justScrolled;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						getScrollDirection(): number {
 | 
				
			||||||
 | 
							return this.scrollDirection;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	getMousePosition(): Vec2 {
 | 
						getMousePosition(): Vec2 {
 | 
				
			||||||
		return this.mousePosition;
 | 
							return this.mousePosition;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,12 +67,13 @@ export default class GameLoop {
 | 
				
			||||||
        this.GAME_CANVAS.style.setProperty("background-color", "whitesmoke");
 | 
					        this.GAME_CANVAS.style.setProperty("background-color", "whitesmoke");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        // Give the canvas a size and get the rendering context
 | 
					        // Give the canvas a size and get the rendering context
 | 
				
			||||||
        this.WIDTH = gameConfig.viewportSize ? gameConfig.viewportSize.x : 800;
 | 
					        this.WIDTH = gameConfig.canvasSize ? gameConfig.canvasSize.x : 800;
 | 
				
			||||||
        this.HEIGHT = gameConfig.viewportSize ? gameConfig.viewportSize.y : 500;
 | 
					        this.HEIGHT = gameConfig.canvasSize ? gameConfig.canvasSize.y : 500;
 | 
				
			||||||
        this.ctx = this.initializeCanvas(this.GAME_CANVAS, this.WIDTH, this.HEIGHT);
 | 
					        this.ctx = this.initializeCanvas(this.GAME_CANVAS, this.WIDTH, this.HEIGHT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Size the viewport to the game canvas
 | 
					        // Size the viewport to the game canvas
 | 
				
			||||||
        this.viewport = new Viewport();
 | 
					        this.viewport = new Viewport();
 | 
				
			||||||
 | 
					        this.viewport.setCanvasSize(this.WIDTH, this.HEIGHT);
 | 
				
			||||||
        this.viewport.setSize(this.WIDTH, this.HEIGHT);
 | 
					        this.viewport.setSize(this.WIDTH, this.HEIGHT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Initialize all necessary game subsystems
 | 
					        // Initialize all necessary game subsystems
 | 
				
			||||||
| 
						 | 
					@ -242,5 +243,5 @@ export default class GameLoop {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GameConfig {
 | 
					class GameConfig {
 | 
				
			||||||
    viewportSize: {x: number, y: number}
 | 
					    canvasSize: {x: number, y: number}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -82,5 +82,10 @@ export default abstract class GameNode implements Positioned, Unique, Updateable
 | 
				
			||||||
		return this.scene.getViewport().getOrigin().mult(this.layer.getParallax());
 | 
							return this.scene.getViewport().getOrigin().mult(this.layer.getParallax());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						getViewportScale(): number {
 | 
				
			||||||
 | 
							return this.scene.getViewport().getZoomLevel();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	abstract update(deltaT: number): void;
 | 
						abstract update(deltaT: number): void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -35,15 +35,16 @@ export default class Rect extends Graphic {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render(ctx: CanvasRenderingContext2D): void {
 | 
					    render(ctx: CanvasRenderingContext2D): void {
 | 
				
			||||||
        let origin = this.getViewportOriginWithParallax();
 | 
					        let origin = this.getViewportOriginWithParallax();
 | 
				
			||||||
 | 
					        let zoom = this.getViewportScale();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(this.color.a !== 0){
 | 
					        if(this.color.a !== 0){
 | 
				
			||||||
            ctx.fillStyle = this.color.toStringRGB();
 | 
					            ctx.fillStyle = this.color.toStringRGB();
 | 
				
			||||||
            ctx.fillRect(this.position.x - this.size.x/2 - origin.x, this.position.y - this.size.y/2 - origin.y, this.size.x, this.size.y);
 | 
					            ctx.fillRect((this.position.x - this.size.x/2 - origin.x)*zoom, (this.position.y - this.size.y/2 - origin.y)*zoom, this.size.x*zoom, this.size.y*zoom);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ctx.strokeStyle = this.borderColor.toStringRGB();
 | 
					        ctx.strokeStyle = this.borderColor.toStringRGB();
 | 
				
			||||||
        ctx.lineWidth = this.borderWidth;
 | 
					        ctx.lineWidth = this.borderWidth;
 | 
				
			||||||
        ctx.strokeRect(this.position.x - this.size.x/2 - origin.x, this.position.y - this.size.y/2 - origin.y, this.size.x, this.size.y);
 | 
					        ctx.strokeRect((this.position.x - this.size.x/2 - origin.x)*zoom, (this.position.y - this.size.y/2 - origin.y)*zoom, this.size.x*zoom, this.size.y*zoom);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -30,15 +30,16 @@ export default class Sprite extends CanvasNode {
 | 
				
			||||||
    render(ctx: CanvasRenderingContext2D): void {
 | 
					    render(ctx: CanvasRenderingContext2D): void {
 | 
				
			||||||
        let image = ResourceManager.getInstance().getImage(this.imageId);
 | 
					        let image = ResourceManager.getInstance().getImage(this.imageId);
 | 
				
			||||||
        let origin = this.getViewportOriginWithParallax();
 | 
					        let origin = this.getViewportOriginWithParallax();
 | 
				
			||||||
 | 
					        let zoom = this.getViewportScale();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ctx.drawImage(image,
 | 
					        ctx.drawImage(image,
 | 
				
			||||||
            this.imageOffset.x, this.imageOffset.y, this.size.x, this.size.y,
 | 
					            this.imageOffset.x, this.imageOffset.y, this.size.x, this.size.y,
 | 
				
			||||||
            this.position.x - origin.x - this.size.x*this.scale.x/2, this.position.y - origin.y - this.size.y*this.scale.y/2,
 | 
					            (this.position.x - origin.x - this.size.x*this.scale.x/2)*zoom, (this.position.y - origin.y - this.size.y*this.scale.y/2)*zoom,
 | 
				
			||||||
            this.size.x * this.scale.x, this.size.y * this.scale.y);
 | 
					            this.size.x * this.scale.x*zoom, this.size.y * this.scale.y*zoom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ctx.lineWidth = 4;
 | 
					        ctx.lineWidth = 4;
 | 
				
			||||||
        ctx.strokeStyle = "#00FF00"
 | 
					        ctx.strokeStyle = "#00FF00"
 | 
				
			||||||
        let b = this.getBoundary();
 | 
					        let b = this.getBoundary();
 | 
				
			||||||
        ctx.strokeRect(b.x - b.hw - origin.x, b.y - b.hh - origin.y, b.hw*2, b.hh*2);
 | 
					        ctx.strokeRect(b.x - b.hw - origin.x, b.y - b.hh - origin.y, b.hw*2*zoom, b.hh*2*zoom);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,9 @@ export default class SceneGraphQuadTree extends SceneGraph {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render(ctx: CanvasRenderingContext2D): void {
 | 
					    render(ctx: CanvasRenderingContext2D): void {
 | 
				
			||||||
        this.qt.render_demo(ctx);
 | 
					        let origin = this.viewport.getOrigin();
 | 
				
			||||||
 | 
					        let zoom = this.viewport.getZoomLevel();
 | 
				
			||||||
 | 
					        this.qt.render_demo(ctx, origin, zoom);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getVisibleSet(): Array<CanvasNode> {
 | 
					    getVisibleSet(): Array<CanvasNode> {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,11 @@
 | 
				
			||||||
import Vec2 from "../DataTypes/Vec2";
 | 
					import Vec2 from "../DataTypes/Vec2";
 | 
				
			||||||
import Vec4 from "../DataTypes/Vec4";
 | 
					 | 
				
			||||||
import GameNode from "../Nodes/GameNode";
 | 
					import GameNode from "../Nodes/GameNode";
 | 
				
			||||||
import CanvasNode from "../Nodes/CanvasNode";
 | 
					import CanvasNode from "../Nodes/CanvasNode";
 | 
				
			||||||
import MathUtils from "../Utils/MathUtils";
 | 
					import MathUtils from "../Utils/MathUtils";
 | 
				
			||||||
import Queue from "../DataTypes/Queue";
 | 
					import Queue from "../DataTypes/Queue";
 | 
				
			||||||
import AABB from "../DataTypes/AABB";
 | 
					import AABB from "../DataTypes/AABB";
 | 
				
			||||||
import Debug from "../Debug/Debug";
 | 
					import Debug from "../Debug/Debug";
 | 
				
			||||||
 | 
					import InputReceiver from "../Input/InputReceiver";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Viewport {
 | 
					export default class Viewport {
 | 
				
			||||||
    private view: AABB;
 | 
					    private view: AABB;
 | 
				
			||||||
| 
						 | 
					@ -22,11 +22,21 @@ export default class Viewport {
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private smoothingFactor: number;
 | 
					    private smoothingFactor: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private scrollZoomEnabled: boolean;
 | 
				
			||||||
 | 
					    private ZOOM_FACTOR: number = 1.2;
 | 
				
			||||||
 | 
					    private canvasSize: Vec2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(){
 | 
					    constructor(){
 | 
				
			||||||
        this.view = new AABB(Vec2.ZERO, Vec2.ZERO);
 | 
					        this.view = new AABB(Vec2.ZERO, Vec2.ZERO);
 | 
				
			||||||
        this.boundary = new AABB(Vec2.ZERO, Vec2.ZERO);
 | 
					        this.boundary = new AABB(Vec2.ZERO, Vec2.ZERO);
 | 
				
			||||||
        this.lastPositions = new Queue();
 | 
					        this.lastPositions = new Queue();
 | 
				
			||||||
        this.smoothingFactor = 10;
 | 
					        this.smoothingFactor = 10;
 | 
				
			||||||
 | 
					        this.scrollZoomEnabled = false;
 | 
				
			||||||
 | 
					        this.canvasSize = Vec2.ZERO;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enableZoom(): void {
 | 
				
			||||||
 | 
					        this.scrollZoomEnabled = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					@ -92,6 +102,23 @@ export default class Viewport {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Sets the size of the canvas that the viewport is projecting to.
 | 
				
			||||||
 | 
					     * @param vecOrX 
 | 
				
			||||||
 | 
					     * @param y 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    setCanvasSize(vecOrX: Vec2 | number, y: number = null): void {
 | 
				
			||||||
 | 
							if(vecOrX instanceof Vec2){
 | 
				
			||||||
 | 
								this.canvasSize = vecOrX.clone();
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								this.canvasSize = new Vec2(vecOrX, y);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getZoomLevel(): number {
 | 
				
			||||||
 | 
					        return this.canvasSize.x/this.view.hw/2
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Sets the smoothing factor for the viewport movement.
 | 
					     * Sets the smoothing factor for the viewport movement.
 | 
				
			||||||
     * @param smoothingFactor The smoothing factor for the viewport
 | 
					     * @param smoothingFactor The smoothing factor for the viewport
 | 
				
			||||||
| 
						 | 
					@ -141,6 +168,37 @@ export default class Viewport {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    update(deltaT: number): void {
 | 
					    update(deltaT: number): void {
 | 
				
			||||||
 | 
					        // If zoom is enabled
 | 
				
			||||||
 | 
					        if(this.scrollZoomEnabled){
 | 
				
			||||||
 | 
					            let input = InputReceiver.getInstance();
 | 
				
			||||||
 | 
					            if(input.didJustScroll()){
 | 
				
			||||||
 | 
					                let currentSize = this.view.getHalfSize().clone();
 | 
				
			||||||
 | 
					                if(input.getScrollDirection() < 0){
 | 
				
			||||||
 | 
					                    // Zoom in
 | 
				
			||||||
 | 
					                    currentSize.scale(1/this.ZOOM_FACTOR);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    // Zoom out
 | 
				
			||||||
 | 
					                    currentSize.scale(this.ZOOM_FACTOR);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(currentSize.x > this.boundary.hw){
 | 
				
			||||||
 | 
					                    let factor = this.boundary.hw/currentSize.x;
 | 
				
			||||||
 | 
					                    currentSize.x = this.boundary.hw;
 | 
				
			||||||
 | 
					                    currentSize.y *= factor;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(currentSize.y > this.boundary.hh){
 | 
				
			||||||
 | 
					                    let factor = this.boundary.hh/currentSize.y;
 | 
				
			||||||
 | 
					                    currentSize.y = this.boundary.hh;
 | 
				
			||||||
 | 
					                    currentSize.x *= factor;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                this.view.setHalfSize(currentSize);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Debug.log("vpzoom", "View size: " + this.view.getHalfSize());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If viewport is following an object
 | 
					        // If viewport is following an object
 | 
				
			||||||
        if(this.following){
 | 
					        if(this.following){
 | 
				
			||||||
            // Update our list of previous positions
 | 
					            // Update our list of previous positions
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@ export default class Boid extends Graphic {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render(ctx: CanvasRenderingContext2D): void {
 | 
					    render(ctx: CanvasRenderingContext2D): void {
 | 
				
			||||||
        let origin = this.getViewportOriginWithParallax();
 | 
					        let origin = this.getViewportOriginWithParallax();
 | 
				
			||||||
 | 
					        let zoom = this.getViewportScale();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let dirVec = this.direction.scaled(this.size.x, this.size.y);
 | 
					        let dirVec = this.direction.scaled(this.size.x, this.size.y);
 | 
				
			||||||
        let finVec1 = this.direction.clone().rotateCCW(Math.PI/2).scale(this.size.x/2, this.size.y/2).sub(this.direction.scaled(this.size.x/1.5, this.size.y/1.5));
 | 
					        let finVec1 = this.direction.clone().rotateCCW(Math.PI/2).scale(this.size.x/2, this.size.y/2).sub(this.direction.scaled(this.size.x/1.5, this.size.y/1.5));
 | 
				
			||||||
| 
						 | 
					@ -31,11 +32,11 @@ export default class Boid extends Graphic {
 | 
				
			||||||
        ctx.lineWidth = 1;
 | 
					        ctx.lineWidth = 1;
 | 
				
			||||||
        ctx.fillStyle = this.color.toString();
 | 
					        ctx.fillStyle = this.color.toString();
 | 
				
			||||||
        ctx.beginPath();
 | 
					        ctx.beginPath();
 | 
				
			||||||
        ctx.moveTo(this.position.x - origin.x + dirVec.x,      this.position.y - origin.y + dirVec.y);
 | 
					        ctx.moveTo((this.position.x - origin.x + dirVec.x)*zoom,      (this.position.y - origin.y + dirVec.y)*zoom);
 | 
				
			||||||
        ctx.lineTo(this.position.x - origin.x + finVec1.x,     this.position.y - origin.y + finVec1.y);
 | 
					        ctx.lineTo((this.position.x - origin.x + finVec1.x)*zoom,     (this.position.y - origin.y + finVec1.y)*zoom);
 | 
				
			||||||
        ctx.lineTo(this.position.x - origin.x - dirVec.x/3,    this.position.y - origin.y - dirVec.y/3);
 | 
					        ctx.lineTo((this.position.x - origin.x - dirVec.x/3)*zoom,    (this.position.y - origin.y - dirVec.y/3)*zoom);
 | 
				
			||||||
        ctx.lineTo(this.position.x - origin.x + finVec2.x,     this.position.y - origin.y + finVec2.y);
 | 
					        ctx.lineTo((this.position.x - origin.x + finVec2.x)*zoom,     (this.position.y - origin.y + finVec2.y)*zoom);
 | 
				
			||||||
        ctx.lineTo(this.position.x - origin.x + dirVec.x,      this.position.y - origin.y + dirVec.y);
 | 
					        ctx.lineTo((this.position.x - origin.x + dirVec.x)*zoom,      (this.position.y - origin.y + dirVec.y)*zoom);
 | 
				
			||||||
        ctx.fill();
 | 
					        ctx.fill();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,6 @@ export default class RunAwayFromPlayer extends State {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    onEnter(): void {
 | 
					    onEnter(): void {
 | 
				
			||||||
        console.log("Entered Running away")
 | 
					 | 
				
			||||||
        this.runAwayDirection = Vec2.ZERO;
 | 
					        this.runAwayDirection = Vec2.ZERO;
 | 
				
			||||||
        this.lastPlayerPosition = Vec2.INF;
 | 
					        this.lastPlayerPosition = Vec2.INF;
 | 
				
			||||||
        this.timeElapsed = 0;
 | 
					        this.timeElapsed = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,10 +7,10 @@ import MarioClone from "./_DemoClasses/MarioClone/MarioClone";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function main(){
 | 
					function main(){
 | 
				
			||||||
    // Create the game object
 | 
					    // Create the game object
 | 
				
			||||||
    let game = new GameLoop({viewportSize: {x: 800, y: 600}});
 | 
					    let game = new GameLoop({canvasSize: {x: 800, y: 600}});
 | 
				
			||||||
    game.start();
 | 
					    game.start();
 | 
				
			||||||
    let sm = game.getSceneManager();
 | 
					    let sm = game.getSceneManager();
 | 
				
			||||||
    sm.addScene(MarioClone);
 | 
					    sm.addScene(BoidDemo);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CanvasRenderingContext2D.prototype.roundedRect = function(x: number, y: number, w: number, h: number, r: number): void {
 | 
					CanvasRenderingContext2D.prototype.roundedRect = function(x: number, y: number, w: number, h: number, r: number): void {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user