restructured game nodes and created canvas node subclass

This commit is contained in:
Joe Weaver 2020-08-10 13:19:59 -04:00
parent 40a05fdbdb
commit 67bcba2c5f
8 changed files with 82 additions and 56 deletions

24
src/Nodes/CanvasNode.ts Normal file
View File

@ -0,0 +1,24 @@
import GameNode from "./GameNode";
import Vec2 from "../DataTypes/Vec2";
export default abstract class CanvasNode extends GameNode{
protected size: Vec2;
constructor(){
super();
this.size = new Vec2(0, 0);
}
getSize(): Vec2 {
return this.size;
}
contains(x: number, y: number): boolean {
if(this.position.x < x && this.position.x + this.size.x > x){
if(this.position.y < y && this.position.y + this.size.y > y){
return true;
}
}
return false;
}
}

View File

@ -1,10 +1,10 @@
import GameNode from "./GameNode";
import CanvasNode from "./CanvasNode";
import Color from "../Utils/Color";
import Vec2 from "../DataTypes/Vec2";
import RandUtils from "../Utils/RandUtils";
export default class ColoredCircle extends GameNode{
private color: Color;
export default class ColoredCircle extends CanvasNode{
private color: Color;
constructor(){
super();

View File

@ -1,35 +1,33 @@
import EventQueue from "../Events/EventQueue";
import InputReceiver from "../Input/InputReceiver";
import Vec2 from "../DataTypes/Vec2";
import Map from "../DataTypes/Map";
import Receiver from "../Events/Receiver";
import GameEvent from "../Events/GameEvent";
export default abstract class GameNode{
protected eventQueue: EventQueue;
private eventQueue: EventQueue;
protected input: InputReceiver;
protected position: Vec2;
protected size: Vec2;
private receiver: Receiver;
constructor(){
this.eventQueue = EventQueue.getInstance();
this.input = InputReceiver.getInstance();
this.position = new Vec2(0, 0);
this.size = new Vec2(0, 0);
}
getPosition(): Vec2 {
return this.position;
}
getSize(): Vec2 {
return this.size;
subscribe(eventType: string){
this.eventQueue.subscribe(this.receiver, eventType);
}
contains(x: number, y: number): boolean {
if(x > this.position.x && x < this.position.x + this.size.x){
if(y > this.position.y && y < this.position.y + this.size.y){
return true;
}
}
return false;
emit(eventType: string, data: Map<any> | Record<string, any> = null){
let event = new GameEvent(eventType, data);
this.eventQueue.addEvent(event);
}
abstract update(deltaT: number): void;

View File

@ -1,7 +1,7 @@
import GameNode from "./GameNode";
import CanvasNode from "./CanvasNode";
import Vec2 from "../DataTypes/Vec2";
export default class Player extends GameNode{
export default class Player extends CanvasNode{
velocity: Vec2;
speed: number;

View File

@ -1,31 +1,34 @@
import GameNode from "./GameNode";
import CanvasNode from "./CanvasNode";
import Color from "../Utils/Color";
import Vec2 from "../DataTypes/Vec2";
import GameEvent from "../Events/GameEvent";
export default class UIElement extends GameNode{
parent: GameNode;
children: Array<GameNode>;
text: string;
backgroundColor: Color;
export default class UIElement extends CanvasNode{
// Style attributes
textColor: Color;
onPress: Function;
onPressSignal: string;
backgroundColor: Color;
borderColor: Color;
text: string;
font: string;
// EventAttributes
onClick: Function;
onClickEventId: string;
onHover: Function;
onHoverEventId: string;
constructor(){
super();
this.parent = null;
this.children = [];
this.text = "";
this.backgroundColor = new Color(0, 0, 0, 0);
this.textColor = new Color(0, 0, 0, 1);
this.backgroundColor = new Color(0, 0, 0, 0);
this.borderColor = new Color(0, 0, 0, 0);
this.text = "";
this.font = "30px Arial";
this.onPress = null;
this.onPressSignal = null;
this.onClick = null;
this.onClickEventId = null;
this.onHover = null;
this.onHoverEventId = null;
}
setPosition(vecOrX: Vec2 | number, y: number = null): void {
@ -58,7 +61,7 @@ export default class UIElement extends GameNode{
update(deltaT: number): void {
if(this.input.isMouseJustPressed()){
let mousePos = this.input.getMousePressPosition();
let mousePos = this.input.getMousePressPosition();
if(mousePos.x >= this.position.x && mousePos.x <= this.position.x + this.size.x){
// Inside x bounds
if(mousePos.y >= this.position.y && mousePos.y <= this.position.y + this.size.y){
@ -67,12 +70,12 @@ export default class UIElement extends GameNode{
this.onHover();
}
if(this.onPress !== null){
this.onPress();
if(this.onClick !== null){
this.onClick();
}
if(this.onPressSignal !== null){
let event = new GameEvent(this.onPressSignal, {});
this.eventQueue.addEvent(event);
if(this.onClickEventId !== null){
let data = {};
this.emit(this.onClickEventId, data);
}
}
}
@ -83,7 +86,7 @@ export default class UIElement extends GameNode{
ctx.fillStyle = this.backgroundColor.toStringRGBA();
ctx.fillRect(this.position.x - viewportOrigin.x, this.position.y - viewportOrigin.y, this.size.x, this.size.y);
ctx.fillStyle = this.textColor.toStringRGBA();
ctx.font = "30px Arial"
ctx.font = this.font;
ctx.fillText(this.text, this.position.x - viewportOrigin.x, this.position.y - viewportOrigin.y + 30);
}
}

View File

@ -1,15 +1,15 @@
import SceneGraph from "./SceneGraph";
import GameNode from "../Nodes/GameNode";
import CanvasNode from "../Nodes/CanvasNode";
import Viewport from "./Viewport";
export default class SceneGraphArray extends SceneGraph{
private nodeList: Array<GameNode>;
private nodeList: Array<CanvasNode>;
private turnOffViewportCulling_demoTool: boolean;
constructor(viewport: Viewport){
super(viewport);
this.nodeList = new Array<GameNode>();
this.nodeList = new Array<CanvasNode>();
this.turnOffViewportCulling_demoTool = false;
}
@ -17,18 +17,18 @@ export default class SceneGraphArray extends SceneGraph{
this.turnOffViewportCulling_demoTool = bool;
}
addNodeSpecific(node: GameNode, id: string): void {
addNodeSpecific(node: CanvasNode, id: string): void {
this.nodeList.push(node);
}
removeNodeSpecific(node: GameNode, id: string): void {
removeNodeSpecific(node: CanvasNode, id: string): void {
let index = this.nodeList.indexOf(node);
if(index > -1){
this.nodeList.splice(index, 1);
}
}
getNodeAtCoords(x: number, y: number): GameNode {
getNodeAtCoords(x: number, y: number): CanvasNode {
// TODO: This only returns the first node found. There is no notion of z coordinates
for(let node of this.nodeList){
if(node.contains(x, y)){
@ -44,17 +44,17 @@ export default class SceneGraphArray extends SceneGraph{
}
}
getVisibleSet(): Array<GameNode> {
getVisibleSet(): Array<CanvasNode> {
// If viewport culling is turned off for demonstration
if(this.turnOffViewportCulling_demoTool){
let visibleSet = new Array<GameNode>();
let visibleSet = new Array<CanvasNode>();
for(let node of this.nodeList){
visibleSet.push(node);
}
return visibleSet;
}
let visibleSet = new Array<GameNode>();
let visibleSet = new Array<CanvasNode>();
for(let node of this.nodeList){
if(this.viewport.includes(node)){

View File

@ -1,6 +1,7 @@
import Vec2 from "../DataTypes/Vec2";
import Vec4 from "../DataTypes/Vec4";
import GameNode from "../Nodes/GameNode";
import CanvasNode from "../Nodes/CanvasNode";
import MathUtils from "../Utils/MathUtils";
export default class Viewport{
@ -39,7 +40,7 @@ export default class Viewport{
}
}
includes(node: GameNode): boolean {
includes(node: CanvasNode): boolean {
let nodePos = node.getPosition();
let nodeSize = node.getSize();
if(nodePos.x + nodeSize.x > this.position.x && nodePos.x < this.position.x + this.size.x){

View File

@ -20,21 +20,21 @@ function main(){
recordButton.setText("Record");
recordButton.setBackgroundColor(new Color(200, 100, 0, 0.3));
recordButton.setPosition(400, 30);
recordButton.onPressSignal = "record_button_press";
recordButton.onClickEventId = "record_button_press";
let stopButton = new UIElement();
stopButton.setSize(100, 50);
stopButton.setText("Stop");
stopButton.setBackgroundColor(new Color(200, 0, 0, 0.3));
stopButton.setPosition(550, 30);
stopButton.onPressSignal = "stop_button_press";
stopButton.onClickEventId = "stop_button_press";
let playButton = new UIElement();
playButton.setSize(100, 50);
playButton.setText("Play");
playButton.setBackgroundColor(new Color(0, 200, 0, 0.3));
playButton.setPosition(700, 30);
playButton.onPressSignal = "play_button_press";
playButton.onClickEventId = "play_button_press";
let cycleFramerateButton = new UIElement();
cycleFramerateButton.setSize(150, 50);
@ -43,7 +43,7 @@ function main(){
cycleFramerateButton.setPosition(5, 400);
let i = 0;
let fps = [15, 30, 60];
cycleFramerateButton.onPress = () => {
cycleFramerateButton.onClick = () => {
game.setMaxFPS(fps[i]);
i = (i + 1) % 3;
}
@ -53,7 +53,7 @@ function main(){
pauseButton.setText("Pause");
pauseButton.setBackgroundColor(new Color(200, 0, 200, 1));
pauseButton.setPosition(700, 400);
pauseButton.onPress = () => {
pauseButton.onClick = () => {
game.getGameState().addScene(pauseMenu);
}
@ -67,7 +67,7 @@ function main(){
resumeButton.setText("Resume");
resumeButton.setBackgroundColor(new Color(200, 0, 200, 1));
resumeButton.setPosition(400, 200);
resumeButton.onPress = () => {
resumeButton.onClick = () => {
game.getGameState().removeScene();
}